/* ============================================================
   HOMMORA — feuille SOURCE de la coquille. dist/ est une SORTIE.
   Releve fait sur la reference EN LIGNE (hommora.framer.website).

   Trois gestes signent cette mise en page, et rien d'autre ne doit
   les imiter :
   1. LA GRILLE DE FILETS. Quatre gouttieres verticales tres pales
      traversent chaque bloc de haut en bas : la page entiere est
      posee sur un papier reglee. Aucune section n'a de fond propre.
   2. LE REGISTRE. L'offre, les etapes, les atouts ne sont pas des
      cartes : ce sont des rangees et des colonnes separees par des
      filets, numerotees, sans ombre ni cadre.
   3. LA PILULE D'APPEL A CHEVAL. L'appel final est une pilule
      orange posee a cheval sur le bord haut du pied encre : elle
      mord sur les deux fonds a la fois.
   Les photos sont tres arrondies (22px) et montees en mosaique
   decalee, jamais alignees au cordeau.

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

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

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

body {
  margin: 0;
  background: var(--fond);
  color: var(--texte);
  font: 400 17px/1.62 'Inter', system-ui, sans-serif;
  letter-spacing: -0.005em;
  overflow-x: hidden;
}

img { display: block; max-width: 100%; }
a { color: inherit; }
button, input, textarea, select { font: inherit; color: inherit; }

h1, h2, h3, h4 {
  margin: 0;
  font-family: 'Rethink Sans', 'Inter', system-ui, sans-serif;
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.02;
}
h1 { font-size: clamp(44px, 6.4vw, 84px); }
h2 { font-size: clamp(32px, 4.1vw, 56px); }

/* 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(32px, 4.1vw, 56px); }
h3 { font-size: clamp(19px, 1.6vw, 23px); letter-spacing: -0.02em; line-height: 1.2; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

/* --- Ossature ------------------------------------------------ */
.conteneur { width: min(1360px, 100% - 44px); margin-inline: auto; }

/* Le bloc porte la grille de filets : quatre gouttieres verticales
   calees sur la largeur du conteneur, jamais au-dela. */
.bloc { position: relative; padding: 104px 0; }
.bloc::before {
  content: ""; position: absolute; inset: 0;
  width: min(1360px, 100% - 44px); margin-inline: auto;
  background-image: repeating-linear-gradient(to right,
    var(--bordure) 0 1px, transparent 1px 25%);
  opacity: .75; pointer-events: none;
}
.bloc > .conteneur { position: relative; }
.bloc--creme { background: var(--fond-2); }
.bloc--serre { padding: 68px 0; }
.bloc--nu::before { display: none; }

/* --- Lexique commun ------------------------------------------ */
.etiq {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: 15px; color:var(--encre-marque,var(--marque)); font-weight: 500;
}
.etiq::before {
  content: ""; width: 9px; height: 9px; border-radius: 50%;
  background:var(--marque);--sur-bande:var(--sur-marque); flex: 0 0 auto;
}
.tete { max-width: 720px; }
.tete--centre { margin-inline: auto; text-align: center; }
.tete--centre .etiq { justify-content: center; }
.tete h2 { margin-top: 18px; }
.tete__chapo { margin-top: 20px; color: var(--texte-doux); max-width: 620px; }
.tete--centre .tete__chapo { margin-inline: auto; }
.accent { color:var(--encre-marque,var(--marque)); }
.mot { color: var(--texte-doux); }
.mot + .mot { margin-top: 14px; }

.appui {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 15px 28px; border-radius: 999px;
  background:var(--marque);--sur-bande:var(--sur-marque); color:var(--sur-bande,var(--sur-marque));
  font-weight: 600; font-size: 16px; text-decoration: none;
  border: 1px solid var(--marque);
}
.appui:hover { filter: brightness(.93); }
.appui--clair {
  background: var(--fond); color: var(--texte);
  border-color: var(--bordure);
}
.appui--fant { background: transparent; border-color: var(--bordure); color: var(--texte); }

.vue { position: relative; overflow: hidden; border-radius: 22px; background: var(--fond-2); }
.vue::after { content: ""; display: block; padding-top: var(--ratio, 72%); }
.vue img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.vue > span {
  position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: center; padding: 20px; text-align: center;
  font-size: 13px; color: var(--texte-doux); border: 1px dashed var(--bordure);
  border-radius: 22px;
}

.jetons { display: flex; flex-wrap: wrap; gap: 10px; }
.jeton {
  padding: 8px 15px; border-radius: 999px; border: 1px solid var(--bordure);
  font-size: 14px; color: var(--texte-doux); background: var(--fond);
}
.puces { display: grid; gap: 13px; }
.puces li { display: flex; gap: 12px; align-items: baseline; font-size: 16px; }
.puces li::before { content: "\2192"; color:var(--encre-marque,var(--marque)); font-weight: 700; }

/* --- Entete --------------------------------------------------- */
.entete { position: sticky; top: 0; z-index: 60; background: var(--fond); border-bottom: 1px solid var(--bordure); }
.entete__c { display: flex; align-items: center; gap: 24px; padding: 16px 0; }
.entete__marque {
  display: inline-flex; align-items: center; gap: 11px;
  font-family: 'Rethink Sans', sans-serif; font-weight: 800; font-size: 23px;
  letter-spacing: -0.03em; text-decoration: none;
}
.entete__logo {
  width: 34px; height: 34px; border-radius: 11px; object-fit: cover; background: #fff;
  display: inline-block; flex: 0 0 auto;
}
.entete__nav { display: flex; align-items: center; gap: 30px; margin-left: auto; }
/* Le lien occupe TOUTE la hauteur de son entree : plus court, il 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. */
.entete__nav > li { position: relative; display: flex; align-items: stretch; }
.entete__nav > li > a { display: inline-flex; align-items: center; }
.entete__nav a { text-decoration: none; font-size: 16px; font-weight: 500; }
.entete__nav a:hover { color:var(--encre-marque,var(--marque)); }
.entete__act { flex: 0 0 auto; }
.entete__bouton {
  display: none; margin-left: auto; width: 46px; height: 46px;
  border-radius: 14px; border: 1px solid var(--bordure);
  background: var(--fond); font-size: 19px; cursor: pointer;
}

