/* =============================================================================
   vitrine.css : la feuille de la page de vente de la plateforme.

   Elle est SÉPARÉE de charte.css et de console.css, exprès. Les deux autres
   feuilles servent les sites des clients et l'administration : leurs couleurs
   viennent des réglages d'UN site, et chaque client peut les changer. Cette
   page-ci n'appartient à aucun site : c'est la vitrine de l'agence. Elle porte
   donc les couleurs de la marque en dur, et une retouche faite dans
   l'administration d'un site client ne peut pas déplacer un pixel ici.

   ─── La charte reprise du site de l'agence ────────────────────────────────
   Les valeurs ci-dessous sont celles de agenceweblocal.com, à l'identique :
   le jaune « volt » (#FACC15), l'encre presque noire (#09090B) et l'échelle de
   gris zinc. Un prospect qui arrive ici depuis le site de l'agence, ou qui fait
   l'aller-retour avant de décider, ne doit pas avoir l'impression de changer
   d'entreprise en route. Les deux pages sont vendues par la même personne.

   ─── Les trois nuances de jaune, et pourquoi il en faut trois ─────────────
   Le jaune de marque #FACC15 donne 1,72:1 sur du blanc. C'est excellent comme
   APLAT sous du texte encre (12,4:1), et inutilisable comme couleur de texte
   sur fond clair. Trois nuances tiennent donc les trois emplois :

     --pal-primaire         #FACC15   aplats, boutons, lueurs, traits, icônes
     --accent-lisible       #A16207   texte accent sur fond clair      4,63:1
     --accent-sur-sombre    #FACC15   texte accent sur fond nuit      11,24:1

   Aucune des trois n'est interchangeable, et `bin/test-vitrine.php` vérifie
   qu'aucun texte blanc n'est posé sur le jaune de marque.
   ============================================================================= */

/* ─── La police ────────────────────────────────────────────────────────────────
   Inter variable, le même fichier que celui du site de l'agence, copié dans
   assets/fonts/. Il est déclaré ICI et non dans fonts.css parce que fonts.css
   est GÉNÉRÉ par bin/fetch-fonts.php pour les habillages des sites clients :
   une déclaration écrite à la main y serait effacée à la première régénération.
   La graisse va jusqu'à 900, ce que le subset Inter 300-600 des habillages ne
   permet pas, et les grands titres de cette page sont en 900. */
@font-face {
  font-family: 'Inter Variable';
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url('/assets/fonts/inter-latin-variable.woff2') format('woff2-variations'),
       url('/assets/fonts/inter-latin-variable.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ─── Jetons ───────────────────────────────────────────────────────────────── */
:root {
  /* Le site est dessiné en clair, et il le déclare : voir le commentaire de
     `includes/plateforme.php`. La méta le dit au navigateur avant le premier
     octet de CSS, cette ligne le redit à tout ce qui lit la feuille seule. */
  color-scheme: light;

  /* L'échelle jaune de la marque. */
  --volt-50:  #FEFCE8;
  --volt-100: #FEF9C3;
  --volt-200: #FEF08A;
  --volt-300: #FDE047;
  --volt-400: #FACC15;
  --volt-500: #EAB308;
  --volt-600: #CA8A04;
  --volt-700: #A16207;

  --pal-primaire:   #FACC15;
  --pal-encre:      #09090B;
  --pal-fond:       #FFFFFF;
  --pal-secondaire: #18181B;
  /* L'accent et la primaire sont la même couleur : la marque n'en a qu'une, et
     deux jetons qui portent deux valeurs proches finissaient par produire deux
     jaunes côte à côte. Le jeton reste distinct parce que la page l'emploie
     pour deux intentions (surligneur d'un côté, boutons de l'autre) et que
     l'une des deux pourrait changer sans l'autre. */
  --pal-accent:     #FACC15;

  /* Les deux nuances dérivées, imposées par la lisibilité. */
  --accent-lisible:    #A16207;
  --accent-sur-sombre: #FACC15;

  /* Neutres : l'échelle zinc du site de l'agence. */
  --encre:        #09090B;
  --encre-douce:  #52525B;
  --encre-tenue:  #71717A;
  --trait:        #E4E4E7;
  --surface:      #FFFFFF;
  --surface-doux: #FAFAFA;
  --surface-accent: #FEFCE8;

  /* Sur fond nuit. */
  --nuit-encre:       rgba(255,255,255,.94);
  --nuit-encre-douce: rgba(255,255,255,.70);
  --nuit-trait:       rgba(255,255,255,.12);
  --nuit-surface:     rgba(255,255,255,.06);

  /* Mesures. Les rayons sont ceux du site de l'agence : des cartes très
     arrondies (24 px), des boutons en pilule pleine. */
  --largeur:    1200px;
  --gouttiere:  1.5rem;
  --rayon:      24px;
  --rayon-petit: 14px;
  --rayon-pilule: 999px;
  --ombre:       0 1px 2px rgba(9,9,11,.04), 0 10px 30px rgba(9,9,11,.06);
  --ombre-forte: 0 2px 6px rgba(9,9,11,.06), 0 24px 60px rgba(9,9,11,.12);
  /* La lueur jaune sous le bouton principal. C'est la signature de la marque :
     elle n'apparaît que sous l'action que l'on veut voir cliquée. */
  --lueur:       0 8px 30px rgba(250,204,21,.38);
  --lueur-forte: 0 12px 38px rgba(250,204,21,.52);

  /* La hauteur de la barre de navigation, qui est collée en haut. Tout ce qui
     se colle à son tour (l'en-tête du tableau comparatif) doit démarrer sous
     elle, sinon il s'y glisse dessous. 72 px de barre, plus son filet. */
  --hauteur-entete: 73px;
  --transition:  220ms cubic-bezier(.4,0,.2,1);

  --police: 'Inter Variable', Inter, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --police-citation: 'Inter Variable', Inter, system-ui, sans-serif;
}

/* ─── Remise à zéro ────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  font-family: var(--police);
  font-weight: 500;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--encre);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg, canvas { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--accent-lisible); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--pal-secondaire); }

:focus-visible {
  outline: 3px solid var(--pal-primaire);
  outline-offset: 3px;
  border-radius: 4px;
}

.evitement {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--pal-encre); color: #fff; padding: .75rem 1.25rem;
  border-radius: 0 0 var(--rayon-petit) 0;
}
.evitement:focus { left: 0; }

/* ─── Structure ────────────────────────────────────────────────────────────── */
.contenant {
  width: 100%; max-width: var(--largeur);
  margin-inline: auto; padding-inline: var(--gouttiere);
}
.contenant--etroit { max-width: 760px; }
.contenant--moyen  { max-width: 980px; }

.section { padding-block: clamp(4rem, 9vw, 7.5rem); }
.section--doux  { background: var(--surface-doux); }
.section--accent  { background: var(--surface-accent); }
.section--nuit  { background: var(--pal-encre); color: var(--nuit-encre); }
.section--serre { padding-block: clamp(3rem, 6vw, 5rem); }

/* ─── Typographie ──────────────────────────────────────────────────────────── */
/* Les titres sont en 900 et très serrés : c'est la signature typographique du
   site de l'agence, et c'est ce qui se reconnaît au premier coup d'œil, avant
   même la couleur. Le corps de texte est en 500, pas en 400 : sur du gris zinc,
   le 400 paraît délavé. */
h1, h2, h3, h4 {
  line-height: 1.1;
  letter-spacing: -0.035em;
  text-wrap: balance;
  font-weight: 900;
}
h1 { font-size: clamp(2.4rem, 5.6vw, 4.25rem); }
h2 { font-size: clamp(1.9rem, 3.6vw, 2.85rem); line-height: 1.12; }
h3 { font-size: clamp(1.15rem, 1.8vw, 1.4rem); font-weight: 800; line-height: 1.3;
     letter-spacing: -.02em; }
h4 { font-size: 1.05rem; font-weight: 800; line-height: 1.4; letter-spacing: -.015em; }

p { line-height: 1.65; }
p + p { margin-top: 1rem; }

.sur-titre {
  display: inline-flex; align-items: center; gap: .55rem;
  font-size: .75rem; font-weight: 900;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--accent-lisible);
  margin-bottom: 1rem;
}
.sur-titre::before {
  content: ''; width: 22px; height: 2px;
  background: var(--pal-primaire); border-radius: 2px;
}
.section--nuit .sur-titre { color: var(--accent-sur-sombre); }

.accroche {
  font-size: clamp(1.05rem, 1.45vw, 1.28rem);
  font-weight: 500; line-height: 1.6;
  color: var(--encre-douce);
  max-width: 64ch;
}
.section--nuit .accroche { color: var(--nuit-encre-douce); }

.mot-colore { color: var(--accent-lisible); }
/* Sur fond clair, le mot coloré d'un grand titre prend la nuance SOMBRE du
   jaune : le jaune de marque y donne 1,72:1, c'est-à-dire un mot de titre que
   personne ne lit, et c'est précisément celui qu'on a voulu mettre en avant.
   Sur fond nuit, la règle suivante rend le jaune vif, qui y donne 11,24:1. */
h1 .mot-colore, h2 .mot-colore { color: var(--accent-lisible); }
.section--nuit .mot-colore { color: var(--accent-sur-sombre); }

.citation {
  font-family: var(--police-citation);
  font-size: clamp(1.25rem, 2.2vw, 1.6rem);
  line-height: 1.4; font-weight: 400;
}

.tete-section { max-width: 680px; margin-bottom: clamp(2.5rem, 5vw, 3.75rem); }
.tete-section--centre { margin-inline: auto; text-align: center; }
.tete-section--centre .sur-titre { justify-content: center; }
.tete-section .accroche { margin-top: 1rem; }
.tete-section--centre .accroche { margin-inline: auto; }

/* ─── Boutons ──────────────────────────────────────────────────────────────── */
.bouton {
  display: inline-flex; align-items: center; justify-content: center; gap: .6rem;
  min-height: 52px; padding: .9rem 1.75rem;
  border: 2px solid transparent; border-radius: var(--rayon-pilule);
  font-weight: 600; font-size: 1rem; line-height: 1;
  text-decoration: none; cursor: pointer;
  transition: transform var(--transition), box-shadow var(--transition),
              background-color var(--transition), color var(--transition),
              border-color var(--transition);
}
.bouton:hover { transform: translateY(-2px); }
.bouton:active { transform: translateY(0); }

/* Le bouton principal est l'aplat jaune de la marque, avec le texte encre
   dessus : 12,4:1, très au-dessus du seuil. L'inverse (texte jaune sur fond
   blanc) donnerait 1,72:1, et c'est précisément la faute que le test de cette
   page interdit.

   La lueur jaune sous le bouton n'est pas une décoration : c'est elle qui
   distingue l'action à cliquer du reste, sur une page qui compte huit boutons
   secondaires. Elle ne sert donc qu'ici. */
.bouton--principal {
  background: var(--pal-primaire); color: var(--pal-encre);
  font-weight: 800;
  box-shadow: var(--lueur);
}
.bouton--principal:hover {
  background: var(--volt-500); color: var(--pal-encre);
  box-shadow: var(--lueur-forte);
}

/* Sur fond nuit, le jaune reste le jaune : il est encore plus visible là qu'sur
   du blanc, et c'est ainsi que le site de l'agence l'emploie. Le secondaire, en
   revanche, doit être éclairci, sinon il sort encre nuit sur fond nuit, c'est-
   à-dire rigoureusement invisible (défaut D1 de la revue de fin de chantier).
   La bannière ne figure plus dans cette liste : elle est passée en fond clair.
   Toute NOUVELLE surface sombre doit être ajoutée ici, et le test le vérifie. */
.section--nuit .bouton--principal,
.bandeau .bouton--principal {
  background: var(--pal-primaire); color: var(--pal-encre);
  box-shadow: 0 8px 30px rgba(250,204,21,.28);
}
.section--nuit .bouton--principal:hover,
.bandeau .bouton--principal:hover { background: var(--volt-300); color: var(--pal-encre); }

/* Le secondaire est blanc bordé de gris, comme sur le site de l'agence : il se
   voit, il ne concurrence pas le jaune. */
.bouton--second {
  background: var(--surface); color: var(--encre); border-color: var(--trait);
  box-shadow: 0 1px 2px rgba(9,9,11,.04);
}
.bouton--second:hover {
  border-color: var(--pal-encre); background: var(--surface-doux); color: var(--encre);
}

/* Les trois surfaces sombres de la page, listées ensemble.
   Ce bouton a été livré une première fois avec la seule règle `.section--nuit`,
   et il est sorti RIGOUREUSEMENT INVISIBLE sur la bannière, qui ne porte pas
   cette classe : encre nuit sur fond nuit. C'est le défaut D1 de la revue de
   fin de chantier, reproduit à l'identique, et pour la même raison : une classe
   écrite pour un contexte, employée dans un autre.
   La règle vit donc au même endroit que le bouton, avec la liste complète des
   surfaces sombres. Ajouter une quatrième surface sombre à cette page veut dire
   ajouter son sélecteur ICI, et le test de la vitrine le vérifie. */
.section--nuit .bouton--second,
.bandeau .bouton--second {
  color: #fff; border-color: var(--nuit-trait); background: rgba(255,255,255,.06);
  box-shadow: none;
}
.section--nuit .bouton--second:hover,
.bandeau .bouton--second:hover { border-color: #fff; background: rgba(255,255,255,.12); color: #fff; }

.bouton--large { width: 100%; }
.actions { display: flex; flex-wrap: wrap; gap: .875rem; }

/* ─── Barre de navigation ──────────────────────────────────────────────────── */
/* La barre est BLANCHE, translucide, comme celle du site de l'agence. Elle
   l'était en encre nuit : sur une page dont la bannière est maintenant claire,
   une barre sombre collée en haut faisait une réglette noire qui n'appartenait
   à rien. */
.entete {
  position: sticky; top: 0; z-index: 50;
  background: rgba(255,255,255,.86);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--trait);
  transition: background var(--transition);
}
.entete__barre {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem; min-height: 72px;
}
/* Le nom seul tient lieu de marque. Sans pastille à côté de lui, il porte
   toute la présence de la barre : il est donc un peu plus grand et un peu plus
   serré qu'un simple lien, faute de quoi il se confondrait avec les entrées du
   menu placées juste à sa droite. */
.entete__marque {
  display: inline-flex; align-items: center; gap: .55rem;
  color: var(--encre); text-decoration: none;
  font-weight: 900; font-size: 1.1rem; letter-spacing: -.04em;
}
.entete__marque:hover { color: var(--encre); }
/* Le carré encre à jaune : le seul signe graphique de la marque, et il est
   repris tel quel du site de l'agence, où il tient lieu de logo. */
.entete__sceau {
  width: 30px; height: 30px; border-radius: 9px; flex: 0 0 auto;
  display: grid; place-items: center;
  background: var(--pal-encre); color: var(--pal-primaire);
  box-shadow: 0 4px 14px rgba(9,9,11,.22);
  transition: transform var(--transition);
}
.entete__marque:hover .entete__sceau { transform: rotate(12deg); }
.entete__marque em { font-style: normal; color: var(--volt-500); }

/* ── Le menu, et pourquoi il n'est plus dans un aplat jaune ─────────────────
   Il l'était : quatre liens posés dans une pilule jaune arrondie, comme sur le
   site de l'agence. Ça tenait quand ils étaient quatre ancres vers la même
   page. Ça ne tient plus depuis qu'il y a quatre MENUS qui ouvrent des
   panneaux : l'aplat devenait la chose la plus voyante de la barre, devant le
   nom de la marque et devant le bouton d'action, et il gardait sa couleur
   pendant qu'un panneau s'ouvrait sous lui, ce qui faisait deux jaunes
   superposés.

   Le jaune n'a pas disparu de la barre, il a changé de place : il est sous
   l'entrée de la page où l'on est, en filet, et sous le bouton d'inscription.
   Une couleur d'accent ne sert qu'à condition d'être rare. */
.entete__nav { display: none; align-items: center; }
.entete__actions { display: flex; align-items: center; gap: .75rem; }
.entete .bouton { min-height: 44px; padding: .65rem 1.25rem; font-size: .925rem; }
/* Dans la barre, l'action est encre à texte jaune : le jaune est déjà pris par
   la pilule du menu juste à gauche, et deux aplats jaunes voisins ne se
   hiérarchisent plus. */
.entete .bouton--principal {
  background: var(--pal-encre); color: var(--pal-primaire);
  box-shadow: 0 4px 15px rgba(9,9,11,.24);
}
.entete .bouton--principal:hover {
  background: var(--pal-secondaire); color: var(--pal-primaire);
  box-shadow: 0 8px 22px rgba(9,9,11,.30);
}
/* Le numéro de téléphone, dans la barre : sur une offre vendue à des artisans,
   il est cliqué plus souvent que n'importe quel formulaire. */
.entete__tel {
  display: none; align-items: center; gap: .45rem;
  color: var(--encre); text-decoration: none;
  font-weight: 800; font-size: .95rem; letter-spacing: -.01em;
}
.entete__tel:hover { color: var(--accent-lisible); }
.entete__tel svg { color: var(--volt-600); flex: 0 0 auto; }

/* ─── La barre sur téléphone ──────────────────────────────────────────────────
   Trois corrections, et chacune répond à un défaut vu à l'écran en 375 px.

   Le nom de la marque passait à la ligne (« Agence Web / Local. »), ce qui
   faisait une barre collée de deux étages avant même le menu. Il est donc plus
   petit et insécable sous 640 px.

   Le libellé du bouton d'appel passait à la ligne aussi. Il ne se raccourcit
   pas (il vient du registre et l'agence choisit ses mots), mais il devient
   insécable et son rembourrage se resserre.

   Le numéro de téléphone, lui, était purement masqué sous 640 px, c'est-à-dire
   à l'endroit exact où l'appareil sait téléphoner. Il reste donc affiché, en
   pictogramme seul : le numéro écrit en clair revient dès 900 px. */
.entete__marque { font-size: 1rem; white-space: nowrap; }
.entete__marque .entete__sceau { width: 28px; height: 28px; }
.entete .bouton { white-space: nowrap; }
.entete__tel { display: inline-flex; }
.entete__tel span { display: none; }
/* Sous 640 px, la barre porte le nom, le pictogramme d'appel et le menu, et
   rien d'autre : à trois éléments plus un bouton d'action, le libellé de
   l'action débordait de l'écran, coupé au milieu d'un mot. L'action n'est pas
   perdue pour autant : elle est le premier bouton de la bannière, juste en
   dessous, et le panneau du menu porte l'appel téléphonique. */
.entete__appel { display: none; }
@media (min-width: 520px) { .entete__appel { display: inline-flex; } }

/* Le bouton du menu, et le panneau qu'il ouvre. */
.entete__bascule {
  display: inline-grid; place-items: center;
  width: 44px; height: 44px; flex: 0 0 auto;
  background: var(--surface); color: var(--encre);
  border: 1px solid var(--trait); border-radius: 14px;
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition);
}
.entete__bascule:hover { background: var(--surface-doux); border-color: var(--pal-encre); }
.entete__bascule[aria-expanded="true"] {
  background: var(--pal-encre); color: var(--pal-primaire); border-color: var(--pal-encre);
}

