/* ═══════════════════════════════════════════════════════════════════════════
   plateforme.css : le site public à plusieurs pages.

   ─── Ce que cette feuille porte, et ce qu'elle ne porte pas ────────────────
   Elle porte ce qui n'existait pas quand la plateforme tenait en une page :
   la barre à menus dépliants, le pied de page à colonnes, les sections de la
   page d'accueil refaite, et les gabarits des pages intérieures.

   Elle NE porte PAS les jetons de la marque, les boutons, les sections, les
   cartes de formules, le tableau comparatif ni les formulaires : tout cela vit
   dans `vitrine.css`, qui est chargée avant, et qui ne bouge pas. Redéclarer
   ici une couleur ou un rayon, c'est se garantir deux jaunes légèrement
   différents le jour où l'un des deux est corrigé.

   ─── Sur la couleur, parce que c'est la question qu'on pose en premier ─────
   Le jaune de la marque (#FACC15) donne 1,72:1 sur du blanc : c'est un aplat,
   jamais un texte. Partout où la maquette d'origine pose un mot en couleur
   d'accent, on pose ici soit `--accent-lisible` (#A16207, mesuré 4,8:1), soit
   le surligneur `.surligne` de `vitrine.css`, qui est un aplat jaune AVEC de
   l'encre dessus. C'est la seule différence de fond avec la maquette, et elle
   n'est pas négociable : un titre invisible n'est pas un titre.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── Jetons propres à cette feuille ──────────────────────────────────────── */
:root {
  /* La durée des deux animations de défilement. Déclarées ici parce qu'elles
     se règlent ensemble : deux bandeaux qui défilent à des vitesses trop
     proches donnent l'impression d'un défaut d'affichage.

     ─── Pourquoi le ruban est si lent ────────────────────────────────────
     Sa piste fait vingt-deux mille pixels, cinquante-deux métiers en double.
     À trente secondes, elle filait à trois cent cinquante pixels par seconde :
     un nom de métier passait sous l'œil en moins d'une demi-seconde, donc
     personne ne lisait le sien, donc le ruban ne servait à rien.

     À deux cent quarante, on est à quarante-sept pixels par seconde : un nom
     de métier met quatre secondes à traverser le champ de vision, c'est-à-dire
     le temps de le reconnaître, de décider, et de cliquer dessus. C'est lent
     pour un bandeau, et c'est voulu : celui-ci n'est pas là pour faire joli,
     il est là pour qu'un carreleur voie le mot « carreleur ». */
  --defilement-bandeau: 240s;
  --defilement-avis:    46s;
}

/* ═══════════════════════════════════════════════════════════════════════════
   1 · LA BARRE DE NAVIGATION
   ═══════════════════════════════════════════════════════════════════════════ */

/* La barre était une rangée de quatre ancres vers la même page. Elle porte
   maintenant quatre entrées dont trois ouvrent un panneau pleine largeur.

   ─── Pourquoi le panneau est large, et pas une colonne sous son bouton ─────
   Une colonne de six mots nus (« Outils », « Blog », « Lexique ») demande au
   visiteur de deviner ce qu'il y a derrière chacun, et il n'en ouvre aucun.
   Le panneau large laisse la place d'écrire une ligne sous chaque nom, et
   cette ligne est ce qui fait cliquer. C'est la seule raison de sa largeur. */

/* La barre reste collée, mais au-dessus des panneaux qu'elle ouvre. Le
   `z-index` de `vitrine.css` (50) la plaçait sous le voile ; celui-ci le
   remonte, et le voile se cale entre les deux. */
.entete { z-index: 60; }

/* Posée : le filet du bas n'apparaît qu'une fois la page descendue. En haut de
   la page d'accueil, un filet gris en travers d'une bannière qui n'a pas de
   fond propre ressemble à une erreur de chargement. */
.entete--flottante:not(.est-posee):not(.est-ouverte) {
  background: transparent;
  border-bottom-color: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.entete__barre { position: relative; z-index: 2; }

/* Le fond de la barre est opaque dès qu'un panneau est ouvert : sur la page
   d'accueil elle est translucide, et un panneau ouvert laissait voir le titre
   défiler derrière les noms des menus. */
.entete.est-ouverte {
  background: var(--surface);
  /* Opaque, et FRANCHEMENT : la translucidité de la barre laissait voir le
     titre de la page défiler derrière les noms des menus pendant qu'un panneau
     était ouvert. */
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.entete__menu {
  display: flex;
  align-items: center;
  gap: .15rem;
  list-style: none;
  margin: 0; padding: 0;
}
.entete__item { position: static; }

.entete__lien {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .55rem .8rem;
  border: 0; background: none;
  border-radius: var(--rayon-pilule);
  font-size: .925rem; font-weight: 600; letter-spacing: -.01em;
  color: var(--encre-douce);
  text-decoration: none; cursor: pointer;
  transition: color var(--transition), background var(--transition);
}
/* ─── Le survol, et pourquoi il ne pose plus d'aplat ─────────────────────
   Il posait un fond gris très pâle sous l'entrée survolée. Sur une barre
   blanche c'est déjà discutable ; sur la bannière, où la barre est
   transparente, le rectangle gris apparaissait par-dessus la page et donnait
   l'impression que la barre elle-même changeait de couleur au passage de la
   souris.

   Le survol se signale donc par l'encre, qui passe de gris à noir, et par le
   chevron, qui pivote. Deux signaux qui ne peignent rien. */
.entete__lien:hover,
.entete__item.est-ouvert .entete__lien {
  color: var(--encre);
}
/* L'entrée de la page affichée. Un trait sous le mot, pas une couleur : le
   jaune de la marque sur du texte est illisible, et le gris foncé seul ne se
   distingue pas assez des trois autres entrées. */
.entete__lien.est-courant {
  color: var(--encre);
  box-shadow: inset 0 -2px 0 0 var(--pal-primaire);
  border-radius: var(--rayon-pilule) var(--rayon-pilule) 2px 2px;
}
.entete__chevron {
  opacity: .5;
  transition: transform var(--transition);
}
.entete__item.est-ouvert .entete__chevron { transform: rotate(180deg); opacity: 1; }

/* ─── Les panneaux ────────────────────────────────────────────────────────── */
.deplie {
  position: absolute; left: 0; right: 0; top: 100%;
  z-index: 1;
  background: var(--surface);
  border-bottom: 1px solid var(--trait);
  box-shadow: 0 30px 60px -30px rgba(9,9,11,.35);
}
/* L'ouverture est animée, mais l'attribut `hidden` retire l'élément du flux :
   une transition sur un élément retiré ne se joue pas. On le laisse donc dans
   le flux pendant l'animation et c'est la classe qui pilote l'opacité. */
.deplie[hidden] { display: none; }
.deplie {
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 180ms ease, transform 180ms ease;
}
.deplie.est-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .deplie { transition: none; transform: none; }
}

.deplie__grille {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 1.75rem;
  padding-block: 1.6rem 1.9rem;
}
.deplie__marqueur {
  grid-column: 1 / -1;
  display: inline-flex; align-items: center; gap: .55rem;
  font-size: .69rem; font-weight: 800;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--accent-lisible);
}
.deplie__marqueur::before {
  content: ''; width: 22px; height: 3px;
  background: var(--pal-primaire); border-radius: 2px;
}

.deplie__liens {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: .55rem;
  align-content: start;
}
.deplie--large .deplie__liens { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.deplie__lien {
  display: flex; align-items: center; gap: .85rem;
  padding: .85rem 1rem;
  background: var(--surface);
  border: 1px solid var(--trait);
  border-radius: var(--rayon-petit);
  text-decoration: none;
  color: inherit;
  transition: transform 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
}
.deplie__lien:hover {
  transform: translateX(3px);
  border-color: var(--volt-300);
  box-shadow: 0 14px 30px -22px rgba(161,98,7,.9);
  color: inherit;
}
.deplie__icone {
  flex: 0 0 auto;
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border-radius: 11px;
  background: var(--surface-accent);
  border: 1px solid var(--volt-200);
  color: var(--accent-lisible);
}
.deplie__texte { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.deplie__texte b {
  font-size: .93rem; font-weight: 700; letter-spacing: -.015em;
  color: var(--encre);
}
.deplie__texte small {
  font-size: .795rem; line-height: 1.35;
  color: var(--encre-douce); font-weight: 500;
}
.deplie__fleche {
  margin-left: auto; flex: 0 0 auto;
  color: var(--encre-tenue);
  opacity: 0; transform: translateX(-4px);
  transition: opacity 160ms ease, transform 160ms ease;
}
.deplie__lien:hover .deplie__fleche {
  opacity: 1; transform: none; color: var(--accent-lisible);
}

/* La carte mise en avant. Encre nuit et non jaune plein : quatre panneaux dont
   le tiers droit est un aplat jaune vif transforment la barre en gyrophare, et
   le jaune perd exactement ce qui le rend utile ailleurs, sa rareté. */
.deplie__vedette {
  position: relative; isolation: isolate; overflow: hidden;
  display: flex; flex-direction: column; justify-content: flex-end;
  min-height: 214px; padding: 1.5rem;
  border-radius: var(--rayon);
  background: var(--pal-encre);
  color: #fff; text-decoration: none;
  transition: transform 180ms ease, box-shadow 180ms ease;
}
.deplie__vedette::after {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: radial-gradient(120% 90% at 85% 8%, rgba(250,204,21,.30), transparent 58%);
}
.deplie__vedette:hover {
  transform: translateY(-3px);
  box-shadow: 0 26px 50px -24px rgba(9,9,11,.7);
  color: #fff;
}
.deplie__vedette-icone {
  width: 48px; height: 48px; margin-bottom: auto;
  display: grid; place-items: center;
  border-radius: 14px;
  background: rgba(250,204,21,.16);
  border: 1px solid rgba(250,204,21,.42);
  color: var(--accent-sur-sombre);
}
.deplie__vedette-titre {
  display: block;
  margin-top: 1.05rem;
  font-size: 1.28rem; font-weight: 900; letter-spacing: -.035em; line-height: 1.1;
}
.deplie__vedette-texte {
  display: block; margin-top: .45rem;
  font-size: .855rem; line-height: 1.45;
  color: var(--nuit-encre-douce);
}
.deplie__vedette-action {
  display: inline-flex; align-items: center; gap: .45rem;
  margin-top: .95rem;
  font-size: .875rem; font-weight: 800;
  color: var(--accent-sur-sombre);
}
.deplie__vedette-action svg { transition: transform 180ms ease; }
.deplie__vedette:hover .deplie__vedette-action svg { transform: translate(3px, -3px); }

/* ─── Le voile derrière un panneau ouvert ────────────────────────────────
   Il commence SOUS la barre, et c'est tout le sujet.

   Il était posé en `inset: 0`, donc il couvrait la fenêtre entière, barre
   comprise. Or il est un enfant de `.entete` : le fond de `.entete` se peint
   sous ses enfants, et le voile passait donc par-dessus le blanc de la barre.
   Mesuré au survol de « Produit » : la barre calculait bien `#FFFFFF`, et on
   voyait du gris, parce que ce qu'on voyait était du blanc recouvert de
   `rgba(9,9,11,.34)`. Le contenu de la barre, lui, est en `z-index: 2` et
   restait net : d'où l'effet exact décrit, une barre qui se grise pendant que
   le panneau reste blanc.

   Le voile sert à éteindre la PAGE pour que le panneau se détache. La barre
   n'est pas la page : elle porte le menu qu'on est en train d'utiliser, et
   l'assombrir revenait à éteindre ce qu'on regarde. */
.entete__voile {
  position: fixed;
  inset: var(--hauteur-entete) 0 0 0;
  z-index: 0;
  background: rgba(9,9,11,.34);
  animation: voile-entree 180ms ease;
}
.entete__voile[hidden] { display: none; }
@keyframes voile-entree { from { opacity: 0; } to { opacity: 1; } }

/* Sous cette largeur, les quatre entrées ne tiennent plus dans la barre : on
   bascule sur le panneau du téléphone, qui les porte toutes à plat. */
@media (max-width: 1060px) {
  .entete__nav { display: none; }
  .deplie { display: none !important; }
}

/* Le panneau du téléphone porte maintenant les titres de groupe. */
.entete__panneau-titre {
  margin-top: 1rem;
  font-size: .68rem; font-weight: 800;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--encre-tenue);
}
.entete__panneau-titre:first-child { margin-top: 0; }
.entete__panneau-titre-lien { font-weight: 800 !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   2 · LE PIED DE PAGE
   ═══════════════════════════════════════════════════════════════════════════ */

.pied__haut {
  display: grid;
  grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
  gap: 3rem;
  align-items: start;
}
.pied__baseline {
  margin-top: .85rem;
  font-size: .875rem; line-height: 1.6;
  color: var(--encre-douce);
  max-width: 34ch;
}
.pied__colonnes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 1.75rem 1.5rem;
}
.pied__colonne h3 {
  font-size: .68rem; font-weight: 800;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--encre-tenue);
  margin-bottom: .9rem;
}
.pied__colonne ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.pied__colonne a {
  font-size: .855rem; font-weight: 500;
  color: var(--encre-douce); text-decoration: none;
}
.pied__colonne a:hover { color: var(--encre); text-decoration: underline; }