/* Le volet touche le lien (`top: 100%`) : le `calc(100% + 14px)` d'origine
   laissait un vide que la souris traversait en descendant, et le volet se
   refermait avant d'y arriver. Il est CENTRE sous sa tete — cale a gauche, une
   carte large sort de la fenetre des que l'entree est du cote droit. */
.deroul {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%); z-index: 5;
  display: none; align-items: flex-start; gap: 30px; padding: 24px 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 du
     `li`. Sans lui, la carte retombe a son `min-width` et la vitrine en sort. */
  width: max-content; min-width: 560px; max-width: min(94vw, 900px);
  background: var(--fond); border: 1px solid var(--bordure);
  border-radius: 20px; box-shadow: 0 22px 46px rgba(0, 0, 0, .09);
}
.entete__nav > li:hover .deroul, .entete__nav > li:focus-within .deroul { display: flex; }
.deroul__col { min-width: 190px; 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: 14px; overflow: hidden; }
.deroul__vitPh img, .deroul__vitPh > * { 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 .deroul__vitZ { font-size: 14px; font-weight: 600; color:var(--encre-marque,var(--marque)); white-space: normal; }
.deroul__t {
  font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--texte-doux); margin-bottom: 12px;
}
.deroul a { display: block; padding: 6px 0; font-weight: 400; white-space: nowrap; }

/* Quand la page s'ouvre sur l'affiche, l'entete se pose SUR la photo au lieu
   de s'empiler au-dessus : c'est le premier geste visible de la reference.
   Le moteur pose la classe sur <body> quand le premier role est l'affiche.
   Le menu deroulant garde son fond clair, donc son encre reste sombre. */
.a-affiche .entete {
  position: absolute; left: 0; right: 0; top: 0;
  background: transparent; border-bottom: 0; color: var(--fond);
}
.a-affiche .entete a { color: var(--fond); }
.a-affiche .entete__nav a:hover { color: var(--fond); opacity: .72; }
.a-affiche .entete__bouton { background: transparent; border-color: rgba(255, 255, 255, .45); color: var(--fond); }
.a-affiche .entete .deroul a,
.a-affiche .entete--ouvert .entete__nav a { color: var(--texte); }
.a-affiche .entete .deroul a:hover { color:var(--encre-marque,var(--marque)); }

/* --- Ariane --------------------------------------------------- */
.ariane { padding: 22px 0; border-bottom: 1px solid var(--bordure); font-size: 14px; color: var(--texte-doux); }
.ariane ol { display: flex; flex-wrap: wrap; gap: 9px; }
.ariane li + li::before { content: "/"; margin-right: 9px; opacity: .5; }
.ariane a { text-decoration: none; }
.ariane a:hover { color:var(--encre-marque,var(--marque)); }

/* --- Affiche (hero) ------------------------------------------- */
.affiche { position: relative; min-height: min(100vh, 900px); display: flex; align-items: flex-end; color: var(--fond); }
.affiche__fond { position: absolute; inset: 0; overflow: hidden; background: var(--accent); }
.affiche__fond img { width: 100%; height: 100%; object-fit: cover; }
.affiche__fond > span {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 13px; color: rgba(255, 255, 255, .8); padding: 24px; text-align: center;
}
/* En ligne l'affiche est une photo profondement assombrie, traversee par une
   seule lueur de marque montant du coin bas gauche — pas un aplat de couleur.
   Deux couches donc : la lueur en premier plan de pile, la nuit dessous. */
.affiche__voile {
  position: absolute; inset: 0;
  background:
    radial-gradient(64% 78% at 6% 86%, color-mix(in srgb, var(--marque) 62%, transparent) 0%, transparent 68%),
    linear-gradient(100deg, rgba(0, 0, 0, .78) 0%, rgba(0, 0, 0, .60) 48%, rgba(0, 0, 0, .46) 100%);
}
.affiche__c { position: relative; padding: 120px 0 76px; }
/* Le mot de l'affiche se tient A GAUCHE, la ou la lueur de marque monte : le
   panneau garde la largeur du conteneur, ce sont ses lignes qui se bornent. */
.affiche__c > * { max-width: 700px; }
.affiche .etiq { color: var(--fond); }
.affiche .etiq::before { background:var(--marque);--sur-bande:var(--sur-marque); }
.affiche h1 { margin-top: 20px; }
/* Sur fond sombre le titre reste monochrome : la couleur de marque y perdrait
   sa lisibilite et, si la palette du site donne un fond proche du ton de
   marque, le mot mis en avant disparaitrait purement et simplement. */
.affiche .accent { color: inherit; }
.affiche__chapo { margin-top: 24px; max-width: 560px; color: rgba(255, 255, 255, .86); }
.affiche__pied { margin-top: 38px; display: flex; flex-wrap: wrap; gap: 18px 30px; align-items: center; }
.affiche__at { display: flex; flex-wrap: wrap; gap: 10px 22px; font-size: 15px; color: rgba(255, 255, 255, .84); }
.affiche__at li { display: flex; gap: 9px; align-items: baseline; }
.affiche__at li::before { content: "\2726"; color:var(--encre-marque,var(--marque)); }

