/* ════════════════════════════════════════════════════════════════════════════
   FrioSoft — feuille de la vitrine, écrite le 2026-08-27.
   Registre : SITE PRODUIT SaaS, transposé de la vitrine NuisiSoft.

   Les mécanismes du registre, conservés :
   · fond clair, grands titres grotesques centrés, sous-titre doux ;
   · étiquettes, navigation et boutons en chasse fixe MAJUSCULE ;
   · un seul accent d'action ;
   · chapitres SOMBRES ouverts par une transition en dégradé, refermés par le
     pied en dégradé ;
   · les pièces du produit sont les vedettes, dans des cartes arrondies.

   Ce qui change par rapport à NuisiSoft, et pourquoi :
   · le fond passe du crème chaud au BLANC GIVRÉ — le sujet est le froid ;
   · l'accent d'action passe du jaune ambre au TURQUOISE GLACÉ ;
   · l'aube monte en BLEU GLACIER, le couchant descend en AURORE (teal),
     là où NuisiSoft montait en violet et descendait en ambre.

   Ce qui ne change pas : zéro ressource tierce (CSP), polices auto-hébergées,
   contrastes tenus, aucune donnée réelle dans les maquettes.

   ⚠️ Le vert, l'ambre et le rouge sont RÉSERVÉS AUX ÉTATS. Les employer comme
   couleur de catégorie fait lire une alerte là où il n'y a qu'une famille.
   ════════════════════════════════════════════════════════════════════════ */

@font-face {
  font-family: 'Archivo';
  src: url('../assets/fonts/archivo-latin.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  src: url('../assets/fonts/archivo-latin-ext.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1EFF, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../assets/fonts/ibmplexmono-400-latin.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../assets/fonts/ibmplexmono-400-latin-ext.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1EFF, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --fond: #F5F6F8;
  --fond-2: #E9ECF1;
  --encre: #14161C;
  --encre-2: #575E6B;
  /* Le gris des références en tête de page — il PORTE du texte, il tient donc
     4,5:1 sur `--fond` comme sur `--blanc`. Le #8E95A2 d'origine n'en donnait
     que 2,7 : il était écrit en dur, donc invisible à `contraste.py`.
     ⚠️ #6B7280, le gris « neutre-500 » de tout le monde, ne donne que 4,471
     sur ce fond : à trente millièmes du seuil, et donc sous le seuil. Un
     chiffre qu'on n'a pas recalculé sur SON fond ne prouve rien. */
  --encre-3: #686E7A;
  --filet: #DDE2EA;
  /* ⚠️ La limite d'un CHAMP est un élément d'interface, pas une séparation
     décorative : WCAG 1.4.11 exige 3:1. `--filet` n'en donne que 1,30. Et la
     valeur doit passer des DEUX côtés du filet — sur le blanc de la carte
     comme sur `--fond`, qui est le remplissage du champ : #8A92A0 donnait
     3,13:1 sur le blanc mais 2,90:1 sur le fond, donc non.
     #828A98 : 3,54:1 sur le blanc, 3,27:1 sur --fond. */
  --filet-champ: #828A98;
  --nuit: #05070D;
  --nuit-carte: #0D1017;
  --nuit-filet: rgba(255, 255, 255, .09);
  --blanc: #FFFFFF;
  --sur-nuit: #C3C8D6;
  --sur-nuit-2: #8A90A1;
  /* L'accent d'action, et il n'y en a qu'un. */
  /* ⚠️ L'ACCENT D'ACTION, et il est le même que celui de l'ERP.
     Avant le 2026-08-27, la vitrine peignait en turquoise le bouton « Suivant »
     de l'écran terrain qu'elle met en démonstration — alors que le vrai bouton
     est indigo. Le seul geste que la démonstration enseignait était peint dans
     une teinte que le produit n'emploie nulle part : le jour où un prospect
     serait passé de la page à l'application, la couleur qui veut dire
     « agissez » aurait changé de sens.
     Blanc sur #2F35C9 = 8,49:1. Voir docs/charte-friosoft.md, décision 01. */
  --sonde: #2F35C9;
  --sonde-2: #262BAA;
  --sonde-pale: #E9EAFF;
  --sonde-filet: #C9C8FF;

  /* Le turquoise reste — mais plus jamais pour une action. Il garde ses deux
     autres rôles : marqueur d'état sur la frise, et aplat de surface. */
  --indigo: #6260FF;
  --indigo-clair: #A9A0FF;
  --indigo-pale: #ECEBFF;
  --bleu: #2E7DFF;
  --bleu-pale: #E4EEFF;
  /* Couleurs d'état — jamais employées comme couleur de catégorie. */
  /* Le résultat d'un calcul, sur le lavis de sélection. Assez sombre pour
     porter du texte là où `--vert-ok` ne tiendrait pas son seuil. */
  --vert-sortie: #0C7671;
  --vert-ok: #1BAF7A;
  --vert-pale: #E0F3EA;
  --ambre: #D98A0B;
  --ambre-pale: #FBF0D8;
  --orange: #EB6834;
  --orange-pale: #FCE7DD;
  --font-sans: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --font-mono: 'IBM Plex Mono', 'Courier New', monospace;
}

/* ── Socle ─────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; background: #000; }
body {
  margin: 0;
  background: var(--fond);
  color: var(--encre);
  font-family: var(--font-sans);
  font-size: 1.125rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* ⚠️ Sans cela, une page courte — la confirmation d'envoi du formulaire,
     la page d'erreur, la 404 — laisse voir le `background: #000` de <html>
     (l. 89) sous le pied de page : 565 px de noir sur 844. C'est l'écran que
     voit le prospect juste après avoir envoyé sa demande. Ne PAS retirer le
     noir de <html> pour autant : `.pied` (l. 1027) est noir et compte dessus
     pendant le rebond de défilement. `svh` pour le navigateur mobile, dont la
     barre d'adresse fausse `vh`. */
  min-height: 100vh;
  min-height: 100svh;
  /* Le pied est poussé en bas plutôt que suivi d'un vide : `min-height` seul
     remplacerait 565 px de noir par 565 px de gris, ce qui reste un trou. */
  display: flex;
  flex-direction: column;
}
body > .pied { margin-top: auto; }
img { display: block; max-width: 100%; height: auto; }
figure, p, h1, h2, h3, ol, ul, dl { margin: 0; }
p + p { margin-top: 1em; }
::selection { background: var(--sonde); color: var(--blanc); }
:focus-visible { outline: 2px solid var(--sonde); outline-offset: 3px; border-radius: 2px; }
a, button, summary, .btn {
  transition: color .16s ease, background-color .16s ease, border-color .16s ease,
              transform .16s ease, box-shadow .16s ease, opacity .16s ease;
}
@media (prefers-reduced-motion: reduce) {
  /* ⚠️ Le `!important` n'est pas une facilité, il est la règle elle-même.
     Sans lui ce bloc ne coupe RIEN : le sélecteur universel pèse 0,0,0 et perd
     contre chacune des quatre animations infinies du site, toutes portées par
     une classe (.tel__ligne l. 674, et les trois autres maquettes). La
     mitigation était déclarée et inerte — c'est pire qu'absente, parce qu'elle
     se croit faite. WCAG 2.2.2 « Pause, Stop, Hide », niveau A.
     `animation-iteration-count` est indispensable : une animation infinie
     raccourcie à .01ms reste infinie, elle clignote juste plus vite. */
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

/* ── Typo ──────────────────────────────────────────────────────────────── */
h1 {
  font-size: clamp(2.5rem, 5.6vw, 5rem);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -.028em;
  text-wrap: balance;
}
h2 {
  font-size: clamp(1.9rem, 3.4vw, 3.1rem);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -.022em;
  text-wrap: balance;
}
h3 { font-size: 1.55rem; font-weight: 500; line-height: 1.2; letter-spacing: -.014em; }
.sous {
  font-size: clamp(1.1rem, 1.5vw, 1.3rem);
  line-height: 1.55;
  color: var(--encre-2);
  max-width: 46em;
}
a { color: inherit; }
em.souligne {
  font-style: normal;
  text-decoration: underline;
  text-decoration-color: var(--sonde);
  text-decoration-thickness: 7px;
  text-underline-offset: 6px;
  text-decoration-skip-ink: none;
}
main p a, main li a, footer a { text-underline-offset: 3px; }
main p a, main li a, main dd a { padding-block: 3px; }
.petit a { padding-block: 5px; }

/* L'étiquette en chasse fixe majuscule : navigation, boutons, puces de
   chapitre — la signature typographique du registre. */
.mono {
  font-family: var(--font-mono);
  font-size: .8125rem;
  letter-spacing: .08em;
  text-transform: uppercase;
}

/* ── Boutons ───────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 46px;
  padding: 0 22px;
  background: var(--sonde);
  color: var(--blanc);
  border: 0;
  border-radius: 9px;
  font-family: var(--font-mono);
  font-size: .8125rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}
.btn::after { content: '→'; font-family: var(--font-sans); font-size: 1rem; transition: transform .16s ease; }
.btn:hover { background: var(--sonde-2); }
.btn:hover::after { transform: translateX(3px); }
.btn--grand { min-height: 52px; padding: 0 28px; }

.lien-mono {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: .8125rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-decoration: underline dotted;
  text-underline-offset: 6px;
  color: inherit;
  min-height: 44px;
}
.lien-mono::after { content: '→'; font-family: var(--font-sans); }
.lien-mono:hover { color: var(--sonde); }

/* La puce de chapitre : un carré coloré + une étiquette, dans une gélule. */
.puce {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 9px 16px;
  border: 1px solid var(--nuit-filet);
  border-radius: 9px;
  background: rgba(255, 255, 255, .04);
  color: var(--blanc);
}
.puce::before { content: ''; width: 9px; height: 9px; border-radius: 2.5px; background: var(--sonde); }
.puce--claire { border-color: var(--filet); background: var(--blanc); color: var(--encre); }
.puce--indigo::before { background: var(--indigo); }
.puce--bleue::before { background: var(--bleu); }
.puce--verte::before { background: var(--vert-ok); }
.puce--orange::before { background: var(--orange); }

/* Le carré de couleur : chaque famille du produit a le sien. */
.pip { display: inline-block; width: 9px; height: 9px; border-radius: 2.5px; background: var(--sonde); flex: none; }
.pip--sonde { background: var(--sonde); }
.pip--indigo { background: var(--indigo); }
.pip--bleu { background: var(--bleu); }
.pip--vert { background: var(--vert-ok); }
.pip--orange { background: var(--orange); }

/* ── Bandeau d'annonce ─────────────────────────────────────────────────── */
.bandeau {
  background: var(--encre);
  color: var(--fond);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 10px 16px;
  font-size: .95rem;
  flex-wrap: wrap;
  text-align: center;
}
.bandeau__chip {
  display: inline-flex;
  align-items: center;
  padding: 5px 12px;
  border-radius: 7px;
  background: var(--fond-2);
  color: var(--encre);
  text-decoration: none;
  min-height: 30px;
}
.bandeau__chip:hover { background: var(--blanc); }

/* ── Le « o » de SOFT est un ventilateur ────────────────────────────────
   ⚠️ Ces cotes ne se règlent pas à l'œil : elles sont celles du VRAI « o »
   d'Archivo 700, mesuré au pixel sur un rendu à 200 px — 107,3 de large,
   110,1 de haut, débord de 2,4 sous la ligne de base, approche latérale 7,65.
   Rapportées à l'em : 0,5365 × 0,5505, débord 0,012, approche 0,0383.

   Le glyphe fait 100 % de cette boîte. Essayé à 104 % et à 108 % : il bombe,
   domine ses voisines et casse le rythme du mot. Un « o » substitué doit tenir
   sa place, pas la prendre.

   Il n'y a plus d'icône à côté du mot : les pales SONT dans le mot. La marque
   seule (assets/favicon.svg) ne sert que là où il n'y a pas de texte. */
.o-pales {
  display: inline-block;
  width: .5365em;
  height: .5505em;
  vertical-align: -.012em;
  margin: 0 .0383em;
}
/* 700 et non 600 : c'est la graisse sur laquelle le glyphe a été calibré, et
   le « o » d'Archivo n'a pas la même chasse d'une graisse à l'autre. */
.tete__logo .nom, .pied__logo .nom { font-weight: 700; }

/* ── L'hélice tourne, et s'arrête quand on la touche ────────────────────────
   Le ventilateur tourne en permanence ; le curseur l'immobilise. C'est le seul
   mouvement gratuit du site, et il est au bon endroit : sur la marque, pas sur
   le contenu.

   ⚠️ 9 SECONDES PAR TOUR, ET C'EST DÉLIBÉRÉ. Au survol, une rotation de 2,4 s
   était juste : elle durait le temps d'un geste. En permanence, la même vitesse
   tire l'œil hors du texte à chaque page — un mouvement rapide et sans fin, à
   côté d'un paragraphe, se lit comme une alerte. À 9 s une pale passe toutes
   les trois secondes : le signe est vivant, il ne réclame rien. C'est le seul
   nombre à changer si le rendu doit être plus vif.

   ⚠️ SEULE L'HÉLICE TOURNE, jamais le SVG entier. La virole est une ELLIPSE
   (43,65 × 45,05, aux proportions du « o ») : la faire tourner la ferait
   vaciller — visible dès 40 px, et d'autant plus que la lettre est grande.

   ⚠️ C'est aussi pour cela que le glyphe est écrit EN CLAIR dans chaque
   verrou au lieu d'un `<use href="#…">`. Un `<use>` construit un arbre
   d'ombre, et aucun sélecteur du document n'y entre : la règle de survol
   n'aurait jamais pris. Le coût est d'environ 1,4 ko par page, deux fois.

   L'arrêt est une PAUSE, jamais un retour à zéro : une hélice à trois branches
   est identique à 120° près, donc aucun angle n'est faux, et un retour brusque
   se verrait. Elle s'immobilise où elle en est — c'est ce que fait un vrai
   ventilateur qu'on freine. */
.o-pales .helice {
  transform-box: view-box;
  transform-origin: 50% 50%;
  animation: fs-tourne 9s linear infinite;
}
.tete__logo:hover .o-pales .helice,
.tete__logo:focus-visible .o-pales .helice,
.pied__logo:hover .o-pales .helice,
.pied__logo:focus-visible .o-pales .helice { animation-play-state: paused; }
@keyframes fs-tourne { to { transform: rotate(360deg); } }

/* ⚠️ CETTE RÈGLE COMPTE DOUBLE DEPUIS QUE L'HÉLICE TOURNE EN PERMANENCE.
   Avant, un visiteur sensible au mouvement ne déclenchait rien tant qu'il ne
   survolait pas la marque ; maintenant elle tourne dès le chargement, sur
   toutes les pages. Sans cette coupure, le réglage système « réduire les
   animations » ne servirait à rien ici.

   ⚠️ Et la règle générale du site ne suffit pas : elle ramène les durées à
   0,01 ms, ce qui sur une animation infinie ferait VIBRER l'hélice au lieu de
   l'arrêter. Elle ne s'appliquerait d'ailleurs pas — `*` pèse moins lourd que
   `.o-pales .helice`. Il faut donc couper explicitement. */
@media (prefers-reduced-motion: reduce) {
  .o-pales .helice,
  .tete__logo:hover .o-pales .helice,
  .pied__logo:hover .o-pales .helice { animation: none; }
}

/* ── En-tête ───────────────────────────────────────────────────────────── */
/* La barre défile avec la page, sans fond ni filet : c'est le registre de la
   vitrine dont celle-ci est transposée, et c'est le réglage demandé.

   ⚠️ Elle a été COLLANTE un temps, avec un filet en bas. Les deux vont
   ensemble et se retirent ensemble : une barre collante sans filet laisse le
   contenu glisser sous un bord invisible, et le chapitre sombre qui remonte
   passerait sous un bandeau clair sans rien pour l'annoncer. Reposer l'un sans
   l'autre serait pire que les deux réglages.

   Ce que le collant apportait, et qui est donc perdu : passé le premier écran
   il n'existe plus de navigation avant le pied de page — jusqu'à 15 600 px
   plus bas sur l'accueil. Si cela devait revenir, c'est `position: sticky`
   + `top: 0` + `z-index: 40` + un fond opaque ET le filet, pas l'un des cinq.

   `relative` reste un ancêtre positionné : le panneau du menu déplié
   (`top: 100%`) et le méga-panneau continuent de se placer contre lui. */
.tete { position: relative; z-index: 40; }
.tete__inner {
  max-width: 1320px;
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: 28px;
  padding: 18px 28px;
}
.tete__logo {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--encre);
  text-decoration: none;
  font-weight: 600;
  font-size: 1.35rem;
  letter-spacing: -.02em;
  min-height: 44px;
}
.tete__nav { display: flex; gap: 2px; flex: 1; justify-content: flex-start; margin-left: 16px; }
.tete__nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 14px;
  color: var(--encre);
  text-decoration: none;
  border-radius: 8px;
  font-family: var(--font-mono);
  font-size: .8125rem;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.tete__nav a:hover { background: var(--fond-2); }