.pied__reseaux { display: flex; gap: .5rem; margin-top: 1.1rem; }
.pied__reseaux a {
  width: 36px; height: 36px;
  display: grid; place-items: center;
  border: 1px solid var(--trait); border-radius: 50%;
  color: var(--encre-tenue);
  transition: color var(--transition), border-color var(--transition);
}
.pied__reseaux a:hover { color: var(--encre); border-color: var(--encre); }

/* Les cinquante-deux métiers, repliés.

   Pas de filet au-dessus : `.pied__haut` en pose déjà un EN DESSOUS de lui, et
   les deux se retrouvaient à deux centimètres l'un de l'autre, ce qui donnait
   deux traits parallèles entre les icônes sociales et le repli. Un filet sert
   à séparer deux choses ; deux filets ne séparent rien de plus, ils signalent
   seulement que deux feuilles ont eu la même idée. */
.pied__secteurs {
  margin-top: 1.75rem;
  padding-top: 0;
}
.pied__secteurs summary {
  cursor: pointer;
  font-size: .78rem; font-weight: 800;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--encre-tenue);
}
.pied__secteurs summary:hover { color: var(--encre); }
.pied__secteurs-liste {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: .4rem 1rem;
  margin-top: 1.1rem;
}
.pied__secteurs-liste a {
  font-size: .8rem; color: var(--encre-tenue); text-decoration: none;
}
.pied__secteurs-liste a:hover { color: var(--encre); text-decoration: underline; }