/* --- Registre (rangees numerotees) ---------------------------- */
.registre { display: flex; flex-wrap: wrap; gap: 40px; align-items: flex-start; margin-top: 54px; }
.registre > * { min-width: 0; }
.registre__liste { flex: 1 1 46%; min-width: min(100%, 380px); }
.rang {
  display: flex; gap: 16px; align-items: baseline;
  padding: 26px 0; border-bottom: 1px solid var(--bordure);
  text-decoration: none;
}
.rang:first-child { border-top: 1px solid var(--bordure); }
.rang__n { font-family: 'Rethink Sans', sans-serif; font-weight: 800; font-size: 22px; color: var(--texte); }
.rang__t { display: block; font-size: clamp(19px, 1.8vw, 25px); font-family: 'Rethink Sans', sans-serif; font-weight: 700; letter-spacing: -0.025em; }
.rang__x { display: block; margin-top: 8px; color: var(--texte-doux); font-size: 16px; }
.rang:hover .rang__t { color:var(--encre-marque,var(--marque)); }
.registre__vue { flex: 1 1 46%; min-width: min(100%, 380px); }
.registre__vue .vue { --ratio: 88%; }

/* --- Colonnes filetees (process, atouts, materiaux…) ---------- */
 /* R3 — une grille n'a qu'une largeur. En `flex: 1 1 30%` la derniere rangee
    s'etire sur ce qui reste : trois colonnes mesuraient 431 px et la
    quatrieme 649, ou 1360. Les pistes sont donc COMPTEES, et le compte
    change au palier, jamais au contenu. */
.colonnes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 34px; margin-top: 56px; }
.colonnes > * { min-width: 0; }
/* Les arguments de `:has()` passent par `:where()` : toutes ces regles pesent
   alors le meme poids et c'est la POSITION qui tranche, jamais un accident de
   specificite. Le compte d'abord, le modificateur ensuite — `--demi` et
   `--quart` disent la largeur voulue et doivent donc gagner. */
.colonnes:has(> :where(:nth-child(4)):where(:last-child)) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.colonnes:has(> :where(:nth-child(2)):where(:last-child)) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.colonnes:has(> :where(:first-child):where(:last-child)) { grid-template-columns: minmax(0, 1fr); }
.colonnes:has(> :where(.colonne--quart)) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.colonnes:has(> :where(.colonne--demi)) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.colonne { min-width: 0; }
.colonne__ic {
  width: 56px; height: 56px; border-radius: 16px; background:var(--marque);--sur-bande:var(--sur-marque);
  color:var(--sur-bande,var(--sur-marque)); display: grid; place-items: center; font-size: 22px;
}
.colonne__fil { height: 1px; background: var(--bordure); margin: 30px 0 26px; }
.colonne__t { font-family: 'Rethink Sans', sans-serif; font-weight: 700; font-size: 21px; letter-spacing: -0.025em; }
.colonne__x { margin-top: 12px; color: var(--texte-doux); font-size: 16px; }
.colonne .puces { margin-top: 16px; }
.colonne__val {
  font-family: 'Rethink Sans', sans-serif; font-weight: 800;
  font-size: clamp(34px, 3.4vw, 46px); letter-spacing: -0.04em;
}

/* --- Mosaique decalee ----------------------------------------- */
.duo { display: flex; flex-wrap: wrap; gap: 46px; align-items: center; }
.duo > * { min-width: 0; }
.duo__mot { flex: 1 1 42%; min-width: min(100%, 340px); }
.duo__vues { flex: 1 1 48%; min-width: min(100%, 340px); display: flex; gap: 22px; }
.duo__vues > * { min-width: 0; flex: 1 1 48%; }
.duo__vues .vue { --ratio: 118%; }
.duo__vues > :first-child { margin-top: 46px; }
.duo--inv .duo__vues { order: -1; }
.duo__chiffres { display: flex; flex-wrap: wrap; gap: 30px; margin-top: 32px; }
.duo__chiffres > * { min-width: 0; }

/* Empilement vertical (mosaique de trois vues) */
.pile { display: flex; flex-direction: column; gap: 22px; }
.pile .vue { --ratio: 66%; }

/* --- Bloc SEO texte + image ----------------------------------- */
.essai { display: flex; flex-wrap: wrap; gap: 52px; align-items: center; }
.essai + .essai { margin-top: 88px; }
.essai > * { min-width: 0; }
.essai__mot { flex: 1 1 46%; min-width: min(100%, 340px); }
.essai__vue { flex: 1 1 44%; min-width: min(100%, 320px); }
.essai__vue .vue { --ratio: 82%; }
.essai--inv .essai__vue { order: -1; }
.essai h2 { margin: 16px 0 22px; }
.essai .appui { margin-top: 28px; }

/* --- Bande immersive (marques, image pleine largeur) ---------- */
.bande { position: relative; overflow: hidden; height: min(46vh, 380px); background: var(--accent); }
.bande img { width: 100%; height: 100%; object-fit: cover; }
.bande > span { position: absolute; inset: 0; display: grid; place-items: center; color: rgba(255, 255, 255, .8); font-size: 13px; }

.logos { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; }
.logos li {
  padding: 13px 24px; border: 1px solid var(--bordure); border-radius: 999px;
  font-size: 15px; color: var(--texte-doux); background: var(--fond);
}