/* `display: grid` gagne contre le `display: none` que le navigateur applique à
   l'attribut `hidden` : sans la règle explicite ci-dessous, le panneau
   s'affichait ouvert au chargement, au-dessus de la bannière, et le script le
   « fermait » sans que rien ne bouge. C'est le piège classique de `hidden`
   contre une règle d'affichage, et il ne se voit qu'à l'écran. */
.entete__panneau[hidden] { display: none; }
.entete__panneau {
  border-top: 1px solid var(--trait);
  background: var(--surface);
  padding: 1rem var(--gouttiere) 1.25rem;
  display: grid; gap: .75rem;
}
.entete__panneau-liens { display: grid; gap: .2rem; }
.entete__panneau-liens a {
  padding: .8rem .9rem; border-radius: 14px;
  color: var(--encre); text-decoration: none; font-weight: 800;
}
.entete__panneau-liens a:hover { background: var(--volt-50); color: var(--accent-lisible); }

@media (min-width: 640px) {
  .entete__marque { font-size: 1.1rem; }
  .entete__marque .entete__sceau { width: 30px; height: 30px; }
}
@media (min-width: 900px) {
  .entete__tel span { display: inline; }
  /* Le menu déplié appartient au téléphone : sur grand écran, la pilule jaune
     est dans la barre, et laisser le bouton afficherait deux menus. */
  .entete__bascule, .entete__panneau { display: none !important; }
}

@media (min-width: 900px) {
  .entete__nav { display: flex; }
}

/* ─── Bannière ─────────────────────────────────────────────────────────────── */
/* La bannière est CLAIRE. Elle était en encre nuit, ce qui est un parti pris
   honorable mais qui n'est pas celui de la marque : le site de l'agence ouvre
   sur un fond gris très clair, deux halos flous (un jaune, un gris) et un titre
   encre en 900. C'est cette ouverture-là qui est reprise ici, à l'identique.

   Conséquence à ne pas perdre de vue : tout ce qui était écrit en blanc dans
   cette bannière (titre, accroche, étiquette, gages) repasse en encre. Une
   règle oubliée donnerait du blanc sur gris clair, donc rien. */
.banniere {
  position: relative; overflow: hidden;
  background: var(--surface-doux); color: var(--encre);
  padding-block: clamp(3.5rem, 8vw, 6.5rem) clamp(4rem, 9vw, 7rem);
  border-bottom: 1px solid var(--trait);
  isolation: isolate;
}
.banniere::before {
  content: ''; position: absolute; inset: 0; z-index: -2;
  background:
    radial-gradient(38% 42% at 22% 8%,   rgba(250,204,21,.34), transparent 70%),
    radial-gradient(45% 45% at 88% 92%,  rgba(228,228,231,.75), transparent 72%),
    radial-gradient(30% 30% at 72% 12%,  rgba(253,224,71,.20), transparent 70%);
  filter: blur(6px);
}
.banniere__grille {
  display: grid; gap: clamp(2.5rem, 5vw, 4rem);
  align-items: center;
}
@media (min-width: 1000px) {
  .banniere__grille { grid-template-columns: 1.08fr .92fr; }
}

.banniere__marqueur {
  display: inline-flex; align-items: center; gap: .6rem;
  padding: .5rem 1.05rem .5rem .6rem;
  border: 1px solid var(--trait); border-radius: var(--rayon-pilule);
  background: var(--surface);
  font-size: .78rem; font-weight: 800; color: var(--encre);
  letter-spacing: .1em; text-transform: uppercase;
  box-shadow: 0 1px 2px rgba(9,9,11,.05);
  margin-bottom: 1.5rem;
}
.banniere__marqueur strong { color: var(--accent-lisible); font-weight: 900; }
.banniere__point {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--pal-primaire); flex: 0 0 auto;
  box-shadow: 0 0 0 4px rgba(250,204,21,.28);
}

/* Le titre de bannière est plafonné plus bas que le h1 générique de la page.
   À 4,25 rem dans une colonne de six cents pixels, « Le site de votre JCE, »
   passait à la ligne au milieu et laissait « enfin » seul sur sa ligne, ce qui
   casse la lecture juste avant le mot surligné, c'est-à-dire à l'endroit exact
   où elle doit porter. */
.banniere h1 { color: var(--encre); font-size: clamp(2.3rem, 4.6vw, 3.8rem); }
.banniere .accroche { margin-top: 1.5rem; color: var(--encre-douce); }
.banniere .actions { margin-top: 2.25rem; }

.banniere__gages {
  display: flex; flex-wrap: wrap; gap: 1.25rem 2rem;
  margin-top: 2.5rem; padding-top: 2rem;
  border-top: 1px solid var(--trait);
}
.banniere__gage {
  display: flex; align-items: center; gap: .6rem;
  font-size: .9rem; font-weight: 600; color: var(--encre-douce);
}
.banniere__gage svg { flex: 0 0 auto; color: var(--volt-600); }
.banniere__gage strong { color: var(--encre); font-weight: 800; }

/* La preuve de nombre, sous les gages : reprise du « Déjà 50+ entreprises
   accompagnées » du site de l'agence, dans la même forme (rond jaune pâle,
   pictogramme, phrase courte). */
.banniere__preuve {
  display: flex; align-items: center; gap: .8rem;
  margin-top: 2rem; font-size: .92rem; font-weight: 700;
  color: var(--encre-tenue);
}
.banniere__preuve span {
  width: 40px; height: 40px; border-radius: 50%; flex: 0 0 auto;
  display: grid; place-items: center;
  background: var(--volt-100); border: 1px solid var(--volt-200);
  color: var(--volt-700);
}
.banniere__preuve strong { color: var(--encre); font-weight: 900; }

/* ─── Le globe ─────────────────────────────────────────────────────────────── */
/* Reprend l'idée du composant « cobe globe pulse » : une sphère qui tourne, des
   marqueurs qui pulsent, une prise en main à la souris. Écrit en canvas 2D
   maison plutôt qu'en WebGL par une bibliothèque tierce, parce que la politique
   de sécurité du contenu de ce moteur interdit tout script d'un autre domaine,
   et que la contrainte fondatrice du projet est « aucune dépendance ». */
/* Le globe est désormais posé sur un PANNEAU SOMBRE arrondi, et non plus
   directement sur le fond de la bannière : la bannière est passée en clair, et
   une sphère encre nuit posée sur du gris très clair flottait comme un trou.
   Le panneau reprend la carte sombre à lueur jaune de la bannière de l'agence,
   et il redonne au globe le fond foncé pour lequel ses couleurs sont faites. */
.globe-cadre {
  position: relative; isolation: isolate; overflow: hidden;
  border-radius: 32px; padding: clamp(1.25rem, 3vw, 2.25rem);
  background: var(--pal-encre);
  border: 1px solid var(--pal-secondaire);
  box-shadow: 0 24px 60px rgba(9,9,11,.28);
}
.globe-cadre::before {
  content: ''; position: absolute; z-index: -1;
  top: -30%; right: -25%; width: 70%; aspect-ratio: 1; border-radius: 50%;
  background: rgba(250,204,21,.22); filter: blur(50px);
}
.globe-cadre__tete {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; margin-bottom: 1rem;
}
.globe-cadre__titre {
  font-size: .7rem; font-weight: 900; letter-spacing: .16em; text-transform: uppercase;
  color: var(--accent-sur-sombre);
}
.globe-cadre__lieu {
  font-size: .78rem; font-weight: 600; color: var(--nuit-encre-douce);
}
.globe-cadre__pied {
  margin-top: 1rem; padding-top: 1rem;
  border-top: 1px solid var(--nuit-trait);
  font-size: .82rem; font-weight: 600; color: var(--nuit-encre-douce);
  text-align: center;
}
.globe-cadre__pied strong { color: #fff; font-weight: 800; }

.globe {
  position: relative; width: 100%; max-width: 520px;
  margin-inline: auto; aspect-ratio: 1;
  touch-action: none;
}
.globe__toile {
  width: 100%; height: 100%;
  cursor: grab;
  opacity: 0; transition: opacity 1.2s ease;
  border-radius: 50%;
}
.globe__toile.est-visible { opacity: 1; }
.globe__toile:active { cursor: grabbing; }
.globe__halo {
  position: absolute; inset: -14%; z-index: -1; border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, rgba(250,204,21,.26), transparent 62%);
  filter: blur(28px);
  pointer-events: none;
}