@media (max-width: 760px) {
  .pied__haut { grid-template-columns: 1fr; gap: 2.25rem; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   3 · LA PAGE D'ACCUEIL
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── 3.1 · La bannière ───────────────────────────────────────────────────── */
/* Pleine hauteur, centrée, avec une lueur jaune diffuse au pied du titre. Le
   titre est énorme et très serré : c'est la signature typographique de la
   maison, et c'est ce qui se reconnaît avant la couleur. */
.ouverture {
  position: relative;
  min-height: calc(100vh - var(--hauteur-entete));
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center;
  padding: 5rem 1.5rem 4rem;
  overflow-x: clip;
}
/* ─── La trame de la bannière, et pourquoi elle est arrivée ───────────────
   Les seize pages intérieures ouvraient sur un quadrillage, l'accueil sur du
   blanc plat. Le visiteur qui arrive par l'accueil puis clique sur « Tarifs »
   change donc de fond d'écran au premier clic, ce qui est exactement le signal
   que renvoie un site assemblé de morceaux. C'est la MÊME classe que celle des
   pages intérieures, pas une copie : une seconde trame aux réglages voisins
   aurait divergé au premier ajustement.

   Le masque est redéfini ici, et seulement lui : sur une bannière pleine
   hauteur, l'effacement à 45 % de `.tete` tombe au milieu du titre. */
.ouverture .tete__trame {
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 52%, transparent 88%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 52%, transparent 88%);
  /* Plus bas qu'ailleurs : la bannière porte DÉJÀ sa lueur jaune au pied du
     titre. Deux lumières à pleine valeur sur le même écran ne se lisent plus
     comme du relief, elles se lisent comme un dégradé raté. Ici le haut ne
     fait que réchauffer, et le bas garde la signature. */
  opacity: .55;
}

.ouverture__lueur {
  position: absolute; bottom: 0; left: 50%;
  transform: translateX(-50%);
  width: min(860px, 100%); height: 380px;
  background: radial-gradient(ellipse, rgba(250,204,21,.22) 0%, transparent 66%);
  pointer-events: none;
}

/* `inline-block` et non `inline-flex` : le texte du marqueur est composé de
   deux morceaux (« pour les » puis le gras), et en flex chacun devient un
   élément qui ne partage pas la ligne de l'autre. Le résultat, sur téléphone,
   était une colonne « POUR / LES » à gauche d'un pavé de deux lignes. En
   `inline-block`, c'est du texte, et il se coupe comme du texte. */
.ouverture__marqueur {
  display: inline-block; text-align: center;
  /* Le padding a repris un cran à gauche : il compensait la pastille, qui
     laissait sinon la pilule visiblement plus creuse d'un côté. */
  padding: .4rem 1.05rem;
  border-radius: var(--rayon-pilule);
  border: 1px solid var(--volt-300);
  background: var(--surface-accent);
  color: var(--accent-lisible);
  font-size: .695rem; font-weight: 800;
  letter-spacing: .14em; text-transform: uppercase;
  margin-bottom: 2rem;
}

/* ─── La mesure du titre, et pourquoi elle a été refaite ──────────────────
   Elle était de 15 ch pour un corps allant jusqu'à 6,2 rem. Les deux ensemble
   donnaient trois lignes là où le registre en prévoit deux : « Le site de votre
   entreprise, » ne tenait pas et laissait « entreprise, » seule sur sa ligne,
   virgule comprise. Un titre dont une ligne ne porte qu'un mot et une virgule
   a l'air d'une erreur de gabarit, parce que c'en est une.

   Le corps descend d'un cran et la mesure monte à 19 ch : la première ligne
   déclarée tient, et le `<br>` du gabarit redevient la seule coupure. */
.ouverture h1 {
  font-size: clamp(2.2rem, 6.1vw, 5.2rem);
  font-weight: 900;
  line-height: 1;
  letter-spacing: -.045em;
  max-width: 19ch;
  /* `balance` répartit les mots entre les lignes, ce qui est bon pour un titre
     dont on laisse le navigateur décider des coupures, et mauvais ici : le
     registre a DÉJÀ décidé, avec son `<br>`, et « balance » se battait contre
     lui à chaque largeur de fenêtre. */
  text-wrap: pretty;
  margin-bottom: 1.4rem;
}
.ouverture__accroche {
  font-size: clamp(1rem, 1.6vw, 1.13rem);
  line-height: 1.62;
  color: var(--encre-douce);
  max-width: 34rem;
  min-height: 3.4em;
  margin-bottom: 2.2rem;
}
/* Le curseur de la machine à écrire. Un trait qui clignote, et rien d'autre :
   un caractère plein donnerait un « | » que les lecteurs d'écran épellent. */
.ouverture__curseur {
  display: inline-block;
  width: 2px; height: 1.05em;
  margin-left: .12em;
  vertical-align: -.16em;
  background: var(--volt-500);
  animation: clignote 1.05s steps(2, start) infinite;
}
@keyframes clignote { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .ouverture__curseur { animation: none; } }

.ouverture__actions {
  display: flex; gap: .75rem; flex-wrap: wrap; justify-content: center;
  margin-bottom: 3rem;
}
.ouverture__gages {
  display: flex; flex-wrap: wrap; gap: .4rem 1.25rem;
  justify-content: center;
  margin-bottom: 3rem;
  font-size: .82rem; color: var(--encre-tenue);
}
.ouverture__gage { display: inline-flex; align-items: center; gap: .4rem; }
.ouverture__gage svg { color: var(--accent-lisible); }

/* ─── 3.2 · Le bandeau défilant ───────────────────────────────────────────── */
/* Il remplace le ruban de cotations de la maquette d'origine. Ce qui défile
   ici, ce sont les métiers servis : c'est la seule chose que cette page puisse
   faire défiler honnêtement, et ça répond à la question que se pose le
   visiteur en arrivant, « est-ce que ça sait faire MON métier ». */
.ruban {
  width: 100%;
  overflow: hidden;
  /* Le fondu part de plus loin qu'avant : à 7 %, sur une fenêtre de 1 100 px,
     il ne faisait que 77 px, c'est-à-dire moins d'un jeton. Un jeton à demi
     effacé au bord ressemble à un texte coupé ; un jeton qui s'efface sur
     deux cents pixels ressemble à ce qu'il est, une bande qui continue. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 16%, #000 84%, transparent);
          mask-image: linear-gradient(to right, transparent, #000 16%, #000 84%, transparent);
}
.ruban__piste {
  display: flex; gap: .65rem; width: max-content;
  animation: ruban var(--defilement-bandeau) linear infinite;
}
@keyframes ruban { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .ruban__piste { animation: none; }
  .ruban { -webkit-mask-image: none; mask-image: none; overflow-x: auto; }
}
.ruban__jeton {
  text-decoration: none;
  display: inline-flex; align-items: center; gap: .55rem;
  flex-shrink: 0;
  padding: .6rem 1rem;
  background: var(--surface-doux);
  border: 1px solid var(--trait);
  border-radius: var(--rayon-petit);
  font-size: .795rem; font-weight: 600;
  color: var(--encre);
  text-decoration: none;
}
.ruban__jeton:hover { border-color: var(--volt-300); background: var(--surface-accent); color: var(--encre); }
.ruban__jeton span { color: var(--encre-tenue); font-weight: 500; }

/* ─── 3.3 · Le vrai problème (fond nuit, colonne collante) ──────────────────
   ─── Sur le nom de cette classe, et le défaut qu'il a coûté ──────────────
   Elle s'appelait `.constat`, et `vitrine.css` a déjà une classe de ce nom :
   un bloc de citation à `max-width: 66ch`. La section noire héritait donc de
   cette largeur maximale et s'arrêtait aux deux tiers de la fenêtre, un aplat
   noir qui ne va pas jusqu'au bord ayant l'air d'un défaut de chargement.

   Deux feuilles chargées ensemble partagent un seul espace de noms, et un nom
   court finit toujours par être pris deux fois. Les classes propres à cette
   feuille portent donc un nom qu'on ne réemploie pas par hasard. */
.diagnostic { background: var(--pal-encre); color: var(--nuit-encre); }
.diagnostic__grille {
  display: grid;
  /* Pas deux moitiés : le titre et ses trois lignes d'accroche tiennent dans
     quatre dixièmes, et les quatre constats respirent dans les six autres.
     À parts égales, la colonne de gauche était presque vide et celle de droite
     serrée, ce qui donnait à la section l'air d'être mal remplie. */
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: 2.5rem clamp(2.5rem, 5vw, 5rem);
  align-items: start;
}
/* La colonne de gauche colle, mais elle ne colle QUE si elle a de quoi : sous
   1 100 px, la colonne de droite est courte et le collage laissait un grand
   vide noir sous le titre pendant qu'on lisait les constats. `align-self` la
   remet en haut, et la hauteur de la section suit le plus long des deux. */
.diagnostic__colonne {
  position: sticky;
  top: calc(var(--hauteur-entete) + 2rem);
  align-self: start;
}
.diagnostic__marqueur {
  font-size: .655rem; font-weight: 800;
  letter-spacing: .14em; text-transform: uppercase;
  color: rgba(255,255,255,.42);
  margin-bottom: 1rem;
}
.diagnostic h2 {
  /* Un cran sous le titre d'une section pleine largeur : celui-ci vit dans
     une colonne, et le corps qui va bien sur 1 100 px de large déborde sur
     450. Le titre en trois lignes du registre y tient, pas au-delà. */
  font-size: clamp(1.7rem, 2.6vw, 2.35rem);
  line-height: 1.07;
  color: #fff;
  margin-bottom: 1rem;
}
.diagnostic__sous {
  font-size: .95rem; line-height: 1.65;
  color: var(--nuit-encre-douce);
  max-width: 32ch;
}
.diagnostic__point {
  display: flex; gap: 1.25rem;
  padding-block: 1.7rem;
  border-bottom: 1px solid rgba(255,255,255,.09);
}
.diagnostic__point:last-child { border-bottom: 0; }
.diagnostic__numero {
  flex: 0 0 1.6rem;
  font-size: .7rem; font-weight: 800;
  color: rgba(255,255,255,.32);
  font-variant-numeric: tabular-nums;
  padding-top: .2rem;
}
.diagnostic__etiquette {
  display: inline-block;
  font-size: .62rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--accent-sur-sombre);
  margin-bottom: .45rem;
}
.diagnostic__point h3 { font-size: 1.03rem; color: #fff; margin-bottom: .45rem; }
.diagnostic__point p {
  font-size: .885rem; line-height: 1.62;
  color: var(--nuit-encre-douce);
}
@media (max-width: 900px) {
  .diagnostic__grille { grid-template-columns: 1fr; gap: 2rem; }
  .diagnostic__colonne { position: static; }
}

/* ─── 3.4 · La bascule ────────────────────────────────────────────────────── */
/* La section « Si vous savez écrire un message » vivait ici. Elle a été
   retirée du gabarit, et ses règles avec elle : voir le commentaire de
   `app/vitrine.php`, section 4. */

/* ─── 3.5 · Les cartes de démonstration ───────────────────────────────────── */
/* Une rangée de vignettes légèrement penchées qu'on fait glisser à la souris.
   Elles montrent des ÉCRANS, parce que la question qu'on ne pose jamais à voix
   haute est « à quoi ça ressemble quand c'est moi qui m'en sers ». */
.demo { overflow-x: hidden; }
.demo__piste {
  display: flex; gap: 1rem;
  padding-inline: max(1.5rem, calc((100vw - var(--largeur)) / 2 + 1.5rem));
  padding-bottom: 1.5rem;
  overflow-x: auto;
  cursor: grab;
  user-select: none;
  scrollbar-width: none;
}
.demo__piste::-webkit-scrollbar { display: none; }
.demo__piste.est-tiree { cursor: grabbing; }

.vignette {
  flex: none; width: 270px;
  background: var(--surface);
  border: 1px solid var(--trait);
  border-radius: 18px;
  overflow: hidden;
  box-shadow: var(--ombre);
  transition: transform 280ms ease, box-shadow 280ms ease;
}
.vignette:nth-child(odd)  { transform: rotate(-1.1deg); }
.vignette:nth-child(even) { transform: rotate(.85deg); }
.vignette:hover {
  transform: rotate(0) translateY(-10px) scale(1.02);
  box-shadow: var(--ombre-forte);
}
@media (prefers-reduced-motion: reduce) {
  .vignette, .vignette:nth-child(odd), .vignette:nth-child(even) { transform: none; }
}
.vignette__chrome {
  display: flex; align-items: center; gap: .35rem;
  padding: .5rem .7rem;
  background: var(--surface-doux);
  border-bottom: 1px solid var(--trait);
}
.vignette__pastille { width: 7px; height: 7px; border-radius: 50%; }
.vignette__adresse {
  margin-left: .5rem;
  font-size: .61rem; color: var(--encre-tenue);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.vignette__corps { padding: 1rem; }
.vignette__titre {
  font-size: .6rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--encre-tenue);
  margin-bottom: .85rem;
}
.vignette__ligne {
  display: flex; align-items: center; gap: .6rem;
  padding: .55rem .65rem; margin-bottom: .45rem;
  background: var(--surface-doux);
  border: 1px solid var(--trait);
  border-radius: 11px;
}
.vignette__ligne:last-child { margin-bottom: 0; }
/* ─── Pourquoi les titres sortaient de la carte ───────────────────────────
   `.vignette__coupe` porte bien `overflow: hidden` et `text-overflow:
   ellipsis`, et ça ne servait à rien : son parent est le `<span>` sans classe
   de cette ligne, donc un élément flex, et un élément flex a par défaut
   `min-width: auto`. Il refuse de descendre sous la largeur intrinsèque de
   son contenu, qui est en `nowrap`. Le span gardait donc la largeur du texte
   entier, l'ellipse n'avait jamais rien à couper, et le texte passait par
   dessus le bord de la carte.

   Mesuré sur « espace/bibliotheque » : « Les questions qu'on vous pose tous
   les jours » dépassait de 62 px à droite, et cinq éléments de cette seule
   carte sortaient de leur cadre.

   `min-width: 0` lève l'interdiction. C'est la ligne que tout le monde oublie
   et sans laquelle aucune troncature ne marche dans un flex. */
.vignette__ligne > span:not([class]) { flex: 1 1 auto; min-width: 0; }
.vignette__ligne b { font-size: .765rem; font-weight: 700; }
.vignette__ligne small { font-size: .655rem; color: var(--encre-tenue); display: block; }
/* ─── Elle était figée à 30 px, et elle porte deux sortes d'étiquettes ────
   Trois lettres dans l'écran des idées d'articles (« Jan », « Mar »), un
   poids de fichier dans celui des photos (« 4,2 Mo », « 180 Ko »). Le poids
   ne tient pas dans 30 px : il se coupait en deux lignes, « 4,2 » au-dessus
   de « Mo », dans une case haute de 30 px. Le carré devient donc une largeur
   MINIMALE : les mois restent carrés, les poids s'étirent. */
.vignette__pastille-carre {
  flex: 0 0 auto;
  min-width: 30px; height: 30px;
  padding-inline: .34rem;
  white-space: nowrap;
  display: grid; place-items: center;
  border-radius: 9px;
  background: var(--surface-accent);
  border: 1px solid var(--volt-200);
  color: var(--accent-lisible);
  font-size: .62rem; font-weight: 800;
}
.vignette__grand {
  font-size: 1.6rem; font-weight: 900; letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
  margin-bottom: .75rem;
}
.vignette__insigne {
  display: inline-block;
  font-size: .62rem; font-weight: 800;
  padding: .12rem .5rem; border-radius: var(--rayon-pilule);
  background: var(--surface-accent);
  border: 1px solid var(--volt-300);
  color: var(--accent-lisible);
}
.vignette__barres { display: flex; align-items: flex-end; gap: .18rem; height: 46px; }
.vignette__barres i {
  flex: 1; border-radius: 2px 2px 0 0;
  background: var(--volt-300);
}
.vignette__note {
  margin-top: .7rem; padding: .6rem .7rem;
  background: var(--surface-accent);
  border: 1px solid var(--volt-200);
  border-radius: 11px;
}
.vignette__note b {
  display: block;
  font-size: .575rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--accent-lisible); margin-bottom: .2rem;
}
.vignette__note p { font-size: .715rem; line-height: 1.4; color: #713F12; }
.vignette__jauge {
  display: flex; align-items: center; gap: .5rem; margin-bottom: .55rem;
}
.vignette__jauge span:first-child { font-size: .68rem; color: var(--encre-tenue); width: 5.5rem; flex: 0 0 auto; }
.vignette__jauge-piste {
  flex: 1; height: 5px; border-radius: var(--rayon-pilule);
  background: var(--trait); overflow: hidden;
}
.vignette__jauge-piste i { display: block; height: 100%; background: var(--volt-400); border-radius: inherit; }
.vignette__jauge b { font-size: .68rem; width: 2.2rem; text-align: right; font-variant-numeric: tabular-nums; }

.demo__consigne {
  display: flex; align-items: center; justify-content: center; gap: .45rem;
  font-size: .78rem; color: var(--encre-tenue);
}
/* Le bouton sous le mur d'avis. Le mur se termine par un voile qui fait
   disparaître les cartes, et un bouton posé juste dessous a l'air d'être tombé
   du mur. Il lui faut sa propre respiration, et pas celle de la section. */
.avis-mur .demo__consigne { margin-top: clamp(2.5rem, 6vw, 4.5rem); }

/* ─── 3.6 · Les atouts ────────────────────────────────────────────────────── */
.atouts__liste { display: flex; flex-direction: column; }
.atout {
  display: flex; gap: 1.25rem; align-items: flex-start;
  padding-block: 1.75rem;
  border-bottom: 1px solid var(--trait);
}
.atout:last-child { border-bottom: 0; }
.atout__icone {
  flex: 0 0 auto;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border-radius: var(--rayon-petit);
  background: var(--surface-accent);
  border: 1px solid var(--volt-200);
  color: var(--accent-lisible);
}
.atout h3 { font-size: 1.06rem; margin-bottom: .5rem; }
.atout p { font-size: .9rem; line-height: 1.65; color: var(--encre-douce); }
.atout__etiquette {
  display: inline-block; margin-top: .75rem;
  font-size: .62rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase;
  padding: .16rem .6rem; border-radius: var(--rayon-pilule);
  background: var(--surface-accent);
  border: 1px solid var(--volt-300);
  color: var(--accent-lisible);
}

/* ─── 3.7 · Les avis, en colonnes qui défilent ────────────────────────────── */
/* Quatre colonnes qui montent et descendent, inclinées dans l'espace. C'est le
   seul effet coûteux de la page, et il l'est assez pour mériter deux garde-fous :
   il s'arrête au survol, et il ne se joue pas du tout si le visiteur a demandé
   moins de mouvement. */
.avis-mur { overflow: hidden; }
.avis-mur__scene {
  position: relative;
  display: flex; justify-content: center; align-items: center;
  gap: .75rem;
  height: 430px;
  perspective: 320px;
  overflow: hidden;
}
.avis-mur__groupe {
  display: flex; gap: .75rem;
  transform: translateX(-40px) translateZ(-70px) rotateX(16deg) rotateY(-7deg) rotateZ(14deg);
}
.avis-mur__colonne {
  display: flex; flex-direction: column; gap: .75rem;
  animation: avis-monte var(--defilement-avis) linear infinite;
}
.avis-mur__colonne--envers { animation-direction: reverse; }
.avis-mur__colonne--lente  { animation-duration: calc(var(--defilement-avis) * 1.18); }
.avis-mur__colonne--vive   { animation-duration: calc(var(--defilement-avis) * .86); }
@keyframes avis-monte { to { transform: translateY(-50%); } }
.avis-mur__scene:hover .avis-mur__colonne { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .avis-mur__colonne { animation: none; }
  .avis-mur__scene { height: auto; perspective: none; }
  .avis-mur__groupe { transform: none; flex-wrap: wrap; justify-content: center; }
  .avis-mur__colonne { max-height: 460px; overflow: hidden; }
}
/* Les cartes sont des liens vers les pages métier : sans ces deux lignes, elles
   héritent du soulignement et de l'ocre des liens de `vitrine.css`, et le mur
   entier part en texte souligné. */
.avis-carte { text-decoration: none; color: inherit; }
.avis-carte:hover { color: inherit; border-color: var(--volt-300); }
.avis-carte:hover .avis-carte__signature b { color: var(--accent-lisible); }

.avis-carte {
  flex: none; width: 258px;
  padding: 1rem;
  background: var(--surface);
  border: 1px solid var(--trait);
  border-radius: 16px;
  box-shadow: var(--ombre);
}
.avis-carte__etoiles { display: flex; gap: .1rem; margin-bottom: .6rem; color: var(--volt-500); }
.avis-carte__texte {
  font-size: .77rem; line-height: 1.55;
  color: var(--encre-douce); font-style: italic;
  margin-bottom: .75rem;
}
.avis-carte__signature { display: flex; align-items: center; gap: .5rem; }
.avis-carte__pastille {
  width: 28px; height: 28px; flex: 0 0 auto;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--pal-encre); color: var(--accent-sur-sombre);
  font-size: .63rem; font-weight: 900;
}
.avis-carte__signature b { display: block; font-size: .72rem; font-weight: 700; }
.avis-carte__signature small { display: block; font-size: .655rem; color: var(--encre-tenue); }
/* Les voiles qui font disparaître les cartes aux quatre bords, plutôt que de
   les couper net. */
.avis-mur__voile { position: absolute; pointer-events: none; }
.avis-mur__voile--haut { inset: 0 0 auto 0; height: 26%; background: linear-gradient(to bottom, var(--surface), transparent); }
.avis-mur__voile--bas  { inset: auto 0 0 0; height: 26%; background: linear-gradient(to top, var(--surface), transparent); }
.avis-mur__voile--gauche { inset: 0 auto 0 0; width: 18%; background: linear-gradient(to right, var(--surface), transparent); }
.avis-mur__voile--droite { inset: 0 0 0 auto; width: 18%; background: linear-gradient(to left, var(--surface), transparent); }

@media (max-width: 900px) { .avis-mur__colonne:nth-child(n+3) { display: none; } }
@media (max-width: 620px) { .avis-mur__colonne:nth-child(n+2) { display: none; } }

/* ─── 3.8 · L'appel final ─────────────────────────────────────────────────── */
.appel {
  background: linear-gradient(135deg, rgba(254,252,232,.9) 0%, #fff 48%, rgba(254,252,232,.65) 100%);
}
.appel__carte {
  max-width: 34rem; margin-inline: auto;
  padding: clamp(1.75rem, 5vw, 3.25rem);
  background: var(--surface);
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-forte);
  text-align: center;
}
.appel__carte h2 {
  font-size: clamp(1.7rem, 3.2vw, 2.6rem);
  line-height: 1.08; margin-bottom: 1rem;
}
.appel__carte p {
  font-size: 1rem; line-height: 1.65;
  color: var(--encre-douce);
  max-width: 30ch; margin-inline: auto; margin-bottom: 1.9rem;
}
.appel__preuve {
  display: flex; align-items: center; justify-content: center; gap: .75rem;
  margin-top: 1.9rem;
  font-size: .8rem; color: var(--encre-tenue);
}
.appel__pastilles { display: flex; }
.appel__pastilles span {
  width: 30px; height: 30px;
  display: grid; place-items: center;
  border-radius: 50%; border: 2px solid #fff;
  background: var(--pal-encre); color: var(--accent-sur-sombre);
}
.appel__pastilles svg { width: 14px; height: 14px; }
.appel__pastilles span + span { margin-left: -10px; }

/* ─── 3.9 · L'apparition au défilement ────────────────────────────────────
   Rien ici : la classe `.revele` de `vitrine.css` fait déjà ce travail, avec
   son garde-fou `@media (scripting: enabled)` et son observateur dans
   `vitrine.js`. Les sections de cette page la portent, comme les autres.
   En écrire une seconde aurait donné deux animations d'entrée aux réglages
   légèrement différents sur la même page. */

/* ═══════════════════════════════════════════════════════════════════════════
   4 · LES PAGES INTÉRIEURES
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── 4.1 · L'en-tête de page ───────────────────────────────────────────────
   Centré, sur deux souffles jaunes, avec ses preuves en dessous.

   ─── Ce qui a changé, et le défaut que ça corrige ────────────────────────
   Il était aligné à gauche sur fond blanc uni, comme le corps de la page. Le
   résultat : les seize pages intérieures démarraient toutes sur un paragraphe
   un peu plus gros que les suivants, et aucune ne se distinguait d'un
   document. Un visiteur venu d'un moteur de recherche décide en deux secondes
   s'il est au bon endroit, et il le décide sur cette zone-là.

   Le fond coûte zéro requête et zéro octet d'image : deux souffles jaunes en
   dégradé radial. Sur un moteur dont la contrainte fondatrice interdit d'aller
   chercher quoi que ce soit ailleurs, c'est la seule façon d'avoir un fond qui
   ne soit pas plat. Il a porté un quadrillage pendant une version ; voir plus
   bas pourquoi il ne le porte plus. */
.tete {
  position: relative;
  isolation: isolate;
  padding-block: clamp(3.25rem, 7vw, 6rem) clamp(2.5rem, 5vw, 4rem);
  border-bottom: 1px solid var(--trait);
  overflow: clip;
  text-align: center;
}
.tete__contenu { position: relative; z-index: 1; }

.tete__trame {
  position: absolute; inset: 0; z-index: 0;
  pointer-events: none;
  /* ─── Le quadrillage est parti, et il ne revient pas ─────────────────
     Deux `repeating-linear-gradient` traçaient une grille de 64 px sous le
     titre de chaque page. Elle a été retirée sur un jugement d'ensemble : sur
     dix-neuf pages, la trame technique ne disait rien de l'offre, elle
     ajoutait du bruit derrière un titre déjà très gras, et elle datait la
     page. Ce qui reste, ce sont les deux souffles jaunes, qui sont de la
     lumière et pas du dessin : ils donnent du relief sans rien raconter.

     Le nom de la classe ne change pas : c'est le même rôle, le fond de la
     tête, et le renommer aurait demandé de toucher vingt gabarits pour un
     mot. */
  background:
    radial-gradient(46% 70% at 18% 0%,  rgba(250,204,21,.16), transparent 62%),
    radial-gradient(40% 62% at 86% 4%,  rgba(250,204,21,.10), transparent 64%);
  /* Les souffles s'éteignent avant le filet de fin de section : sans ce
     masque, le jaune se coupe net sur un trait et fait un bord visible. */
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 55%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 55%, transparent 100%);
  opacity: .9;
}