/* --- Cartes a etiquette superposee (realisations, journal) ---- */
/* R3 — pistes comptees, comme les colonnes. */
.cartes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 26px; margin-top: 52px; }
.cartes > * { min-width: 0; }
.cartes:has(> :where(:nth-child(4)):where(:last-child)) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.cartes:has(> :where(:nth-child(2)):where(:last-child)) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cartes:has(> :where(:first-child):where(:last-child)) { grid-template-columns: minmax(0, 1fr); }
.carte {
  min-width: 0;
  background: var(--fond); border: 1px solid var(--bordure);
  border-radius: 22px; overflow: hidden; text-decoration: none;
  display: flex; flex-direction: column;
}
.carte__vue { position: relative; }
.carte__vue .vue { --ratio: 66%; border-radius: 0; }
.carte__vue .vue > span { border-radius: 0; }
.carte__et {
  position: absolute; left: 16px; bottom: 16px; z-index: 2;
  padding: 8px 16px; border-radius: 999px; background: var(--fond);
  font-size: 14px; font-weight: 500;
}
/* Sans visuel, le cadre n'a pas de hauteur : la pastille redevient un element
   de flux, sinon elle depasse et se fait couper par le cadre de la carte. */
.carte__vue:not(:has(.vue)) { padding: 22px 24px 0; }
.carte__vue:not(:has(.vue)) .carte__et { position: static; display: inline-block; }
.carte__c { padding: 22px 24px 26px; display: flex; flex-direction: column; gap: 10px; flex: 1 1 auto; }
.carte__t { font-family: 'Rethink Sans', sans-serif; font-weight: 700; font-size: 20px; letter-spacing: -0.025em; }
.carte__x { color: var(--texte-doux); font-size: 15px; }
.carte__attrs { display: flex; flex-wrap: wrap; gap: 8px 16px; margin-top: auto; padding-top: 16px; font-size: 14px; color: var(--texte-doux); }
.carte:hover .carte__t { color:var(--encre-marque,var(--marque)); }

/* --- Paroles (avis) : pas de carte, juste la grille de filets -- */
/* R3 — pistes comptees, comme les colonnes. */
.dires { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 44px 34px; margin-top: 54px; }
.dires > * { min-width: 0; }
.dires:has(> :where(:nth-child(4)):where(:last-child)) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.dires:has(> :where(:nth-child(2)):where(:last-child)) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.dires:has(> :where(:first-child):where(:last-child)) { grid-template-columns: minmax(0, 1fr); }
.dire { min-width: 0; }
.dire__n { color:var(--encre-marque,var(--marque)); letter-spacing: .16em; font-size: 15px; }
.dire__x { margin-top: 16px; font-size: 17px; }
.dire__qui { display: flex; align-items: center; gap: 13px; margin-top: 22px; }
.dire__av {
  width: 44px; height: 44px; border-radius: 50%; flex: 0 0 auto;
  background: var(--fond-2); border: 1px solid var(--bordure);
  display: grid; place-items: center; font-weight: 700;
}
.dire__nom { font-weight: 600; font-size: 16px; }
.dire__role { font-size: 14px; color: var(--texte-doux); }

/* --- Communes ------------------------------------------------- */
.communes { display: flex; flex-wrap: wrap; gap: 20px; margin-top: 50px; }
.communes > * { min-width: 0; }
.commune {
  flex: 1 1 22%; min-width: min(100%, 230px); text-decoration: none;
  padding-top: 22px; border-top: 2px solid var(--texte);
}
.commune__t { font-family: 'Rethink Sans', sans-serif; font-weight: 700; font-size: 19px; }
.commune__x { margin-top: 8px; font-size: 14px; color: var(--texte-doux); }
.commune:hover { border-top-color:var(--encre-marque,var(--marque)); }
.commune:hover .commune__t { color:var(--encre-marque,var(--marque)); }

/* --- Carte du secteur ----------------------------------------- */
.carto { display: flex; flex-wrap: wrap; gap: 34px; align-items: stretch; margin-top: 46px; }
.carto > * { min-width: 0; }
.carto__vue { flex: 1 1 56%; min-width: min(100%, 340px); }
.carto__vue .vue { --ratio: 58%; height: 100%; }
.carto__vue .vue::after { padding-top: 58%; }
.carto__c {
  flex: 1 1 32%; min-width: min(100%, 280px);
  background: var(--fond); border: 1px solid var(--bordure);
  border-radius: 22px; padding: 32px 30px; align-self: center;
}
.carto__ad { margin-top: 20px; font-size: 16px; }
.carto__ad li + li { margin-top: 5px; }
.carto .jetons { margin-top: 24px; }

/* --- Tarifs --------------------------------------------------- */
.prix {
  flex: 1 1 30%; min-width: min(100%, 290px);
  border-top: 2px solid var(--texte); padding-top: 26px;
}
.prix__v { font-family: 'Rethink Sans', sans-serif; font-weight: 800; font-size: 40px; letter-spacing: -0.04em; margin-top: 12px; }
.prix__u { font-size: 15px; color: var(--texte-doux); font-weight: 400; letter-spacing: 0; }
.prix__x { margin-top: 14px; color: var(--texte-doux); font-size: 16px; }
.prix .puces { margin-top: 18px; }
.prix .appui { margin-top: 24px; }
.mention { margin-top: 32px; font-size: 14px; color: var(--texte-doux); }