.burger, .tete__nav .seul-mobile { display: none; }
.groupe { position: relative; }
.groupe .chevron { margin-left: 7px; opacity: .55; font-size: 1em; line-height: 0; }
.panneau {
  position: absolute;
  top: calc(100% + 6px);
  left: -24px;
  width: min(800px, calc(100vw - 48px));
  background: var(--blanc);
  border: 1px solid var(--filet);
  border-radius: 16px;
  box-shadow: 0 30px 90px rgba(20, 22, 28, .18);
  padding: 26px;
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity .18s ease, transform .18s ease, visibility .18s;
  z-index: 20;
}
.groupe:hover .panneau, .groupe:focus-within .panneau {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.panneau__colonnes { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 26px; }
.panneau__titre { display: flex; align-items: center; gap: 9px; color: var(--encre-2); padding-bottom: 10px; border-bottom: 1px solid var(--filet); margin-bottom: 4px; }
.panneau__groupe a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 11px 2px;
  min-height: 44px;
  font: 400 .98rem/1.3 var(--font-sans);
  letter-spacing: 0;
  text-transform: none;
  color: var(--encre);
  text-decoration: none;
  border-bottom: 1px dotted var(--filet);
  border-radius: 0;
}
.panneau__groupe a:last-child { border-bottom: 0; }
.panneau__groupe a span { color: var(--encre-2); }
.panneau__groupe a:hover { color: var(--sonde); background: none; }
.panneau__bas {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 18px;
  padding: 14px 16px;
  min-height: 48px;
  border: 1px solid var(--filet);
  border-radius: 12px;
  background: var(--fond);
  text-decoration: none;
  color: var(--encre);
  font-size: .95rem;
}
.panneau__bas:hover { border-color: var(--orange); background: var(--orange-pale); }
.panneau__bas .panneau__liste { color: var(--encre-2); flex: 1; }
.tete__nav a[aria-current] { color: var(--encre); background: var(--fond-2); }

/* ── Le héros ──────────────────────────────────────────────────────────── */
.heros {
  position: relative;
  text-align: center;
  padding: clamp(80px, 11vw, 150px) 24px clamp(64px, 8vw, 110px);
  overflow: hidden;
}
.heros h1 { max-width: 1180px; margin-inline: auto; position: relative; }
.heros .sous { margin: 28px auto 0; position: relative; }
.heros__actions { margin-top: 40px; position: relative; display: flex; justify-content: center; gap: 18px; flex-wrap: wrap; }
/* La trame décorative : des amas de pixels aux bords, comme les coins d'un
   QR — le motif même que le produit colle sur chaque équipement. Peinte très
   faible, elle donne la matière du fond sans jamais toucher le texte. */