/* ─── Le catalogue des variantes, et il est FERMÉ ─────────────────────────
   Il en existe trois, pas quatre, et `page_tete()` refuse le reste.

   ─── Ce qui a été retiré, et le défaut que ça corrige ────────────────────
   Il existait une quatrième variante, `--accent`, qui posait un aplat crème
   (#FEFCE8) sous la tête. Le quadrillage, dessiné avec `--trait` (#E4E4E7),
   s'y confondait exactement : la page qui la portait, `/tarifs`, était donc
   la SEULE du site sans trame visible, et elle passait pour « la page toute
   jaune ». Relevé à l'écran sur les dix-neuf pages fixes : douze en trame
   claire, une en crème, une en nuit, une en nuit alignée à gauche, deux en
   blanc nu, plus la bannière de l'accueil qui n'en portait aucune. Six rendus
   pour trois variantes déclarées.

   La leçon est la même que celle de la grille tarifaire : ce n'est pas la
   variante de trop qui coûte, c'est qu'aucune règle ne disait combien il
   pouvait y en avoir. */

/* ── nuit · retirée le 2026-09-16 ───────────────────────────────────────
   Elle n'avait plus qu'une page, `/formation`, et une page sombre au milieu de
   dix-huit pages claires se lit comme un oubli plutôt que comme une intention.
   La page est passée en clair, et la variante est partie avec elle : une
   variante sans aucune page est du CSS que plus personne ne relit et que
   quelqu'un finit par employer au hasard six mois plus tard. C'est ce qui
   avait donné six rendus pour trois variantes déclarées.

   Le fond nuit n'a pas disparu du site pour autant : il reste sur les
   SECTIONS (`.section--nuit`, le constat de l'accueil, le parrainage, le ruban
   d'appel), où il sépare deux moments d'une même page. Ce qui est retiré,
   c'est une porte d'entrée sombre pour une page sur dix-neuf. */

/* ── sobre · retirée avant d'avoir servi ────────────────────────────────
   Elle avait été écrite pour `/cgv`, `/mentions-legales` et `/lexique`, en
   pariant qu'on les ferait passer par `page_tete()`. Ce n'est pas ce qu'on a
   fait : ces trois pages gardent `.lex-tete`, leur propre composant, qui est
   passé en clair (voir `vitrine.css`). Elles n'ont ni marqueur, ni preuves, ni
   appel à l'action, et faire accepter trois arguments vides à `page_tete()`
   aurait été une variante de plus à maintenir pour trois pages qui n'en
   demandent pas.

   Il ne reste donc qu'UNE tête de page, et c'est le bon nombre : le catalogue
   qui en déclarait trois pour six rendus à l'écran n'avait pas trop de
   variantes, il avait trop peu de règles. */

.tete h1 {
  font-size: clamp(2.1rem, 4.6vw, 3.5rem);
  max-width: 19ch;
  margin-inline: auto;
  margin-bottom: 1.1rem;
}
.tete__marqueur {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: .68rem; font-weight: 800;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--accent-lisible);
  margin-bottom: 1rem;
}
.tete__marqueur::before {
  content: ''; width: 22px; height: 3px;
  background: var(--pal-primaire); border-radius: 2px;
}
.tete__accroche {
  font-size: clamp(1.02rem, 1.5vw, 1.18rem);
  line-height: 1.65;
  color: var(--encre-douce);
  max-width: 58ch;
  margin-inline: auto;
}
.tete__actions {
  display: flex; flex-wrap: wrap; gap: .7rem;
  justify-content: center;
  margin-top: 2rem;
}

/* Les preuves. Séparées par un filet vertical plutôt que posées dans des
   cartes : à cet endroit de la page, quatre cartes de plus feraient une
   deuxième section avant la première. */
.tete__preuves {
  list-style: none; margin: 2.5rem auto 0; padding: 0;
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 1rem 0;
  max-width: 56rem;
}
.tete__preuves li {
  flex: 1 1 9rem;
  padding-inline: 1.25rem;
  border-left: 1px solid var(--trait);
}
.tete__preuves li:first-child { border-left: 0; }
.tete__preuves b {
  display: block;
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  font-weight: 900; letter-spacing: -.04em; line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.tete__preuves span {
  display: block; margin-top: .3rem;
  font-size: .78rem; line-height: 1.45;
  color: var(--encre-tenue);
}

/* Le fil d'Ariane. Il n'est pas décoratif : il porte le balisage que Google
   affiche sous le titre dans ses résultats, à la place de l'adresse brute. */
.fil {
  display: flex; flex-wrap: wrap; align-items: center; gap: .4rem;
  justify-content: center;
  font-size: .78rem; color: var(--encre-tenue);
  margin-bottom: 1.25rem;
  list-style: none; padding: 0;
}
.fil a { color: var(--encre-tenue); text-decoration: none; }
.fil a:hover { color: var(--encre); text-decoration: underline; }
.fil li { display: inline-flex; align-items: center; gap: .4rem; }
.fil li + li::before { content: '/'; color: var(--trait); }

@media (max-width: 620px) {
  .tete__preuves li { flex-basis: 45%; border-left: 0; }
  .tete__preuves { gap: 1.5rem 0; }
}

/* ─── 4.2 · Les grilles de cartes ─────────────────────────────────────────── */
.grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.25rem;
}
.grille--deux  { grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); }
.grille--large { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }

.carte-lien {
  display: flex; flex-direction: column;
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  text-decoration: none; color: inherit;
  transition: transform 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
}
.carte-lien:hover {
  transform: translateY(-4px);
  border-color: var(--volt-300);
  box-shadow: var(--ombre);
  color: inherit;
}
.carte-lien__icone {
  width: 42px; height: 42px; margin-bottom: 1rem;
  display: grid; place-items: center;
  border-radius: var(--rayon-petit);
  background: var(--surface-accent);
  border: 1px solid var(--volt-200);
  color: var(--accent-lisible);
}
.carte-lien h3 { font-size: 1.06rem; margin-bottom: .5rem; }
.carte-lien p { font-size: .875rem; line-height: 1.6; color: var(--encre-douce); }
.carte-lien__pied {
  display: inline-flex; align-items: center; gap: .4rem;
  margin-top: auto; padding-top: 1.1rem;
  font-size: .82rem; font-weight: 700;
  color: var(--accent-lisible);
}
.carte-lien:hover .carte-lien__pied svg { transform: translateX(3px); }
.carte-lien__pied svg { transition: transform 160ms ease; }
.carte-lien__sur {
  font-size: .655rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--encre-tenue); margin-bottom: .55rem;
}

/* La carte d'un article : son étiquette, son titre, sa durée de lecture. */
.article-carte__etiquette {
  display: inline-block; margin-bottom: .7rem;
  font-size: .62rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase;
  padding: .16rem .6rem; border-radius: var(--rayon-pilule);
  background: var(--surface-accent);
  border: 1px solid var(--volt-300);
  color: var(--accent-lisible);
}
.article-carte__meta {
  display: flex; gap: .75rem; align-items: center;
  margin-top: auto; padding-top: 1.1rem;
  font-size: .74rem; color: var(--encre-tenue);
}

/* ─── 4.3 · Les blocs de texte longs ──────────────────────────────────────── */
.prose { max-width: 68ch; }
.prose > * + * { margin-top: 1.1rem; }
.prose h2 { font-size: clamp(1.4rem, 2.6vw, 1.95rem); margin-top: 2.75rem; }
.prose h3 { font-size: 1.15rem; margin-top: 2rem; }
.prose p, .prose li { font-size: .975rem; line-height: 1.72; color: var(--encre-douce); }
.prose strong { color: var(--encre); font-weight: 700; }
.prose ul, .prose ol { padding-left: 1.25rem; display: grid; gap: .5rem; }
.prose blockquote {
  margin-inline: 0; padding: 1.1rem 1.4rem;
  border-left: 3px solid var(--pal-primaire);
  background: var(--surface-accent);
  border-radius: 0 var(--rayon-petit) var(--rayon-petit) 0;
  font-size: .95rem;
}

/* ─── 4.4 · Les chiffres ──────────────────────────────────────────────────── */
.chiffres-grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1rem;
}
.chiffre-carte {
  padding: 1.35rem;
  background: var(--surface-doux);
  border: 1px solid var(--trait);
  border-radius: var(--rayon-petit);
}
.chiffre-carte b {
  display: block;
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  font-weight: 900; letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
}
.chiffre-carte span { display: block; margin-top: .35rem; font-size: .8rem; color: var(--encre-douce); line-height: 1.5; }
.chiffre-carte cite { display: block; margin-top: .55rem; font-size: .68rem; color: var(--encre-tenue); font-style: normal; }

/* ─── 4.5 · Les questions, en accordéon ───────────────────────────────────── */
.questions-liste { display: grid; gap: .65rem; }
.question-bloc {
  border: 1px solid var(--trait);
  border-radius: var(--rayon-petit);
  background: var(--surface);
  overflow: hidden;
}
.question-bloc summary {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1.05rem 1.25rem;
  cursor: pointer;
  font-size: .975rem; font-weight: 700; letter-spacing: -.015em;
  list-style: none;
}
.question-bloc summary::-webkit-details-marker { display: none; }
.question-bloc summary::after {
  content: ''; flex: 0 0 auto;
  width: 10px; height: 10px;
  border-right: 2.2px solid var(--encre-tenue);
  border-bottom: 2.2px solid var(--encre-tenue);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--transition);
}
.question-bloc[open] summary::after { transform: rotate(-135deg) translate(-3px, -3px); }
.question-bloc[open] summary { color: var(--encre); }
.question-bloc p {
  padding: 0 1.25rem 1.25rem;
  font-size: .915rem; line-height: 1.7;
  color: var(--encre-douce);
}