/* --- 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: 26px 44px; 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 20px; border-radius: 999px;
  border: 1px solid var(--bordure); background: var(--fond);
  font-size: 15px; 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(--marque);--sur-bande:var(--sur-marque); border-color:var(--encre-marque,var(--marque)); color:var(--sur-bande,var(--sur-marque)); }

.carte__bas {
  display: flex; flex-wrap: wrap; gap: 14px 18px;
  align-items: center; justify-content: space-between;
  margin-top: auto; padding-top: 18px; border-top: 1px solid var(--bordure);
}
.carte__bas > * { min-width: 0; }
.carte__bas .appui { margin-top: 0; }
.carte__prix { font-family: 'Rethink Sans', sans-serif; font-weight: 800; font-size: 26px; letter-spacing: -0.03em; }
.dep { display: block; font-size: 13px; color: var(--texte-doux); }

.duo--haut { align-items: flex-start; }
.fiche__vue { flex: 1 1 48%; min-width: min(100%, 340px); }
.fiche__dep { margin-top: 26px; }
.colonne__val--menu { font-size: clamp(24px, 2.2vw, 30px); }
/* Un libelle long ne pousse jamais l'appel hors de sa colonne. */
.appui { max-width: 100%; overflow-wrap: anywhere; }

/* --- Bande d'urgence ------------------------------------------ */
.veille {
  background: var(--accent); color: var(--fond); border-radius: 26px;
  padding: 44px 46px; display: flex; flex-wrap: wrap; gap: 30px; align-items: center;
}
.veille > * { min-width: 0; }
.veille__mot { flex: 1 1 52%; min-width: min(100%, 320px); }
.veille .etiq { color: var(--fond); }
.veille h2 { margin-top: 16px; font-size: clamp(26px, 2.8vw, 38px); }
.veille__x { margin-top: 16px; color: rgba(255, 255, 255, .84); }
.veille__act { flex: 1 1 30%; min-width: min(100%, 260px); display: flex; flex-direction: column; gap: 14px; align-items: flex-start; }
.veille__tel {
  font-family: 'Rethink Sans', sans-serif; font-weight: 800; font-size: 30px;
  letter-spacing: -0.03em; text-decoration: none;
}
.veille .puces li { color: rgba(255, 255, 255, .84); }

/* --- Avant / apres : decoupe HORIZONTALE ---------------------- */
.jauge { position: relative; border-radius: 26px; overflow: hidden; --pos: 50%; }
.jauge__vue { position: relative; }
.jauge__vue .vue { --ratio: 62%; border-radius: 0; }
.jauge__vue--avant { position: absolute; inset: 0; clip-path: inset(0 0 calc(100% - var(--pos)) 0); }
.jauge__vue--avant .vue::after { padding-top: 0; }
.jauge__vue--avant .vue { position: absolute; inset: 0; }
.jauge__barre {
  position: absolute; left: 0; right: 0; top: var(--pos); height: 2px;
  background: var(--fond); z-index: 3; pointer-events: none;
}
.jauge__poignee {
  position: absolute; left: 50%; top: var(--pos); transform: translate(-50%, -50%); z-index: 4;
  width: 52px; height: 52px; border-radius: 50%; background: var(--fond);
  color:var(--encre-marque,var(--marque)); display: grid; place-items: center; font-size: 19px;
  box-shadow: 0 8px 22px rgba(0, 0, 0, .18);
}
.jauge__range {
  position: absolute; right: 18px; top: 0; z-index: 4;
  writing-mode: vertical-lr; width: 44px; height: 100%;
  margin: 0; background: transparent; cursor: ns-resize; opacity: 0;
}
.jauge__lab {
  position: absolute; left: 18px; z-index: 3; padding: 7px 15px;
  border-radius: 999px; background: var(--fond); font-size: 14px; font-weight: 500;
}
.jauge__lab--avant { top: 18px; }
.jauge__lab--apres { bottom: 18px; }
.ab { display: flex; flex-wrap: wrap; gap: 40px; align-items: center; margin-top: 50px; }
.ab > * { min-width: 0; }
.ab__vue { flex: 1 1 54%; min-width: min(100%, 320px); }
.ab__mot { flex: 1 1 34%; min-width: min(100%, 280px); }
.ab__mot .jetons { margin-top: 20px; }

/* --- Questions ------------------------------------------------ */
.questions { display: flex; flex-wrap: wrap; gap: 44px; align-items: flex-start; }
.questions > * { min-width: 0; }
.questions__tete { flex: 1 1 32%; min-width: min(100%, 300px); position: sticky; top: 104px; }
.questions__liste { flex: 1 1 56%; min-width: min(100%, 340px); display: grid; gap: 16px; }
.question {
  background: var(--fond); border: 1px solid var(--bordure);
  border-radius: 20px; padding: 6px 26px;
}
.question summary {
  display: flex; gap: 18px; align-items: center; justify-content: space-between;
  padding: 22px 0; cursor: pointer; list-style: none;
  font-family: 'Rethink Sans', sans-serif; font-weight: 700; font-size: 19px; letter-spacing: -0.02em;
}
.question summary::-webkit-details-marker { display: none; }
.question__s {
  width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--bordure);
  display: grid; place-items: center; flex: 0 0 auto; font-size: 17px; color: var(--texte-doux);
}
.question[open] .question__s { background:var(--marque);--sur-bande:var(--sur-marque); color:var(--sur-bande,var(--sur-marque)); border-color:var(--encre-marque,var(--marque)); }
.question__r { padding: 0 0 24px; color: var(--texte-doux); max-width: 70ch; }

/* --- Formulaires ---------------------------------------------- */
.form { display: grid; gap: 16px; }
.champ { display: grid; gap: 8px; }
.champ span { font-size: 14px; color: var(--texte-doux); }
.champ input, .champ textarea, .champ select {
  width: 100%; padding: 15px 18px; border-radius: 14px;
  border: 1px solid var(--bordure); background: var(--fond); color: var(--texte);
}
.champ textarea { min-height: 128px; resize: vertical; }
.champ input:focus, .champ textarea:focus { outline: 2px solid var(--marque); outline-offset: 1px; }