/* ─── Chiffres ─────────────────────────────────────────────────────────────── */
.chiffres {
  display: grid; gap: 1px;
  grid-template-columns: repeat(2, 1fr);
  background: var(--trait);
  border: 1px solid var(--trait); border-radius: var(--rayon);
  overflow: hidden;
}
@media (min-width: 780px) { .chiffres { grid-template-columns: repeat(4, 1fr); } }
.chiffre { background: var(--surface); padding: 1.75rem 1.25rem; text-align: center; }
/* Le chiffre est en encre, pas en jaune : le jaune sur blanc donne 1,72:1, et
   un nombre de trois centimètres de haut reste un texte. Le jaune est gardé
   pour la ligne du dessous, en aplat, et pour le libellé en capitales. */
.chiffre__valeur {
  font-size: clamp(2rem, 3.6vw, 2.9rem); font-weight: 900;
  color: var(--encre); line-height: 1; letter-spacing: -.04em;
}
.chiffre__libelle {
  margin-top: .6rem; font-size: .74rem; font-weight: 800;
  letter-spacing: .14em; text-transform: uppercase; color: var(--encre-tenue);
}

/* ─── Cartes ───────────────────────────────────────────────────────────────── */
.grille { display: grid; gap: 1.5rem; }
.grille--2 { grid-template-columns: 1fr; }
.grille--3 { grid-template-columns: 1fr; }
@media (min-width: 720px) {
  .grille--2 { grid-template-columns: repeat(2, 1fr); }
  .grille--3 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1000px) {
  .grille--3 { grid-template-columns: repeat(3, 1fr); }
}

.carte {
  background: var(--surface); border: 1px solid var(--trait);
  border-radius: var(--rayon); padding: 1.75rem;
  transition: transform var(--transition), box-shadow var(--transition),
              border-color var(--transition);
}
.carte--survol:hover {
  transform: translateY(-4px);
  box-shadow: var(--ombre-forte);
  border-color: var(--pal-primaire);
}
.carte h3 { margin-bottom: .6rem; }
.carte p { color: var(--encre-douce); font-size: .95rem; }
/* Une carte sur deux porte l'icône en aplat encre à pictogramme jaune, l'autre
   en jaune pâle à pictogramme brun : c'est l'alternance des bénéfices du site
   de l'agence, et elle évite la grille de six pastilles identiques. */
.carte__icone {
  width: 48px; height: 48px; border-radius: 14px;
  display: grid; place-items: center; margin-bottom: 1.15rem;
  background: var(--volt-50); border: 1px solid var(--volt-100);
  color: var(--volt-700);
}
.carte:nth-child(even) .carte__icone {
  background: var(--pal-encre); border-color: var(--pal-encre);
  color: var(--pal-primaire);
  box-shadow: 0 6px 18px rgba(9,9,11,.18);
}
.section--nuit .carte__icone,
.section--nuit .carte:nth-child(even) .carte__icone {
  background: rgba(250,204,21,.14); border-color: rgba(250,204,21,.28);
  color: var(--accent-sur-sombre); box-shadow: none;
}
.carte__etiquette {
  display: inline-block; margin-bottom: .85rem;
  padding: .3rem .7rem; border-radius: var(--rayon-pilule);
  background: var(--pal-primaire); color: var(--pal-encre);
  font-size: .72rem; font-weight: 900; letter-spacing: .1em; text-transform: uppercase;
}
.section--nuit .carte {
  background: var(--nuit-surface); border-color: var(--nuit-trait); color: var(--nuit-encre);
}
.section--nuit .carte p { color: var(--nuit-encre-douce); }

/* ─── L'essentiel en trente secondes ───────────────────────────────────────────
   Quatre réponses courtes, en tête de page. La question est le titre, la
   réponse est dessous : c'est la forme d'un bloc de réponse, pas celle d'un
   argumentaire, et c'est voulu. Le filet jaune à gauche de chaque carte les
   rattache visuellement entre elles sans ajouter quatre cadres complets, qui
   alourdiraient une page qui en compte déjà beaucoup. */
.resume__grille { display: grid; gap: 1.25rem; }
@media (min-width: 720px)  { .resume__grille { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .resume__grille { grid-template-columns: repeat(4, 1fr); } }

.resume__fait {
  position: relative;
  padding: 1.4rem 1.4rem 1.5rem;
  background: var(--surface);
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
}
.resume__fait::before {
  content: ''; position: absolute; left: 0; top: 1.4rem; bottom: 1.5rem;
  width: 4px; border-radius: 0 4px 4px 0;
  background: var(--pal-primaire);
}
.resume__fait h3 {
  font-size: 1rem; font-weight: 900; letter-spacing: -.02em;
  margin-bottom: .55rem; color: var(--encre);
}
/* La réponse est en 500 sur du zinc 600 : elle doit se lire vite et ne pas
   concurrencer la question, qui est le point d'entrée. */
.resume__fait p { font-size: .93rem; font-weight: 500; color: var(--encre-douce); line-height: 1.6; }
.resume__fait strong { color: var(--encre); font-weight: 800; }

/* ─── Où nous intervenons ──────────────────────────────────────────────────────
   Les communes en pastilles, et la fiche d'établissement à côté. Ce n'est pas
   un ornement : c'est la « citation » que cherche le référencement local, le
   nom, l'adresse et le téléphone écrits à l'identique de la fiche Google. */
.zone-bloc { display: grid; gap: 2rem; align-items: start; }
@media (min-width: 940px) { .zone-bloc { grid-template-columns: 1.6fr 1fr; } }

.zone-communes {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-wrap: wrap; gap: .55rem;
}
.zone-communes li {
  padding: .5rem .95rem;
  background: var(--surface); border: 1px solid var(--trait);
  border-radius: var(--rayon-pilule);
  font-size: .88rem; font-weight: 700; color: var(--encre);
  transition: border-color var(--transition), background var(--transition);
}
/* Les quatre premières communes sont celles du bassin immédiat : elles portent
   l'aplat de marque, les autres restent blanches. La hiérarchie dit où l'agence
   est vraiment, sans avoir à l'écrire une deuxième fois. */
.zone-communes li:nth-child(-n+4) {
  background: var(--pal-primaire); border-color: var(--pal-primaire);
  font-weight: 800;
}
.zone-communes li:hover { border-color: var(--pal-encre); }

.zone-fiche {
  padding: 1.6rem;
  background: var(--pal-encre); color: var(--nuit-encre);
  border-radius: var(--rayon);
  box-shadow: 0 18px 44px rgba(9,9,11,.22);
}
.zone-fiche__titre {
  font-size: .72rem; font-weight: 900; letter-spacing: .16em; text-transform: uppercase;
  color: var(--accent-sur-sombre); margin-bottom: .9rem;
}
.zone-fiche__nap {
  display: grid; gap: .3rem; font-style: normal;
  font-size: .95rem; font-weight: 600; color: var(--nuit-encre);
}
.zone-fiche__nap strong { font-weight: 900; font-size: 1.05rem; }
.zone-fiche__nap a { color: var(--accent-sur-sombre); text-decoration: none; font-weight: 800; }
.zone-fiche__nap a:hover { text-decoration: underline; }
.zone-fiche__mention {
  margin-top: 1.1rem; padding-top: 1.1rem;
  border-top: 1px solid var(--nuit-trait);
  font-size: .86rem; font-weight: 500; color: var(--nuit-encre-douce);
}
.zone-fiche__mention strong { color: #fff; font-weight: 800; }

/* ─── Étapes numérotées ────────────────────────────────────────────────────── */
.etapes { display: grid; gap: 2rem; counter-reset: etape; }
@media (min-width: 900px) { .etapes { grid-template-columns: repeat(3, 1fr); gap: 2.5rem; } }
/* Le titre démarre plus bas que le trait bleu, qui est posé en absolu à
   3,55 rem du haut. À 3,5 rem de réserve, le trait touchait presque la hampe
   des majuscules : l'œil lisait un seul bloc au lieu d'un numéro PUIS un
   titre. Un demi-rem de plus suffit à séparer les deux. */
.etape { position: relative; padding-top: 4.1rem; }
.etape::before {
  counter-increment: etape; content: counter(etape, decimal-leading-zero);
  position: absolute; top: 0; left: 0;
  font-size: 2.5rem; font-weight: 900; line-height: 1;
  /* Le numéro était en jaune vif à 28 % d'opacité : sur blanc, cela donne
     1,1:1, c'est-à-dire un chiffre décoratif que personne ne voit. Il porte
     désormais la nuance sombre du jaune à pleine opacité (4,63:1), comme les
     « 01 02 03 » de la section « comment ça marche » du site de l'agence. */
  color: var(--accent-lisible); letter-spacing: -.04em;
}
.etape::after {
  content: ''; position: absolute; top: 1.35rem; left: 0;
  width: 44px; height: 3px; border-radius: 3px; background: var(--pal-primaire);
  transform: translateY(2.2rem);
}
.etape h3 { margin-bottom: .55rem; }
.etape p { color: var(--encre-douce); font-size: .95rem; }

/* ─── Calendrier de passation ──────────────────────────────────────────────── */
.frise { position: relative; display: grid; gap: 0; }
.frise__jalon {
  position: relative; padding: 0 0 2.25rem 2.25rem;
  border-left: 2px solid var(--trait);
}
.frise__jalon:last-child { border-left-color: transparent; padding-bottom: 0; }
.frise__jalon::before {
  content: ''; position: absolute; left: -9px; top: .35rem;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--surface); border: 3px solid var(--pal-primaire);
}
.frise__jalon--fort::before { background: var(--pal-primaire); }
.frise__mois {
  font-size: .78rem; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--pal-secondaire); margin-bottom: .3rem;
}
/* La frise vit sur le fond nuit de la section passation. Le marine y donne
   2,34:1 et l'encre douce 2,34 également : les deux sont prévus pour un fond
   clair. Mesuré à l'écran, pas déduit. */
.section--nuit .frise__mois { color: var(--accent-sur-sombre); }
.section--nuit .frise__jalon { border-left-color: var(--nuit-trait); }
.section--nuit .frise__jalon::before { background: var(--pal-encre); border-color: var(--accent-sur-sombre); }
.section--nuit .frise__jalon--fort::before { background: var(--accent-sur-sombre); }
.section--nuit .frise__titre { color: #fff; }
.section--nuit .frise__jalon p { color: var(--nuit-encre-douce); }
.frise__titre { font-size: 1.05rem; font-weight: 600; line-height: 1.4; margin-bottom: .3rem; }
.frise__jalon p { color: var(--encre-douce); font-size: .93rem; }

/* ─── Tarifs ───────────────────────────────────────────────────────────────── */
.offres {
  display: grid; gap: 1.5rem; align-items: start;
  grid-template-columns: 1fr;
}
.offre {
  position: relative; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--trait);
  border-radius: var(--rayon); padding: 2rem 1.75rem;
  height: 100%;
}
.offre--vedette {
  border-color: var(--pal-primaire); border-width: 2px;
  box-shadow: var(--ombre-forte);
}
@media (min-width: 860px) { .offre--vedette { transform: scale(1.035); z-index: 1; } }
.offre__fanion {
  position: absolute; top: -13px; left: 50%; transform: translateX(-50%);
  background: var(--accent-lisible); color: #fff;
  padding: .3rem 1rem; border-radius: var(--rayon-pilule);
  font-size: .74rem; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; white-space: nowrap;
}
.offre__nom { font-size: 1.3rem; font-weight: 700; }
.offre__pour {
  margin-top: .5rem; font-size: .9rem; color: var(--encre-douce);
  min-height: 3.6rem;
}
.offre__prix {
  margin-top: 1.5rem; padding-top: 1.5rem; border-top: 1px solid var(--trait);
}
.offre__montant {
  font-size: 2.4rem; font-weight: 700; line-height: 1;
  letter-spacing: -.03em; color: var(--encre);
}
.offre__unite { font-size: .875rem; color: var(--encre-tenue); margin-top: .4rem; }
.offre__mensuel { margin-top: 1rem; font-size: 1.05rem; font-weight: 600; }
.offre__mensuel span { font-size: .875rem; font-weight: 400; color: var(--encre-tenue); }
.offre__total {
  margin-top: .85rem; padding: .6rem .8rem; border-radius: var(--rayon-petit);
  background: var(--surface-doux); font-size: .84rem; color: var(--encre-douce);
}
.offre__liste { list-style: none; padding: 0; margin: 1.5rem 0 2rem; display: grid; gap: .7rem; }
.offre__liste li {
  display: flex; gap: .65rem; align-items: flex-start;
  font-size: .92rem; color: var(--encre-douce);
}
.offre__liste svg { flex: 0 0 auto; margin-top: .18rem; color: var(--pal-accent); }
.offre__liste li.est-absent { color: var(--encre-tenue); }
.offre__liste li.est-absent svg { color: var(--encre-tenue); opacity: .55; }
.offre__titre-groupe {
  font-size: .78rem; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--pal-secondaire);
  margin-top: .35rem;
}
.offre .bouton { margin-top: auto; }

/* ─── L'alignement des trois colonnes, et le calage qui ne tenait pas ─────
   Chaque carte était une pile indépendante. Conséquence mesurée à 1 440 px :
   la phrase « pour qui » de la formule du milieu tient sur une ligne de plus
   que les deux autres, donc son prix démarrait 14 px plus bas, et sa liste de
   prestations 15 px plus bas. Trois prix qui ne sont pas sur la même ligne
   dans un tableau de prix, c'est la première chose que l'œil voit, et il la
   lit comme un défaut d'assemblage.

   `min-height: 3.6rem` sur la phrase tentait de le rattraper par un nombre
   choisi à la main. Un nombre choisi à la main est juste pour le texte du
   jour, pour cette largeur, et dans cette police : il redevient faux au
   premier mot ajouté depuis la console, et personne ne le relit.

   La subgrille règle le problème à la source : les cinq rangées (nom, pour
   qui, prix, prestations, bouton) sont déclarées sur la GRILLE, et chaque
   carte s'y accroche. La rangée fait la hauteur de la carte la plus haute,
   pour les trois à la fois, quel que soit le texte. */