/* ─── 4.6 · Le hub des secteurs ───────────────────────────────────────────── */
.famille { margin-top: 3rem; }
.famille:first-of-type { margin-top: 0; }
.famille__tete { display: flex; align-items: center; gap: .85rem; margin-bottom: 1.25rem; }
.famille__icone {
  width: 42px; height: 42px; flex: 0 0 auto;
  display: grid; place-items: center;
  border-radius: var(--rayon-petit);
  background: var(--pal-encre); color: var(--accent-sur-sombre);
}
.famille__tete h2 { font-size: 1.3rem; margin: 0; }
.famille__tete p { font-size: .845rem; color: var(--encre-douce); margin-top: .2rem; }

.secteur-puces { display: flex; flex-wrap: wrap; gap: .5rem; }
.secteur-puce {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .5rem .9rem;
  border: 1px solid var(--trait);
  border-radius: var(--rayon-pilule);
  background: var(--surface);
  font-size: .855rem; font-weight: 600;
  color: var(--encre); text-decoration: none;
  transition: border-color 160ms ease, background 160ms ease, transform 160ms ease;
}
.secteur-puce:hover {
  border-color: var(--volt-400);
  background: var(--surface-accent);
  transform: translateY(-2px);
  color: var(--encre);
}
/* Un secteur sans matière détaillée le dit, plutôt que de promettre une page
   nourrie et de servir un gabarit. */
.secteur-puce--court { opacity: .72; }
.secteur-puce--court::after {
  content: ''; width: 5px; height: 5px; border-radius: 50%;
  background: var(--trait);
}
.secteur-puce--complet::after {
  content: ''; width: 5px; height: 5px; border-radius: 50%;
  background: var(--volt-400);
}

/* ─── 4.7 · Le comparateur ────────────────────────────────────────────────── */
.compare { width: 100%; overflow-x: auto; }
.compare table { width: 100%; border-collapse: collapse; min-width: 720px; }
.compare th, .compare td {
  padding: .9rem 1rem;
  border-bottom: 1px solid var(--trait);
  text-align: left; vertical-align: top;
  font-size: .875rem;
}
.compare thead th {
  font-size: .68rem; font-weight: 800;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--encre-tenue);
  border-bottom-width: 2px;
}
.compare tbody th { font-weight: 700; color: var(--encre); }
.compare td { color: var(--encre-douce); }
.compare .est-nous { background: var(--surface-accent); }
.compare thead .est-nous { color: var(--accent-lisible); }

/* ─── 4.8 · Le ruban d'appel de bas de page ───────────────────────────────── */
.ruban-appel {
  background: var(--pal-encre); color: var(--nuit-encre);
  text-align: center;
}
.ruban-appel h2 { color: #fff; font-size: clamp(1.6rem, 3vw, 2.4rem); margin-bottom: .9rem; max-width: 24ch; margin-inline: auto; }
.ruban-appel p { color: var(--nuit-encre-douce); max-width: 52ch; margin-inline: auto; margin-bottom: 1.8rem; font-size: .975rem; line-height: 1.65; }
.ruban-appel .actions { display: flex; gap: .75rem; justify-content: center; flex-wrap: wrap; }

/* ─── Deux sections noires qui se suivent ─────────────────────────────────
   Le ruban d'appel est sur toutes les pages intérieures, et il est noir. Quand
   la page finit déjà sur une section nuit, les deux se touchent : mesuré sur
   `/tarifs`, 879 px de parrainage suivis de 455 px de ruban, soit 1 334 px
   d'un seul noir où rien ne dit où l'un s'arrête. Le visiteur n'y voit pas
   deux blocs, il y voit un bas de page qui n'en finit pas.

   La règle ne change pas le balisage : elle rapproche les deux blocs et pose
   un filet à la jointure. C'est de l'adjacence, donc ça vaut partout où le cas
   se présente, y compris sur les pages qui n'existent pas encore. */
.section--nuit + .ruban-appel {
  padding-top: clamp(2.5rem, 5vw, 4rem);
  border-top: 1px solid var(--nuit-trait);
}

/* ─── 4.9 · L'encart latéral ──────────────────────────────────────────────── */
.deux-colonnes {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 320px);
  gap: 3rem;
  align-items: start;
}
.encart-colle { position: sticky; top: calc(var(--hauteur-entete) + 1.5rem); }
.encart-bloc {
  padding: 1.5rem;
  background: var(--surface-doux);
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
}
.encart-bloc h3 { font-size: 1rem; margin-bottom: .7rem; }
.encart-bloc p { font-size: .85rem; line-height: 1.6; color: var(--encre-douce); margin-bottom: 1.1rem; }
@media (max-width: 900px) {
  .deux-colonnes { grid-template-columns: 1fr; gap: 2rem; }
  .encart-colle { position: static; }
}

/* ─── 4.10 · Les étapes numérotées ────────────────────────────────────────── */
.etapes-liste { display: grid; gap: 1rem; counter-reset: etape; }
.etape-bloc {
  display: flex; gap: 1.15rem;
  padding: 1.35rem 1.5rem;
  background: var(--surface);
  border: 1px solid var(--trait);
  border-radius: var(--rayon-petit);
}
.etape-bloc__numero {
  counter-increment: etape;
  flex: 0 0 auto;
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--pal-primaire); color: var(--encre);
  font-size: .82rem; font-weight: 900;
}
.etape-bloc__numero::before { content: counter(etape); }
.etape-bloc h3 { font-size: 1rem; margin-bottom: .35rem; }
.etape-bloc p { font-size: .875rem; line-height: 1.62; color: var(--encre-douce); }

/* ─── 4.11 · Les jetons de mots-clés ──────────────────────────────────────── */
.jetons { display: flex; flex-wrap: wrap; gap: .4rem; }
.jeton {
  padding: .3rem .7rem;
  border-radius: var(--rayon-pilule);
  background: var(--surface-doux);
  border: 1px solid var(--trait);
  font-size: .765rem; color: var(--encre-douce);
}

/* ═══════════════════════════════════════════════════════════════════════════
   5 · CE QUI S'ADAPTE AUX PETITS ÉCRANS
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 720px) {
  .ouverture { min-height: auto; padding-block: 3.5rem 3rem; }
  /* Le marqueur tient sur deux lignes à cette largeur, et l'espacement de
     lettres le fait alors casser au milieu de « POUR LES ». On lui rend un peu
     de place en retirant la traque, qui n'a d'intérêt qu'en une ligne. */
  .ouverture__marqueur {
    font-size: .625rem; letter-spacing: .08em;
    padding: .4rem .8rem; text-align: center;
  }
  .ouverture h1 { max-width: 100%; }
  .ouverture__accroche { min-height: 4.6em; }
  .demo__piste { padding-inline: 1.25rem; }
  .vignette { width: 244px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   6 · LES DÉTAILS DES VIGNETTES, QUI N'ONT PAS LEUR PLACE EN LIGNE
   ═══════════════════════════════════════════════════════════════════════════
   La politique de sécurité du moteur interdit les styles en ligne, et un
   navigateur les jette EN SILENCE : un attribut `style` n'est pas « du CSS
   rapide », il est purement ignoré. Les trois pastilles du chrome, les quatre
   jauges et les douze barres du graphique vivent donc ici. */

.vignette__pastille--rouge { background: #F87171; }
.vignette__pastille--jaune { background: var(--volt-400); }
.vignette__pastille--vert  { background: #34D399; }

.vignette__jauge-piste i.est-100 { width: 100%; }
.vignette__jauge-piste i.est-60  { width: 60%; }
.vignette__jauge-piste i.est-30  { width: 30%; background: var(--volt-200); }

/* Les douze barres du petit graphique. Une courbe qui monte, mesurée sur douze
   mois : les hauteurs sont posées ici plutôt qu'en attribut, pour la raison
   ci-dessus. */
.vignette__barres i:nth-child(1)  { height: 28%; }
.vignette__barres i:nth-child(2)  { height: 34%; }
.vignette__barres i:nth-child(3)  { height: 31%; }
.vignette__barres i:nth-child(4)  { height: 46%; }
.vignette__barres i:nth-child(5)  { height: 52%; }
.vignette__barres i:nth-child(6)  { height: 61%; }
.vignette__barres i:nth-child(7)  { height: 58%; }
.vignette__barres i:nth-child(8)  { height: 74%; }
.vignette__barres i:nth-child(9)  { height: 81%; }
.vignette__barres i:nth-child(10) { height: 88%; }
.vignette__barres i:nth-child(11) { height: 92%; }
.vignette__barres i:nth-child(12) { height: 100%; }

/* Le bloc des quatre réponses courtes. Il porte son propre nom de classe et
   non les classes de grille génériques, pour une raison qui n'est pas
   esthétique : c'est ce sélecteur exact que désigne `speakable` dans les
   données structurées, et c'est lui que `bin/test-vitrine.php` cherche dans le
   HTML servi. Un sélecteur `speakable` qui ne correspond à rien ne désigne
   rien, et personne ne s'en aperçoit : aucun navigateur ne s'en plaint. */
.resume__grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 1.25rem;
}

/* Le bloc des quatre réponses courtes porte des `h2`, un par question : ce sont
   de vraies questions, et un assistant qui lit la page doit les trouver comme
   telles. Ils sont donc ramenés à la taille d'un titre de carte, sans quoi
   quatre `h2` de section se suivraient en tête de page. */
.resume .carte-lien h2 { font-size: 1.06rem; margin-bottom: .5rem; }

/* ─── La portée ─────────────────────────────────────────────────────────────
   Le globe posé à même la page, sans panneau. Il a sa propre grille et non
   celle du diagnostic : la colonne de gauche n'y colle pas, les deux colonnes
   sont centrées verticalement, et le globe déborde volontiers de sa colonne
   sur les grands écrans, ce qu'une grille partagée n'aurait pas permis. */
/* ─── Les proportions, et ce qu'elles corrigent ───────────────────────────
   Deux colonnes égales et un globe à 460 px donnaient une figure aussi large
   que tout le discours de la section, posée à côté de lui. Une illustration
   qui pèse autant que le texte qu'elle illustre ne l'illustre plus, elle le
   concurrence.

   Le texte prend donc six dixièmes, le globe quatre, et son diamètre est borné
   à 380 px. Il reste la plus grande chose de la section, ce qui est juste : il
   est ce qu'on regarde en premier. Il n'est plus ce qu'on regarde à la place
   du reste. */
.portee__grille {
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 4fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.portee__globe {
  position: relative;
  display: grid; place-items: center;
  aspect-ratio: 1;
  max-width: 380px; margin-inline: auto; width: 100%;
}
/* Le halo. Sans lui, le globe clair posé sur du blanc n'a plus de sol : ses
   points de trame les plus pâles se perdent dans la page, et la sphère a l'air
   de flotter dans du vide. Un souffle jaune très dilué lui rend son assise
   sans rien colorer. */
.portee__halo {
  position: absolute; inset: -12%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(250,204,21,.20) 0%, rgba(250,204,21,.06) 42%, transparent 68%);
  pointer-events: none;
}
.portee__globe .globe__toile {
  position: relative; z-index: 1;
  width: 100%; height: 100%;
  cursor: grab;
}
.portee__globe .globe__toile:active { cursor: grabbing; }

@media (max-width: 900px) {
  .portee__grille { grid-template-columns: 1fr; }
  .portee__globe { max-width: 340px; order: -1; }
}

/* La liste des communes, sous le globe. C'est une vraie liste (`<ul>`/`<li>`),
   parce que c'en est une et qu'un lecteur d'écran annonce alors « liste de 8
   éléments » avant de les lire. Les puces sont retirées, pas la sémantique. */
ul.jetons { list-style: none; margin: 0; padding: 0; }
ul.jetons li {
  padding: .3rem .7rem;
  border-radius: var(--rayon-pilule);
  background: var(--surface-doux);
  border: 1px solid var(--trait);
  font-size: .765rem; color: var(--encre-douce);
}

/* ─── Les deux portes de la barre ────────────────────────────────────────────
   « Connexion » est un bouton fantôme, « Inscription » le bouton jaune.

   ─── Ce qui saute quand la place manque, et dans quel ordre ──────────────
   Quatre menus, un numéro et deux pilules ne tiennent pas sous 1 060 px, et
   c'est là que les menus passent derrière le bouton du téléphone. Entre les
   deux, on resserre plutôt que de retirer : les paddings et l'écart se
   réduisent, et les deux portes restent visibles jusqu'au bout.

   Si quelque chose devait disparaître, ce serait « Connexion » et non
   « Inscription » : un client déjà équipé connaît le chemin et le retrouve
   dans le pied de page, un visiteur qui découvre n'a que ce bouton-là. */
.entete__connexion { padding: .5rem 1rem; font-size: .86rem; white-space: nowrap; }
.entete__appel     { padding: .5rem 1.15rem; font-size: .86rem; white-space: nowrap; }

@media (max-width: 1280px) {
  .entete__actions { gap: .5rem; }
  .entete__menu { gap: 0; }
  .entete__lien { padding-inline: .55rem; font-size: .885rem; }
  .entete__tel span { display: none; }   /* le pictogramme suffit, le lien reste */
}

/* Les deux portes, sur téléphone : côte à côte, en bas du panneau, avec le
   numéro en clair dessous. L'appel reste un lien et non un troisième bouton :
   trois pilules empilées, personne n'en clique aucune. */
.entete__panneau-actions {
  display: grid; grid-template-columns: 1fr 1fr; gap: .6rem;
  margin-top: 1.25rem;
}
.entete__panneau-tel {
  display: block; margin-top: .9rem; text-align: center;
  font-size: .85rem; font-weight: 700;
  color: var(--encre-douce); text-decoration: none;
}
.entete__panneau-tel:hover { color: var(--encre); text-decoration: underline; }

/* Le bouton unique de la bannière. Seul, il doit porter à lui tout seul le
   poids que deux boutons se partageaient : un peu plus grand, et c'est tout.
   Grossir davantage ferait un bouton de démonstration de framework. */
.bouton--grand { padding: 1.05rem 2.2rem; font-size: 1.02rem; }

/* Les communes servies, au pied de page. Une vraie liste (`<ul>`/`<li>`),
   affichée en ligne continue plutôt qu'en puces : c'en est une pour un lecteur
   d'écran, qui annonce « liste de 8 éléments », et c'est une phrase pour l'œil,
   qui n'a pas besoin de huit puces pour huit noms de villes. */
.pied__zone-titre {
  margin-top: 1.1rem;
  font-size: .68rem; font-weight: 800;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--encre-tenue);
}
.pied__zone {
  list-style: none; margin: .4rem 0 0; padding: 0;
  font-size: .82rem; line-height: 1.7; color: var(--encre-douce);
}
.pied__zone li { display: inline; }
.pied__zone li + li::before { content: ' · '; color: var(--trait); }

/* ─── L'encadré dans le fil du texte ─────────────────────────────────────────
   Un point d'arrêt dans une page longue, et la phrase qu'on veut voir retenue
   par quelqu'un qui n'aura lu que les encadrés. Trois tons, pas quatre : au
   delà, personne ne se souvient de ce que la couleur veut dire. */
.encadre {
  margin-block: 1.75rem;
  padding: 1.15rem 1.4rem;
  background: var(--surface-doux);
  border: 1px solid var(--trait);
  border-left: 3px solid var(--encre-tenue);
  border-radius: 0 var(--rayon-petit) var(--rayon-petit) 0;
}
.encadre b {
  display: block; margin-bottom: .35rem;
  font-size: .68rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--encre-tenue);
}
.encadre p { font-size: .945rem; line-height: 1.68; color: var(--encre-douce); margin: 0; }