.contact { display: flex; flex-wrap: wrap; gap: 46px; align-items: flex-start; }
.contact > * { min-width: 0; }
.contact__mot { flex: 1 1 38%; min-width: min(100%, 300px); }
.contact__form {
  flex: 1 1 52%; min-width: min(100%, 320px);
  background: var(--fond); border: 1px solid var(--bordure);
  border-radius: 26px; padding: 36px 34px;
}
.coord { display: grid; gap: 22px; margin-top: 34px; }
.coord__t { font-weight: 600; }
.coord__l { color: var(--texte-doux); font-size: 16px; }

/* --- Article -------------------------------------------------- */
.article { display: flex; flex-wrap: wrap; gap: 46px; align-items: flex-start; }
.article > * { min-width: 0; }
.article__c { flex: 1 1 58%; min-width: min(100%, 340px); }
.article__som {
  flex: 1 1 26%; min-width: min(100%, 250px); position: sticky; top: 104px;
  border-top: 2px solid var(--texte); padding-top: 22px;
}
.article__som li { padding: 7px 0; }
.article__som a { text-decoration: none; color: var(--texte-doux); font-size: 15px; }
.article__som a:hover { color:var(--encre-marque,var(--marque)); }
.article__vue { margin: 34px 0; }
.article__vue .vue { --ratio: 54%; }
.article h2 { font-size: clamp(26px, 2.6vw, 34px); margin: 42px 0 18px; }
.article .puces { margin: 20px 0; }
.article__meta { color: var(--texte-doux); font-size: 15px; margin-top: 16px; }

.legal { max-width: 78ch; }
.legal h3 { margin: 36px 0 14px; font-size: 21px; }
.legal__maj { color: var(--texte-doux); font-size: 15px; margin-top: 14px; }

/* --- Appel final : la plaque a cheval sur le pied --------------
   En ligne c'est une plaque courte, a angles doucement casses (pas un
   stade), qui mord le bord haut du pied sur environ un tiers de sa
   hauteur. Elle ne s'etale jamais sur toute la largeur. */