@media (min-width: 860px) {
  .offres {
    grid-template-columns: repeat(3, 1fr);
    gap: 1.25rem;
    /* nom · pour qui · prix · prestations · bouton.
       La quatrième prend le reste, pour que les boutons se posent en bas. */
    grid-template-rows: auto auto auto 1fr auto;
  }
  .offre {
    display: grid;
    grid-row: span 5;
    grid-template-rows: subgrid;
    gap: 0;
  }
  /* Le calage à la main n'a plus lieu d'être : la rangée le fait, et mieux. */
  .offre__pour { min-height: 0; }
}

/* ═══ Le sélecteur de rythme de règlement ═════════════════════════════════
   Deux boutons radio, une bascule, zéro JavaScript.

   ─── Pourquoi `:has()` et pas un script ──────────────────────────────────
   Un script aurait demandé un fichier de plus, un écouteur, et un premier
   rendu où le prix affiché est celui du HTML avant que le script ne passe.
   La feuille lit l'état des radios et montre l'un des deux prix : le bon prix
   est peint dès la première image, et il ne dépend de rien qui puisse échouer.

   ─── Le repli, qui n'est pas une option ──────────────────────────────────
   Tout ce bloc vit dans `@supports selector(:has(*))`. Chez un navigateur qui
   ne le comprend pas, `.prix--mensuel` reste caché, `.prix--annuel` reste
   visible, et le sélecteur lui-même n'apparaît pas. Ce visiteur voit donc le
   prix annuel, qui est celui annoncé partout ailleurs sur le site, et aucun
   bouton qui ne ferait rien. C'est la règle du dépôt, la même qui gouverne le
   repli du tableau comparatif : rien n'est masqué si rien ne peut le révéler. */
.rythme { display: none; }
.prix--mensuel { display: none; }

@supports selector(:has(*)) {
  .rythme {
    display: inline-flex;
    gap: .25rem;
    margin: 0 auto clamp(2rem, 4vw, 2.75rem);
    padding: .3rem;
    background: var(--surface);
    border: 1px solid var(--trait);
    border-radius: var(--rayon-pilule);
  }
  /* Le conteneur est en ligne : il faut un bloc autour pour le centrer, et
     `text-align` suffit, sans ajouter un flex de plus. */
  .grille-prix { text-align: center; }
  .offres { text-align: left; }

  .rythme input {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    overflow: hidden; clip-path: inset(50%);
    white-space: nowrap;
  }
  .rythme label {
    display: flex; flex-direction: column; gap: .1rem;
    padding: .6rem 1.15rem;
    border-radius: var(--rayon-pilule);
    font-size: .93rem; font-weight: 700; line-height: 1.2;
    color: var(--encre-douce);
    cursor: pointer;
    transition: background var(--transition), color var(--transition);
  }
  .rythme label small {
    font-size: .72rem; font-weight: 500;
    color: var(--encre-tenue);
  }
  .rythme label:hover { color: var(--encre); }
  .rythme input:checked + label {
    background: var(--pal-encre);
    color: #fff;
  }
  .rythme input:checked + label small { color: var(--nuit-encre-douce); }
  /* L'anneau de focus est sur le label, puisque le bouton lui-même est
     visuellement retiré : sans cette règle, une personne au clavier déplace
     une sélection qu'elle ne voit pas. */
  .rythme input:focus-visible + label {
    outline: 2px solid var(--accent-lisible);
    outline-offset: 2px;
  }

  .grille-prix:has(#rythme-mensuel:checked) .prix--annuel  { display: none; }
  .grille-prix:has(#rythme-mensuel:checked) .prix--mensuel { display: block; }
}

/* Le montant porte maintenant son unité sur la même ligne, en plus petit :
   « de mise en service » n'existe plus, et un nombre seul ne dit pas s'il
   s'agit d'un mois, d'une année ou d'un forfait. */
.offre__montant span {
  font-size: .95rem; font-weight: 600;
  letter-spacing: 0; color: var(--encre-tenue);
}

.mention-tva {
  margin-top: 2rem; font-size: .85rem; color: var(--encre-tenue); text-align: center;
}

/* ─── Le récapitulatif ligne par ligne ─────────────────────────────────────── */
/* Un vrai <table>, pas une grille de <div> : c'est un tableau de comparaison,
   et l'en-tête de colonne comme l'en-tête de ligne doivent être annoncés à
   chaque case par le lecteur d'écran. Une grille CSS lit trente valeurs sans
   jamais dire de quelle formule elles parlent.

   Pas d'`overflow: hidden` sur le bloc, contrairement aux autres cartes de la
   page : il rognerait les coins, ce dont ce bloc n'a pas besoin (son en-tête et
   son pied n'ont pas de fond à eux), et surtout il ferait de ce bloc le repère
   de `position: sticky` pour l'en-tête du tableau, qui se retrouverait décalé
   de 73 px vers le bas au lieu de suivre la fenêtre. */
.comparatif {
  border: 1px solid var(--trait); border-radius: var(--rayon);
  background: var(--surface);
  /* Replier depuis le bouton du bas ramène ce bloc en vue. Sans cette marge de
     défilement, il se calerait à zéro, c'est-à-dire SOUS la barre de navigation
     collée en haut : le visiteur retomberait sur un bloc dont le bouton
     « Voir toutes les fonctionnalités » est caché par la barre. */
  scroll-margin-top: calc(var(--hauteur-entete) + 1rem);
}

/* ── Le repli ──────────────────────────────────────────────────────────────
   Les deux boutons n'existent que si le SCRIPT a pris la main : c'est lui qui
   pose `est-repliable`. Sans lui, le tableau est déplié et les boutons restent
   cachés, plutôt qu'un bouton mort devant un tableau qui ne s'ouvrira pas.
   Même raisonnement que `@media (scripting: enabled)` plus bas, en plus sûr :
   la requête média dit que JavaScript est autorisé, pas que NOTRE fichier est
   bien arrivé. */
.comparatif__deplier, .comparatif__replier { display: none; }
.comparatif.est-repliable .comparatif__deplier { display: block; padding: 1.25rem; margin: 0; }
.comparatif.est-repliable .comparatif__replier { display: inline-flex; }
.comparatif.est-repliable .comparatif__detail { display: none; }
.comparatif.est-repliable.est-ouvert .comparatif__deplier { display: none; }
.comparatif.est-repliable.est-ouvert .comparatif__detail { display: block; }

/* La flèche du bouton pointe vers le bas quand il ouvre, vers le haut quand le
   tableau est déjà là : c'est le seul indice qui distingue « déplier » de
   « aller au tableau » avant d'avoir lu l'étiquette. */
.comparatif__deplier .bouton { gap: .6rem; }
.comparatif__replier { flex: 0 0 auto; align-self: flex-start; white-space: nowrap; }

.comparatif__tete {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1.5rem; padding: 2rem 1.75rem 1.5rem;
}
.comparatif__tete p {
  margin-top: .5rem; font-size: .93rem; color: var(--encre-douce); max-width: 54ch;
}

.comparatif__cadre { min-width: 0; }

.comparatif__table {
  width: 100%;
  border-collapse: collapse;
  font-size: .9rem; text-align: left;
}
.comparatif__table th,
.comparatif__table td {
  padding: .8rem 1rem;
  border-top: 1px solid var(--trait);
  vertical-align: middle;
}

.comparatif__table thead th {
  background: var(--surface-doux);
  border-top: 0; border-bottom: 1px solid var(--trait);
  padding-block: 1rem;
}
.comparatif__coin {
  font-size: .74rem; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--encre-tenue);
}
.comparatif__colonne { text-align: center; }
.comparatif__colonne.est-vedette { background: var(--surface-accent); }
.comparatif__nom {
  display: block; font-size: 1.02rem; font-weight: 700; color: var(--encre);
}
.comparatif__colonne.est-vedette .comparatif__nom { color: var(--accent-lisible); }
.comparatif__prix {
  display: block; margin-top: .2rem;
  font-size: .78rem; font-weight: 400; color: var(--encre-tenue);
}

/* Le titre de groupe : une ligne pleine largeur, qui découpe les trente et une
   lignes en cinq lectures possibles. */
.comparatif__groupe th {
  background: var(--surface-doux);
  font-size: .74rem; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--pal-secondaire);
}

/* Pas de `display: flex` ici, si tentant soit-il pour aligner le « i » : il
   sortirait la cellule de la mise en page du tableau et ferait glisser toute la
   ligne d'une colonne. Le libellé et l'infobulle sont en ligne, comme du texte,
   et c'est `vertical-align` qui les aligne. */
.comparatif__table tbody th[scope="row"] {
  font-weight: 500; color: var(--encre-douce);
}
.comparatif__table tbody th[scope="row"] .infobulle {
  vertical-align: middle; margin-left: .25rem;
}
.comparatif__oui, .comparatif__non, .comparatif__valeur { text-align: center; }
.comparatif__oui svg, .comparatif__non svg { margin-inline: auto; }
.comparatif__oui svg { color: var(--pal-accent); }
/* La croix est volontairement PÂLE. Un « non » en rouge sur une grille de prix
   se lit comme un reproche fait à la formule la moins chère, alors qu'Essentiel
   est une offre qu'on assume et qu'on vend. */
.comparatif__non svg { color: var(--trait); }
.comparatif__valeur { font-size: .84rem; font-weight: 600; color: var(--encre); }
.comparatif__table tbody td.est-vedette { background: var(--surface-accent); }

/* L'étiquette de formule dans la case ne sert que sur téléphone, où l'en-tête
   de colonne n'existe plus. */
.comparatif__etiquette { display: none; }

/* ── Grand écran : l'en-tête suit la lecture ──────────────────────────────── */
/* Trente et une lignes, c'est deux écrans. Sans en-tête collant, une case
   cochée au milieu du tableau n'appartient plus visiblement à aucune formule.
   Il se cale sous la barre de navigation, elle-même collée en haut. */
@media (min-width: 761px) {
  .comparatif__table thead th {
    position: sticky; top: var(--hauteur-entete); z-index: 2;
  }
}