/* Une précaution, un piège. Jaune de marque, parce que c'est exactement son
   emploi ailleurs sur le site : ce qu'il faut regarder avant de continuer. */
.encadre--garde {
  background: var(--surface-accent);
  border-color: var(--volt-200);
  border-left-color: var(--volt-400);
}
.encadre--garde b { color: var(--accent-lisible); }
.encadre--garde p { color: #713F12; }

/* Une mesure, un chiffre. Encre, parce qu'un fait ne se signale pas par une
   couleur d'alerte. */
.encadre--preuve {
  background: var(--pal-encre);
  border-color: transparent;
  border-left-color: var(--volt-400);
}
.encadre--preuve b { color: var(--accent-sur-sombre); }
.encadre--preuve p { color: var(--nuit-encre); }
.encadre--preuve a { color: var(--accent-sur-sombre); }

.prose .encadre { margin-block: 1.75rem; }

/* ─── Couper du texte : le navigateur, jamais PHP ────────────────────────────
   Les titres d'idées d'articles et les accroches du mur étaient coupés en PHP,
   à trente-quatre et cent dix-huit caractères. Deux défauts, et le second est
   le pire : la coupe tombait au milieu d'un mot une fois sur trois (« avant
   l'hiv », « de l'anné »), et le compte juste n'existe pas, puisque cent
   dix-huit caractères font trois lignes dans un métier et cinq dans un autre.

   Le navigateur, lui, sait où sont les mots ET combien de lignes tiennent. Il
   coupe donc, et il pose ses points de suspension lui-même. Le texte complet
   reste dans le HTML : un lecteur d'écran et un moteur de recherche le lisent
   en entier, ce que la coupe en PHP leur interdisait. */
.vignette__coupe {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.avis-carte__texte {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ─── Le métier qui défile, sous l'accroche ──────────────────────────────────
   Une pilule encre avec le mot en jaune. C'est le seul endroit de la page où
   le jaune porte du TEXTE, et c'est possible ici parce que le fond est encre :
   #FACC15 sur #09090B donne 12,4:1, là où le même jaune sur blanc en donne
   1,7 et disparaît. La règle n'a pas changé, c'est le fond qui a changé. */
.ouverture__metier {
  display: inline-flex; align-items: baseline; gap: .5rem;
  padding: .55rem 1.1rem;
  /* Deux pilules empilées à trente-cinq pixels l'une de l'autre se lisent
     comme un seul bloc, et le bouton perd ce qui en fait un bouton : d'être
     seul. Le double d'écart le détache sans le repousser en bas de page. */
  margin-bottom: 3.25rem;
  border-radius: var(--rayon-pilule);
  background: var(--pal-encre);
  font-size: .92rem;
}
.ouverture__metier span { color: var(--nuit-encre-douce); }
.ouverture__metier b {
  display: inline-flex; align-items: baseline;
  color: var(--accent-sur-sombre);
  font-weight: 800; letter-spacing: -.01em;
  /* La largeur est réservée d'avance : sans elle, la pilule s'allonge et se
     raccourcit à chaque lettre tapée, et toute la bannière tressaute. Le
     curseur est DANS ce bloc et non après lui, sinon il reste planté au bout
     de la largeur réservée pendant que le mot se tape en dessous de lui. */
  min-width: 9ch;
}
.ouverture__metier .ouverture__curseur {
  background: var(--accent-sur-sombre);
  margin-left: .1rem;
}
@media (max-width: 520px) {
  .ouverture__metier { font-size: .84rem; padding: .5rem .9rem; }
  .ouverture__metier b { min-width: 8ch; }
}

/* ─── Ce que le surligneur coûte en hauteur, et que personne ne compte ───────
   L'aplat d'un mot surligné déborde sous la ligne de base : `bottom: .1em` le
   fait descendre dans l'interligne. Quand la phrase surlignée termine un titre,
   ce débord vient toucher le paragraphe qui suit, et les deux se collent.

   Ce n'est visible que sur les titres qui FINISSENT par un surlignage, ce qui
   est justement la forme que prennent ceux du registre. D'où cette réserve,
   posée sur les titres de section et non sur `.surligne` : le surligneur sert
   aussi en milieu de phrase, où il n'a rien à réserver. */
.portee h2, .bascule h2, .diagnostic h2 { margin-bottom: 1.1rem; }
.portee .accroche, .bascule p { margin-top: 0; }

/* Le titre de la portée vit dans une colonne, comme celui du diagnostic : même
   raison de descendre d'un cran, et même mesure. */
.portee h2 { font-size: clamp(1.7rem, 2.8vw, 2.5rem); max-width: 16ch; }
.portee .sur-titre { margin-bottom: .9rem; }

/* Les quatre chiffres de la portée tiennent en DEUX colonnes, pas trois.
   La colonne de texte s'est élargie en même temps que le globe rétrécissait,
   et `auto-fit` y a logé trois cartes sur la première ligne et une seule sur
   la seconde. Trois plus un se lit comme un oubli ; deux plus deux se lit
   comme une grille. */
.portee .chiffres-grille { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 560px) {
  .portee .chiffres-grille { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   5 · L'ARTICLE DE BLOG
   ═══════════════════════════════════════════════════════════════════════════

   Un article tenait en une colonne de 980 px : le chapeau, le corps, puis les
   articles voisins tout en bas. Trois choses manquaient, et chacune se paie.

   Le SOMMAIRE. Sur un texte de sept minutes, un lecteur veut savoir où il va
   avant de commencer, et un moteur veut la carte des sections. Aucun des deux
   ne l'avait.

   Le MAILLAGE. Les articles voisins étaient sous l'article, c'est-à-dire à
   l'endroit exact où un lecteur a déjà décidé de partir. Remontés dans la
   colonne, ils sont visibles pendant la lecture.

   La SORTIE. Rien ne proposait d'action avant le pied de page.
   ─────────────────────────────────────────────────────────────────────── */

/* ─── Trois enfants, deux dispositions ─────────────────────────────────────
   `.post-wrap` porte le sommaire, l'article et la colonne latérale, dans cet
   ordre dans le HTML. Sur téléphone c'est déjà le bon ordre : on parcourt le
   sommaire, on lit, puis on trouve la suite. Sur grand écran, les zones
   nommées remettent le sommaire en haut de la colonne de droite sans toucher
   au balisage.

   Le sommaire est un frère de l'article et non un enfant de l'aside : une
   grille ne réordonne que ses enfants DIRECTS, et à l'intérieur de l'aside il
   se serait retrouvé sous le texte qu'il sert à parcourir. */
.post-wrap {
  display: grid;
  gap: clamp(1.5rem, 3vw, 2.25rem) clamp(2rem, 4vw, 3.5rem);
  grid-template-columns: 1fr;
}
/* La colonne latérale apparaît quand il reste de la place pour une mesure de
   lecture correcte à côté. En dessous, le texte passerait sous les 60
   caractères par ligne, et un article illisible avec un beau sommaire reste
   illisible. */
/* Sur téléphone, l'enveloppe se dissout et ses deux enfants redeviennent des
   enfants de la grille. `order` les remet dans l'ordre de lecture : on
   parcourt le sommaire, on lit, puis on trouve la suite. Sans lui, la colonne
   entière serait passée avant l'article. */
@media (max-width: 999px) {
  .post-cote { display: contents; }
  .post-bloc--sommaire { order: 1; }
  .post-main           { order: 2; }
  .post-side           { order: 3; }
}
@media (min-width: 1000px) {
  .post-wrap {
    grid-template-columns: minmax(0, 1fr) 300px;
    grid-template-areas: 'texte cote';
    align-items: start;
  }
  .post-main { grid-area: texte; }
  /* L'enveloppe entière est collante : le sommaire, les voisins et l'appel
     descendent d'un seul bloc. Trois éléments collants séparés se seraient
     rattrapés et superposés, et les caler l'un sous l'autre aurait demandé
     d'écrire en dur la hauteur du sommaire, qui change avec le nombre de
     sections de l'article. */
  .post-cote {
    grid-area: cote;
    position: sticky;
    top: calc(var(--hauteur-entete) + 1.5rem);
    display: grid;
    gap: 1rem;
    align-content: start;
    /* Une colonne plus haute que l'écran ne peut pas coller : le navigateur
       la laisse défiler jusqu'à son bas. Sur un article à dix sections, elle
       défile donc dans son propre cadre plutôt que de bloquer. */
    max-height: calc(100vh - var(--hauteur-entete) - 3rem);
    overflow-y: auto;
    scrollbar-width: thin;
  }
}
.post-main { min-width: 0; }

/* ─── La réponse courte ────────────────────────────────────────────────────
   Le bloc le plus utile de la page pour un moteur génératif : une question
   posée comme on la pose, une réponse autonome qui se cite sans son contexte.
   Il est en tête parce que c'est là que les extracteurs regardent, et c'est
   aussi là que le lecteur pressé s'arrête. */
.reponse-courte {
  background: var(--surface-accent);
  border: 1px solid var(--volt-200);
  border-radius: var(--rayon);
  padding: clamp(1.25rem, 3vw, 1.85rem);
  margin-bottom: clamp(2rem, 4vw, 2.75rem);
}
.reponse-courte__etiquette {
  font-size: .68rem; font-weight: 800;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--accent-lisible);
  margin-bottom: .6rem;
}
.reponse-courte h2 {
  font-size: clamp(1.15rem, 2vw, 1.4rem);
  line-height: 1.3; margin-bottom: .7rem;
}
.reponse-courte p { color: var(--encre-douce); line-height: 1.7; margin: 0; }

/* ─── La colonne latérale ────────────────────────────────────────────────── */
.post-side { display: grid; gap: 1rem; align-content: start; }
.post-cote > .post-bloc { margin: 0; }
.post-bloc {
  border: 1px solid var(--trait);
  border-radius: var(--rayon-petit);
  padding: 1.1rem 1.2rem;
  background: var(--surface);
}
.post-bloc__titre {
  font-size: .7rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--encre-tenue);
  margin-bottom: .75rem;
}
.post-bloc p { font-size: .88rem; line-height: 1.6; color: var(--encre-douce); }

.post-sommaire { list-style: none; margin: 0; padding: 0; counter-reset: som; }
.post-sommaire li { counter-increment: som; }
.post-sommaire a {
  display: flex; gap: .55rem;
  padding: .38rem 0;
  font-size: .85rem; line-height: 1.45;
  color: var(--encre-douce); text-decoration: none;
  border-left: 2px solid transparent; padding-left: .7rem; margin-left: -.7rem;
  transition: color var(--transition), border-color var(--transition);
}
.post-sommaire a::before {
  content: counter(som) '.';
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  color: var(--encre-tenue); font-weight: 700;
}
.post-sommaire a:hover { color: var(--encre); border-left-color: var(--pal-primaire); }

.post-voisins { list-style: none; margin: 0; padding: 0; display: grid; gap: .1rem; }
.post-voisins a {
  display: block; padding: .5rem 0;
  text-decoration: none;
  border-bottom: 1px solid var(--trait);
}
.post-voisins li:last-child a { border-bottom: 0; }
.post-voisins__titre {
  display: block;
  font-size: .87rem; font-weight: 700; line-height: 1.35;
  color: var(--encre);
}
.post-voisins__meta {
  display: block; margin-top: .2rem;
  font-size: .74rem; color: var(--encre-tenue);
}
.post-voisins a:hover .post-voisins__titre { color: var(--accent-lisible); }

.post-bloc--appel { background: var(--pal-encre); border-color: transparent; }
.post-bloc--appel .post-bloc__titre { color: var(--accent-sur-sombre); }
.post-bloc--appel p { color: var(--nuit-encre-douce); margin-bottom: 1rem; }
.post-bloc--appel .bouton--bloc { display: block; width: 100%; text-align: center; }
.post-bloc__lien {
  display: block; margin-top: .7rem; text-align: center;
  font-size: .82rem; color: var(--nuit-encre-douce);
}
.post-bloc__lien:hover { color: #fff; }

/* ─── Le quiz ──────────────────────────────────────────────────────────────
   Tout le balisage rendu est celui de l'état RÉPONDU : les explications sont
   dans le HTML et la feuille les masque. Sans script, on lit donc les
   questions et leurs réponses, plutôt que de cliquer sur des boutons morts.
   C'est la règle du dépôt, la même que pour le repli du tableau des tarifs :
   rien n'est masqué si rien ne peut le révéler. */
.quiz {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: clamp(2rem, 4vw, 2.75rem);
  border-top: 1px solid var(--trait);
}
.quiz__accroche { color: var(--encre-douce); margin-bottom: 1.75rem; }
.quiz__item {
  border: 1px solid var(--trait);
  border-radius: var(--rayon-petit);
  padding: 1.15rem 1.25rem;
  margin-bottom: .85rem;
}
.quiz__question {
  display: flex; gap: .7rem; align-items: baseline;
  font-weight: 700; line-height: 1.4;
  margin-bottom: .9rem;
}
.quiz__numero {
  flex: 0 0 auto;
  display: grid; place-items: center;
  width: 24px; height: 24px; border-radius: 7px;
  background: var(--surface-accent); border: 1px solid var(--volt-200);
  color: var(--accent-lisible);
  font-size: .72rem; font-weight: 800;
}
.quiz__options { display: grid; gap: .45rem; }
.quiz__option {
  display: flex; gap: .65rem; align-items: center;
  width: 100%; text-align: left;
  padding: .65rem .8rem;
  border: 1px solid var(--trait); border-radius: var(--rayon-petit);
  background: var(--surface);
  font: inherit; font-size: .9rem; color: var(--encre);
  cursor: pointer;
  transition: border-color var(--transition), background var(--transition);
}
.quiz__option:hover:not([disabled]) { border-color: var(--encre-tenue); }
.quiz__option[disabled] { cursor: default; }
.quiz__lettre {
  flex: 0 0 auto;
  display: grid; place-items: center;
  width: 22px; height: 22px; border-radius: 50%;
  border: 1px solid var(--trait);
  font-size: .7rem; font-weight: 800; color: var(--encre-tenue);
}
/* Le vert et le rouge ne portent JAMAIS l'information seuls : la bonne réponse
   prend aussi une coche, la mauvaise une croix, dans la pastille de lettre.
   Une personne qui ne distingue pas le rouge du vert, soit environ un homme
   sur douze, lit la correction exactement comme les autres. */
.quiz__option.est-juste {
  border-color: #15803D; background: #F0FDF4;
}
.quiz__option.est-juste .quiz__lettre {
  border-color: #15803D; color: #15803D;
}
.quiz__option.est-fausse {
  border-color: #B91C1C; background: #FEF2F2; color: var(--encre-douce);
}
.quiz__option.est-fausse .quiz__lettre { border-color: #B91C1C; color: #B91C1C; }

/* La marque REMPLACE la lettre, elle ne s'ajoute pas dessous. Le texte de la
   pastille est un nœud de texte direct, sans balise autour : on ne peut donc
   pas le masquer par un sélecteur, et `font-size: 0` est ici la seule façon
   de le faire disparaître sans toucher au balisage. La marque est restituée
   par `::after`, à sa propre taille. */
.quiz__option.est-juste .quiz__lettre,
.quiz__option.est-fausse .quiz__lettre { font-size: 0; }
.quiz__option.est-juste .quiz__lettre::after,
.quiz__option.est-fausse .quiz__lettre::after { font-size: .8rem; font-weight: 700; }
.quiz__option.est-juste .quiz__lettre::after  { content: '✓'; }
.quiz__option.est-fausse .quiz__lettre::after { content: '✕'; }

.quiz__explication {
  margin-top: .8rem; padding: .7rem .85rem;
  background: var(--surface-doux); border-radius: var(--rayon-petit);
  font-size: .86rem; line-height: 1.6; color: var(--encre-douce);
}
/* Masquée seulement si le script peut la révéler. `data-quiz` n'est posé dans
   le balisage que pour être lu par le script ; c'est lui qui pose
   `est-actif` sur le bloc, et rien n'est caché avant. */
.quiz.est-actif .quiz__explication { display: none; }
.quiz.est-actif .quiz__item.est-repondu .quiz__explication { display: block; }

.quiz__score {
  margin-top: 1.25rem; padding: .9rem 1.1rem;
  background: var(--pal-encre); color: #fff;
  border-radius: var(--rayon-petit);
  font-weight: 700;
}
.quiz__score[hidden] { display: none; }

/* ─── La FAQ de l'article ──────────────────────────────────────────────────
   Un `<details>` par question. Le premier est ouvert : une page de questions
   entièrement repliée ne montre au lecteur que des titres, et il ne clique
   que s'il sait déjà qu'il y a quelque chose derrière. Le contenu reste dans
   le HTML dans les deux cas, donc lisible par un moteur. */
.faq-article {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: clamp(2rem, 4vw, 2.75rem);
  border-top: 1px solid var(--trait);
}
.faq-article h2 { margin-bottom: 1.5rem; }
.faq-article__item {
  border-bottom: 1px solid var(--trait);
}
.faq-article__item summary {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1rem 0;
  font-weight: 700; line-height: 1.4;
  cursor: pointer;
  list-style: none;
}
.faq-article__item summary::-webkit-details-marker { display: none; }
.faq-article__item summary::after {
  content: ''; flex: 0 0 auto;
  width: 10px; height: 10px;
  border-right: 2px solid var(--encre-tenue);
  border-bottom: 2px solid var(--encre-tenue);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--transition);
}
.faq-article__item[open] summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.faq-article__item summary:hover { color: var(--accent-lisible); }
.faq-article__item p {
  padding-bottom: 1.1rem;
  color: var(--encre-douce); line-height: 1.7;
  max-width: 68ch;
}

/* ─── La bande de sommaire des pages métier ────────────────────────────────
   Une barre horizontale collée sous la barre de navigation, qui suit toute la
   descente. Elle remplace la colonne latérale des articles, qui n'a pas sa
   place sur une page faite de sections pleine largeur.

   Elle se colle à `--hauteur-entete` et rien d'autre : c'est le seul jeton qui
   connaît la hauteur de la barre, et un nombre écrit ici se serait désaccordé
   au premier changement de la barre, en silence. */
.sommaire-bande {
  position: sticky;
  top: var(--hauteur-entete);
  z-index: 40;
  background: rgba(255,255,255,.88);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--trait);
}
.sommaire-bande ul {
  display: flex;
  gap: .25rem;
  list-style: none;
  margin: 0; padding: 0;
  /* La bande défile horizontalement plutôt que de passer à la ligne : neuf
     entrées sur deux lignes doublent la hauteur de quelque chose qui est là
     pour ne pas gêner. Le fondu du bord droit dit qu'il y a une suite, ce
     qu'une barre de défilement masquée ne dit pas. */
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to right, #000 92%, transparent);
          mask-image: linear-gradient(to right, #000 92%, transparent);
}
.sommaire-bande ul::-webkit-scrollbar { display: none; }
.sommaire-bande a {
  display: block;
  padding: .7rem .8rem;
  white-space: nowrap;
  font-size: .84rem; font-weight: 600;
  color: var(--encre-douce); text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color var(--transition), border-color var(--transition);
}
.sommaire-bande a:hover {
  color: var(--encre);
  border-bottom-color: var(--pal-primaire);
}
/* La section visée par l'adresse prend la marque : après un clic, la bande dit
   où l'on est, ce qu'une simple ancre ne fait pas. */
.sommaire-bande a:target,
.sommaire-bande a:focus-visible { color: var(--encre); }

/* Une ancre cliquée amène la section SOUS deux barres collées, la navigation
   et le sommaire. Sans cette marge, le titre visé se retrouve caché derrière
   elles, et le visiteur atterrit au milieu d'un paragraphe sans savoir
   pourquoi. */
[id]:is(section, h2) { scroll-margin-top: calc(var(--hauteur-entete) + 4rem); }

@media (max-width: 640px) {
  .sommaire-bande { top: var(--hauteur-entete); }
  .sommaire-bande a { padding: .6rem .65rem; font-size: .8rem; }
}

/* ─── La page « Gérer mes cookies » ────────────────────────────────────────
   Une liste de définitions, parce que c'en est une : un terme, ce qu'il
   recouvre. Le balisage `<dl>` le dit aux lecteurs d'écran, qui annoncent
   alors « liste de 5 termes » et permettent de sauter de l'un à l'autre.

   Le préfixe est `familles-` et non `cookies-` : `vitrine.css` emploie déjà
   `.familles-traceurs__item` et ses cinq dérivés pour le PANNEAU de préférences, qui
   est un autre composant, avec des cases à cocher. Le contrôle des collisions
   l'a dit à la première exécution, ce qui est exactement son travail. */
.familles-traceurs { margin: 2rem 0 0; padding: 0; display: grid; gap: .75rem; }
.familles-traceurs__item {
  border: 1px solid var(--trait);
  border-radius: var(--rayon-petit);
  padding: 1.1rem 1.25rem;
  background: var(--surface);
}
.familles-traceurs__item dt {
  display: flex; flex-wrap: wrap; align-items: center; gap: .6rem;
  font-weight: 800; font-size: 1.02rem;
  margin-bottom: .5rem;
}
.familles-traceurs__item dd { margin: 0; color: var(--encre-douce); line-height: 1.65; }
.familles-traceurs__marque {
  font-size: .68rem; font-weight: 800;
  letter-spacing: .1em; text-transform: uppercase;
  padding: .22rem .6rem; border-radius: var(--rayon-pilule);
  background: var(--surface-doux); color: var(--encre-tenue);
  border: 1px solid var(--trait);
}
.familles-traceurs__marque--libre {
  background: var(--surface-accent);
  border-color: var(--volt-200);
  color: var(--accent-lisible);
}
.familles-traceurs__actions { margin-top: 1.25rem; justify-content: flex-start; }

/* ─── L'extrait de contenu livré ───────────────────────────────────────────
   Un `<blockquote>`, parce que c'en est un : du texte dont l'auteur n'est pas
   la page qui l'affiche. Le filet jaune à gauche et le retrait disent à l'œil
   ce que la balise dit à la machine, et le `<footer>` porte l'attribution. */
.exemple-livre {
  margin: 0;
  padding: 1.35rem 1.5rem;
  border-left: 4px solid var(--pal-primaire);
  background: var(--surface);
  border-radius: 0 var(--rayon-petit) var(--rayon-petit) 0;
}
.exemple-livre p {
  margin: 0;
  font-size: 1.04rem; line-height: 1.75;
  color: var(--encre-douce);
}
.exemple-livre footer {
  margin-top: 1rem;
  font-size: .8rem; color: var(--encre-tenue);
}

/* ═══════════════════════════════════════════════════════════════════════════
   6 · LE HUB DU BLOG
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── La recherche et les pastilles ────────────────────────────────────────
   Le bloc est rendu avec `hidden` et c'est le script qui l'ouvre : sans lui,
   on lit un blog complet plutôt qu'un champ de recherche qui ne cherche rien. */
.blog-filtres {
  display: grid; gap: 1rem;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}
.blog-filtres[hidden] { display: none; }

.blog-recherche {
  display: flex; align-items: center; gap: .75rem;
  background: var(--surface);
  border: 1.5px solid var(--trait);
  border-radius: var(--rayon-pilule);
  padding: .2rem 1.25rem;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.blog-recherche:focus-within {
  border-color: var(--pal-primaire);
  box-shadow: 0 0 0 4px rgba(250,204,21,.22);
}
.blog-recherche svg { flex: 0 0 auto; color: var(--encre-tenue); }
.blog-recherche input {
  flex: 1 1 auto; min-width: 0;
  border: 0; background: none; outline: none;
  font: inherit; font-size: 1rem;
  padding: .85rem 0;
  color: var(--encre);
}
.blog-recherche input::placeholder { color: var(--encre-tenue); }
/* La croix que WebKit ajoute dans un `type="search"` se pose sur un fond
   arrondi et clair : elle y est invisible, et elle double le bouton de
   réinitialisation qu'on propose déjà en toutes lettres. */
.blog-recherche input::-webkit-search-cancel-button { display: none; }

.blog-familles { display: flex; flex-wrap: wrap; gap: .5rem; }
.blog-pastille {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .5rem 1rem;
  border: 1px solid var(--trait);
  border-radius: var(--rayon-pilule);
  background: var(--surface);
  font: inherit; font-size: .88rem; font-weight: 600;
  color: var(--encre-douce);
  cursor: pointer;
  transition: border-color var(--transition), background var(--transition), color var(--transition);
}
.blog-pastille span {
  font-size: .72rem; font-weight: 700;
  color: var(--encre-tenue);
  font-variant-numeric: tabular-nums;
}
.blog-pastille:hover { border-color: var(--encre-tenue); color: var(--encre); }
.blog-pastille.est-active {
  background: var(--pal-encre); border-color: var(--pal-encre); color: #fff;
}
.blog-pastille.est-active span { color: var(--accent-sur-sombre); }

.blog-vide { font-size: .93rem; color: var(--encre-douce); }
.blog-vide[hidden] { display: none; }

/* ─── L'article mis en avant ───────────────────────────────────────────────
   Pleine largeur, deux colonnes sur grand écran. La couverture est DESSINÉE :
   le blog explique lui-même qu'une image de banque ne sert à rien, en poser
   une ici aurait été la première chose qu'un lecteur remarque. Un dégradé, un
   motif et le nom de la famille, en zéro requête et zéro octet d'image. */
.blog-vedette {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  overflow: hidden;
  background: var(--surface);
  text-decoration: none;
  transition: border-color var(--transition), box-shadow var(--transition), transform var(--transition);
}
.blog-vedette[hidden] { display: none; }
.blog-vedette:hover {
  border-color: var(--volt-300);
  box-shadow: var(--ombre-forte);
  transform: translateY(-2px);
}
@media (min-width: 820px) {
  .blog-vedette { grid-template-columns: 38% 1fr; }
}

.blog-vedette__couverture {
  position: relative;
  display: grid; place-items: center;
  min-height: 190px;
  background: linear-gradient(135deg, var(--volt-300) 0%, var(--volt-400) 55%, var(--volt-500) 100%);
  overflow: hidden;
}
.blog-vedette__motif {
  position: absolute; inset: -20%;
  background:
    radial-gradient(circle at 22% 28%, rgba(255,255,255,.45), transparent 42%),
    radial-gradient(circle at 78% 72%, rgba(9,9,11,.14), transparent 46%);
}
.blog-vedette__famille {
  position: relative; z-index: 1;
  padding: .5rem 1.1rem;
  border-radius: var(--rayon-pilule);
  background: var(--pal-encre); color: #fff;
  font-size: .74rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase;
}

.blog-vedette__texte {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: .75rem;
  padding: clamp(1.5rem, 3vw, 2.25rem);
}
.blog-vedette__texte h2 {
  font-size: clamp(1.4rem, 2.6vw, 2rem);
  line-height: 1.18;
  color: var(--encre);
}
.blog-vedette__texte p {
  color: var(--encre-douce); line-height: 1.65;
  max-width: 62ch;
}
.blog-vedette:hover .blog-vedette__texte h2 { color: var(--accent-lisible); }

/* Une carte filtrée disparaît vraiment : `hidden` seul serait annulé par le
   `display: flex` de `.carte-lien`, qui est plus spécifique qu'un attribut. */
.carte-lien[hidden] { display: none !important; }

/* ═══ Le bloc de repères ════════════════════════════════════════════════════
   ─── Pourquoi les classes s'appellent « boussole » et non « repères » ────
   Parce que `.reperes` était déjà pris, dans `vitrine.css`, par la ligne de
   preuve sous la bannière : du texte clair, prévu pour un fond sombre. Posé
   sur cette section-ci, il rendait le titre blanc sur blanc. C'est exactement
   le défaut que la relecture du 13 septembre avait trouvé avec `.constat`, et
   la leçon écrite ce jour-là tient : deux feuilles chargées ensemble partagent
   un seul espace de noms, et un nom court finit toujours par être pris deux
   fois. La clé du bloc et ses champs restent `reperes` : eux ne sont pas dans
   cet espace de noms.

   Trois choses dans une section : le numéro, le plan du site, six questions.
   Elles sont séparées par de l'espace et par deux titres de rang trois, et non
   par des cadres : trois cadres empilés dans une section qui en est déjà un
   auraient fait quatre bordures pour une seule idée. */

/* ─── Le numéro ────────────────────────────────────────────────────────────
   Écrit à la taille d'un titre, et pas dans un bouton. Un numéro dans un
   bouton se lit comme un libellé : on clique ou on passe, on ne le retient
   pas, et on ne le recopie pas sur un carnet. Écrit en grand, il fait les
   deux, et il reste cliquable là où ça compte, c'est-à-dire sur un téléphone.

   La couleur est l'encre et non le jaune de la marque : posé en texte, ce
   jaune donne 1,72:1 sur blanc, c'est-à-dire rien. Il sert ici de liseré et de
   fond de pastille, où il n'a pas à être lu. */
.boussole__appel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(1.25rem, 3vw, 2.5rem);
  padding: clamp(1.5rem, 3.5vw, 2.5rem);
  margin-bottom: clamp(3rem, 6vw, 4.5rem);
  background: var(--surface);
  border: 1px solid var(--trait);
  border-left: 4px solid var(--pal-primaire);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
}
.boussole__appel-sur {
  font-size: .655rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--encre-tenue);
}
.boussole__tel {
  display: inline-flex; align-items: center; gap: .7rem;
  margin: .35rem 0 .6rem;
  font-size: clamp(2rem, 5.5vw, 3.1rem);
  font-weight: 800; line-height: 1.05;
  letter-spacing: -.03em;
  /* Un numéro coupé en deux lignes n'est plus un numéro : on lit « 07 68 70 80 »
     puis on cherche la suite. Il tient sur une ligne à toutes les largeurs, et
     c'est la taille qui cède, pas le numéro. */
  white-space: nowrap;
  /* Les chiffres d'un numéro se lisent groupe par groupe : les chasses fixes
     empêchent le « 11 » de paraître deux fois plus étroit que le « 70 ». */
  font-variant-numeric: tabular-nums;
  color: var(--encre); text-decoration: none;
  transition: color var(--transition);
}
.boussole__tel:hover, .boussole__tel:focus-visible { color: var(--accent-lisible); }
.boussole__tel-icone {
  flex: 0 0 auto;
  width: 46px; height: 46px;
  display: grid; place-items: center;
  border-radius: var(--rayon-pilule);
  background: var(--pal-primaire);
  color: var(--pal-encre);
  box-shadow: var(--lueur);
}
.boussole__appel-aide {
  font-size: .875rem; line-height: 1.65;
  color: var(--encre-douce);
  max-width: 54ch;
}

/* ─── Les deux titres intérieurs ───────────────────────────────────────── */
.boussole__titre {
  font-size: clamp(1.15rem, 2.2vw, 1.45rem);
  letter-spacing: -.02em;
  margin-bottom: 1.35rem;
}

/* ─── Le plan ──────────────────────────────────────────────────────────────
   Les mêmes cartes que partout, mais elles ne sont pas cliquables dans leur
   ensemble : ce sont des listes de liens. Le survol ne les soulève donc pas,
   sans quoi la carte promettrait une destination qu'elle n'a pas. */
/* Trois colonnes, et pas une grille qui se remplit toute seule : les colonnes
   sont SIX, et un remplissage automatique les rangeait quatre puis deux, avec
   une moitié de rangée vide au milieu du bloc. Trois et trois se lisent, et
   chaque rangée garde des cartes de même hauteur. */
.boussole__plan {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  /* Chaque carte à sa hauteur, et non à celle de sa rangée : les colonnes ont
     de trois à sept liens, et l'étirement laissait une demi-carte blanche sous
     « L'agence » pour rattraper les six articles d'à côté. Une boîte à moitié
     vide se lit comme un contenu manquant. */
  align-items: start;
  margin-bottom: clamp(3rem, 6vw, 4.5rem);
}
@media (max-width: 900px) { .boussole__plan { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .boussole__plan { grid-template-columns: 1fr; } }
.boussole__plan .carte-lien:hover { transform: none; box-shadow: none; }
.boussole__plan .carte-lien h4 {
  font-size: 1.02rem; font-weight: 700;
  letter-spacing: -.015em;
  margin-bottom: .75rem;
}
/* Le retrait par défaut d'une `ul` est remis à zéro ici, et non dans la
   remise à plat générale : `.prose ul` en a besoin, et le lui retirer
   aurait décalé les listes à puces de vingt pages. */
.boussole__liste {
  list-style: none;
  display: grid; gap: .45rem;
  padding-inline-start: 0; margin: 0;
}
.boussole__liste a {
  font-size: .875rem; line-height: 1.45;
  color: var(--encre-douce);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 160ms ease, border-color 160ms ease;
}
.boussole__liste a:hover, .boussole__liste a:focus-visible {
  color: var(--accent-lisible);
  border-bottom-color: var(--volt-300);
}

/* ─── Les six questions ────────────────────────────────────────────────────
   En colonne de lecture, et non sur toute la largeur : une réponse de trois
   lignes étalée sur mille deux cents pixels se relit de gauche à droite en
   perdant la ligne. */
.boussole__faq { max-width: 860px; margin-inline: auto; }
.boussole__faq .boussole__titre { text-align: center; }
/* La réponse respire moins quand un lien la suit : sans cela, deux marges de
   bas de bloc se cumulaient et le lien semblait appartenir à la question
   d'après. */
.question-bloc p:not(:last-child) { padding-bottom: .55rem; }
.question-bloc__vers a {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .82rem; font-weight: 700;
  color: var(--accent-lisible);
  text-decoration: none;
}
.question-bloc__vers a:hover { text-decoration: underline; }
.question-bloc__vers a svg { transition: transform 160ms ease; }
.question-bloc__vers a:hover svg { transform: translateX(3px); }
.boussole__faq-aide {
  margin: 1.35rem 0 1.25rem;
  font-size: .855rem; line-height: 1.65;
  color: var(--encre-tenue);
  text-align: center;
}
.boussole__faq > .bouton { display: flex; margin-inline: auto; width: fit-content; }

@media (max-width: 720px) {
  /* Le bouton passe sous le numéro et prend la largeur : à côté, il devenait
     une colonne de deux mots empilés. */
  .boussole__appel { grid-template-columns: 1fr; }
  .boussole__appel .bouton { justify-content: center; }
  .boussole__tel { font-size: min(2.4rem, 7vw); gap: .5rem; }
  .boussole__tel-icone { width: 36px; height: 36px; }
}