.heros__trame {
  position: absolute;
  inset: 0;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cg fill='%2314161C' opacity='.06'%3E%3Crect x='20' y='20' width='11' height='11'/%3E%3Crect x='36' y='20' width='11' height='11'/%3E%3Crect x='20' y='36' width='11' height='11'/%3E%3Crect x='52' y='20' width='11' height='11'/%3E%3Crect x='20' y='52' width='11' height='11'/%3E%3Crect x='36' y='36' width='11' height='11'/%3E%3Crect x='210' y='60' width='11' height='11'/%3E%3Crect x='226' y='60' width='11' height='11'/%3E%3Crect x='210' y='76' width='11' height='11'/%3E%3Crect x='242' y='76' width='11' height='11'/%3E%3Crect x='226' y='92' width='11' height='11'/%3E%3Crect x='90' y='180' width='11' height='11'/%3E%3Crect x='106' y='180' width='11' height='11'/%3E%3Crect x='90' y='196' width='11' height='11'/%3E%3Crect x='122' y='196' width='11' height='11'/%3E%3Crect x='230' y='230' width='11' height='11'/%3E%3Crect x='246' y='246' width='11' height='11'/%3E%3Crect x='230' y='246' width='11' height='11'/%3E%3Crect x='246' y='230' width='11' height='11'/%3E%3Crect x='262' y='230' width='11' height='11'/%3E%3Crect x='160' y='40' width='11' height='11'/%3E%3Crect x='60' y='120' width='11' height='11'/%3E%3Crect x='180' y='140' width='11' height='11'/%3E%3Crect x='30' y='250' width='11' height='11'/%3E%3Crect x='150' y='260' width='11' height='11'/%3E%3Crect x='270' y='150' width='11' height='11'/%3E%3C/g%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cg fill='%2314161C' opacity='.045'%3E%3Crect x='20' y='20' width='11' height='11'/%3E%3Crect x='36' y='20' width='11' height='11'/%3E%3Crect x='20' y='36' width='11' height='11'/%3E%3Crect x='52' y='20' width='11' height='11'/%3E%3Crect x='210' y='60' width='11' height='11'/%3E%3Crect x='226' y='60' width='11' height='11'/%3E%3Crect x='210' y='76' width='11' height='11'/%3E%3Crect x='90' y='180' width='11' height='11'/%3E%3Crect x='106' y='180' width='11' height='11'/%3E%3Crect x='230' y='230' width='11' height='11'/%3E%3Crect x='246' y='246' width='11' height='11'/%3E%3Crect x='160' y='40' width='11' height='11'/%3E%3Crect x='60' y='120' width='11' height='11'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 300px 300px, 460px 460px;
  background-position: 0 0, 160px 90px;
  -webkit-mask-image: radial-gradient(ellipse 52% 58% at 50% 40%, transparent 52%, #000 100%);
  mask-image: radial-gradient(ellipse 52% 58% at 50% 40%, transparent 52%, #000 100%);
  pointer-events: none;
}

/* La barre des référentiels : la place où un SaaS met ses logos clients.
   Ici, pas de faux clients — les textes que le produit sait servir. */
.referentiels { text-align: center; padding: 8px 24px 72px; }
.referentiels__titre { color: var(--encre-2); margin-bottom: 26px; }
.referentiels__liste {
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: clamp(24px, 3.6vw, 52px);
  flex-wrap: wrap;
  list-style: none;
  margin: 0;
  padding: 0;
}
.referentiels__liste li {
  font-weight: 600;
  font-size: 1.28rem;
  letter-spacing: -.01em;
  /* ⚠️ Un hexa écrit ici échappait à `contraste.py`, qui ne contrôle que des
     JETONS. Cette couleur porte du texte : elle doit tenir 4,5:1, et personne
     ne pouvait le vérifier tant qu'elle n'avait pas de nom. */
  color: var(--encre-3);
}
.referentiels__liste .mono { font-size: 1.05rem; font-weight: 400; letter-spacing: .04em; }

/* ── La rangée des familles : autant de portes d'entrée ──────────────────── */
.familles { max-width: 1320px; margin: 0 auto; padding: 0 28px 92px; text-align: center; }
.familles > .mono { color: var(--encre-2); display: block; margin-bottom: 22px; }
.familles__grille { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; text-align: left; }
.familles__grille a {
  display: flex;
  align-items: center;
  gap: 13px;
  min-height: 76px;
  padding: 14px 20px;
  background: var(--blanc);
  border: 1px solid var(--filet);
  border-radius: 15px;
  text-decoration: none;
  color: var(--encre);
  font-size: 1.08rem;
  font-weight: 500;
  letter-spacing: -.01em;
  transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.familles__grille a:hover {
  border-color: var(--sonde);
  transform: translateY(-3px);
  box-shadow: 0 14px 34px rgba(20, 22, 28, .10);
}
.familles__grille .pip { width: 11px; height: 11px; }
.familles__grille .fleche { margin-left: auto; color: var(--encre-2); transition: transform .16s ease; }
.familles__grille a:hover .fleche { transform: translateX(4px); color: var(--sonde); }

/* ── Le mat teinté sous une vitrine ───────────────────────────────────────── */
.mat { border-radius: 24px; padding: clamp(18px, 3vw, 36px); background: var(--sonde-pale); }
.mat--indigo { background: var(--indigo-pale); }
.mat--bleu { background: var(--bleu-pale); }
.mat--vert { background: var(--vert-pale); }
.mat .maquette { border: 1px solid var(--filet); border-radius: 14px; box-shadow: 0 20px 50px rgba(20, 22, 28, .12); }
.mat .tel { margin-inline: auto; }
.mat .legende { margin: 14px 6px 0; }

/* ── Le plan vivant ─────────────────────────────────────────────────────── */
.plan-bloc { min-width: 0; }
.plan-vivant { position: relative; background: var(--blanc); border-radius: 14px; border: 1px solid var(--filet); overflow: hidden; box-shadow: 0 20px 50px rgba(20, 22, 28, .12); }
.plan-vivant > svg { display: block; width: 100%; height: auto; }
.poste {
  position: absolute;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.poste__point {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2.5px solid #FFFFFF;
  background: rgb(var(--etat));
  box-shadow: 0 1px 6px rgba(0, 0, 0, .35);
}
.poste__nom {
  font-family: var(--font-mono);
  font-size: .78125rem;
  letter-spacing: .04em;
  background: rgba(255, 255, 255, .92);
  border: 1px solid var(--filet);
  border-radius: 6px;
  padding: 1px 7px;
  color: var(--encre);
  white-space: nowrap;
}
.poste--rouge { --etat: 220, 38, 38; }
.poste--orange { --etat: 217, 119, 6; }
.poste--jaune { --etat: 234, 179, 8; }
.poste--vert { --etat: 27, 175, 122; }
/* La pulsation : l'échéance dépassée bat, le reste dort. */
@keyframes pouls {
  0% { box-shadow: 0 1px 6px rgba(0, 0, 0, .35), 0 0 0 0 rgba(var(--etat), .5); }
  70% { box-shadow: 0 1px 6px rgba(0, 0, 0, .35), 0 0 0 16px rgba(var(--etat), 0); }
  100% { box-shadow: 0 1px 6px rgba(0, 0, 0, .35), 0 0 0 0 rgba(var(--etat), 0); }
}
.poste--pulse .poste__point { animation: pouls 2.2s cubic-bezier(.4, 0, .6, 1) infinite; }
/* Les positions, en pourcentage du plan — chaque équipement DANS son local. */
.poste--q1 { left: 15%; top: 24%; }
.poste--q2 { left: 40%; top: 24%; }
.poste--q3 { left: 64%; top: 24%; }
.poste--q4 { left: 87%; top: 24%; }
.poste--q5 { left: 10%; top: 77%; }
.poste--q6 { left: 31%; top: 77%; }
.poste--q7 { left: 60%; top: 77%; }
.poste--q8 { left: 87%; top: 77%; }
.plan-legende {
  display: flex;
  gap: 22px;
  flex-wrap: wrap;
  margin-top: 16px;
  padding-inline: 6px;
  font-size: .875rem;
  color: var(--encre-2);
}
.plan-legende span { display: inline-flex; align-items: center; gap: 8px; }
.plan-legende i {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: rgb(var(--etat));
  border: 1.5px solid #FFFFFF;
  box-shadow: 0 0 0 1px var(--filet);
}

/* ── Les documents dessinés ─────────────────────────────────────────────────
   Les pièces du produit, refaites en HTML : texte vectoriel, net à toutes
   les tailles. Les couleurs d'état sont celles du métier. */
.maquette { background: var(--blanc); color: var(--encre); }
/* ⚠️ `container-type` : le document se replie sur SA propre largeur, pas sur
   celle de la fenêtre. Les deux ne se confondent pas — mesuré à 1024 px, la
   fiche de conformite.html vit dans une colonne de 354 px et n'en montrait que
   les deux tiers, alors qu'une requête de fenêtre l'aurait crue au large. Un
   `@media` ne peut pas savoir dans quelle colonne il est tombé ; un
   `@container` le sait. */
.doc {
  container-type: inline-size;
  padding: clamp(20px, 3vw, 34px);
  font-size: .875rem;
  line-height: 1.5;
}
.doc__tete { display: flex; justify-content: space-between; gap: 18px; flex-wrap: wrap; border-bottom: 2px solid var(--encre); padding-bottom: 14px; }
.doc__tete strong { display: block; font-size: 1.05rem; letter-spacing: -.01em; }
.doc__tete span { display: block; color: var(--encre-2); font-size: .8125rem; }
.doc__titre { text-align: right; }
.doc__titre strong { font-size: 1.2rem; }
.doc__parties { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; padding: 16px 0; }
.doc__parties > div { border: 1px solid var(--filet); border-radius: 8px; padding: 10px 12px; }
.doc__parties strong { display: block; margin: 2px 0; }
.doc__parties span { display: block; color: var(--encre-2); font-size: .8125rem; }
.doc__etiq { color: var(--encre-2); font-size: .78125rem; }
.doc__section { color: var(--encre-2); margin: 10px 0 8px; border-bottom: 1px solid var(--filet); padding-bottom: 6px; }
.doc-tbl { width: 100%; border-collapse: collapse; font-size: .8125rem; }
.doc-tbl th { font-family: var(--font-mono); font-size: .78125rem; letter-spacing: .05em; text-transform: uppercase; font-weight: 400; color: var(--encre-2); text-align: left; padding: 7px 10px 7px 0; border-bottom: 1px solid var(--encre); }
.doc-tbl td { padding: 9px 10px 9px 0; border-bottom: 1px solid var(--filet); vertical-align: top; }
.doc-lot { color: var(--encre-2); font-size: .78125rem; }
.doc-vide { color: var(--encre-2); font-style: italic; }
.doc-nb { font-family: var(--font-mono); font-size: .8125rem; white-space: nowrap; }
.doc__note { color: var(--encre-2); font-size: .8125rem; margin-top: 12px; }
.doc__totaux { max-width: 320px; margin-left: auto; padding-top: 12px; }
.doc__totaux > div { display: flex; justify-content: space-between; padding: 5px 0; color: var(--encre-2); }
.doc__totaux .doc__ttc { color: var(--encre); font-weight: 500; font-size: 1.05rem; border-top: 2px solid var(--encre); margin-top: 6px; padding-top: 9px; }
.doc__mention { margin-top: 16px; border: 1px solid var(--filet); border-radius: 8px; padding: 10px 12px; color: var(--encre-2); font-size: .8125rem; display: flex; gap: 10px; align-items: baseline; }
/* Les deux signatures du Cerfa : elles vont ensemble, sur place. */
.doc__signatures { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 16px; }
.doc__signatures > div { border: 1px dashed var(--filet); border-radius: 8px; padding: 10px 12px; }
.doc__signatures .mono { color: var(--encre-2); font-size: .78125rem; display: block; margin-bottom: 6px; }
.doc__signatures strong { font-weight: 500; }
.doc__signatures span { display: block; color: var(--encre-2); font-size: .78125rem; }
.paraphe { display: block; height: 26px; margin: 6px 0 2px; background-repeat: no-repeat; background-size: contain;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 150 34'%3E%3Cpath d='M4 26c10-16 16-20 21-12s2 18 8 16 10-16 15-19 6 6 11 8 12-4 18-9 12-6 16 0 9 8 14 4' fill='none' stroke='%2314161C' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }

/* Les pastilles et mots d'état : la légende réglementaire du produit. */
.etat-point { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 7px; background: rgb(var(--etat)); vertical-align: -1px; }
.etat-mot { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: .78125rem; letter-spacing: .03em; text-transform: uppercase; padding: 2px 8px; border-radius: 6px; background: rgba(var(--etat), .12); color: rgb(var(--etat-encre, var(--etat))); white-space: nowrap; }
.etat--vert { --etat: 27, 175, 122; --etat-encre: 13, 122, 80; }
.etat--jaune { --etat: 234, 179, 8; --etat-encre: 141, 99, 5; }
.etat--orange { --etat: 217, 119, 6; --etat-encre: 166, 91, 5; }
.etat--rouge { --etat: 220, 38, 38; --etat-encre: 185, 28, 28; }
.etat--glace { --etat: 33, 196, 188; --etat-encre: 12, 118, 113; }

/* ── LA PIÈCE CENTRALE : la chaîne réglementaire ───────────────────────────
   charge × PRP → teqCO₂ → périodicité → prochaine échéance.
   C'est le calcul que personne sur le marché ne ferme, et c'est pour cela
   qu'il est montré en entier, opérande par opérande, et pas résumé. */
.calcul { padding: clamp(18px, 2.6vw, 30px); }
.calcul__tete { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; padding-bottom: 14px; border-bottom: 1px solid var(--filet); }
.calcul__tete strong { font-size: 1.05rem; font-weight: 500; }
.calcul__tete .mono { color: var(--encre-2); }
.calcul__ligne { display: flex; align-items: stretch; gap: 10px; flex-wrap: wrap; margin-top: 18px; }
.calcul__op {
  flex: 1 1 120px;
  min-width: 0;
  border: 1px solid var(--filet);
  border-radius: 10px;
  padding: 10px 12px;
  background: var(--fond);
}
/* ⚠️ .8125rem = 13px, et pas .7rem = 11,2px. Ces étiquettes descendaient sous
   le plancher de 12,5 px — sur un téléphone, dans un local technique, pour le
   libellé qui dit CE QU'EST le chiffre juste en dessous. Le lecteur visé a
   plus de quarante-cinq ans. Trouvé par `lisibilite.mjs` le 2026-08-28, au
   premier passage des portes. */
.calcul__op .mono { display: block; color: var(--encre-2); font-size: .8125rem; letter-spacing: .07em; }
.calcul__op b { display: block; font-family: var(--font-mono); font-size: 1.35rem; font-weight: 400; letter-spacing: -.01em; margin-top: 3px; }
.calcul__op i { display: block; font-style: normal; color: var(--encre-2); font-size: .78125rem; }
.calcul__signe { display: flex; align-items: center; font-family: var(--font-mono); font-size: 1.1rem; color: var(--encre-2); flex: none; }
.calcul__op--sortie { background: var(--sonde-pale); border-color: var(--sonde-filet); }
/* ⚠️ Le hexa était écrit ICI, en dur, hors de la palette : `contraste.py` ne
   contrôle que des JETONS, et cette couleur — la seule du site à porter un
   chiffre sur le lavis de sélection — échappait donc à toute vérification. Un
   jeton, et la paire entre dans les portes. */
.calcul__op--sortie b { color: var(--vert-sortie); }
/* Le verdict : ce que le calcul impose, et depuis quel texte. */
.calcul__verdict {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 18px;
  padding: 14px 16px;
  border-radius: 12px;
  background: var(--encre);
  color: var(--blanc);
}
.calcul__verdict b { font-family: var(--font-mono); font-size: 1.1rem; font-weight: 400; letter-spacing: .02em; }
.calcul__verdict .mono { color: var(--sur-nuit-2); }
.calcul__verdict span { color: var(--sur-nuit); font-size: .875rem; }
.calcul__note { margin-top: 12px; color: var(--encre-2); font-size: .8125rem; }
/* La ligne d'arbitrage : quatre sources, une seule gagne. */
.arbitrage { display: grid; gap: 8px; margin-top: 16px; }
.arbitrage__l {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  border: 1px solid var(--filet);
  border-radius: 9px;
  font-size: .875rem;
  background: var(--blanc);
}
/* Même correction : .72rem valait 11,52 px. La largeur passe de 8,5 à 8 em
   parce que la chasse grandit avec la taille — sans quoi la colonne des
   libellés poussait la valeur hors de la carte à 390 px. */
.arbitrage__l .mono { color: var(--encre-2); flex: none; width: 8em; font-size: .8125rem; }
.arbitrage__l b { font-family: var(--font-mono); font-weight: 400; margin-left: auto; white-space: nowrap; }
.arbitrage__l--gagne { border-color: var(--sonde); background: var(--sonde-pale); }
.arbitrage__l--gagne .mono { color: #0C7671; }

/* La grille des trois seuils — l'argument le plus court du produit. */
.seuils { width: 100%; border-collapse: collapse; font-size: .875rem; }
.seuils th, .seuils td { padding: 10px 12px 10px 0; border-bottom: 1px solid var(--filet); text-align: left; vertical-align: top; }
.seuils th { font-family: var(--font-mono); font-size: .78125rem; letter-spacing: .06em; text-transform: uppercase; font-weight: 400; color: var(--encre-2); border-bottom-color: var(--encre); }
.seuils td:first-child { font-family: var(--font-mono); white-space: nowrap; }
.seuils tbody tr:last-child td { border-bottom: 0; }

/* La jauge de charge : où tombe cet équipement dans la grille. */
.jauge { padding: 20px; border-radius: 14px; border: 1px solid var(--filet); background: var(--blanc); }
.jauge__tete { display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.jauge__tete span { color: var(--encre-2); }
.jauge__barre { position: relative; height: 12px; border-radius: 999px; background: var(--fond-2); overflow: hidden; }
.jauge__barre i { position: absolute; inset: 0 auto 0 0; background: var(--sonde); border-radius: 999px; }
.jauge__bornes { display: flex; justify-content: space-between; margin-top: 8px; color: var(--encre-2); font-size: .78125rem; }
.jauge__note { margin-top: 12px; font-size: .8125rem; color: var(--encre-2); }

/* La bouteille et son solde : un registre, pas une date de péremption. */
.bouteille { padding: 20px; border-radius: 14px; border: 1px solid var(--filet); background: var(--blanc); }
.bouteille__tete { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; padding-bottom: 12px; border-bottom: 1px solid var(--filet); }
.bouteille__tete strong { font-weight: 500; }
.bouteille__tete .mono { color: var(--encre-2); }
.bouteille__solde { display: flex; align-items: baseline; gap: 10px; margin: 14px 0 4px; }
.bouteille__solde b { font-family: var(--font-mono); font-size: 2.1rem; font-weight: 400; letter-spacing: -.02em; }
.bouteille__solde .mono { color: var(--encre-2); }
.bouteille__mvt { display: flex; align-items: center; gap: 12px; padding: 9px 2px; border-bottom: 1px solid var(--filet); font-size: .875rem; }
.bouteille__mvt:last-child { border-bottom: 0; }
.bouteille__mvt .mono { color: var(--encre-2); flex: none; font-size: .78125rem; }
.bouteille__mvt b { font-family: var(--font-mono); font-weight: 400; margin-left: auto; white-space: nowrap; }
.bouteille__mvt b.moins { color: #B91C1C; }
.bouteille__mvt b.plus { color: #0D7A50; }

/* La frise des interdictions : une date, un régime, ce qui reste permis. */
.frise { padding: 20px; border-radius: 14px; border: 1px solid var(--filet); background: var(--blanc); }
.frise__ligne { display: flex; align-items: center; gap: 0; margin: 14px 0 8px; }
.frise__pas { flex: 1; display: flex; align-items: center; min-width: 0; }
.frise__pas i { width: 14px; height: 14px; border-radius: 50%; background: var(--sonde); border: 2.5px solid var(--blanc); box-shadow: 0 0 0 1px var(--filet); flex: none; }
.frise__pas::after { content: ''; flex: 1; height: 2px; background: var(--filet); }
/* ⚠️ `flex: 0` vaut `flex: 0 1 0%` : la base tombe à zéro et le dernier jalon
   se retrouve avec une largeur nulle pour un point de 14 px, qui déborde donc
   de son rang et vient se coller au bord de la carte, décalé de son étiquette.
   `flex: none` lui laisse sa largeur naturelle. */
.frise__pas:last-child { flex: none; }
.frise__pas:last-child::after { content: none; }
.frise__pas--fait i { background: #DC2626; }
.frise__etiqs { display: flex; justify-content: space-between; gap: 8px; color: var(--encre-2); font-size: .78125rem; }
.frise__note { margin-top: 12px; font-size: .8125rem; color: var(--encre-2); }

/* La fiche d'attestation : deux dates à suivre, pas une. */
.fiche-certif { padding: 20px; border-radius: 14px; border: 1px solid var(--filet); background: var(--blanc); display: grid; gap: 10px; }
.fiche-certif__ligne { display: flex; justify-content: space-between; gap: 12px; border-bottom: 1px solid var(--filet); padding-bottom: 9px; font-size: .875rem; }
.fiche-certif__ligne:last-child { border-bottom: 0; padding-bottom: 0; }
.fiche-certif__ligne .mono { color: var(--encre-2); }
.fiche-certif strong { font-weight: 500; }

/* Les fiches en vis-à-vis : texte d'un côté, objet de l'autre. */
.vis { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 4fr); gap: 28px; align-items: center; }
.vis > * { min-width: 0; }
.vis--inverse > :first-child { order: 2; }

/* L'écran de contrôle, dans un cadre de téléphone sobre. */
.tel { border-radius: 18px; padding: 16px; max-width: 420px; }
.tel__tete { display: flex; flex-direction: column; gap: 6px; padding-bottom: 12px; border-bottom: 1px solid var(--filet); }
.tel__tete strong { font-size: .95rem; }
.tel__tete .etat-mot { align-self: flex-start; }
.tel__ligne { display: flex; align-items: center; gap: 12px; padding: 11px 6px; border-bottom: 1px solid var(--filet); font-size: .875rem; border-radius: 8px; animation: ligne-cochee 10s ease-in-out infinite; }
.tel__ligne > span:nth-child(2) { flex: 1; min-width: 0; }
.tel__ligne strong { display: block; font-weight: 500; }
.tel__ligne span span { display: block; color: var(--encre-2); font-size: .78125rem; }
.tel__code { background: var(--fond-2); border-radius: 6px; padding: 3px 7px; font-size: .78125rem; }
.tel__pied { display: flex; justify-content: space-between; align-items: center; padding-top: 12px; color: var(--encre-2); }
.tel__suivant { background: var(--sonde); color: var(--blanc); border-radius: 7px; padding: 8px 12px; }
/* Le refus : la règle qui parle au technicien, pas au programme. */
.tel__refus { margin-top: 12px; border: 1px solid #F3C6C6; background: #FDECEC; border-radius: 10px; padding: 10px 12px; font-size: .8125rem; color: #7F1D1D; }
.tel__refus .mono { display: block; color: #B91C1C; margin-bottom: 4px; }

/* Le mouvement des maquettes : il raconte, il ne décore pas. */
@keyframes ligne-cochee {
  0%, 100% { background: transparent; }
  5% { background: var(--sonde-pale); }
  12% { background: transparent; }
}
.tel__ligne:nth-of-type(1) { animation-delay: .4s; }
.tel__ligne:nth-of-type(2) { animation-delay: 2.2s; }
.tel__ligne:nth-of-type(3) { animation-delay: 4s; }
.tel__ligne:nth-of-type(4) { animation-delay: 5.8s; }
.tel__ligne:nth-of-type(5) { animation-delay: 7.6s; }

@keyframes balayage { from { top: -60px; } to { top: 110%; } }
.planche__grille::after {
  content: '';
  position: absolute;
  left: -8px;
  right: -8px;
  height: 54px;
  top: -60px;
  background: linear-gradient(180deg, transparent, rgba(56, 214, 206, .18), transparent);
  animation: balayage 5.5s linear infinite;
  pointer-events: none;
}

@keyframes urgence-bat {
  0%, 100% { background: rgba(var(--etat), .09); }
  50% { background: rgba(var(--etat), .22); }
}

/* L'agenda : la semaine remplie. */
.agenda { padding: 18px; border-radius: 16px; }
.agenda__tete { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; flex-wrap: wrap; padding-bottom: 12px; border-bottom: 1px solid var(--filet); margin-bottom: 12px; }
.agenda__tete span { color: var(--encre-2); }
.agenda__grille { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.agenda__jour { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.agenda__jour > .mono { color: var(--encre-2); padding-bottom: 4px; border-bottom: 1px solid var(--filet); }
.rdv { display: flex; flex-direction: column; gap: 1px; border-left: 3px solid rgb(var(--etat, 46, 125, 255)); background: rgba(var(--etat, 46, 125, 255), .09); border-radius: 6px; padding: 6px 8px; font-size: .78125rem; line-height: 1.35; }
.rdv .mono { color: var(--encre-2); font-size: .78125rem; }
.rdv--bleu { --etat: 46, 125, 255; }
.rdv--indigo { --etat: 98, 96, 255; }
.rdv--vert { --etat: 27, 175, 122; }
.rdv--alerte { --etat: 217, 119, 6; animation: urgence-bat 2.4s ease-in-out infinite; }
.agenda__note { margin-top: 12px; color: var(--encre-2); font-size: .8125rem; }

/* La planche d'étiquettes. */
.planche { padding: clamp(18px, 2.5vw, 28px); }
.planche__tete { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; padding-bottom: 12px; border-bottom: 1px solid var(--filet); margin-bottom: 14px; }
.planche__tete span { color: var(--encre-2); }
.planche__grille { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; position: relative; overflow: hidden; }
.planche__cellule { display: flex; flex-direction: column; align-items: center; gap: 7px; border: 1px dashed var(--filet); border-radius: 8px; padding: 12px 8px; font-size: .78125rem; color: var(--encre-2); }
.qr {
  width: 54px;
  height: 54px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 21 21'%3E%3Cpath fill='%2314161C' d='M0 0h7v7H0zM14 0h7v7h-7zM0 14h7v7H0zM2 2h3v3H2zM16 2h3v3h-3zM2 16h3v3H2zM9 0h2v2H9zM12 3h2v2h-2zM9 4h2v3H9zM0 9h2v2H0zM3 9h2v2H3zM6 10h3v2H6zM10 9h2v2h-2zM14 9h2v3h-2zM17 10h2v2h-2zM20 9h1v3h-1zM9 13h2v2H9zM12 12h2v2h-2zM9 16h3v2H9zM13 15h2v3h-2zM16 14h2v2h-2zM19 15h2v2h-2zM14 19h3v2h-3zM19 19h2v2h-2z'/%3E%3C/svg%3E");
  background-size: contain;
  background-repeat: no-repeat;
}

/* ── La bande d'appel médiane : UNE par page au plus ──────────────────────── */
.cta-bande { max-width: 1320px; margin: 0 auto; padding: 0 28px; }
.cta-bande__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  flex-wrap: wrap;
  background: var(--sonde-pale);
  border: 1px solid #B6E9E5;
  border-radius: 24px;
  padding: 36px 44px;
}
.cta-bande h2 { font-size: clamp(1.5rem, 2.4vw, 2.1rem); max-width: 640px; }
.cta-bande .sous { margin-top: 8px; font-size: 1.0625rem; }
/* Quand la bande d'appel termine la page, c'est elle qui porte la respiration
   avant le dégradé du pied. Une section vide posée là pour l'espacement
   laisserait un grand blanc que personne ne saurait expliquer six mois plus
   tard — et c'était le cas ici avant cette règle. */
main > .cta-bande:last-child { padding-bottom: clamp(64px, 8vw, 104px); }

/* ── Les transitions de chapitre ───────────────────────────────────────── */
.aube {
  height: clamp(280px, 38vw, 560px);
  background: linear-gradient(180deg,
    var(--fond) 0%, #E8F0F7 10%, #C6DEF3 24%, #93BEEA 38%, #5C90DC 50%,
    #3562B6 61%, #1E3A80 71%, #12224E 80%, #0A1128 89%, var(--nuit) 100%);
}
.crepuscule {
  height: clamp(220px, 30vw, 420px);
  background: linear-gradient(180deg,
    var(--nuit) 0%, #0A1128 14%, #1E3A80 30%, #3562B6 46%, #5C90DC 58%,
    #93BEEA 70%, #C6DEF3 82%, #E8F0F7 92%, var(--fond) 100%);
}

/* ── Le chapitre sombre ────────────────────────────────────────────────── */
.nuit { background: var(--nuit); color: var(--blanc); padding: 24px 0 130px; position: relative; }
.nuit::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: min(1100px, 90vw);
  height: 620px;
  background: radial-gradient(ellipse 50% 50% at 50% 30%, rgba(56, 214, 206, .12), transparent 70%);
  pointer-events: none;
}
/* La vitrine flottante : le document au centre — cadre arrondi, filet, halo. */
.scene { position: relative; max-width: 960px; margin: 76px auto 110px; padding-inline: 28px; }
.scene__cadre {
  border-radius: 16px;
  border: 1px solid var(--nuit-filet);
  overflow: hidden;
  box-shadow: 0 50px 140px rgba(56, 214, 206, .14), 0 30px 90px rgba(0, 0, 0, .65);
}
.scene__cadre img { width: 100%; }
.nuit__tete { text-align: center; max-width: 900px; margin: 0 auto; padding-inline: 24px; position: relative; }
.nuit__tete h2 { color: var(--blanc); margin: 26px 0 18px; font-size: clamp(2.1rem, 4vw, 3.6rem); }
.nuit__tete .sous { color: var(--sur-nuit); margin-inline: auto; }
.nuit__tete .lien-mono { margin-top: 22px; color: var(--blanc); }
.nuit__tete .lien-mono:hover { color: var(--indigo-clair); }

.cartes { max-width: 1320px; margin-inline: auto; padding-inline: 28px; display: grid; gap: 28px; }
.carte-nuit {
  position: relative;
  background: var(--nuit-carte);
  border: 1px solid var(--nuit-filet);
  border-radius: 24px;
  overflow: hidden;
  display: flex;
  min-height: 520px;
}
.carte-nuit__texte {
  flex: 0 0 42%;
  padding: 52px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 32px;
}
.carte-nuit__texte h3 { color: var(--blanc); font-size: clamp(1.6rem, 2.4vw, 2.2rem); margin-bottom: 14px; }
.carte-nuit__texte p { color: var(--sur-nuit); font-size: 1.0625rem; max-width: 34em; }
.carte-nuit .mono { color: var(--sur-nuit-2); }
.carte-nuit .lien-mono { color: var(--blanc); }
.carte-nuit .lien-mono:hover { color: var(--indigo-clair); }
/* La pièce déborde du bord droit et du bas : le document est plus grand
   que la carte. */
.carte-nuit__visuel { flex: 1; position: relative; min-height: 300px; background: radial-gradient(ellipse 90% 80% at 30% 40%, rgba(56, 214, 206, .09), transparent 70%); }
/* ⚠️ Une seule règle pour les deux formes de carte. La feuille dont celle-ci
   est transposée en avait deux, et la seconde s'écrivait
   `.carte-nuit--haute .carte-nuit__visuel img, .carte-nuit__visuel .maquette`
   — dont le second sélecteur n'était PAS limité aux cartes hautes et écrasait
   donc la première pour toutes les maquettes. Le rendu obtenu était le bon ;
   il l'était par accident. Il est écrit ici une fois, exprès. */
.carte-nuit__visuel img, .carte-nuit__visuel .maquette {
  position: absolute;
  top: 0;
  left: 52px;
  max-width: none;
  width: calc(100% - 52px);
  border-radius: 12px 0 0 0;
  border: 1px solid var(--nuit-filet);
  box-shadow: 0 24px 80px rgba(0, 0, 0, .5);
}
.paire { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; }
.carte-nuit--haute { flex-direction: column; min-height: 520px; }
.carte-nuit--haute .carte-nuit__texte { flex: none; padding-bottom: 10px; }

/* ⚠️ Le bloc `.clair` / `.accordeon` vivait ici. Il a été retiré avec la
   séquence épinglée de l'accueil, qui a pris sa place : l'accueil était la
   seule page à porter un accordéon, et une classe définie pour personne est
   du poids transféré à chaque visiteur. `node outils/classes-mortes.mjs` le
   redira le jour où cela se reproduit. */

.legende { font-size: .875rem; color: var(--encre-2); margin-top: 14px; }

/* Deux utilitaires, et deux seulement. Au-delà, c'est un composant qui manque.
   Ils existent pour éviter les `style=` en ligne dans les pages : la CSP les
   tolère, mais une couleur écrite dans une page ne suit plus le thème. */
.mt-l { margin-top: 28px; }
.gris { color: var(--encre-2); }

/* ── La chorégraphie du défilement ──────────────────────────────────────────
   Trois mécanismes, tous en AMÉLIORATION PROGRESSIVE : sans la classe `js`
   posée par `assets/site.js` sur <html>, rien n'est masqué et la page est
   entière. C'est la règle qui rend l'effet sans risque — un script qui ne
   part pas (erreur, CSP, réseau coupé au mauvais moment) laisserait sinon un
   site aux trois quarts invisible, et personne ne le verrait avant un client.

   ⚠️ Le bloc `prefers-reduced-motion` de la fin est indispensable et il doit
   rester APRÈS ces règles : la mitigation universelle de la ligne 142 ne
   remet ni l'opacité ni la translation, elle les rend seulement instantanées.
   Un visiteur qui a demandé « moins d'animations » verrait une page vide tant
   que l'observateur n'a pas posé `.vu`. ─────────────────────────────────── */
html.js .rev,
html.js .rev-groupe > * {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .65s ease, transform .65s cubic-bezier(.16, 1, .3, 1);
}
html.js .rev.vu,
html.js .rev-groupe > .vu { opacity: 1; transform: none; }
/* Les enfants d'un groupe entrent en cascade : le décalage se lit comme une
   main qui pose les cartes, là où un groupe qui apparaît d'un bloc se lit
   comme un rechargement. Huit paliers — au-delà, la dernière carte attendrait
   près d'une seconde après la première, et l'effet devient une attente. */
html.js .rev-groupe > :nth-child(2) { transition-delay: .09s; }
html.js .rev-groupe > :nth-child(3) { transition-delay: .18s; }
html.js .rev-groupe > :nth-child(4) { transition-delay: .27s; }
html.js .rev-groupe > :nth-child(5) { transition-delay: .36s; }
html.js .rev-groupe > :nth-child(6) { transition-delay: .45s; }
html.js .rev-groupe > :nth-child(7) { transition-delay: .54s; }
html.js .rev-groupe > :nth-child(8) { transition-delay: .63s; }

/* Les maquettes ne jouent leur animation qu'une fois VISIBLES : une ligne qui
   se coche, un balayage de planche ou un rendez-vous qui bat hors de l'écran
   sont des animations pour personne — et sur cette page elles tournent en
   boucle infinie, donc elles auraient déjà joué douze fois avant qu'on arrive.
   ⚠️ L'hélice du logo n'est PAS dans cette liste : elle est la marque, elle
   est visible dès le premier pixel de la page, et elle a sa propre pause au
   survol (l. 350). */
html.js .anime-en-vue :is(.tel__ligne, .rdv--alerte, .poste--pulse .poste__point),
html.js .anime-en-vue .planche__grille::after { animation-play-state: paused; }
html.js .anime-en-vue.vu :is(.tel__ligne, .rdv--alerte, .poste--pulse .poste__point),
html.js .anime-en-vue.vu .planche__grille::after { animation-play-state: running; }

/* ── La séquence épinglée ───────────────────────────────────────────────────
   Le texte et son index restent fixés à gauche pendant que les volets défilent
   à droite ; le volet au centre de l'écran s'allume et l'index le suit. C'est
   l'effet validé sur nuisisoft.fr, et la raison est de fond : une chaîne de
   travail (une saisie qui devient un document, qui devient une obligation) se
   raconte mal en quatre cartes côte à côte, où le lecteur choisit son ordre.
   Ici l'ordre est le propos.

   ⚠️ Un seul par page, et jamais sur une page de conversion (tarifs, contact)
   ni de référence (FAQ, mentions) : un récit épinglé y retarde le geste qu'on
   attend du visiteur. ───────────────────────────────────────────────────── */
.epingle { max-width: 1320px; margin-inline: auto; padding: 104px 28px 40px; }
.epingle__inner { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 6fr); gap: 64px; align-items: start; }
/* 110px : la hauteur de l'en-tête collée, plus l'air qu'il lui faut. */
.epingle__gauche { position: sticky; top: 110px; }
.epingle__droite { min-width: 0; }
.epingle__gauche h2 { margin: 22px 0 16px; }
.epingle__index { list-style: none; padding: 0; margin-top: 36px; border-top: 1px solid var(--filet); }
.epingle__index li {
  padding: 13px 2px;
  border-bottom: 1px solid var(--filet);
  color: var(--encre-2);
  transition: color .2s ease, padding-left .2s ease;
}
.epingle__index li.actif { color: var(--encre); padding-left: 10px; border-left: 3px solid var(--sonde); }
.volet { min-height: 62vh; display: flex; flex-direction: column; justify-content: center; gap: 14px; }
html.js .volet { opacity: .3; transform: scale(.975); transition: opacity .45s ease, transform .45s cubic-bezier(.16, 1, .3, 1); }
html.js .volet.actif { opacity: 1; transform: none; }
.volet h3 { margin-bottom: 2px; }
.volet > p { max-width: 34em; color: var(--encre-2); }

@media (prefers-reduced-motion: reduce) {
  html.js .rev,
  html.js .rev-groupe > *,
  html.js .volet { opacity: 1; transform: none; transition: none; }
}

/* ── Sections claires génériques ───────────────────────────────────────── */
.entete-page { text-align: center; max-width: 880px; margin-inline: auto; padding: clamp(48px, 6vw, 84px) 24px 8px; }
.entete-page h1 { font-size: clamp(2.2rem, 4vw, 3.6rem); margin: 22px 0 16px; }
.entete-page .sous { margin-inline: auto; }
.sec { max-width: 1320px; margin-inline: auto; padding: 104px 28px 0; }
.sec--fin { padding-bottom: 96px; }
.sec__tete { max-width: 820px; margin-bottom: 48px; }
.sec__tete h2 { margin: 22px 0 16px; }

.duo { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; }
/* Les enfants d'une grille gardent min-width auto par défaut : un tableau au
   contenu large ÉLARGIT alors sa colonne au-delà de l'écran. Vu à 390 px. */
.duo > *, .trio > *, .paire > * { min-width: 0; }
.trio { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.carte {
  background: var(--blanc);
  border: 1px solid var(--filet);
  border-radius: 18px;
  padding: 32px;
}
.carte--sonde { background: var(--sonde-pale); border-color: var(--sonde-filet); }
.carte--bleue { background: var(--bleu-pale); border-color: #C7DCFF; }
.carte--verte { background: var(--vert-pale); border-color: #BFE5D0; }
.carte--orange { background: var(--orange-pale); border-color: #F3C6A9; }
.carte .mono .pip { margin-right: 9px; vertical-align: 1px; }
.carte h3 { margin-bottom: 12px; }
.carte p, .carte li { color: var(--encre-2); font-size: 1.0625rem; }
.carte .mono { color: var(--encre-2); display: block; margin-bottom: 16px; }
.carte ul { padding-left: 20px; margin-top: 10px; }
.carte li + li { margin-top: 8px; }

/* Le bento : des cartes de tailles variées, pas huit blocs identiques. */
.bento { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.bento > * { min-width: 0; }
.bento__large { grid-column: span 2; }
.bento .carte { display: flex; flex-direction: column; gap: 8px; }
.bento .carte .maquette { margin-top: 14px; border: 1px solid var(--filet); border-radius: 12px; }
.jetons { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.jeton { font-family: var(--font-mono); font-size: .78125rem; letter-spacing: .04em; text-transform: uppercase; border: 1px solid var(--filet); border-radius: 999px; padding: 5px 12px; color: var(--encre-2); background: var(--blanc); }

/* Les limites : dites clairement, sans en faire un tribunal. */
.limites li {
  display: flex;
  gap: 22px;
  align-items: baseline;
  padding: 18px 4px;
  border-bottom: 1px solid var(--filet);
  font-size: 1.0625rem;
  color: var(--encre-2);
}
.limites { list-style: none; padding-left: 0; max-width: 900px; border-top: 1px solid var(--filet); }
.limites strong { color: var(--encre); font-weight: 500; }
.limites .mono { flex: none; color: var(--encre-2); }

/* ── Tableaux ──────────────────────────────────────────────────────────── */
/* ⚠️ Un tableau qui défile sans le dire perd ses colonnes de droite en
   silence. Mesuré à 393 px sur la table des fiches CEE (pac.html) : la
   colonne « État » — celle qui dit qu'une fiche est ABROGÉE, donc la seule
   qu'on vient lire — était coupée, et rien à l'écran n'indiquait qu'il y
   avait de la matière au-delà du bord.
   Le repère est celui déjà employé par `.doc` (l. 1416) : deux voiles blancs
   qui s'effacent en bout de course (`background-attachment: local`) et deux
   ombres fixes qui restent tant qu'il reste à lire d'un côté. Même règle,
   même écriture — la recopier autrement les ferait diverger.
   ⚠️ Le voile doit avoir la couleur de CE QU'IL Y A DERRIÈRE, sinon il ne
   s'efface pas, il se voit : le même tableau vit sur le fond de page dans un
   volet, sur du blanc dans une carte, et sur du bleu pâle dans la carte de la
   grille HFO. D'où `--voile`, redéfini par contexte. */
.tablewrap {
  --voile: var(--fond);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  background-color: var(--voile);
  background-image:
    linear-gradient(90deg, var(--voile), rgba(255, 255, 255, 0)),
    linear-gradient(90deg, rgba(255, 255, 255, 0), var(--voile)),
    linear-gradient(90deg, rgba(20, 22, 28, .13), rgba(20, 22, 28, 0)),
    linear-gradient(90deg, rgba(20, 22, 28, 0), rgba(20, 22, 28, .13));
  background-position: 0 0, 100% 0, 0 0, 100% 0;
  background-repeat: no-repeat;
  background-size: 36px 100%, 36px 100%, 14px 100%, 14px 100%;
  background-attachment: local, local, scroll, scroll;
}
.carte .tablewrap { --voile: var(--blanc); }
.carte--sonde .tablewrap { --voile: var(--sonde-pale); }
.carte--bleue .tablewrap { --voile: var(--bleu-pale); }
.carte--verte .tablewrap { --voile: var(--vert-pale); }
.carte--orange .tablewrap { --voile: var(--orange-pale); }
.tbl { width: 100%; border-collapse: collapse; font-size: .95rem; }
.tbl th {
  text-align: left;
  font-family: var(--font-mono);
  font-size: .8rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--encre-2);
  font-weight: 400;
  padding: 0 18px 12px 0;
  border-bottom: 1px solid var(--encre);
}
.tbl td { padding: 13px 18px 13px 0; border-bottom: 1px solid var(--filet); vertical-align: top; color: var(--encre-2); }
.tbl strong { color: var(--encre); font-weight: 500; }
/* ⚠️ Un identifiant réglementaire ne se coupe pas. Les codes de fiche CEE se
   cassaient sur trois lignes à leurs traits d'union — « BAR- » / « TH- » /
   « 171 » — et devenaient illisibles, donc irrecopiables. La classe est posée
   sur le tableau et non sur `.tbl` en général : ailleurs, une première colonne
   insécable déborderait. */
.tbl--refs td:first-child { white-space: nowrap; }

/* Les liens de secours de la 404 : sur cette page, ce sont la seule issue.
   Ils sont donc empilés et visables au doigt, pas séparés par des points
   médians dans du texte courant. Le séparateur est le filet, pas le « · ». */
.liens-secours { display: flex; flex-direction: column; }
.liens-secours a {
  display: flex;
  align-items: center;
  min-height: 44px;
  border-top: 1px solid var(--filet);
}
.liens-secours a:first-child { border-top: 0; }

/* ── FAQ ── Une colonne centrée, groupée par thème, chaque groupe dans sa
   feuille : une page de réponses, pas une liste brute collée à gauche. */
.faq { max-width: 780px; margin-inline: auto; }
.faq__groupe { background: var(--blanc); border: 1px solid var(--filet); border-radius: 18px; padding: 10px 26px; margin-top: 26px; }
.faq__groupe > .mono { display: flex; align-items: center; gap: 9px; color: var(--encre-2); padding: 16px 0 10px; }
.faq details { border-top: 1px solid var(--filet); }
.faq summary { padding: 17px 2px; font-weight: 500; font-size: 1.1rem; cursor: pointer; list-style: none; display: flex; align-items: baseline; gap: 12px; min-height: 44px; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: '+'; margin-left: auto; color: var(--encre-2); font-size: 1.2rem; }
.faq details[open] summary { color: var(--sonde); }
.faq details[open] summary::after { content: '−'; }
.faq summary:hover { color: var(--sonde); }
.faq p { padding: 0 2px 20px; color: var(--encre-2); max-width: none; }

/* ── Formulaire ────────────────────────────────────────────────────────── */
.formulaire { background: var(--blanc); border: 1px solid var(--filet); border-radius: 18px; padding: 36px; }
/* ⚠️ `auto-fit` et non `1fr 1fr` : le formulaire vit dans une colonne de
   `.duo`, qui ne se replie qu'à 860 px. Entre 861 et 1003 px, deux champs
   forcés côte à côte dans cette colonne étroite débordaient de 58 px — seule
   la page contact était touchée, et c'est la seule page qui convertit. La
   paire se replie maintenant d'elle-même, sans dépendre d'un palier. */
.form__duo { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 18px; margin-bottom: 18px; }
.form__duo > .champ, .champ input, .champ select, .champ textarea { min-width: 0; }
/* ⚠️ Le rythme était inversé sous 860 px, où la paire passe en une colonne :
   54 px entre les deux champs d'une MÊME paire (les 18 px de `gap`, plus les
   18 px de `margin-bottom` du champ, plus les 18 px que `p + p` ajoute) contre
   18 px entre deux paires. Deux champs liés paraissaient plus éloignés que
   deux champs sans rapport. C'est la paire qui porte l'écart, pas le champ. */
.form__duo > .champ { margin: 0; }
.champ { display: flex; flex-direction: column; gap: 7px; margin-bottom: 18px; }
.champ label { font-family: var(--font-mono); font-size: .8rem; letter-spacing: .07em; text-transform: uppercase; color: var(--encre-2); }
/* Le mot, pas l'astérisque : une étoile demande une légende que personne ne
   lit, et les lecteurs d'écran l'annoncent « astérisque ». */
.requis { color: var(--sonde); letter-spacing: .07em; }
.champ input, .champ select, .champ textarea {
  font: 400 1.05rem var(--font-sans);
  color: var(--encre);
  background: var(--fond);
  border: 1px solid var(--filet-champ);
  border-radius: 10px;
  min-height: 48px;
  padding: 10px 14px;
}
.champ input:focus-visible, .champ select:focus-visible, .champ textarea:focus-visible { border-color: var(--sonde); box-shadow: 0 0 0 3px rgba(47, 53, 201, .28); }
.champ textarea { resize: vertical; }
.pot { position: absolute; left: -9999px; }
.petit { font-size: .875rem; line-height: 1.5; color: var(--encre-2); }

/* ── Mentions ──────────────────────────────────────────────────────────── */
.onglets { display: flex; gap: 8px; flex-wrap: wrap; margin: 24px 0 8px; padding: 0; }
.onglets a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 16px;
  border: 1px solid var(--filet);
  border-radius: 999px;
  text-decoration: none;
  color: var(--encre);
  font-size: .95rem;
}
.onglets a:hover { background: var(--blanc); }
.prose { max-width: 760px; }
.prose h2 { margin-top: 56px; font-size: 1.8rem; }
.prose h3 { margin: 30px 0 8px; }
.prose p, .prose ul { margin-top: 12px; color: var(--encre-2); }
.prose dt { font-family: var(--font-mono); font-size: .8rem; letter-spacing: .07em; text-transform: uppercase; color: var(--encre-2); margin-top: 14px; }
.prose dd { margin: 3px 0 0; }
.prose a { color: var(--encre); }

/* ── Le pied : la seconde aube, en aurore ──────────────────────────────── */
.couchant {
  height: clamp(260px, 34vw, 520px);
  background: linear-gradient(180deg,
    var(--fond) 0%, #D9F5F0 18%, #8CE4DA 36%, #34C6C2 52%, #14868F 68%,
    #0A3C4E 82%, #041520 92%, #000 100%);
}
.pied { background: #000; color: var(--blanc); padding: 40px 0 56px; }
.pied__inner { max-width: 1320px; margin-inline: auto; padding-inline: 28px; }
.pied__appel { display: flex; align-items: center; justify-content: space-between; gap: 32px; padding-bottom: 48px; }
.pied__appel h2 { color: var(--blanc); max-width: 660px; font-size: clamp(1.8rem, 3vw, 2.7rem); }
.pied__plan {
  border-top: 1px solid var(--nuit-filet);
  padding-top: 44px;
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 32px;
}
.pied__plan p { color: var(--sur-nuit-2); font-size: .95rem; max-width: 26em; margin-top: 14px; }
.pied__t { color: var(--sur-nuit-2); display: block; margin-bottom: 10px; }
.pied__plan nav a {
  display: flex;
  align-items: center;
  min-height: 44px;
  color: var(--sur-nuit);
  text-decoration: none;
  font-size: .98rem;
}
.pied__plan nav a:hover { color: var(--blanc); }
.pied__bas {
  border-top: 1px solid var(--nuit-filet);
  margin-top: 44px;
  padding-top: 28px;
  display: flex;
  align-items: center;
  gap: 28px;
  flex-wrap: wrap;
}
.pied__logo { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; color: var(--blanc); font-weight: 600; font-size: 1.2rem; text-decoration: none; }
.pied__copy { color: var(--sur-nuit-2); margin-left: auto; }

/* Le libellé court du bouton de démo n'existe que sous 400 px. */
.tete__action--court { display: none; }

.passe { position: absolute; left: -9999px; background: var(--blanc); padding: 12px 20px; z-index: 50; }
.passe:focus-visible { left: 12px; top: 12px; }

/* ── Tablette ──────────────────────────────────────────────────────────── */
@media (max-width: 1100px) {
  /* ⚠️ Entre 861 et 1003 px, le méga-panneau poussait le document à 1004 px de
     large sur les DOUZE pages — un défilement horizontal permanent, dans la
     bande que personne ne teste parce qu'on vérifie le bureau puis le
     téléphone. Sa LARGEUR était pourtant bornée au viewport
     (`min(800px, 100vw - 48px)`, l. 347) ; c'est son ANCRAGE qui ne l'était
     pas : il part du bord gauche de l'entrée « Produit », donc plus l'écran
     rétrécit, plus il sort par la droite.
     En rendant `.groupe` statique, le panneau s'ancre sur `.tete` — qui est
     positionné depuis qu'il est collant — et non plus sur l'entrée de menu.
     Bordé des deux côtés, il ne peut plus déborder par construction.
     Sous 860 px la question ne se pose pas : `.panneau` y est masqué. */
  .groupe { position: static; }
  .panneau { left: 28px; right: 28px; width: auto; }

  .trio { grid-template-columns: 1fr 1fr; }
  .bento { grid-template-columns: 1fr 1fr; }
  .bento__large { grid-column: span 2; }
  .carte-nuit { flex-direction: column; min-height: 0; }
  .carte-nuit__texte { flex: none; }
  /* ⚠️ Le débord de la pièce (l. 839-848) est un effet de GRAND écran : il
     montre un coin de document et suggère qu'il continue au-delà de la carte.
     Sous 1100 px la carte fait la largeur de l'écran — un pourcentage
     supérieur à 100 % ne suggère plus rien, il jette le tiers droit derrière
     l'`overflow: hidden` de .carte-nuit (l. 813), sans défilement ni recours.
     Mesuré avant correction : 335 px coupés à 1000 px, 305 à 900, 435 à 860.
     La pièce revient donc dans le cadre. */
  .carte-nuit__visuel { padding: 0 22px 22px; min-height: 0; }
  .carte-nuit__visuel img,
  .carte-nuit--haute .carte-nuit__visuel img,
  .carte-nuit__visuel .maquette {
    position: static;
    top: auto;
    left: auto;
    width: 100%;
    max-width: 100%;
    border-radius: 12px;
  }
  /* ⚠️ Cette ligne n'est pas facultative. Le `max-width: 100%` ci-dessus pèse
     0,2,0 et bat `.tel { max-width: 420px }` (0,1,0, l. 670) — lequel est de
     toute façon déjà neutralisé par `max-width: none` (l. 843). Sans elle,
     l'écran de téléphone est dessiné à 782 px de large à 860 px de fenêtre,
     près de deux fois sa limite de conception : ce n'est plus un téléphone. */
  .carte-nuit__visuel .tel { max-width: 420px; margin-inline: auto; }

  /* ⚠️ Le document défile dès 1100 px, et pas seulement sous 860. Le défaut
     vivait dans la bande 862-1100 px — celle que personne ne teste, parce
     qu'on vérifie le bureau puis le téléphone : conformite.html était la seule
     page du site à défiler latéralement à 1024 px, les deux tableaux du
     registre sortant du cadre du document, du panneau vert et de la page. Et
     c'est la page qui vend la conformité.
     Les quatre dégradés annoncent le défilement : deux voiles blancs qui
     s'effacent en bout de course (`background-attachment: local`) et deux
     ombres fixes qui restent tant qu'il y a de la matière à droite ou à
     gauche. Sans ce repère, deux colonnes du Cerfa sur six restent hors champ
     sans que rien ne le dise. */
  .doc {
    overflow-x: auto;
    overscroll-behavior-x: contain;
    background-color: var(--blanc);
    background-image:
      linear-gradient(90deg, var(--blanc), rgba(255, 255, 255, 0)),
      linear-gradient(90deg, rgba(255, 255, 255, 0), var(--blanc)),
      linear-gradient(90deg, rgba(20, 22, 28, .13), rgba(20, 22, 28, 0)),
      linear-gradient(90deg, rgba(20, 22, 28, 0), rgba(20, 22, 28, .13));
    background-position: 0 0, 100% 0, 0 0, 100% 0;
    background-repeat: no-repeat;
    background-size: 36px 100%, 36px 100%, 14px 100%, 14px 100%;
    background-attachment: local, local, scroll, scroll;
  }
  .doc-tbl { min-width: 30rem; }

  /* La séquence épinglée garde ses deux colonnes jusqu'au palier téléphone —
     c'est là qu'elle raconte quelque chose. Seuls la gouttière et l'ancrage
     collant se resserrent : la barre d'en-tête est plus basse dès 1010 px, et
     un `top` de 110 px laisserait un trou au-dessus du titre fixé. */
  .epingle { padding: 72px 20px 32px; }
  .epingle__inner { gap: 36px; }
  .epingle__gauche { top: 92px; }
}

/* ── Téléphone ─────────────────────────────────────────────────────────── */
@media (max-width: 860px) {
  .bandeau { font-size: .85rem; padding: 8px 12px; gap: 10px; }
  /* ⚠️ Première cible tactile des douze pages, et elle faisait 30,8 px de haut.
     Ne pas corriger la ligne 245 : à la souris le bandeau de bureau est juste. */
  .bandeau__chip { min-height: 44px; padding: 10px 14px; }
  .scene { margin: 48px auto 64px; padding-inline: 16px; }
}

/* ── En-tête replié ────────────────────────────────────────────────────── */
/* ⚠️ 1010 px et non 860 : ces règles vivaient dans le palier téléphone, et
   entre 861 et 1003 px la barre de bureau complète — logo, navigation, lien
   Contact, bouton de démo — poussait le document à 1004 px de large sur les
   DOUZE pages. Un défilement horizontal permanent, sur toute une classe de
   fenêtres : tablette en paysage, portable 1280 avec deux fenêtres côte à
   côte, navigateur simplement pas plein écran. Personne ne l'avait vu parce
   qu'on vérifie le bureau, puis le téléphone, jamais l'entre-deux.
   La navigation se replie donc dès que la barre cesse de tenir, et non
   quand l'écran devient un téléphone. */
@media (max-width: 1010px) {
  /* L'en-tête tient sur UNE ligne : logo, démo, burger. Le menu se déplie
     sous la barre, en panneau blanc pleine largeur. */
  .tete__inner { gap: 8px; padding: 10px 14px; }
  .tete__logo { font-size: 1.15rem; }
  .tete__action { margin-left: auto; padding: 0 12px; font-size: .78125rem; min-height: 44px; }
  .burger {
    display: inline-flex;
    /* ⚠️ Sans `flex: none`, le bouton est ÉCRASÉ à 22 px de large dès 360 px —
       largeur Android courante — et pousse la page à 320 px : ses trois <span>
       vides lui donnent un `min-content` minuscule, quand le bouton démo
       résiste grâce à son `white-space: nowrap`. La seule cible tactile qui
       ouvre la navigation est alors perdue. */
    flex: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 44px;
    height: 44px;
    padding: 10px;
    background: none;
    border: 1px solid var(--filet);
    border-radius: 9px;
    cursor: pointer;
  }
  .burger span { display: block; height: 2px; background: var(--encre); border-radius: 2px; transition: transform .18s ease, opacity .18s ease; }
  .tete--ouverte .burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .tete--ouverte .burger span:nth-child(2) { opacity: 0; }
  .tete--ouverte .burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

  .tete__nav { display: none; }
  .tete--ouverte .tete__nav {
    display: flex;
    flex-direction: column;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin: 0;
    padding: 8px 18px 22px;
    background: var(--blanc);
    border-bottom: 1px solid var(--filet);
    box-shadow: 0 30px 70px rgba(20, 22, 28, .16);
    z-index: 30;
  }
  .tete--ouverte .tete__nav a, .tete--ouverte .groupe > a {
    width: 100%;
    min-height: 54px;
    border-bottom: 1px solid var(--filet);
    border-radius: 0;
    justify-content: flex-start;
    padding-inline: 4px;
  }
  .tete--ouverte .seul-mobile { display: inline-flex; border-bottom: 0; }
  .groupe { width: 100%; }
  .groupe .chevron { display: none; }
  .panneau { display: none; }
}

/* ── Téléphone (suite) ─────────────────────────────────────────────────── */
@media (max-width: 860px) {
  .heros { padding-top: 44px; }
  .heros__actions { flex-direction: column; align-items: center; gap: 10px; }
  .referentiels__liste { gap: 22px 28px; }
  /* 1,0625rem = 17px : le plancher du texte courant. 1,05rem valait 16,8. */
  .referentiels__liste li { font-size: 1.0625rem; }
  .familles { padding-bottom: 64px; }
  .familles__grille { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .familles__grille a { font-size: .98rem; padding: 12px 14px; min-height: 62px; }
  .poste__nom { display: none; }

  .nuit { padding-bottom: 88px; }
  .nuit__tete { padding-inline: 18px; }
  .cartes { padding-inline: 16px; gap: 18px; }
  .paire { grid-template-columns: 1fr; gap: 18px; }
  .carte-nuit__texte { padding: 26px 22px; }
  /* ⚠️ Ce bloc portait `left: 22px; width: 150%`. À spécificité égale (0,2,0)
     il est plus bas dans le fichier que celui du palier 1100 : corriger le
     seul palier 1100 laissait donc le 150 % recasser l'affichage sous 860 px.
     Il ne reste ici que le resserrement du cadre. */
  .carte-nuit__visuel { padding: 0 16px 16px; }

  .duo, .trio, .form__duo { grid-template-columns: 1fr; }
  .cta-bande__inner { padding: 26px 22px; }
  .cta-bande .btn { width: 100%; justify-content: center; }
  .pied__plan { grid-template-columns: 1fr; gap: 20px; }
  .pied__bas { justify-content: center; }
  .pied__copy { margin-left: 0; text-align: center; }
  .agenda__grille { grid-template-columns: 1fr 1fr; }
  .bento { grid-template-columns: 1fr; }
  .bento__large { grid-column: auto; }
  .vis { grid-template-columns: 1fr; }
  .vis--inverse > :first-child { order: 0; }
  .pied__appel { flex-direction: column; align-items: stretch; }
  .pied__appel .btn { width: 100%; justify-content: center; }

  .sec { padding-top: 56px; padding-inline: 16px; }
  .sec--fin { padding-bottom: 64px; }
  .entete-page { padding-top: 40px; }
  .carte { padding: 24px 20px; }
  .formulaire { padding: 24px 18px; }
  .mat { border-radius: 18px; }
  .limites li { flex-direction: column; gap: 6px; }
  .doc__parties { grid-template-columns: 1fr; }
  .doc__tete { flex-direction: column; }
  .doc__titre { text-align: left; }
  .doc__signatures { grid-template-columns: 1fr; }
  /* ⚠️ Ne PAS masquer de colonnes ici. La feuille d'origine cachait les
     colonnes 3 à 5, ce qui retirait « Quantité » et « Bouteille » du tableau
     des opérations sur le fluide — c'est-à-dire précisément ce que la fiche
     d'intervention sert à montrer. Le document garde donc toutes ses colonnes
     et défile dans son propre cadre. */
  /* Le défilement du document et son repère de bord sont posés au palier
     1100 px : ils valent aussi ici, inutile de les réécrire. Une règle métier
     écrite en double finit par diverger. */
  .mat .maquette, .mat .legende { max-width: 100%; }
  .tel__ligne span span { display: none; }

  /* Le calcul reste lisible : les opérandes passent en colonne, les signes
     disparaissent — une flèche verticale n'aurait aucun sens. */
  .calcul__ligne { flex-direction: column; gap: 8px; }
  .calcul__signe { display: none; }

  /* ⚠️ Sur téléphone la séquence épinglée redevient une suite de blocs, et ce
     n'est pas un repli par défaut : un titre COLLÉ mange le tiers d'un écran
     de 844 px de haut, et les volets défileraient sous lui dans le peu qui
     reste. L'index numéroté disparaît avec l'épinglage — il ne servait qu'à
     suivre la colonne fixe, et sans elle il répète les titres qui suivent.
     Les volets, eux, sont PLEINEMENT VISIBLES : l'estompe à .3 d'opacité n'a
     de sens que face à un voisin actif au centre de l'écran. */
  .epingle { padding: 56px 16px 24px; }
  .epingle__inner { grid-template-columns: 1fr; gap: 24px; }
  .epingle__gauche { position: static; }
  .epingle__index { display: none; }
  .volet { min-height: 0; padding-block: 28px; }
  html.js .volet { opacity: 1; transform: none; }
  .arbitrage__l { flex-wrap: wrap; }
  .arbitrage__l .mono { width: auto; }
  .arbitrage__l b { margin-left: 0; width: 100%; }
}

/* ── Petit téléphone ───────────────────────────────────────────────────── */
/* ⚠️ Ces deux paliers n'existaient pas : la feuille passait de 860 px à rien.
   Tout ce qui suit tient à une mesure, et une seule — la barre d'en-tête fait
   368 px de large sur les DOUZE pages, à l'identique, parce que le logo, le
   bouton de démo et le bouton de menu ne se compriment plus une fois la cible
   tactile du menu rendue rigide. À 360 px il manque 8 px, à 320 px il en
   manque 48. En dessous de 368 px, aucune page ne tenait dans l'écran. */
@media (max-width: 640px) {
  .sec, .cartes, .scene { padding-inline: 14px; }
  .nuit__tete { padding-inline: 14px; }

  /* ⚠️ La gouttière des tableaux de CONTENU RÉEL passe de 18 à 8 px. Ceux-là
     ne se replient pas — ils gardent leur sémantique de tableau, parce qu'un
     lecteur d'écran doit pouvoir les parcourir colonne par colonne : ce sont
     les obligations réglementaires et les fiches CEE, pas des maquettes.
     Trois colonnes × 10 px rendent 30 px, et c'est exactement ce qui manquait
     pour que `pac.html` (393 px de contenu dans 361 visibles) et
     `conformite.html` cessent de glisser sur un téléphone courant.
     ⚠️ À 320 px il reste du glissement sur `.tbl--refs`, et c'est ASSUMÉ : la
     première colonne y est insécable exprès (un code de fiche CEE cassé sur
     trois lignes est irrecopiable). Glisser de 37 px vaut mieux qu'un
     identifiant réglementaire illisible. */
  .tbl th, .tbl td { padding-right: 8px; }
}

/* ── Les documents se REPLIENT sur téléphone ─────────────────────────────── */
/* ⚠️ ON SUPPRIME LE DÉFILEMENT DU DOCUMENT, ON NE L'AMÉLIORE PAS.
   Mesuré sur iPhone 15 Pro (393 px) : la fiche Cerfa faisait 541 px de large
   pour 363 visibles. Un TIERS du document hors champ, à aller chercher au
   doigt — et comme le conteneur qui défilait était `.doc` tout entier, tirer
   vers la gauche pour voir la colonne « Motif » emportait AUSSI l'en-tête, les
   trois cartes d'identité et les signatures, qui se coupaient au bord. C'est
   ce que montrait la copie d'écran : un document qui glisse en bloc.

   ⚠️ Et le lecteur n'est pas n'importe qui : l'entrepreneur qui découvre le
   produit le fait très probablement depuis son téléphone. La fiche Cerfa est
   l'argument central de la page — la montrer coupée, c'est démontrer le
   contraire de ce qu'on affirme.

   Le palier 1100 px garde son défilement, et il a raison de l'avoir : entre
   700 et 1100 px il reste assez de largeur pour que le document RESSEMBLE à
   un document, et le replier là serait absurde. Les deux mécanismes se
   relaient, ils ne se contredisent pas.

   ⚠️ CE REPLI NE COÛTE RIEN EN ACCESSIBILITÉ, et c'est ce qui l'autorise.
   `display: block` sur un `<table>` détruit la sémantique de tableau pour les
   lecteurs d'écran — ce serait rédhibitoire sur du contenu réel. Mais les huit
   `.doc-tbl` du site vivent toutes dans une maquette `role="img"` porteuse
   d'un `aria-label` : leur intérieur est DÉJÀ remplacé par cette description.
   ⚠️ Ne jamais reprendre ce bloc pour `.tbl`, qui est du contenu réel (les
   obligations réglementaires de conformite.html, les fiches CEE de pac.html).
   Celui-là garde son `.tablewrap` qui défile, et c'est volontaire. */
/* ⚠️ CE BLOC-CI RESTE UNE REQUÊTE DE FENÊTRE, et c'est volontaire : il éteint
   le décor du DOCUMENT LUI-MÊME — son défilement et les quatre dégradés qui
   l'annoncent. Un `@container` ne peut pas styler son propre conteneur, et
   `.doc` est le conteneur. Sur téléphone il occupe toute la largeur, donc la
   fenêtre est une bonne approximation de sa largeur : les deux règles disent
   la même chose au même moment.
   ⚠️ Le défilement reste en place au-dessus de 700 px, et c'est le FILET pour
   un navigateur sans `@container` : il glisse comme avant plutôt que de
   pousser la page hors de l'écran. Ne pas le supprimer en croyant nettoyer. */
@media (max-width: 700px) {
  .doc {
    overflow-x: visible;
    background-image: none;
  }
}

/* ⚠️ 34rem — 544 px — est une MESURE, pas un chiffre rond : le plus large des
   huit tableaux (les six colonnes du Cerfa) demande 534 px pour tenir sans
   comprimer ses colonnes. Sous cette largeur il n'y a pas de tableau possible,
   seulement un tableau serré ou un tableau qui glisse ; au-dessus, il n'y a
   rien à replier. Le seuil est là où la matière l'a mis. */
@container (max-width: 34rem) {
  .doc-tbl { min-width: 0; }

  /* L'en-tête disparaît : chaque libellé est réimprimé devant sa valeur, il
     ferait doublon. C'est `data-libelle` sur chaque `<td>` qui le porte —
     posé sur les 87 cellules des pages sources, pas à la main. */
  .doc-tbl thead { display: none; }
  .doc-tbl,
  .doc-tbl tbody,
  .doc-tbl tr,
  .doc-tbl td { display: block; width: auto; }

  /* Une ligne du tableau devient un bloc, séparé du suivant par le même filet
     que le reste du document : le registre typographique ne change pas, seule
     la mise en page cède. */
  .doc-tbl tr { border-bottom: 1px solid var(--filet); padding: 9px 0; }
  .doc-tbl tr:last-child { border-bottom: 0; }

  /* ⚠️ `align-items: start` et non `baseline` : une valeur qui tient sur trois
     lignes alignerait sa PREMIÈRE ligne sur le libellé en `baseline`, ce qui
     est juste — mais une gélule d'état (`.etat-mot`) n'a pas la même ligne de
     base que du texte nu, et le libellé sautait de deux pixels d'une ligne à
     l'autre. En `start`, tout part du haut.

     ⚠️ LA VALEUR EST ENVELOPPÉE DANS `.doc-v`, ET C'EST INDISPENSABLE. Une
     cellule au contenu mixte — la pastille d'état PUIS le mot « Charge », ou
     un libellé PUIS un `<br>` PUIS sa précision — donne DEUX enfants de
     grille : le second retombait dans la colonne du libellé, une ligne plus
     bas. « Charge » s'affichait sous « NATURE » au lieu d'être en face. Le
     `<span>` unique règle la question à la racine plutôt que de la rattraper
     au sélecteur, et il est invisible sur grand écran. */
  .doc-tbl td {
    border: 0;
    padding: 3px 0;
    display: grid;
    grid-template-columns: 7.5rem 1fr;
    gap: 4px 10px;
    align-items: start;
  }
  .doc-tbl td::before {
    content: attr(data-libelle);
    font-family: var(--font-mono);
    font-size: .7rem;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--encre-2);
    line-height: 1.5;
  }

  /* ⚠️ `.doc-v` ÉTAIT EMPLOYÉE DANS LES PAGES ET DÉCLARÉE NULLE PART.
     Elle fonctionnait par accident : un `<span>` devient bloc dès qu'il est
     enfant de grille, et la colonne tenait. Rien ne l'écrivait pourtant, et
     rien n'aurait prévenu le jour où la cellule cesse d'être une grille.
     `min-width: 0` n'est pas décoratif non plus : c'est la leçon mobile de ce
     dépôt — un enfant de grille sans lui refuse de rétrécir sous la largeur
     de son plus long mot, et un numéro de bouteille déborde la carte. */
  .doc-v { display: block; min-width: 0; }
  /* Le nombre reste insécable, mais il n'est plus aligné à droite : dans une
     colonne de valeurs empilées, une seule quantité alignée à droite pendrait
     dans le vide. */
  .doc-tbl .doc-nb { text-align: left; }

  /* Les deux signatures passent l'une sous l'autre : côte à côte sur 353 px,
     chacune reçoit 170 px et le nom du signataire se coupe. */
  .doc__signatures { grid-template-columns: 1fr; }

  /* Les trois cartes d'identité du Cerfa faisaient 3 × 110 px : « Attestation
     de capacité AC-000000 » y tenait sur quatre lignes. Empilées, elles se
     lisent d'un coup d'œil. */
  .doc__parties { grid-template-columns: 1fr; }

  /* L'en-tête du document et son titre : à droite sur 353 px, le numéro de
     fiche se serrait contre la raison sociale. */
  .doc__titre { text-align: left; }
}

/* ⚠️ 380 px et pas 400 : la barre complète mesure 368 px, donc elle tient
   encore à 375 et à 390 — les deux largeurs de téléphone les plus répandues.
   Raccourcir le libellé au-dessus de 380 px, c'est abîmer la conversion là où
   rien ne l'exigeait. Le seuil suit la mesure, pas un chiffre rond. */
@media (max-width: 380px) {
  /* Le libellé cède, pas le bouton : c'est la seule conversion de la page, et
     le palier téléphone la maintient visible exprès. Un « Démo » qu'on peut
     viser vaut mieux qu'un « Demander une démo » qui pousse la page hors de
     l'écran. */
  .tete__action--long { display: none; }
  .tete__action--court { display: inline; }
  .tete__inner { gap: 6px; padding: 10px; }
  .tete__logo { font-size: 1.05rem; }
  .tete__action { padding: 0 12px; }

  /* Une gélule d'état ne se coupe pas, elle passe à la ligne. */
  .fiche-certif__ligne, .tel__tete, .tel__ligne, .tel__pied { flex-wrap: wrap; }
}