.appel { position: relative; z-index: 2; margin-bottom: -34px; display: flex; justify-content: center; }
.appel__c {
  background:var(--marque);--sur-bande:var(--sur-marque); color:var(--sur-bande,var(--sur-marque));
  border-radius: 22px; padding: 26px 54px; max-width: min(940px, 100% - 44px);
  display: flex; flex-wrap: wrap; gap: 18px 34px; align-items: center; justify-content: center;
  text-align: center;
}
.appel__t { font-family: 'Rethink Sans', sans-serif; font-weight: 800; font-size: clamp(21px, 2.3vw, 32px); letter-spacing: -0.03em; }
.appel .appui { background: var(--fond); color: var(--texte); border-color: var(--fond); }
.appel__form { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
.appel__form > * { min-width: 0; }
.appel__form input, .appel__form textarea {
  flex: 1 1 30%; min-width: min(100%, 180px);
  padding: 13px 18px; border-radius: 999px; border: 1px solid transparent;
  background: var(--fond); color: var(--texte);
}
.appel__form textarea { border-radius: 22px; min-height: 52px; }

/* --- Pied ----------------------------------------------------- */
/* Le pied de la reference est une nuit profonde, pas un aplat de couleur vive :
   dans un socle a huit jetons, la seule surface sombre disponible est --texte.
   Son encre est donc --fond, exactement l'inverse du corps de page. */
.pied { background:var(--texte);--sur-bande:var(--sur-texte,var(--fond)); color: var(--fond); padding: 96px 0 34px; }
.pied__h { display: flex; flex-wrap: wrap; gap: 46px; }
.pied__h > * { min-width: 0; }
.pied__mot { flex: 1 1 36%; min-width: min(100%, 300px); }
.pied__mot h2 { font-size: clamp(26px, 2.6vw, 38px); }
.pied__x { margin-top: 18px; color: rgba(255, 255, 255, .74); font-size: 16px; }
.pied__cols { flex: 1 1 52%; min-width: min(100%, 300px); display: flex; flex-wrap: wrap; gap: 34px; }
.pied__cols > * { min-width: 0; }
.pied__col { flex: 1 1 28%; min-width: min(100%, 170px); }
.pied__t { font-weight: 600; margin-bottom: 16px; }
.pied__col li { padding: 6px 0; }
.pied__col a, .pied__nap li { color: rgba(255, 255, 255, .74); text-decoration: none; font-size: 16px; }
.pied__col a:hover { color: var(--fond); }
.pied__nap li { display: flex; gap: 10px; padding: 6px 0; }
.pied__bas {
  display: flex; flex-wrap: wrap; gap: 16px 30px; align-items: center; justify-content: space-between;
  margin-top: 66px; padding-top: 26px; border-top: 1px solid rgba(255, 255, 255, .16);
  font-size: 14px; color: rgba(255, 255, 255, .62);
}
.pied__liens { display: flex; flex-wrap: wrap; gap: 22px; }
.pied__liens a { text-decoration: none; }

/* --- Appoints : les habits des morceaux que le socle fournit et que la
       reference ne montrait pas — second appel, libelle de lien, vignette
       de puce, encadre de rappel. ---------------------------------- */
.actes { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; margin-top: 34px; }
.actes > * { min-width: 0; }
.appui--nu { background: transparent; color: var(--texte); border-color: var(--bordure); }

/* Regle 7 : la porte d'appel se pose aux points de conversion, sur la pilule
   de marque comme sur un fond clair. Elle ne fixe donc NI son encre NI son
   filet : elle lit le courant, et reste lisible partout ou la paire se pose.
   La surcharge par emplacement vit apres le bloc generique — meme
   specificite, c'est la position qui tranche. */
.appui--cote { background: transparent; color: inherit; border-color: currentColor; }
.appel .appui--cote { background: transparent; color: inherit; border-color: currentColor; }
/* La paire de cloture vit DANS une boite deja espacee : elle ne rouvre pas
   la marge haute des rangees d'appels de section. */
.actes--cote { margin-top: 0; justify-content: center; }
.contact__form .actes--cote { margin-top: 18px; justify-content: flex-start; }

/* Un atout peut porter un nom, un propos et ses precisions : la puce
   passe alors en colonne, sans quitter la ligne des atouts simples. */
.affiche__at li:has(b) { flex: 1 1 40%; min-width: min(100%, 250px); display: block; }
.affiche__at li:has(b)::before { display: none; }
.affiche__at b { display: block; color: #fff; }
.affiche__at em { display: block; margin-top: 3px; font-style: normal; opacity: .8; }

.rang__l {
  display: block; margin-top: 8px; font-size: 12px; letter-spacing: .1em;
  text-transform: uppercase; color:var(--encre-marque,var(--marque));
}

/* La vignette de commune reste minuscule : la ligne demeure une ligne. */
.commune__v { width: 34px; height: 34px; margin-bottom: 12px; }
.commune__v .vue { width: 34px; height: 34px; border-radius: 999px; }
.commune__v .vue::before { display: none; }
.commune__v .vue span { font-size: 0; }
.commune__v img { width: 100%; height: 100%; object-fit: cover; }

.colonne__v { margin: 14px 0 4px; }
.colonne__v .vue { border-radius: 14px; }

.lecture { margin-top: 26px; max-width: 68ch; }

.rappel {
  margin-top: 26px; padding: 24px 26px; background: var(--fond);
  border: 1px solid var(--bordure); border-radius: 22px;
}
.rappel .actes { margin-top: 18px; }
.bloc--creme .rappel { background: var(--fond); }

.appel__vue { flex: 1 1 240px; min-width: 0; }
.appel__vue .vue { border-radius: 22px; }

/* --- Replis --------------------------------------------------- */
@media (max-width: 1000px) {
  .entete__nav {
    display: none; position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: stretch; gap: 0; padding: 14px 22px 24px;
    background: var(--fond); border-bottom: 1px solid var(--bordure);
  }
  .entete--ouvert .entete__nav { display: flex; }
  /* Au doigt, le volet est a plat sous sa tete : l'entree redevient une colonne. */
  .entete__nav > li { padding: 10px 0; display: block; }
  .entete__bouton { display: block; }
  .entete__act { display: none; }
  .deroul {
    position: static; transform: none; display: flex; flex-direction: column; gap: 14px;
    padding: 12px 0 0; border: 0; box-shadow: none; border-radius: 0;
    width: auto; min-width: 0; max-width: none;
  }
  /* 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; }
  .questions__tete, .article__som { position: static; }
  .duo__vues > :first-child { margin-top: 0; }
  /* R3 au palier tablette : le compte de pistes descend, il ne se devine pas.
     Les surcharges par compte d'enfants sont reprises ici, sinon la regle a
     quatre pistes du bloc generique resterait gagnante. */
  .colonnes, .cartes, .dires,
  .colonnes:has(> :where(:nth-child(4)):where(:last-child)),
  .cartes:has(> :where(:nth-child(4)):where(:last-child)),
  .dires:has(> :where(:nth-child(4)):where(:last-child)),
  .colonnes:has(> :where(.colonne--quart)) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .colonnes:has(> :where(:first-child):where(:last-child)),
  .cartes:has(> :where(:first-child):where(:last-child)),
  .dires:has(> :where(:first-child):where(:last-child)) { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 720px) {
  body { font-size: 16px; }
  .conteneur, .bloc::before { width: min(1360px, 100% - 30px); }
  .bloc { padding: 66px 0; }
  .bloc--serre { padding: 48px 0; }
  .bloc::before { background-image: repeating-linear-gradient(to right, var(--bordure) 0 1px, transparent 1px 50%); }
  .affiche__c { padding: 88px 0 56px; }
  .veille, .contact__form, .appel__c { padding: 28px 24px; border-radius: 22px; }
  .appel { margin-bottom: -26px; }
  .pied { padding: 74px 0 28px; }
  .essai + .essai { margin-top: 58px; }
  .registre, .duo, .essai, .ab, .questions, .contact, .article, .carto { gap: 30px; }
  /* Au doigt, une seule piste : toute autre valeur donnerait des colonnes de
     moins de sept cadratins (T5). */
  .colonnes, .cartes, .dires,
  .colonnes:has(> :where(:nth-child(2)):where(:last-child)), .cartes:has(> :where(:nth-child(2)):where(:last-child)), .dires:has(> :where(:nth-child(2)):where(:last-child)),
  .colonnes:has(> :where(:nth-child(4)):where(:last-child)), .cartes:has(> :where(:nth-child(4)):where(:last-child)), .dires:has(> :where(:nth-child(4)):where(:last-child)),
  .colonnes:has(> :where(.colonne--quart)), .colonnes:has(> :where(.colonne--demi)) { grid-template-columns: minmax(0, 1fr); }
}

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

/* SIGNATURE — la REVELATION PAR LE BAS. Le modele ne pose jamais un voile
   plein sur une photo : il DECOUPE une pellicule claire montante par
   `clip-path: inset(0 0 N%)`, et il change la hauteur de coupe d une vue a
   l autre (30, 40, 50 et 60 pour cent, une occurrence chacune). La photo
   s eclaircit vers le bas la ou les autres modeles assombrissent. Chaque
   vue garde donc sa propre hauteur de coupe, jamais une valeur unique. */
.registre__vue .vue::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg, transparent 0%, var(--fond) 54%, var(--fond) 100%);
  opacity: .30; clip-path: inset(50% 0 0 0);
}
.essai__vue .vue::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg, transparent 0%, var(--fond) 54%, var(--fond) 100%);
  opacity: .26; clip-path: inset(60% 0 0 0);
}
.duo__vues > :first-child .vue::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg, transparent 0%, var(--fond) 54%, var(--fond) 100%);
  opacity: .32; clip-path: inset(40% 0 0 0);
}
.carte__vue .vue::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg, transparent 0%, var(--fond) 54%, var(--fond) 100%);
  opacity: .24; clip-path: inset(70% 0 0 0);
}