.comparatif__table tbody tr:hover td,
.comparatif__table tbody tr:hover th[scope="row"] { background: var(--surface-doux); }
.comparatif__table tbody tr:hover td.est-vedette { background: #E4F1F9; }
.comparatif__groupe:hover th { background: var(--surface-doux); }

.comparatif__pied {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.25rem;
  padding: 1.25rem 1.75rem 1.5rem;
  border-top: 1px solid var(--trait);
  font-size: .88rem; color: var(--encre-tenue);
}
.comparatif__pied p { margin: 0; }

/* ── Téléphone : le tableau se déplie en blocs ────────────────────────────── */
/* Quatre colonnes ne rentrent pas dans 375 px. La version précédente les
   faisait défiler de côté dans un cadre : la moitié du tableau était hors
   champ en permanence, et il fallait deviner qu'on pouvait pousser. Ici chaque
   ligne devient un bloc qui tient dans la largeur, avec les trois formules
   côte à côte sous son libellé. Rien n'est coupé, rien ne défile de côté, et
   les trois formules restent comparables d'un coup d'œil, ce qui est le seul
   intérêt du tableau.

   `display: block` sur un <table> lui retire sa nature de tableau dans l'arbre
   d'accessibilité. Les rôles ARIA écrits dans le balisage la lui rendent : les
   retirer casserait la lecture ici, et nulle part ailleurs, donc sans que rien
   ne le montre sur grand écran. */
@media (max-width: 760px) {
  .comparatif__table,
  .comparatif__table thead,
  .comparatif__table tbody,
  .comparatif__table tr,
  .comparatif__table th,
  .comparatif__table td { display: block; width: auto; }

  /* L'en-tête de colonne disparaît : chaque case porte désormais son étiquette. */
  .comparatif__table thead { display: none; }

  .comparatif__table tbody tr {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: .45rem;
    padding: .95rem 1rem;
    border-top: 1px solid var(--trait);
  }
  .comparatif__table tbody th[scope="row"] {
    grid-column: 1 / -1;
    padding: 0 0 .2rem; border: 0;
    font-size: .95rem; font-weight: 600; color: var(--encre);
  }

  .comparatif__table tbody td {
    padding: .55rem .35rem; border: 0;
    border-radius: var(--rayon-petit);
    background: var(--surface-doux);
    text-align: center;
    display: flex; flex-direction: column; align-items: center; gap: .3rem;
    justify-content: flex-start;
  }
  .comparatif__table tbody td.est-vedette { background: var(--surface-accent); }

  /* Les trois noms tiennent chacun sur UNE ligne, et c'est ce qui décide de
     leur corps : « Rayonnement » fait onze caractères pour une case de
     soixante-seize pixels. Coupé en « Rayonneme / nt », il donne trois
     étiquettes de hauteurs différentes, donc trois cases de hauteurs
     différentes, ce qui se lit comme une hiérarchie entre les formules alors
     qu'il n'y en a pas ici. */
  .comparatif__etiquette {
    display: block;
    font-size: .64rem; font-weight: 700; letter-spacing: 0;
    line-height: 1.25; white-space: nowrap;
    color: var(--encre-tenue);
  }
  .comparatif__valeur { font-size: .78rem; line-height: 1.3; }

  /* Le survol n'existe pas au doigt, et sa trame grise écraserait le fond des
     cases, qui est ici le seul repère de colonne. */
  .comparatif__table tbody tr:hover td,
  .comparatif__table tbody tr:hover th[scope="row"] { background: var(--surface-doux); }
  .comparatif__table tbody tr:hover td.est-vedette { background: var(--surface-accent); }

  /* Le titre de groupe est une LIGNE de tableau comme les autres : sans ce
     sélecteur aussi précis que celui des lignes de données, il hérite de leur
     grille à trois colonnes et se recroqueville dans la première, en petite
     boîte alignée à gauche au lieu d'un bandeau pleine largeur. */
  .comparatif__table tbody tr.comparatif__groupe { display: block; padding: 0; }
  .comparatif__groupe th {
    padding: .7rem 1rem;
    border-top: 1px solid var(--trait);
  }

  .comparatif__tete, .comparatif__pied {
    display: block;
    padding-inline: 1.25rem;
  }
  .comparatif__replier { margin-top: 1rem; width: 100%; justify-content: center; }
  .comparatif.est-repliable .comparatif__replier { display: flex; }

  /* « Voir toutes les fonctionnalités » plus le chevron font trente et un
     caractères : au corps et aux marges de la page, ils passent à la ligne dans
     une pilule, ce qui fait un bouton haut de deux étages. On resserre. */
  .comparatif.est-repliable .comparatif__deplier { padding: 1rem; }
  .comparatif__deplier .bouton { padding-inline: 1rem; font-size: .9rem; }

  /* L'infobulle se cale sur la LIGNE, pas sur son petit « i ».
     Ailleurs sur la page elle est centrée sur son déclencheur et large de
     268 px : dans une colonne de 375 px, cette bulle centrée sur un rond de
     18 px déborde de quarante pixels à droite, et sa moitié droite est rognée
     par `overflow-x: hidden` du corps de page. Autrement dit, la précision
     qu'on est allé chercher est illisible exactement là où on en a le plus
     besoin. Le repère devient donc la cellule du libellé, et la bulle prend sa
     largeur : elle ne peut plus sortir de l'écran. */
  .comparatif__table tbody th[scope="row"] { position: relative; }
  .comparatif .infobulle { position: static; }
  .comparatif .infobulle__texte {
    left: 0; right: 0;
    width: auto; max-width: none;
    transform: translateY(4px);
  }
  .comparatif .infobulle__declencheur:hover + .infobulle__texte,
  .comparatif .infobulle__declencheur:focus-visible + .infobulle__texte {
    transform: translateY(0);
  }
  /* Sans repère centré, la pointe n'a plus rien à désigner. */
  .comparatif .infobulle__texte::after { display: none; }
}

/* Le « i » qui dit ce que couvre une ligne. Pas un titre natif : il doit être
   atteignable au clavier et lisible au toucher. */
.infobulle { position: relative; display: inline-flex; }
.infobulle__declencheur {
  width: 18px; height: 18px; border-radius: 50%; padding: 0;
  border: 1px solid var(--trait); background: var(--surface-doux);
  color: var(--encre-douce); font-size: .7rem; font-weight: 700;
  line-height: 1; cursor: help; display: grid; place-items: center;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.infobulle__declencheur:hover,
.infobulle__declencheur:focus-visible { background: var(--accent-lisible); color: #fff; border-color: var(--accent-lisible); }

/* La zone que le doigt atteint est plus grande que le rond qu'on voit.
   Le rond fait 18 px, ce qui est juste à l'œil dans une ligne de liste et bien
   trop petit pour un pouce : le seuil est 44. Agrandir le rond déséquilibrerait
   la ligne, donc c'est la zone sensible qui s'étend, pas le dessin. */
.infobulle__declencheur::after {
  content: ''; position: absolute; top: 50%; left: 50%;
  width: 44px; height: 44px; transform: translate(-50%, -50%);
}
.infobulle__texte {
  position: absolute; bottom: calc(100% + 10px); left: 50%;
  transform: translateX(-50%) translateY(4px);
  width: max-content; max-width: 268px;
  background: var(--pal-encre); color: #fff;
  padding: .7rem .85rem; border-radius: var(--rayon-petit);
  font-size: .82rem; line-height: 1.45; font-weight: 400;
  text-align: left; text-transform: none; letter-spacing: 0;
  box-shadow: var(--ombre-forte);
  opacity: 0; visibility: hidden; pointer-events: none; z-index: 20;
  transition: opacity var(--transition), transform var(--transition), visibility var(--transition);
}
.infobulle__texte::after {
  content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  border: 6px solid transparent; border-top-color: var(--pal-encre);
}
.infobulle__declencheur:hover + .infobulle__texte,
.infobulle__declencheur:focus-visible + .infobulle__texte {
  opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0);
}

/* ─── Simulateur ──────────────────────────────────────────────────────────── */
.simulateur {
  display: grid; gap: 0;
  border: 1px solid var(--trait); border-radius: var(--rayon);
  overflow: hidden; background: var(--surface);
  box-shadow: var(--ombre);
}
@media (min-width: 940px) { .simulateur { grid-template-columns: .95fr 1.05fr; } }

.simulateur__saisie { padding: clamp(1.75rem, 3vw, 2.5rem); }
.simulateur__sortie {
  padding: clamp(1.75rem, 3vw, 2.5rem);
  background: var(--pal-encre); color: var(--nuit-encre);
  display: flex; flex-direction: column;
}

.champ { margin-bottom: 1.5rem; }
.champ:last-child { margin-bottom: 0; }
.champ > label, .champ__legende {
  display: block; font-size: .9rem; font-weight: 600; margin-bottom: .5rem;
}
.champ__aide { font-size: .82rem; color: var(--encre-tenue); margin-top: .4rem; }
.champ input[type="number"] {
  width: 100%; padding: .8rem 1rem;
  border: 1px solid var(--trait); border-radius: var(--rayon-petit);
  background: var(--surface); font-size: 1rem;
  transition: border-color var(--transition), box-shadow var(--transition);
  -moz-appearance: textfield;
}
.champ input[type="number"]:focus {
  border-color: var(--pal-primaire);
  box-shadow: 0 0 0 3px rgba(250,204,21,.35);
  outline: none;
}
.champ__unite { position: relative; }
.champ__unite input { padding-right: 2.5rem; }
.champ__unite::after {
  content: '€'; position: absolute; right: 1rem; top: 50%; transform: translateY(-50%);
  color: var(--encre-tenue); font-weight: 600; pointer-events: none;
}

/* Groupe de choix : des étiquettes qui se comportent comme des onglets, sans un
   octet de JavaScript pour l'apparence. L'entrée radio reste la source de
   vérité, donc le clavier et le lecteur d'écran fonctionnent tels quels. */
.choix { display: grid; gap: .5rem; }
.choix--ligne { grid-template-columns: repeat(3, 1fr); }
.choix--paire { grid-template-columns: repeat(2, 1fr); }
.choix input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.choix label {
  display: block; text-align: center; cursor: pointer;
  padding: .7rem .5rem; border: 1px solid var(--trait);
  border-radius: var(--rayon-petit); font-size: .9rem; font-weight: 600;
  transition: border-color var(--transition), background var(--transition), color var(--transition);
}
.choix label small { display: block; font-weight: 400; font-size: .76rem; color: var(--encre-tenue); margin-top: .15rem; }
.choix label:hover { border-color: var(--pal-primaire); }
.choix input:checked + label {
  border-color: var(--pal-primaire); background: var(--surface-accent); color: var(--pal-secondaire);
}
.choix input:checked + label small { color: var(--pal-secondaire); }
.choix input:focus-visible + label { outline: 3px solid var(--pal-primaire); outline-offset: 2px; }

.resultat { margin-bottom: 1.5rem; }
.resultat__etiquette {
  font-size: .78rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent-sur-sombre); margin-bottom: .5rem;
}
.resultat__valeur {
  font-size: clamp(2rem, 4vw, 2.9rem); font-weight: 700;
  line-height: 1; letter-spacing: -.03em; color: #fff;
}
.resultat__detail { margin-top: .5rem; font-size: .9rem; color: var(--nuit-encre-douce); }

.bascule {
  display: grid; gap: 1rem; margin-top: auto;
  padding-top: 1.5rem; border-top: 1px solid var(--nuit-trait);
}
@media (min-width: 520px) { .bascule { grid-template-columns: repeat(2, 1fr); } }
.bascule__bloc {
  background: rgba(255,255,255,.06); border: 1px solid var(--nuit-trait);
  border-radius: var(--rayon-petit); padding: 1.1rem;
}
.bascule__nombre {
  font-size: 2rem; font-weight: 700; line-height: 1; color: var(--pal-accent);
  letter-spacing: -.02em;
}
.bascule__texte { margin-top: .45rem; font-size: .86rem; color: var(--nuit-encre-douce); }

.reperes { margin-top: 1.25rem; font-size: .84rem; color: var(--nuit-encre-douce); }
.reperes strong { color: #fff; font-weight: 600; }

/* ─── Défi régional ────────────────────────────────────────────────────────── */
.paliers { display: grid; gap: 1.25rem; }
@media (min-width: 860px) { .paliers { grid-template-columns: repeat(3, 1fr); } }
.palier {
  position: relative; padding: 1.75rem;
  border: 1px solid var(--nuit-trait); border-radius: var(--rayon);
  background: var(--nuit-surface);
}
.palier--atteint { border-color: rgba(250,204,21,.60); }
.palier__rang {
  font-size: .76rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent-sur-sombre); margin-bottom: .75rem;
}
.palier h3 { color: #fff; margin-bottom: .5rem; }
.palier p { font-size: .92rem; color: var(--nuit-encre-douce); }
.palier__onde {
  position: absolute; top: 1.5rem; right: 1.5rem;
  width: 34px; height: 34px; border-radius: 50%;
  border: 2px solid var(--pal-accent); opacity: .3;
}

/* ─── Questions ────────────────────────────────────────────────────────────── */
.questions { display: grid; gap: .75rem; }
.question {
  border: 1px solid var(--trait); border-radius: var(--rayon);
  background: var(--surface); overflow: hidden;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.question[open] { border-color: rgba(250,204,21,.65); box-shadow: var(--ombre); }
.question summary {
  display: flex; align-items: center; justify-content: space-between; gap: 1.25rem;
  padding: 1.25rem 1.5rem; cursor: pointer;
  font-weight: 600; font-size: 1.02rem; list-style: none;
}
.question summary::-webkit-details-marker { display: none; }
.question summary::after {
  content: ''; flex: 0 0 auto; width: 11px; height: 11px;
  border-right: 2px solid var(--pal-primaire); border-bottom: 2px solid var(--pal-primaire);
  transform: rotate(45deg) translateY(-3px);
  transition: transform var(--transition);
}
.question[open] summary::after { transform: rotate(-135deg) translateY(-3px); }
.question summary:hover { color: var(--accent-lisible); }
.question__corps { padding: 0 1.5rem 1.5rem; color: var(--encre-douce); font-size: .95rem; }
.question__corps p + p { margin-top: .75rem; }

/* ─── Ce qui n'est pas compris ─────────────────────────────────────────────── */
.hors-perimetre {
  display: grid; gap: .65rem; list-style: none; padding: 0;
  grid-template-columns: 1fr;
}
@media (min-width: 720px) { .hors-perimetre { grid-template-columns: repeat(2, 1fr); } }
.hors-perimetre li {
  display: flex; gap: .6rem; align-items: flex-start;
  font-size: .92rem; color: var(--encre-douce);
}
.hors-perimetre svg { flex: 0 0 auto; margin-top: .2rem; color: var(--encre-tenue); }

/* ─── Formulaire de contact ────────────────────────────────────────────────── */
.contact {
  display: grid; gap: 0;
  border-radius: var(--rayon); overflow: hidden;
  border: 1px solid var(--nuit-trait);
}
@media (min-width: 940px) { .contact { grid-template-columns: 1fr 1fr; } }
.contact__discours { padding: clamp(1.75rem, 3.5vw, 3rem); }
.contact__discours h2 { color: #fff; }
.contact__formulaire {
  padding: clamp(1.75rem, 3.5vw, 3rem);
  background: var(--surface); color: var(--encre);
}
.contact__formulaire .champ > label { color: var(--encre); }
.contact input[type="text"],
.contact input[type="email"],
.contact textarea {
  width: 100%; padding: .8rem 1rem;
  border: 1px solid var(--trait); border-radius: var(--rayon-petit);
  background: var(--surface); font-size: 1rem;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.contact textarea { min-height: 110px; resize: vertical; }
.contact input:focus, .contact textarea:focus {
  border-color: var(--pal-primaire); box-shadow: 0 0 0 3px rgba(250,204,21,.35); outline: none;
}
.contact__rendez-vous {
  margin-top: 2rem; padding-top: 2rem; border-top: 1px solid var(--nuit-trait);
}
.contact__liste { list-style: none; padding: 0; margin-top: 1.5rem; display: grid; gap: .8rem; }
.contact__liste li { display: flex; gap: .65rem; align-items: flex-start; font-size: .93rem; color: var(--nuit-encre-douce); }
.contact__liste svg { flex: 0 0 auto; margin-top: .15rem; color: var(--pal-accent); }

/* Le piège à robots : jamais affiché, jamais atteignable au clavier, jamais lu à
   voix haute. `display:none` suffirait pour l'œil, pas pour un lecteur d'écran. */
.piege {
  position: absolute !important; left: -9999px !important;
  width: 1px; height: 1px; overflow: hidden;
}

.encart {
  padding: 1rem 1.15rem; border-radius: var(--rayon-petit);
  font-size: .93rem; margin-bottom: 1.25rem;
  border: 1px solid transparent;
}
.encart--ok      { background: #E8F7EF; border-color: #A9E0C4; color: #16603A; }
.encart--erreur  { background: #FDECEC; border-color: #F3B9B9; color: #8A1F1F; }

/* ─── Vidéo ────────────────────────────────────────────────────────────────── */
.video {
  position: relative; aspect-ratio: 16 / 9;
  border-radius: var(--rayon); overflow: hidden;
  background: linear-gradient(135deg, #1B2140, var(--pal-encre));
  border: 1px solid var(--nuit-trait);
  display: grid; place-items: center; text-align: center;
  padding: 2rem;
}
.video__marque {
  width: 72px; height: 72px; border-radius: 50%;
  background: rgba(255,255,255,.1); border: 1px solid var(--nuit-trait);
  display: grid; place-items: center; margin: 0 auto 1.25rem;
  color: var(--accent-sur-sombre);
}
.video p { color: var(--nuit-encre-douce); font-size: .95rem; max-width: 42ch; margin-inline: auto; }

/* ─── Bandeau d'appel ──────────────────────────────────────────────────────── */
.bandeau {
  position: relative; overflow: hidden; isolation: isolate;
  background: var(--pal-secondaire); color: #fff;
  border-radius: var(--rayon);
  padding: clamp(2.5rem, 5vw, 4rem);
  text-align: center;
}
.bandeau::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(70% 90% at 12% 10%, rgba(250,204,21,.28), transparent 60%),
    radial-gradient(60% 80% at 88% 90%, rgba(228,228,231,.16), transparent 62%);
}
.bandeau h2 { color: #fff; }
.bandeau .accroche { color: rgba(255,255,255,.82); margin: 1rem auto 0; }
.bandeau .actions { justify-content: center; margin-top: 2rem; }

/* ─── Pied de page ─────────────────────────────────────────────────────────── */
/* Le pied de page est BLANC, comme celui du site de l'agence : titres de
   colonne en 900 encre, liens gris qui passent au brun doré au survol. Il était
   en encre nuit, ce qui refermait la page sur un grand bloc noir juste après
   une section de contact déjà sombre : deux aplats sombres collés, dont le
   second n'apportait rien. */
.pied {
  background: var(--surface); color: var(--encre-douce);
  border-top: 1px solid var(--trait);
  padding-block: 4rem 2.5rem; font-size: .92rem;
}
.pied__haut {
  display: grid; gap: 2.5rem;
  padding-bottom: 2.5rem; border-bottom: 1px solid var(--trait);
}
@media (min-width: 820px) { .pied__haut { grid-template-columns: 1.5fr 1fr 1fr 1fr; } }
.pied h3 { color: var(--encre); margin-bottom: 1rem; font-size: .95rem; font-weight: 900;
           letter-spacing: -.02em; }
.pied ul { list-style: none; padding: 0; display: grid; gap: .6rem; }
.pied a { color: var(--encre-douce); text-decoration: none; font-weight: 600;
          transition: color var(--transition); }
.pied a:hover { color: var(--accent-lisible); text-decoration: none; }
/* La marque du pied de page reprend le sceau de la barre du haut. */
.pied__marque {
  display: inline-flex; align-items: center; gap: .55rem;
  color: var(--encre); font-weight: 900; font-size: 1.15rem; letter-spacing: -.04em;
  margin-bottom: .9rem; text-decoration: none;
}
.pied__marque em { font-style: normal; color: var(--volt-500); }
/* `font-style: normal` : un `<address>` est rendu en italique par défaut, et
   des coordonnées en italique dans un pied de page se lisent comme une note de
   bas de page. Ce sont pourtant la seule adresse et le seul numéro de la page :
   ils doivent se lire comme tels. */
.pied__nap {
  margin-top: 1.1rem; display: grid; gap: .45rem; font-style: normal;
  font-size: .88rem; font-weight: 600; color: var(--encre-douce);
}
.pied__nap a { text-decoration: none; }
.pied__bas {
  display: flex; flex-wrap: wrap; gap: .75rem 1.5rem;
  justify-content: space-between; align-items: center;
  padding-top: 1.75rem; font-size: .85rem; color: var(--encre-tenue);
}
/* Le lien de l'espace membres est celui par lequel un bureau élu en 2031 doit
   retrouver l'outil. Il ne baisse donc pas d'opacité : c'est le défaut D9b
   relevé sur le thème des sites, et il ne se répète pas ici. */
.pied__membres { color: var(--encre); font-weight: 800; text-decoration: underline;
                 text-decoration-color: var(--pal-primaire); text-decoration-thickness: 2px;
                 text-underline-offset: 3px; }

/* La signature de l'agence, dans la ligne de copyright. Elle est discrète par
   construction : c'est une signature, pas un appel à l'action, et elle ne doit
   pas concurrencer « Espace client » juste au-dessus, qui est le seul lien de
   ce pied de page dont un bureau ait vraiment besoin. */
.pied__agence {
  color: var(--encre-douce); font-weight: 700;
  text-decoration: underline; text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color var(--transition);
}
.pied__agence:hover, .pied__agence:focus-visible { color: var(--accent-lisible); }

/* ─── Le surligneur des titres ─────────────────────────────────────────────── */
/* Le mot important est posé sur un rectangle sarcelle légèrement penché, comme
   un coup de surligneur donné à la main. C'est le seul ornement de la page qui
   n'est pas fonctionnel, et il gagne sa place en faisant lire le titre en deux
   temps : la phrase, puis le mot qui compte.

   ─── Trois précautions, chacune payée d'un défaut réel ──────────────────
   1. Le rectangle est un `::before` DERRIÈRE le texte (`z-index: -1`), pas un
      fond sur l'élément : un fond suivrait les retours à la ligne et donnerait
      deux rectangles décalés sur mobile, l'un sous l'autre.
   2. L'élément est `inline-block` et le rectangle déborde de part et d'autre,
      donc le titre a besoin d'`isolation: isolate` sur son conteneur, sinon le
      `z-index: -1` fait passer le rectangle SOUS le fond de la section et il
      disparaît purement et simplement.
   3. La rotation est minuscule (1,2 degré). Au-delà, la ligne de base du titre
      paraît fautive plutôt que délibérée, et le rectangle mord sur la ligne du
      dessus dans un titre à trois lignes. */
/* ─── Pourquoi ce n'est plus un `inline-block` ────────────────────────────
   L'aplat était un `::before` calé sur les bords de la BOÎTE du span. Tant
   que le span tient sur une ligne, la boîte et le texte se confondent et tout
   va bien. Dès qu'il passe à la ligne, ils divergent : mesuré sur la section
   « Ce n'est pas l'envie qui manque », le span « le temps et le mode
   d'emploi » occupe une boîte de 450 px sur deux lignes, et le trait se
   dessinait donc sur 450 px sous une dernière ligne qui en fait 230. Un trait
   qui dépasse le mot de deux cents pixels vers la droite : c'est exactement ce
   qu'on voyait, et ça n'avait l'air de rien d'autre que d'un défaut.

   `box-decoration-break: clone` règle le cas à la racine : le fond appartient
   maintenant au TEXTE et non à sa boîte, et le navigateur le redessine sur
   chaque ligne, à la largeur de cette ligne. Deux lignes, deux traits, chacun
   sous ses mots. Sur une ligne, le rendu est identique à avant.

   `white-space: nowrap` disparaît du même coup. Il était là pour empêcher la
   coupure, c'est-à-dire pour éviter le défaut plutôt que le corriger, et il
   coûtait un débordement d'écran sous 520 px, que la feuille annulait plus
   bas par une exception. L'exception n'a plus lieu d'être. */
.surligne {
  position: relative;
  isolation: isolate;
  padding-inline: .38em;
  -webkit-box-decoration-break: clone;
          box-decoration-break: clone;
}
.surligne::before {
  content: '';
  position: absolute; z-index: -1;
  /* Calé sur la boîte de PADDING de chaque fragment de ligne, que
     `box-decoration-break: clone` recrée à chaque passage à la ligne. */
  left: 0; right: 0;
  /* Le rectangle ne fait pas toute la hauteur de la ligne : il couvre les
     lettres, pas l'interligne. Sinon il ressemble à un bandeau de titre. */
  top: .14em; bottom: .1em;
  background: var(--pal-accent);
  transform: rotate(-1.2deg) skewX(-4deg);
  border-radius: 2px;
}
/* Le texte posé SUR l'aplat jaune est encre, quelle que soit la couleur du
   titre autour. Mesuré : encre #09090B sur #FACC15 donne 12,42:1 ; blanc sur ce
   même jaune donnerait 1,72:1, c'est-à-dire un titre invisible. La règle est
   portée par le surligneur et non par la section : c'est ce qui empêche un
   futur titre blanc de reposer le défaut ailleurs dans la page. */
.surligne:not(.surligne--clair) { color: var(--encre); }

/* ═══ Le titre de page garde son aplat ════════════════════════════════════
   Le mot avait été passé en couleur pleine, sans rectangle. Essayé, regardé,
   refusé : le seul jaune qui tient sur du blanc est `--accent-lisible`
   (#A16207, 4,92:1), et à cette valeur ce n'est plus le jaune de la marque,
   c'est un or brun. La marque y perdait plus que le titre n'y gagnait.

   L'aplat reste donc, et c'est le bon arbitrage : il porte le vrai #FACC15,
   avec de l'encre dessus à 12,42:1. C'est la seule construction qui permet au
   jaune de la marque d'apparaître à pleine saturation dans un titre sur fond
   clair. Le jaune en TEXTE n'est possible que sur fond nuit, où il donne
   15,3:1, et c'est pour ça qu'il n'apparaît que là. */

/* Sur fond nuit, l'aplat jaune plein resterait lisible mais crierait sur une
   ligne entière de titre. La variante claire est donc un jaune dense mais
   transparent, avec son propre filet : le blanc du titre reste dessus, sur un
   fond composite mesuré à 7,9:1. */
.surligne--clair::before {
  background: rgba(250,204,21,.26);
  box-shadow: inset 0 0 0 1.5px rgba(250,204,21,.55);
}
/* La variante fine, pour les h2 : un trait épais au lieu d'un bloc, quand le
   titre est déjà long et qu'un aplat le rendrait lourd. */
.surligne--fin::before {
  top: auto; bottom: .02em; height: .38em;
  border-radius: 1px;
}

/* ═══ L'accent sans rectangle, sur fond nuit ══════════════════════════════
   Il existe un cas où aucune forme d'aplat ne fonctionne : un titre LONG, sur
   plusieurs lignes, sur fond noir. Le trait fin y a été essayé dans trois
   versions successives (bloc, trait plein, trait qui suit les lignes), et
   aucune n'a tenu à l'œil : sous un titre de deux ou trois lignes, le trait
   souligne la dernière et fait croire que les précédentes ont été oubliées.

   Sur fond nuit, on n'en a pas besoin. Le jaune de la marque donne 15,3:1 sur
   #09090B : il peut porter le texte directement, à pleine saturation, sans
   aucune forme derrière. C'est le même mot mis en valeur, avec une chose en
   moins à dessiner. */
.accent-nuit { color: var(--accent-sur-sombre); }
/* L'exception qui rendait `white-space: normal` sous 520 px a été retirée avec
   le `nowrap` qu'elle annulait : le surlignage se coupe désormais proprement à
   toutes les largeurs, et il n'y a plus de largeur à traiter à part. */

/* ─── La variante souple, pour les titres qui vivent dans une colonne ───────
   `white-space: nowrap` est la bonne règle par défaut : il garantit que
   l'aplat reste d'un seul tenant, ce qui est tout l'effet recherché. Il devient
   faux dès que la phrase surlignée est longue ET que la colonne est étroite :
   sur la section de diagnostic, « le temps et le mode d'emploi » débordait de
   sa colonne et passait par-dessus le texte d'à côté.

   La variante souple accepte la coupure. Elle n'est proposée qu'avec
   `--fin`, c'est-à-dire avec le trait épais et non l'aplat : un aplat coupé en
   deux donne deux rectangles décalés, un trait coupé en deux donne deux traits,
   ce qui reste lisible comme un soulignement. */
.surligne--souple { white-space: normal; }

/* ─── Lueurs de section ────────────────────────────────────────────────────── */
/* Un halo diffus posé derrière le contenu des sections sombres. Purement
   décoratif, donc `aria-hidden` dans le balisage et `pointer-events: none`
   ici : il ne doit jamais intercepter un clic destiné à un bouton. */
.section--nuit { position: relative; overflow: hidden; isolation: isolate; }
.section__lueur, .banniere__lueur {
  position: absolute; z-index: -1; pointer-events: none;
  top: -30%; right: -10%; width: min(680px, 80%); aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(250,204,21,.20), transparent 66%);
  filter: blur(40px);
}
.banniere__lueur { top: auto; bottom: -40%; left: -12%; right: auto;
  background: radial-gradient(circle, rgba(250,204,21,.18), transparent 64%); }

/* ─── Grilles supplémentaires ──────────────────────────────────────────────── */
.grille--4 { grid-template-columns: 1fr; }
.grille--5 { grid-template-columns: 1fr; gap: 1.25rem; }
@media (min-width: 640px) {
  .grille--4 { grid-template-columns: repeat(2, 1fr); }
  .grille--5 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1000px) {
  .grille--4 { grid-template-columns: repeat(4, 1fr); }
  /* Cinq colonnes égales : les habillages sont cinq alternatives de même rang,
     et les mettre sur deux rangs de 3 + 2 laisserait croire à une hiérarchie. */
  .grille--5 { grid-template-columns: repeat(5, 1fr); }
}

/* ─── Le bandeau des locales clientes ──────────────────────────────────────── */
.bandeau-clients { padding-block: clamp(2rem, 4vw, 3rem); overflow: hidden; }
.bandeau-clients__titre {
  text-align: center; margin-bottom: 1.75rem;
  font-size: .78rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--encre-tenue);
}

/* Deux pistes identiques côte à côte, décalées en boucle d'exactement la
   largeur d'une piste : au moment où la copie atteint la place de l'originale,
   l'animation revient à zéro et personne ne voit la couture. Un carrousel à
   flèches serait ici une fausse bonne idée : il n'y a rien à lire, seulement
   un nombre à faire sentir, et un contrôle qui ne sert à rien est un contrôle
   qu'on doit quand même rendre accessible. */
.defile {
  display: flex; width: max-content;
  animation: defile 42s linear infinite;
}
.defile__piste {
  display: flex; align-items: center; gap: clamp(2.5rem, 5vw, 4.5rem);
  list-style: none; margin: 0; padding: 0 clamp(1.25rem, 2.5vw, 2.25rem);
}
.defile__marque { flex: 0 0 auto; }
.defile__marque img {
  /* Le logo JCI est plus haut que large (le bouclier surmonte le nom de la
     locale), là où la plupart des logos d'association sont en bandeau. On
     contraint donc la HAUTEUR, jamais la largeur : imposer une largeur écrase
     ce logo-ci et étire les autres. */
  height: 62px; width: auto; max-width: none;
  /* Les logos arrivent de dix associations différentes, avec dix palettes.
     Les désaturer les met sur un pied d'égalité et empêche qu'un logo rouge
     vif attire l'œil plus que les neuf autres. Ils reprennent leur couleur au
     survol, ce qui donne au bandeau sa seule interaction. */
  filter: grayscale(1); opacity: .62;
  transition: filter var(--transition), opacity var(--transition);
}
.defile__marque img:hover { filter: none; opacity: 1; }

/* Au survol du bandeau, le défilement s'arrête : sans ça, on ne peut pas lire
   un nom qui passe, ni cliquer si un jour ces logos deviennent des liens. */
.defile:hover { animation-play-state: paused; }

@keyframes defile {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* Mouvement réduit : le bandeau ne bouge plus du tout. Il devient une bande
   qu'on fait défiler au doigt ou au clavier, et la piste dupliquée disparaît
   pour ne pas montrer deux fois les mêmes locales. */
@media (prefers-reduced-motion: reduce) {
  .defile { animation: none; width: 100%; overflow-x: auto; }
  .defile__piste[aria-hidden="true"] { display: none; }
}

/* ─── Les cartes du problème ───────────────────────────────────────────────── */
/* Le titre de ces cartes est une citation de rendez-vous, pas un argument
   rédigé. Il est donc en italique et sans guillemets typographiques ajoutés :
   ils sont déjà dans le texte, où ils appartiennent au contenu. */
.carte--probleme h3 {
  font-style: italic; font-weight: 600;
  font-size: 1.05rem; color: var(--pal-secondaire);
}

/* ─── Le constat de fin de section ─────────────────────────────────────────── */
.constat {
  margin-top: clamp(2rem, 4vw, 3rem);
  padding: 1.15rem 1.5rem;
  border-left: 3px solid var(--pal-primaire);
  background: var(--surface);
  border-radius: 0 var(--rayon-petit) var(--rayon-petit) 0;
  font-size: 1rem; color: var(--encre-douce);
  max-width: 66ch;
}
.section--doux .constat { background: var(--surface); }

/* ─── Les gestes du quotidien ──────────────────────────────────────────────── */
.gestes { display: grid; gap: 1.25rem; grid-template-columns: 1fr; }
@media (min-width: 700px)  { .gestes { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1020px) { .gestes { grid-template-columns: repeat(3, 1fr); } }
.geste {
  position: relative;
  background: var(--surface); border: 1px solid var(--trait);
  border-radius: var(--rayon); padding: 1.75rem 1.5rem 1.5rem;
  transition: transform var(--transition), box-shadow var(--transition),
              border-color var(--transition);
}
.geste:hover { transform: translateY(-3px); box-shadow: var(--ombre); border-color: var(--pal-primaire); }
/* La durée est le vrai argument de la carte : elle passe donc avant le titre,
   en gros, parce que « facile » ne veut rien dire tant qu'on ne l'a pas mis en
   minutes. */
.geste__duree {
  display: inline-block; margin-bottom: .75rem;
  padding: .3rem .7rem; border-radius: var(--rayon-pilule);
  background: var(--surface-accent); color: var(--accent-lisible);
  font-size: .82rem; font-weight: 700; letter-spacing: .02em;
}
.geste h3 { font-size: 1.08rem; margin-bottom: .5rem; }
.geste p { color: var(--encre-douce); font-size: .93rem; }

/* ─── Les idées d'articles ─────────────────────────────────────────────────── */
.idees { display: grid; gap: 1.25rem; grid-template-columns: 1fr; }
@media (min-width: 700px)  { .idees { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1020px) { .idees { grid-template-columns: repeat(3, 1fr); } }
.idee {
  background: var(--nuit-surface);
  border: 1px solid var(--nuit-trait);
  border-radius: var(--rayon); padding: 1.6rem 1.5rem;
  transition: border-color var(--transition), background var(--transition);
}
.idee:hover { border-color: rgba(250,204,21,.55); background: rgba(255,255,255,.08); }
.idee__moment {
  font-size: .74rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--pal-accent);
  margin-bottom: .6rem;
}
.idee h3 { color: #fff; font-size: 1.08rem; margin-bottom: .5rem; }
.idee p { font-size: .93rem; }

/* ─── Les habillages ───────────────────────────────────────────────────────── */
.habillage {
  background: var(--surface); border: 1px solid var(--trait);
  border-radius: var(--rayon); padding: 1.25rem;
  transition: transform var(--transition), box-shadow var(--transition);
}
.habillage:hover { transform: translateY(-3px); box-shadow: var(--ombre); }
.habillage h3 { font-size: 1rem; margin-bottom: .35rem; }
.habillage p { font-size: .87rem; color: var(--encre-douce); }
/* Un aperçu dessiné en CSS plutôt qu'une capture d'écran : cinq captures
   pèseraient plus lourd que toute la page, et elles seraient fausses le jour
   où un habillage bouge. Ce sont des silhouettes, elles disent une ambiance
   sans prétendre montrer le site. */
.habillage__apercu {
  display: block; height: 92px; margin-bottom: 1rem;
  border-radius: var(--rayon-petit);
  background: var(--surface-doux);
  border: 1px solid var(--trait);
  position: relative; overflow: hidden;
}
.habillage__apercu::before {
  content: ''; position: absolute; inset: 10px 12px auto 12px; height: 8px;
  border-radius: 2px; background: var(--pal-primaire); opacity: .85;
}
.habillage__apercu::after {
  content: ''; position: absolute; inset: 26px 12px 12px 12px;
  border-radius: 3px; background: var(--trait);
}
.habillage__apercu--0::before { width: 46%; inset-inline: 12px auto; }
.habillage__apercu--1::before { background: var(--pal-secondaire); width: 62%; inset-inline: 12px auto; }
.habillage__apercu--1::after  { inset: 26px 12px 12px 12px; background:
  linear-gradient(180deg, var(--trait) 0 46%, transparent 46% 54%, var(--trait) 54%); }
.habillage__apercu--2::before { background: var(--pal-encre); width: 34%; inset-inline: 12px auto; }
.habillage__apercu--2::after  { inset: 26px 12px 12px 12px; background:
  linear-gradient(90deg, var(--trait) 0 58%, transparent 58% 64%, var(--surface-accent) 64%); }
.habillage__apercu--3::before { background: var(--pal-accent); width: 72%; inset-inline: 12px auto; }
.habillage__apercu--3::after  { background: var(--pal-encre); opacity: .12; }
.habillage__apercu--4::before { background: var(--pal-accent); width: 52%; inset-inline: 12px auto; }
.habillage__apercu--4::after  { inset: 26px 12px 12px 12px; background:
  radial-gradient(circle at 30% 55%, var(--pal-accent) 0 14px, var(--trait) 14px); }

/* ─── Le mot lié au lexique ────────────────────────────────────────────────── */
/* Un mot technique qu'on ne pouvait pas éviter. Souligné en pointillé, il
   annonce qu'il y a quelque chose à savoir ; au survol et au clavier, la
   définition courte s'affiche ; au clic, on va au lexique.

   Il n'est PAS de la couleur des liens. Un texte truffé de liens bleus se lit
   comme un sommaire : le pointillé signale sans crier, et c'est le bon niveau
   pour un mot qu'on peut très bien ignorer. */
.mot {
  position: relative;
  color: inherit; font-weight: 600;
  text-decoration: underline dotted var(--pal-primaire);
  text-decoration-thickness: 1.5px; text-underline-offset: 3px;
  cursor: help;
}
.mot:hover, .mot:focus-visible { color: var(--accent-lisible); }
.section--nuit .mot:hover, .section--nuit .mot:focus-visible { color: var(--accent-sur-sombre); }
.mot__bulle {
  position: absolute; bottom: calc(100% + 10px); left: 50%;
  transform: translateX(-50%) translateY(4px);
  width: max-content; max-width: min(300px, 78vw);
  background: var(--pal-encre); color: #fff;
  padding: .75rem .9rem; border-radius: var(--rayon-petit);
  font-size: .82rem; line-height: 1.45; font-weight: 400;
  text-align: left; text-decoration: none;
  box-shadow: var(--ombre-forte);
  opacity: 0; visibility: hidden; pointer-events: none; z-index: 30;
  transition: opacity var(--transition), transform var(--transition), visibility var(--transition);
}
.mot__bulle strong { color: var(--pal-accent); font-weight: 700; display: block; margin-bottom: .2rem; }
.mot:hover .mot__bulle, .mot:focus-visible .mot__bulle {
  opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0);
}
/* Sur téléphone, une bulle centrée sur un mot en bord de ligne sort de l'écran
   et sa moitié est rognée. Elle s'aligne alors sur le bloc de texte. */
@media (max-width: 620px) {
  .mot__bulle { left: 0; transform: translateY(4px); max-width: 82vw; }
  .mot:hover .mot__bulle, .mot:focus-visible .mot__bulle { transform: translateY(0); }
}

/* ─── Le fil d'Ariane des documents ────────────────────────────────────────
   Il était écrit pour un fond nuit : gris clair sur noir, liens en jaune vif.
   La tête de ces pages est passée en clair (voir juste en dessous), et ces
   deux couleurs y devenaient illisibles, le jaune le premier, à 1,72:1. */
.fil-ariane {
  font-size: .84rem; color: var(--encre-tenue); margin-bottom: 1.25rem;
}
.fil-ariane a { color: var(--encre-douce); text-decoration: underline; text-underline-offset: 3px; }
.fil-ariane a:hover { color: var(--encre); }
.fil-ariane span { margin-inline: .4rem; opacity: .6; }

/* ─── La tête des trois documents ──────────────────────────────────────────
   `/lexique`, `/cgv` et `/mentions-legales` n'ouvrent pas comme les seize
   autres pages : elles n'ont ni marqueur, ni bandeau de preuves, ni appel à
   l'action, parce qu'elles ne vendent rien. Ce sont des documents, et un
   document s'ouvre à gauche, là où commence la première ligne qu'on va lire.

   ─── Ce qui a changé, et pourquoi ────────────────────────────────────────
   Elles ouvraient sur du NOIR (`section--nuit`), et c'était le dernier reste
   des six têtes différentes que le site portait : douze pages en clair, une
   en crème, deux en nuit centré, trois en nuit à gauche. Un visiteur qui
   clique sur « Mentions légales » dans le pied de page changeait de site.

   Elles gardent leur propre composant plutôt que de passer par `page_tete()` :
   ce dernier compose un marqueur, un bandeau de preuves et un appel à
   l'action dont aucune de ces pages n'a l'usage, et le faire accepter trois
   arguments vides aurait été une variante de plus à maintenir pour trois
   pages qui n'en demandent pas. Deux composants aux rôles nets valent mieux
   qu'un composant à option. */
.lex-tete {
  padding-block: clamp(2.5rem, 5vw, 4rem) clamp(2rem, 4vw, 3rem);
  border-bottom: 1px solid var(--trait);
}
.lex-tete h1 {
  font-size: clamp(1.9rem, 3.6vw, 2.85rem);
  max-width: 24ch;
}
.lex-tete .accroche { color: var(--encre-douce); max-width: 58ch; }

.lex-outils { margin-bottom: clamp(2rem, 4vw, 3rem); }
.lex-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);
}
.lex-recherche:focus-within { border-color: var(--pal-primaire); box-shadow: 0 0 0 4px rgba(250,204,21,.30); }
.lex-recherche svg { color: var(--encre-tenue); flex: 0 0 auto; }
.lex-recherche input {
  flex: 1; min-width: 0; border: 0; background: none; outline: none;
  padding-block: .95rem; font-size: 1rem;
}
.lex-recherche input::-webkit-search-cancel-button { cursor: pointer; }

.lex-familles { display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center; margin-top: 1.25rem; }
.lex-puce {
  border: 1.5px solid var(--trait); background: var(--surface);
  color: var(--encre-douce); border-radius: var(--rayon-pilule);
  padding: .5rem 1rem; font-size: .85rem; font-weight: 600; cursor: pointer;
  min-height: 40px;
  transition: border-color var(--transition), color var(--transition), background var(--transition);
}
.lex-puce:hover { border-color: var(--pal-primaire); color: var(--accent-lisible); }
.lex-puce[aria-pressed="true"] {
  background: var(--accent-lisible); border-color: var(--accent-lisible); color: #fff;
}

.lex-alphabet { display: flex; flex-wrap: wrap; gap: 2px; justify-content: center; margin-top: 1.25rem; }
.lex-alphabet a, .lex-alphabet span {
  width: 32px; height: 32px; display: grid; place-items: center;
  border-radius: 8px; font-size: .82rem; font-weight: 700; text-decoration: none;
}
.lex-alphabet a { color: var(--encre-douce); }
.lex-alphabet a:hover { background: var(--accent-lisible); color: #fff; }
.lex-alphabet span { color: var(--trait); }

.lex-liste { display: grid; gap: 1rem; }
.lex-ancre { display: block; height: 0; scroll-margin-top: calc(var(--hauteur-entete) + 1.5rem); }
.lex-terme {
  background: var(--surface); border: 1px solid var(--trait);
  border-radius: var(--rayon); padding: 1.5rem;
  scroll-margin-top: calc(var(--hauteur-entete) + 1.5rem);
}
/* Un terme atteint par un lien direct est mis en évidence une fois : quelqu'un
   qui arrive depuis la page de vente doit voir LEQUEL des soixante termes il
   est venu lire, sans avoir à comparer les titres. */
.lex-terme:target { border-color: var(--pal-primaire); box-shadow: 0 0 0 4px rgba(250,204,21,.30); }
.lex-terme__tete { display: flex; align-items: center; flex-wrap: wrap; gap: .65rem; margin-bottom: .6rem; }
.lex-terme h2 { font-size: 1.15rem; font-weight: 700; }
.lex-terme dfn { font-style: normal; }
.lex-terme p { color: var(--encre-douce); font-size: .95rem; }
/* Le « # » qui permet de citer une définition seule. Il est discret au repos
   et se révèle au survol, mais au survol il était en jaune de marque, soit
   1,72:1 sur blanc : le lien apparaissait pour redevenir illisible. Il prend
   donc la nuance sombre du jaune, et il porte un état de focus visible, sans
   quoi il n'existe simplement pas pour qui navigue au clavier. */
.lex-terme__lien {
  margin-left: auto; color: #D4D4D8; font-weight: 800; text-decoration: none;
  padding-inline: .3rem;
  transition: color var(--transition);
}
.lex-terme:hover .lex-terme__lien,
.lex-terme__lien:focus-visible { color: var(--accent-lisible); }

.lex-etiquette {
  font-size: .72rem; font-weight: 700; letter-spacing: .05em;
  padding: .25rem .65rem; border-radius: var(--rayon-pilule);
  background: var(--surface-doux); color: var(--encre-tenue);
}
.lex-etiquette--bases   { background: var(--surface-accent);        color: var(--accent-lisible); }
.lex-etiquette--site    { background: rgba(250,204,21,.18);       color: #7A5B04; }
.lex-etiquette--espace  { background: rgba(9,9,11,.07);        color: var(--pal-secondaire); }
.lex-etiquette--trouve  { background: rgba(250,204,21,.22);       color: #7A5B04; }
.lex-etiquette--contenu { background: rgba(250,204,21,.30);        color: var(--accent-lisible); }
.lex-etiquette--regles  { background: rgba(9,9,11,.07);         color: var(--encre); }

.lex-vide { text-align: center; padding: 2.5rem 1rem; color: var(--encre-tenue); }
.lex-appel {
  text-align: center; background: var(--surface);
  border: 1px solid var(--trait); border-radius: var(--rayon);
  padding: clamp(2rem, 5vw, 3rem);
}
.lex-appel .actions { justify-content: center; }

/* ─── Révélation au défilement ─────────────────────────────────────────────── */
/* Le contenu n'est masqué QUE si un script peut le révéler.
   Sans cette condition, `.revele { opacity: 0 }` s'applique toujours et la page
   entière (48 blocs, soit tout sauf la bannière) reste blanche dès que le
   fichier JS ne s'exécute pas : script bloqué, erreur réseau, ou politique de
   sécurité réécrite par un intermédiaire. Ce dernier cas n'est pas théorique
   sur ce projet, le CDN de l'hébergeur remplace déjà l'en-tête de politique de
   sécurité du moteur par le sien.
   Une animation d'entrée est un agrément. Elle ne doit jamais être la condition
   pour que le texte existe. `scripting: enabled` pose exactement cette question,
   et un navigateur qui ne connaît pas la requête ignore le bloc, donc montre
   tout : le repli va dans le bon sens. */
@media (scripting: enabled) {
  .revele { opacity: 0; transform: translateY(22px); }
}
.revele.est-vu {
  opacity: 1; transform: none;
  transition: opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1);
}
@media (prefers-reduced-motion: reduce) {
  .revele, .revele.est-vu { opacity: 1; transform: none; transition: none; }
  .globe__toile { opacity: 1; transition: none; }
  .bouton:hover, .carte--survol:hover { transform: none; }
}

/* ─── Cibles tactiles ──────────────────────────────────────────────────────── */
/* Le thème des sites laissait treize cibles sous 44 pixels, dont les liens du
   pied de page. Ici la règle est posée une fois pour toutes. */
@media (max-width: 719px) {
  .pied ul a, .pied__bas a, .entete__nav a {
    display: inline-block; min-height: 44px; line-height: 44px;
  }
}

@media print {
  .entete, .globe, .video, .bandeau { display: none; }
  body { color: #000; background: #fff; }
}


/* ─── Utilitaires d'espacement et de couleur ───────────────────────────────
   La politique de sécurité du moteur interdit les styles en ligne autant que
   les scripts en ligne (`style-src 'self'`, sans 'unsafe-inline'). Un
   attribut `style=""` n'est donc pas « du CSS rapide » ici : il est purement
   et simplement ignoré par le navigateur, en silence. Cette page en portait
   dix-huit à sa première écriture, et quatre d'entre eux étaient les seules
   choses qui rendaient la frise lisible sur son fond sombre.
   D'où ces quelques classes : ce ne sont pas des utilitaires de confort, c'est
   le seul moyen d'exprimer ces règles. */
.espace-haut-sm { margin-top: .6rem; }
.espace-haut    { margin-top: 1rem; }
.espace-haut-md { margin-top: 1.25rem; }
.espace-haut-lg { margin-top: 1.5rem; }
.espace-bas-md  { margin-bottom: 1.25rem; }
.tete-section--eloignee { margin-top: clamp(2.5rem, 5vw, 3.5rem); margin-bottom: 1.5rem; }
.mesure-44 { max-width: 44ch; }
.mesure-70 { max-width: 70ch; }
.sur-nuit { color: #fff; }
.sur-nuit-doux { color: var(--nuit-encre-douce); }

/* Lu, jamais vu. Sert au tableau comparatif, dont les cases disent « compris »
   ou « non compris » par un pictogramme : le pictogramme est décoratif, donc
   muet, et sans ce texte une lectrice d'écran entendrait trente cases vides.
   `display: none` ne conviendrait pas, il masque AUSSI pour elle. */
.pour-lecteur-ecran {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.champ--groupe { border: 0; padding: 0; }

/* ─── Les pages légales ────────────────────────────────────────────────────── */
.legal-maj { margin-top: 1.5rem; font-size: .86rem; color: var(--nuit-encre-douce); }

.legal-grille { display: grid; gap: clamp(2rem, 4vw, 3.5rem); }
@media (min-width: 940px) {
  /* Le sommaire à gauche, collé sous la barre de navigation : dix-sept
     articles, on doit pouvoir sauter de l'un à l'autre sans remonter. */
  .legal-grille { grid-template-columns: 260px 1fr; align-items: start; }
  .legal-sommaire { position: sticky; top: calc(var(--hauteur-entete) + 1.5rem); }
}

.legal-sommaire {
  background: var(--surface-doux);
  border: 1px solid var(--trait); border-radius: var(--rayon);
  padding: 1.5rem 1.25rem;
}
.legal-sommaire__titre {
  font-size: .74rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--encre-tenue); margin-bottom: .9rem;
}
.legal-sommaire ol { margin: 0; padding-left: 1.1rem; display: grid; gap: .5rem; }
.legal-sommaire li { font-size: .86rem; }
.legal-sommaire a { color: var(--encre-douce); text-decoration: none; }
.legal-sommaire a:hover { color: var(--accent-lisible); text-decoration: underline; }
.legal-sommaire__autres {
  display: grid; gap: .45rem;
  margin-top: 1.25rem; padding-top: 1.1rem;
  border-top: 1px solid var(--trait);
  font-size: .84rem; font-weight: 600;
}

.legal-corps { max-width: 72ch; }
.legal-article { scroll-margin-top: calc(var(--hauteur-entete) + 1.5rem); }
.legal-article + .legal-article { margin-top: 2.75rem; }
.legal-article h2 {
  font-size: 1.22rem; line-height: 1.35;
  padding-bottom: .6rem; margin-bottom: 1rem;
  border-bottom: 1px solid var(--trait);
}
.legal-article p { color: var(--encre-douce); margin-bottom: 1rem; }
.legal-article ul {
  margin: 0 0 1.1rem; padding-left: 1.3rem;
  color: var(--encre-douce); display: grid; gap: .5rem;
}
.legal-fin {
  margin-top: 3rem; padding: 1.15rem 1.5rem;
  border-left: 3px solid var(--pal-primaire);
  background: var(--surface-doux);
  border-radius: 0 var(--rayon-petit) var(--rayon-petit) 0;
  font-size: .95rem; color: var(--encre-douce);
}
/* Le bloc portait un seul `<p>` écrit dans le gabarit ; il porte maintenant le
   texte de la console, qui sort en paragraphes. Sans ces deux règles, la marge
   du navigateur ajoute un blanc sous la dernière ligne, à l'intérieur du cadre. */
.legal-fin p { margin: 0; }
.legal-fin p + p { margin-top: .8rem; }

/* ─── Bandeau de consentement ─────────────────────────────────────────────────
 *
 * Même balisage et même script que la coquille des sites clients : seul
 * l'habillage est refait, parce que cette page a sa propre feuille et ses propres
 * jetons. Les deux boutons portent la même classe, et ce n'est pas un oubli :
 * refuser doit être aussi simple qu'accepter, donc aucun des deux n'est le bouton
 * jaune qui appelle le clic ailleurs sur la page.
 */
.bandeau-cookies {
  position: fixed; left: 1rem; right: 1rem; bottom: 1rem; z-index: 90;
  max-width: 42rem; margin-inline: auto; padding: 1.35rem 1.5rem;
  background: var(--surface); color: var(--encre);
  border: 1px solid var(--trait); border-radius: 14px;
  box-shadow: 0 14px 40px rgba(9, 9, 11, .16), 0 2px 6px rgba(9, 9, 11, .07);
}
.bandeau-cookies[hidden] { display: none; }
.bandeau-cookies__titre { font-weight: 700; margin: 0 0 .4rem; }
.bandeau-cookies p { font-size: .9rem; line-height: 1.55; color: var(--encre-douce); margin: 0; }
.bandeau-cookies__actions { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: 1.1rem; }
.bandeau-cookies__actions .bouton { flex: 1 1 11rem; justify-content: center; }
.bandeau-cookies__lien { margin-top: .9rem; font-size: .8rem; }
.bandeau-cookies__texte strong { color: var(--encre); }
/* Au téléphone, deux lignes et une rangée de boutons, comme sur les sites des
   clients (audit UX, III.2 n° 5 ; PHASE-3-UX, UX-0.9). */
@media (max-width: 600px) {
  .bandeau-cookies { left: .75rem; right: .75rem; bottom: .75rem; padding: .8rem .95rem; }
  .bandeau-cookies p.bandeau-cookies__texte { font-size: .875rem; line-height: 1.45; }
  .bandeau-cookies__premier .bandeau-cookies__actions { flex-wrap: nowrap; gap: .5rem; margin-top: .65rem; }
  .bandeau-cookies__premier .bandeau-cookies__actions .bouton {
    flex: 1 1 0; min-width: 0; min-height: 44px; padding: .5rem .75rem;
  }
  .bandeau-cookies__premier .bandeau-cookies__lien { margin-top: .45rem; }
}

/* Revenir sur son choix depuis le pied de page, comme sur les sites clients. */
.pied__traceurs {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; font-size: inherit; color: inherit;
  text-decoration: underline; text-underline-offset: 2px;
}


/* ─── Le panneau des familles ─────────────────────────────────────────────────
 *
 * Écrit par consentement_bandeau(), commun aux trois documents. Il s'ouvre sous
 * le premier écran, dans le MÊME bandeau : une fenêtre par-dessus donnerait
 * l'impression d'un piège, et le visiteur perdrait de vue le bouton « tout
 * refuser » qu'il cherchait.
 *
 * La liste défile quand elle est longue, plutôt que de pousser les boutons hors
 * de l'écran sur un téléphone : un « tout refuser » qu'on ne peut pas atteindre
 * n'est pas un refus possible.
 */
.cookies-familles {
  list-style: none; margin: 1rem 0 0; padding: 0;
  max-height: 46vh; overflow-y: auto;
}
.cookies-famille + .cookies-famille {
  margin-top: .85rem; padding-top: .85rem; border-top: 1px solid var(--trait);
}
.cookies-famille__tete {
  display: flex; align-items: center; gap: .6rem; cursor: pointer; font-weight: 600;
}
.cookies-famille__tete input { flex: none; width: 1.05rem; height: 1.05rem; cursor: pointer; }
/* Une case qu'on ne peut pas décocher n'est pas un choix : elle doit le DIRE,
 * pas seulement refuser le clic. D'où la mention à côté, et le curseur normal. */
.cookies-famille__tete input:disabled { cursor: default; }
.cookies-famille__nom { flex: 1 1 auto; }
.cookies-famille__marque {
  flex: none; font-size: .72rem; font-weight: 500; text-transform: uppercase;
  letter-spacing: .04em; color: var(--encre-tenue);
}
.cookies-famille__quoi { margin: .35rem 0 0 1.65rem; }
.cookies-famille__services {
  margin: .25rem 0 0 1.65rem; font-size: .76rem; color: var(--encre-tenue);
}

/* Le panneau a TROIS boutons là où le premier écran en a deux. Sans cette règle,
 * le troisième passait seul à la ligne, ce qui lui donnait le poids d'une
 * conclusion alors que c'est « Enregistrer mes choix » qui conclut. */
.bandeau-cookies__panneau .bandeau-cookies__actions .bouton { flex: 1 1 7rem; }

/* La couverture d'un article, quand il en porte une. Le rapport est imposé et
   l'image recadrée dedans : une photo panoramique et un portrait donneraient
   deux pages de hauteurs très différentes au même endroit. */
.article-couverture {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--rayon-moyen, 18px);
}
/* Sur le hub, la couverture remplace le dessin : même boîte, même arrondi. */
.blog-vedette__couverture--photo { position: relative; overflow: hidden; }
.blog-vedette__couverture--photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.blog-vedette__couverture--photo .blog-vedette__famille { position: absolute; }