/* SIGNATURE — la bande d image APPARAIT PAR LE BAS : elle ne commence pas
   net en tete, elle se leve d un masque en degre. Le modele pose ce fondu
   `transparent 0 -> plein` une fois, sur son seul bandeau plein cadre. */
.bande img {
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 22%, #000 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 22%, #000 100%);
}

/* SIGNATURE — la file de logos s efface aux deux bouts : la rangee n a pas
   de fin franche, elle se dissout dans le fond de part et d autre. */
.logos {
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 6%, #000 94%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 6%, #000 94%, transparent 100%);
}

/* SIGNATURE — le volet deroulant PEND sous la barre : coins bas seuls
   arrondis, coins hauts vifs (`0 0 12px 12px`, releve deux fois). Le
   panneau se lit comme la suite de l en-tete, pas comme une carte flottante. */
.deroul { border-radius: 0 0 20px 20px; }

/* SIGNATURE — l ombre est PLATE et courte (`0 4px 12px` a 4 pour cent,
   trois occurrences) : le modele pose des blocs a peine decolles du fond,
   jamais un halo profond. */
.carte, .commune, .carto__c {
  box-shadow: 0 4px 12px color-mix(in srgb, var(--texte) 4%, transparent);
}

/* contraste-source — bandes sombres : chacune declare son encre (--sur-bande) ; marque en texte : --encre-marque. */
/* contraste-bandes (2026-09-14) — marque et aplats utilises comme porteurs de TEXTE.
   Les encres lisent des jetons CALCULES dans shell/render.mjs : --encre-marque (encreLisible contre
   --fond puis --fond-2, meme teinte assombrie seulement si la palette ne passe pas 4,5:1) et
   --sur-accent (encreSur de l accent). La marque brute reste la marque pour les aplats et CTA. */

/* Bouton d appel de l en-tete pose sur l affiche : `.a-affiche .entete a { color: var(--fond) }`
   (0,2,1) ecrasait `.appui { color: var(--sur-marque) }` (0,1,0). L intention ecrite est l encre de
   l APLAT de marque : on la restaure. Demo 2 (or #B57505) : blanc 3,81 -> #101010 ~4,9. */
.a-affiche .entete .appui { color: var(--sur-marque); }

/* Etiquettes de section sur les bandes claires (--fond, --fond-2 creme).
   Demo 2 : 3,81 (blanc) / 3,38 (creme) -> 4,5 et plus. */
.bloc .etiq { color: var(--encre-marque); }

/* Lien « Voir la prestation » du registre de prestations, sur bande blanche. Demo 2 : 3,81 -> 4,5+. */
.bloc .rang .rang__l { color: var(--encre-marque); }

/* Etoiles d avis (arbitrage Mixte : encre assombrie en gardant la teinte, pas un decor), dans la
   bande creme. Demo 2 : 3,38 -> 4,5 et plus. */
.bloc .dire .dire__n { color: var(--encre-marque); }

/* Bande d urgence : APLAT d accent. Son encre etait l encre claire du fond (--fond, blanc a 84 %),
   posee comme si l accent etait sombre. Elle suit desormais l encre calculee de l aplat.
   Demo 2 (orange #FA9727) : etiquette, titre et telephone 2,21 ; texte et puces 1,95 -> ~8,6 / ~6,8.
   Spécificite (0,3,0) : passe devant `.bloc .etiq` ci-dessus. */
.bloc .veille { color: var(--sur-accent); }
.bloc .veille .etiq,
.bloc .veille h2,
.bloc .veille .veille__tel { color: var(--sur-accent); }
.bloc .veille .veille__x,
.bloc .veille .puces li { color: color-mix(in srgb, var(--sur-accent) 84%, transparent); }

/* >>> 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-09-15 sur 1 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.

   Et il se tait EN ENTIER : une legende dessinee en pastille (fond, padding,
   ombre) laissait, a font-size 0, une plaquette claire vide sur le cadre
   sombre, lue 2,07 puis 4,40 par le gate voile (template-1, 14 et 15 sept).
   Seuls les enfants qui portent du texte perdent leur habillage : la trame
   et les decors vides du cadre restent. */
[data-slot="vue--hero"]:not(:has(img)):not(:has(video)) {
  --cadre-vide-fond: #575757;
  --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--hero"]:not(:has(img)):not(:has(video)) > * {
  font-size: 0 !important;
}
[data-slot="vue--hero"]:not(:has(img)):not(:has(video)) > *:not(:empty) {
  background: transparent !important;
  padding: 0 !important;
  border-color: transparent !important;
  box-shadow: none !important;
}
/* <<< NORME COQUILLE — teinte des cadres porteurs */
