/* =========================================================================
   NUQUE — feuille de style applicative
   Mobile d'abord. Le desktop est la déclinaison, jamais l'inverse (§7 du brief).
   Aucune couleur, aucune police en dur : tout vient de design-system.css.

   Rythme tonal de la page : sombre (décider) → clair (comprendre) → sombre
   (disponibilité). Le navy est la couleur maîtresse du brief, pas un appoint.
   ========================================================================= */

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

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

body {
  margin: 0;
  background: var(--color-paper);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
}

/* Chiffres tabulaires (§4) — sur les colonnes de données qui s'alignent,
   jamais en global : en mode tabulaire la virgule prend la largeur d'un
   chiffre et se détache (« 2 511 , 60 € »). */
.nameplate__val, .scale { font-variant-numeric: tabular-nums; }

img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  line-height: 1.02;
  margin: 0;
}

p { margin: 0; }

:focus-visible { outline: 2px solid var(--color-volt); outline-offset: 3px; }

.shell {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--page-pad);
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* Le petit trait qui précède chaque intitulé reprend la ligne d'attache d'un
   plan coté : c'est le fil structurel de la page. */
.eyebrow {
  display: flex; align-items: center; gap: var(--space-3);
  font-family: var(--font-util);
  font-size: var(--step--2); font-weight: 600;
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
  color: var(--color-cool);
  margin: 0 0 var(--space-4);
}
.eyebrow::before {
  content: ""; width: 1.75rem; height: 1px;
  background: currentColor; flex: none;
}

/* =========================================================================
   EN-TÊTE — elle REVIENT au navy.

   ⚠️ **Annule le passage au clair de la direction 1a**, constaté au navigateur
   le 13 août. La bascule avait donné à l'en-tête `--color-paper`, c'est-à-dire
   la valeur EXACTE du corps de page et de `.deck` : plus de barre, un filet
   d'1 px à 12 % pour seule séparation, et le logo posé sur rien.

   Le défaut sérieux n'était pas en haut de page mais AU DÉFILEMENT. Une barre
   claire sans ombre qui passe sur la bande navy des spécifications la tranche
   en deux : « 128 cm » et « 150 kg » sectionnés à mi-hauteur. Ça ne se lit pas
   comme une barre collante, ça se lit comme un défaut d'affichage. Le dock du
   bas, lui, avait bien reçu son traitement de barre flottante (blanc + ombre) :
   le système savait faire, l'en-tête ne l'avait pas reçu.

   Le navy règle les deux d'un coup — séparation absolue d'avec le papier, et
   une barre sombre qui glisse sur une section sombre se FOND au lieu de
   couper. La crainte inscrite ici (« elle volerait au deck le seul aplat
   sombre qui lui reste ») ne tient plus : le deck a l'encart FIPU et deux
   boutons pleins.

   Ces trois règles ne sont pas neuves — elles sont celles de l'en-tête d'avant
   1a (commit 9246060), que la bascule avait emportées ensemble : fond navy,
   plaque INVERSÉE, et « Mon devis » en lien de texte. On garde en revanche les
   acquis de 1a : plaque à 34 px, baseline en capitales utilitaires.
   ========================================================================= */

/* ⚠️ **Elle n'est PLUS collante en mobile.** Arbitrage de Jeremy le 13 août :
   « aucun intérêt d'avoir le logo toujours visible ». C'est juste — sur un
   site d'une seule page, le bandeau ne portait qu'une marque déjà lue et un
   lien secondaire, pour 72 px sur 844. Avec la barre du bas, également
   retirée, c'était 17,7 % de l'écran occupés en permanence.

   Elle le RESTE à partir de 60 rem, où la hauteur n'est pas une ressource
   rare et où une barre de navigation persistante est ce qu'on attend. */
.masthead {
  position: static;
  background: var(--color-navy);
  color: var(--color-on-navy);
  /* ⚠️ **L'arête doit tenir sur DEUX fonds — vrai là où la barre est encore
     collante, c'est-à-dire au-delà de 60 rem.** Passer l'en-tête au navy ne
     suffisait pas : sur les sections navy elle a exactement la couleur de ce
     qu'elle recouvre, et le filet `--rule-on-navy` (blanc 12 %) n'y donne que
     1,6 de contraste. Mesuré : le bord disparaissait, et le « 128 cm » des
     spécifications se coupait sans cause visible — le défaut d'origine
     retourné, pas résolu.

     D'où DEUX marques cumulées, chacune pour un cas :
     — le filet clair à 22 % se voit sur les sections NAVY, où l'ombre ne peut
       rien puisqu'elle assombrit du presque-noir ;
     — l'ombre portée se voit sur le PAPIER, où le filet clair se noierait.
     Aucune des deux ne suffit seule ; ensemble le bord se lit partout.

     En mobile la barre ne recouvre plus rien, donc les deux marques n'y
     servent qu'à poser le bandeau sur le premier écran. Elles sont conservées
     telles quelles : elles y sont justes aussi, et une valeur qui change avec
     la largeur pour un gain nul est une pièce de plus à maintenir. */
  border-bottom: 1px solid rgba(255, 255, 255, .22);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .28);
}
.masthead__inner {
  display: flex; align-items: center; justify-content: space-between;
  /* ⚠️ **`nowrap`, et c'est le cœur du défaut mobile.** En `wrap`, à 390 px,
     « Mon devis » repassait SOUS le logo dans la même colonne : deux plaques
     navy empilées, et plus moyen de savoir si le site s'appelle NUQUE ou
     Devis. L'en-tête montait à 142 px — dessinée pour 56 — soit, avec le dock,
     26 % de l'écran occupés en permanence sur un site nourri par TikTok.
     Avec la baseline repliée et le lien redevenu du texte, la ligne tient
     largement à 320 px : mesuré à 157 px de contenu pour 280 disponibles. */
  flex-wrap: nowrap;
  gap: var(--space-4);
  min-height: 3.5rem;
  padding-block: var(--space-3);
}
/* L'accent de focus par défaut est `--color-volt` (#2f6fed) : 2,6 sur le navy,
   sous le seuil de 3 exigé pour un indicateur non textuel. Dans l'en-tête il
   passe au bleu clair du système, déjà prévu pour les fonds sombres. */
.masthead :focus-visible { outline-color: var(--color-soft-blue); }

/* Le FILET DE PROGRESSION — 2 px au bas de la barre, qui se remplit avec
   l'avancement. Il n'ajoute AUCUNE hauteur de chrome : il se pose sur le
   filet existant, en `::after`.

   ⚠️ **À partir de 60 rem seulement, et ce n'est pas un choix esthétique.**
   En deçà, la barre n'est plus collante : un indicateur d'avancement qui
   défile hors de l'écran au bout de 72 px n'indique plus rien. Il ne survit
   donc que là où la barre reste, faute de quoi il serait un ornement qui
   ment.

   ⚠️ **Le pseudo-élément n'existe QUE dans le `@supports`**, et ce n'est pas
   de la coquetterie : `animation: … both` sans `animation-timeline` reconnue
   retombe sur une animation de DURÉE, soit 0 s ici — le filet sauterait à
   `scaleX(1)` et afficherait une barre pleine, en permanence, annonçant « page
   terminée » dès l'arrivée. Le déclarer dehors serait pire que ne rien faire.

   Bleu clair et non `--color-volt` : sur navy l'accent tombe à 2,6, la même
   raison qui fait passer les kickers au bleu doux plus bas dans cette feuille.

   `scaleX` plutôt que `width` : la transformation est composée par le GPU,
   elle ne déclenche ni calcul de disposition ni repeinture à chaque pixel
   défilé — sur une page longue, c'est la différence entre fluide et haché. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) and (min-width: 60rem) {
    .masthead::after {
      content: "";
      position: absolute;
      left: 0; right: 0; bottom: -1px;
      height: 2px;
      background: var(--color-soft-blue);
      transform: scaleX(0);
      transform-origin: 0 50%;
      animation: progression-page linear both;
      animation-timeline: scroll(root block);
    }
  }
}

@keyframes progression-page {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* Le logo « bloc » : le nom réservé dans un plein, comme une marque estampée.
   Il s'inverse selon le fond — plein navy sur clair, plein blanc sur navy. */
.wordmark { display: block; text-decoration: none; }

/* ⚠️ **La plaque fait 34 px de haut**, comme dans la maquette — elle en
   faisait 27. Le calcul, pour qu'on puisse le refaire : la hauteur du bloc
   vaut `font-size × (1 + .34 + .34)`, soit 1,68 em. Pour 34 px il faut donc
   20 px de corps, et non 16.

   Cette plaque est dessinée en CSS, pas posée en image, et c'est délibéré :
   `logo-nuque.svg` porte exactement le même dessin — un rectangle navy et le
   mot en blanc — pour 4,7 Ko et une requête de plus. Le texte reste
   sélectionnable, net à tous les grossissements, et suit la police du site.
   Les deux SVG sont conservés tels quels pour les usages hors navigateur
   (email, PDF, impression), où aucune règle CSS ne s'applique. */
.wordmark__block {
  display: inline-block;
  background: var(--color-navy);
  color: #fff;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.25rem;                  /* 20 px × 1,68 = 34 px de plaque */
  letter-spacing: var(--tracking-block);
  line-height: 1;
  /* le padding droit compense l'interlettrage traînant du dernier E */
  padding: .34em .5em .34em .62em;
}

/* L'INVERSION, portée par l'en-tête et par elle seule. Elle est écrite ici et
   non sur `.wordmark__block` parce que le PIED DE PAGE emploie la même plaque
   sur fond papier : une inversion non cadrée l'aurait retournée aussi, en
   blanc sur blanc. Le pied garde donc son plein navy sans qu'on y touche. */
.masthead .wordmark__block { background: #fff; color: var(--color-navy); }

.wordmark__tag {
  /* ⚠️ **Repliée sous 30 em.** Elle répète mot pour mot le kicker « BAC À
     SHAMPOING ÉLECTRIQUE » qui arrive 100 px plus bas : sur téléphone c'est le
     même texte deux fois, payé 86 px de barre collante — 10 % de l'écran.
     Elle reparaît dès qu'il y a de la place, où elle qualifie la marque avant
     que le kicker n'entre dans le champ. Ce sélecteur n'existe que dans
     l'en-tête (le pied de page n'a pas de baseline) : rien d'autre à cadrer. */
  display: none;
  font-family: var(--font-util);
  font-size: var(--step--2); font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  /* Sur navy, `--color-cool` (#5b6675) tombe à 2,4 : c'est exactement le piège
     du 13 août, un jeton juste sur un fond qui a changé de camp. */
  color: var(--color-on-navy-dim);
  margin-top: .45rem;
}

/* « Mon devis » REDEVIENT un lien de texte, et ce n'est pas un recul.
   En bouton navy plein il portait le même aplat, la même famille et la même
   forme rectangulaire que la plaque du logo : deux plaques navy pour deux mots
   de même rang, et un visiteur qui ne sait plus lequel est le nom du site.

   La distinction ne pouvait pas venir de la police — `--font-util` et
   `--font-display` sont toutes deux Archivo. Elle vient donc de tout le reste :
   pas de plaque, 13 px contre 20, graisse 600 contre 700, interlettrage normal
   contre .16em, et un souligné que le logo n'a jamais.

   On ne le supprime pas : c'est la porte FIPU, ouverte avant le 10 septembre
   quand le tunnel de commande répond encore 404 — la seule action possible
   d'ici là. Il n'est doublé que par « Générer mon devis », à 1 143 px du haut
   sur téléphone ; le pied de page ne le porte pas. */
/* ⚠️ **Une PASTILLE VERTE, et c'est une exception assumée à la charte** —
   10 septembre, arbitrage de Jeremy : « mets-le dans une couleur un peu
   différente pour qu'on le voie mieux ». Le lien souligné se lisait comme un
   lien de plus dans une barre qui n'en a qu'un.

   La direction artistique réserve les boutons au navy et n'emploie l'accent
   que pour les kickers et les filets. Le vert est la seule couleur du site qui
   porte un SENS — l'argent que le salon ne paiera pas — et c'est exactement ce
   que ce bouton ouvre : la simulation d'aide. Il annonce sa couleur avant
   d'être lu.

   Contrepartie assumée : sur le premier écran, il tient tête à « Passer
   commande ». C'est le choix de Jeremy — la subvention est son argument le
   plus fort.

   `inline-flex` + `min-height` plutôt qu'un `padding-block` : la cible tactile
   fait 44 px sans dépendre de la hauteur de ligne, et la pastille garde la
   même hauteur quelle que soit la police de repli. */
.masthead__link {
  display: inline-flex; align-items: center;
  font-family: var(--font-util);
  font-size: var(--step--1); font-weight: 700;
  white-space: nowrap;
  color: var(--color-navy);
  background: var(--color-aide-clair);
  border: 0;
  border-radius: var(--radius);
  text-decoration: none;
  min-height: 2.75rem;
  padding-inline: .9rem;
  transition: background-color .15s var(--ease);
}
@media (hover: hover) {
  .masthead__link:hover { background: #6FE0B6; }
}

/* La baseline reparaît dès 30 em (480 px). Mesuré à ce palier : plaque 110 px
   + baseline 205 + lien 80 + gouttière = 419 pour 440 disponibles. La ligne
   tient, et l'en-tête reprend ses deux niveaux de lecture. */
@media (min-width: 30rem) {
  .wordmark__tag { display: block; }
}

/* =========================================================================
   LE DECK — premier écran.

   ⚠️ **Il passe du navy au CLAIR.** C'était le bloc sombre où tout se
   décidait ; la direction 1a en fait une page de catalogue : photo sur carte
   blanche à gauche, décision à droite, et le navy réduit au seul encart FIPU
   et aux boutons. Le contraste ne vient plus d'un aplat mais des filets et de
   la carte blanche posée sur le papier.
   ========================================================================= */

.deck {
  background: var(--color-paper);
  color: var(--color-ink);
  /* Plus de coussin en haut : la photo du héros ouvre la section (1er
     septembre) et touche l'en-tête, comme quand elle vivait hors du deck.
     Le grand écran remet le sien — la photo y est en colonne, pas en bande. */
  padding-block: 0 0;
}
/* L'espace entre la photo et le titre, que le padding du deck donnait avant. */
.deck__photo { margin-block-end: clamp(2rem, 5vw, 4rem); }

/* La planche produit : carte BLANCHE bordée, angles vifs. Elle était un aplat
   gris posé sur le navy — sur fond papier, le blanc la détache sans ombre. */
.plate {
  margin: 0;
  background: var(--color-surface);
  border: 1px solid var(--rule-firm);
  border-radius: 0;
  padding: 1.25rem;
  color: var(--color-ink);
}
.plate__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 3.25rem;
  gap: var(--space-3);
  align-items: stretch;
}
.plate__img { width: 100%; }

/* ⚠️ **Sous 60 rem, la carte sort de ses gouttières.** Mesuré le 13 août : la
   photo faisait 244 px de large sur un écran de 390 — 63 % — parce qu'elle
   payait deux fois la marge de page, deux fois le rembourrage de la carte, et
   la colonne de cote. Un produit à 2 990 € montré en vignette de 244 px n'a pas
   l'air d'un produit à 2 990 €.

   La carte perd donc son cadre et son fond au téléphone : sur un fond papier,
   une carte blanche bordée n'apportait qu'un liseré, et elle coûtait 80 px de
   largeur d'image. La ligne de cote reste — c'est elle qui montre l'amplitude
   93→115, c'est-à-dire l'argument du produit.

   Le fond de la photo est #f5f4f0, à une unité du papier de la page : sans
   cadre, on ne voit AUCUNE jointure. C'est ce qui rend le retrait possible. */
@media (max-width: 59.999rem) {
  .plate {
    margin-inline: calc(-1 * var(--page-pad));
    padding: 0;
    border: 0;
    background: none;
  }
  /* ⚠️ La gouttière droite est REMISE, et seulement elle. Sans elle, « 115 cm »
     et « 93 » se retrouvaient à 0 px de la tranche de l'écran — mesuré, non
     rogné mais illisible : un chiffre collé au bord se lit comme une erreur
     d'affichage. La photo, elle, garde son débordement à GAUCHE. L'asymétrie
     est assumée : c'est le cadrage d'une image qui sort du cadre, pas un
     centrage raté. */
  .plate__body { padding-right: var(--page-pad); }
  .plate__caption { padding-inline: var(--page-pad); }
}

/* La légende passe en deux blocs opposés — description à gauche, amplitude à
   droite —, sans filet supérieur : la bordure de la carte suffit. */
.plate__caption {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
  margin-top: .875rem;
  padding-top: 0;
  border-top: 0;
  font-family: var(--font-util);
  font-size: var(--step--1);
  color: var(--color-cool);
}

/* L'échelle de réglage : la seule pièce de dessin technique de la page.
   Elle dit l'amplitude comme un plan la dit, sans animer une photo fixe. */
.scale { position: relative; font-family: var(--font-util); }

.scale__num {
  position: absolute; right: 0;
  font-size: var(--step--1); font-weight: 700; line-height: 1;
  color: var(--color-ink);
}
.scale__num--top    { top: 0; }
.scale__num--bottom { bottom: 0; }
.scale__unit {
  position: absolute; right: 0; top: 1.05rem;
  font-size: var(--step--2); font-weight: 500; line-height: 1;
  color: var(--color-cool);
}
.scale__ext {
  position: absolute; right: 1.35rem;
  width: 1.5rem; height: 1px;
  background: var(--rule-strong);
}
.scale__ext--top    { top: .34rem; }
.scale__ext--bottom { bottom: .34rem; }
.scale__rule {
  position: absolute; right: 1.75rem; top: .34rem; bottom: .34rem;
  width: 1px; background: var(--color-ink);
  transform: scaleY(0); transform-origin: 50% 0;
  animation: rise .9s var(--ease) .3s forwards;
}
.scale__rule::before, .scale__rule::after {
  content: ""; position: absolute; left: 50%;
  width: 0; height: 0;
  border-left: 3.5px solid transparent;
  border-right: 3.5px solid transparent;
  transform: translateX(-50%);
  opacity: 0; animation: fade .4s var(--ease) 1.15s forwards;
}
.scale__rule::before { top: 0;    border-bottom: 6px solid var(--color-ink); }
.scale__rule::after  { bottom: 0; border-top:    6px solid var(--color-ink); }

@keyframes rise { to { transform: scaleY(1); } }
@keyframes fade { to { opacity: 1; } }

/* --- La colonne de décision -------------------------------------------- */

/* La colonne devient une pile régulière : la maquette pose un `gap` unique de
   20 px entre tous ses blocs, au lieu d'une marge propre à chacun. Les marges
   individuelles sont donc neutralisées plus bas — deux systèmes d'espacement
   qui se superposent produisent des écarts qu'on ne sait plus expliquer. */
.buy {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

/* Le kicker est le seul endroit où l'accent devient du petit texte sur clair :
   d'où le jeton assombri. Le trait qui le précède reste, c'est le fil
   structurel de la page. */
.buy .eyebrow { color: var(--color-volt-text); margin: 0; }

.buy__title {
  font-size: var(--title-l);
  font-weight: 800;
  letter-spacing: var(--tracking-tight);
  line-height: 1.02;
  color: var(--color-ink);
  margin: 0;
  text-wrap: balance;
}
.buy__lede {
  font-family: var(--font-body);
  font-size: var(--step-3);
  line-height: 1.55;
  max-width: 44ch;
  color: var(--color-ink-muted);
  margin: 0;
}

/* --- Bande de specs : RETIRÉE le 13 août 2026 ---------------------------
   128 cm / 150 kg / 5 ans. Aucune information perdue : la charge utile est
   dans la fiche technique, la garantie a sa propre section et son entrée de
   FAQ, la longueur est dans la FAQ. Trois chiffres répétés trois écrans plus
   bas, ce n'est pas de la redondance utile sur l'écran qui décide. */

/* Le prix, sur fond clair. Tout tient sur une ligne qui se replie : montant,
   ancien tarif rayé, pastille de remise, équivalent TTC. */
.price { display: flex; flex-direction: column; gap: .375rem; }

.price__now {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: .5rem .875rem;
  font-family: var(--font-display);
  font-size: var(--step-price);
  font-weight: 800;
  letter-spacing: var(--tracking-tight);
  line-height: 1.1;
  color: var(--color-ink);
}
.price__unit {
  font-size: var(--step-1); font-weight: 600;
  letter-spacing: 0; color: var(--color-cool);
}
.price__meta {
  display: flex; align-items: baseline; flex-wrap: wrap;
  gap: .5rem .875rem;
  margin-top: 0;
  font-family: var(--font-util);
  font-size: .9375rem;                 /* 15px — l'équivalent TTC */
  color: var(--color-cool);
}
/* ⚠️ `--color-cool` et non le #98a1ad de la maquette : ce gris tombait à 2,38
   de contraste sur le papier. Un ancien tarif rayé reste une information de
   prix — s'il n'est pas lisible, la remise ne se comprend pas. */
.price__was {
  font-family: var(--font-body);
  font-size: var(--step-0);
  text-decoration: line-through;
  color: var(--color-cool);
}
/* La pastille de remise passe au ROUGE — 13 août. Elle était navy sur papier,
   c'est-à-dire de la même couleur que tout le reste : la seule information de
   la ligne qui devait sauter aux yeux ne sautait à rien.
   Le trait suit le texte plutôt que de rester gris : une pastille rouge cerclée
   de gris paraît décolorée. */
.price__off {
  font-family: var(--font-util);
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--color-sale);
  border: 1px solid currentColor;
  border-radius: 0;                    /* pastille à angles vifs, comme les cartes */
  padding: .25rem .5rem;
}
.price__deadline {
  margin-top: 0;
  font-family: var(--font-body);
  font-style: italic;
  font-size: .875rem;                  /* 14px */
  color: var(--color-cool);
}

/* ⚠️ **L'ENCART FIPU CHIFFRÉ EST RETIRÉ** — 13 août 2026.
   Il affichait « 747 € à votre charge », le taux et le montant financé, plus
   sa réserve. Quatre lignes et trois montants pour dire une chose : le
   matériel ouvre droit à une aide. Il reste une phrase, `.eligible`.

   Ce n'est pas qu'un allègement : une simulation chiffrée devait porter sa
   réserve, faute de quoi un salon refusé par sa caisse se retournait vers
   nous, acompte versé. Une mention d'éligibilité ne promet rien.

   Le trait à gauche remplace l'aplat : sur une page où le navy sert déjà
   deux sections entières, une boîte sombre de plus dans le premier écran
   entrait en concurrence avec le bouton — le seul aplat qui doit attirer. */
.eligible {
  margin: 0;
  padding-left: var(--space-4);
  border-left: 2px solid var(--color-volt);
  font-family: var(--font-util);
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--color-ink-muted);
}
.eligible b { color: var(--color-ink); font-weight: 600; }

/* --- Actions ------------------------------------------------------------ */

/* Un seul bouton depuis le 13 août — « Générer mon devis » est descendu dans
   la section Financement. `flex-wrap` reste : la règle sert aussi le tunnel,
   et elle ne coûte rien tant qu'il n'y a qu'un enfant. */
.actions {
  display: flex;
  flex-wrap: wrap;
  gap: .875rem;
  margin: 0;
}
/* Les deux gestes du premier écran — commander, recevoir un devis — se
   partagent la ligne quand elle est assez large, et s'empilent chacun pleine
   largeur à 390 px : deux boutons de largeur naturelle, l'un sous l'autre et
   alignés à gauche, ne ressemblent plus à un choix. */
.deck .actions .btn,
/* `actions--paire` porte la MÊME intention en bas de page (16 septembre), où les
   deux gestes ont un poids égal. La règle n'est pas élargie à tous les `.actions` :
   la classe sert dans six gabarits — document de devis, merci, annulée, showroom —
   qui n'attendent pas ce comportement. */
.actions--paire .btn { flex: 1 1 12rem; }

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-2);
  min-height: 3.25rem;
  padding: 1rem 1.75rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-util);
  font-size: var(--step-0); font-weight: 600;
  text-align: center; text-decoration: none; cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

/* ⚠️ Le bouton principal devient NAVY, pas bleu. C'est le déplacement le plus
   structurant de la direction : l'accent #2f6fed ne porte plus les boutons,
   il ne sert qu'aux kickers et aux filets. Le navy redevient la couleur de
   l'action, ce qui le rend lisible sur une page devenue claire. */
.btn--primary { background: var(--color-navy); color: #fff; }

.btn--ghost {
  background: transparent;
  color: var(--color-ink);
  border-color: var(--rule-strong);
  font-weight: 600;
}

/* Sur les deux sections navy, le fantôme s'inverse — sinon texte sombre sur
   fond sombre. Une seule classe, deux contextes : un gabarit ne peut pas se
   tromper de variante puisqu'il n'a pas à choisir. */
:is(.band--navy, main > .band:nth-of-type(2n+3)) .btn--ghost { color: #fff; border-color: var(--rule-on-navy); }
:is(.band--navy, main > .band:nth-of-type(2n+3)) .btn--primary { background: #fff; color: var(--color-navy); }

@media (hover: hover) {
  .btn--primary:hover { background: #1a2c44; }        /* valeur de la maquette */
  .btn--ghost:hover   { border-color: var(--color-ink); }
  :is(.band--navy, main > .band:nth-of-type(2n+3)) .btn--primary:hover { background: var(--color-on-navy); }
  :is(.band--navy, main > .band:nth-of-type(2n+3)) .btn--ghost:hover   { border-color: #fff; }
}

/* L'acompte, sur fond clair désormais. */
.deposit {
  margin: 0;
  font-family: var(--font-body);
  font-size: .9375rem;                 /* 15px */
  font-weight: 400;
  color: var(--color-ink-muted);
  line-height: 1.5;
}
.deposit small {
  display: inline;
  font-size: .875rem; font-weight: 400;
  color: var(--color-cool);
  margin: 0;
}

/* ⚠️ Sur navy, `--color-cool` tombe à 2,97 — c'est le dernier défaut relevé
   par l'audit après le lot 3. Un jeton juste, posé sur le mauvais fond : le
   même piège que la mention légale du deck, à l'autre bout de la page. */
:is(.band--navy, main > .band:nth-of-type(2n+3)) .deposit { color: var(--color-on-navy); }
:is(.band--navy, main > .band:nth-of-type(2n+3)) .deposit small { color: var(--color-on-navy-dim); }

/* La section Réservation est CENTRÉE dans la maquette, et elle est la seule.
   Le titre y est plafonné à 20 caractères pour qu'il tienne sur deux lignes
   pleines au lieu d'une ligne longue suivie d'un mot orphelin. */
:is(.band--navy, main > .band:nth-of-type(2n+3)) .band__title,
:is(.band--navy, main > .band:nth-of-type(2n+3)) .band__body { margin-inline: auto; }
#reserver { text-align: center; }
#reserver .eyebrow { justify-content: center; }
#reserver .band__title { max-width: 20ch; }
#reserver .band__body { max-width: 58ch; }
#reserver .actions { justify-content: center; }

/* ⚠️ **Le bouton était collé au texte — 0 px, mesuré le 14 août.** Relevé par
   Jeremy, et l'écart d'APRÈS valait 0 lui aussi : la mention « De 1 à 5 bacs »
   touchait le bas du bouton. Trois blocs empilés sans une respiration, à
   l'endroit exact où le visiteur décide.

   La cause n'est ni `.band__body` ni `.actions` — les deux portent `margin: 0`
   à dessein, et c'est juste : le rythme vertical d'une bande est posé par la
   section qui l'emploie, pas par des marges qui s'additionneraient de bloc en
   bloc. Le deck le fait déjà pour son propre bouton (20 px mesurés).
   `#reserver` ne l'avait jamais fait, parce qu'il est la seule section centrée
   et qu'il a hérité de sa géométrie sans hériter de son espacement.

   Deux valeurs différentes, et volontairement : l'appel à l'action se détache
   de l'argument (2 rem), la mention de service reste rattachée au bouton
   (1,5 rem). Un espacement égal des deux côtés ferait flotter le bouton entre
   deux blocs sans dire auquel il appartient. */
#reserver .actions  { margin-block-start: var(--space-6); }
#reserver .deposit  { margin-block-start: var(--space-5); }

/* Le détail des conditions de subvention, sous le bouton : la réserve
   essentielle reste collée au chiffre, le reste ne s'intercale pas entre
   l'argument et l'action. */
/* ⚠️ Ce bloc portait `--color-on-navy-dim` : un gris conçu pour le navy, qui
   se retrouve sur fond papier maintenant que le deck est clair. Contraste
   mesuré dans cet état : 1,9 — sur une mention légale FIPU. Le passage à une
   dominante claire ne casse pas seulement des couleurs de décor, il rend
   illisibles des textes qui engagent. Cherché sur toute la feuille plutôt
   que corrigé ici seulement. */
.legal {
  margin: 0;
  padding-top: var(--space-4);
  border-top: 1px solid var(--rule);
  font-family: var(--font-util);
  font-size: var(--step--2);
  line-height: 1.5;
  color: var(--color-cool);
}

/* =========================================================================
   GARANTIE — le différenciateur, traité comme tel.
   Le « 5 ans » en encre répond au « 747 € » en bleu du premier écran :
   un grand chiffre de chaque côté de la bascule tonale.
   ========================================================================= */

/* Le « 5 ans » devient le plus gros caractère de la page — 72 px. La mention
   qui le qualifie passe SOUS lui, en serif et en gros, au lieu d'un petit
   libellé en capitales à côté : c'est l'écriture éditoriale de la direction,
   un chiffre puis sa légende, pas une étiquette technique. */
.warranty__figure {
  display: block;
  font-family: var(--font-display);
  font-size: var(--title-xl);
  font-weight: 800;
  letter-spacing: var(--tracking-tight);
  line-height: 1;
  margin: 0 0 .625rem;
}
.warranty__figure span {
  display: block;
  font-family: var(--font-body);
  font-size: var(--step-3);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--color-cool);
  margin-top: .5rem;
}

.warranty__rows {
  margin: 0;
  border-top: 0;
  max-width: none;
}
/* Chaque ligne porte son propre filet supérieur, et la dernière ferme avec un
   filet inférieur — la maquette dessine un tableau, pas une liste bordée. */
.warranty__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-2) var(--space-4);
  padding-block: .875rem;
  border-top: 1px solid var(--rule);
  border-bottom: 0;
}
.warranty__row:last-of-type { border-bottom: 1px solid var(--rule); }
.warranty__row dt {
  font-family: var(--font-util);
  font-size: var(--step-0);
  font-weight: 500;
  color: var(--color-ink);
  margin: 0;
  min-width: 0;
}
/* La précision vit à gauche, avec le terme qu'elle qualifie : à droite, elle
   élargissait la colonne et cassait « Moteur / et / vérins ». */
.warranty__row dt span {
  display: block;
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 400;
  line-height: 1.45;
  color: var(--color-ink-muted);
  margin-top: .3rem;
}
.warranty__row dd {
  font-family: var(--font-util);
  font-size: var(--step-0);
  font-weight: 700;
  color: var(--color-ink);
  text-align: right;
  white-space: nowrap;
  margin: 0;
}
.warranty__note {
  margin-top: var(--space-4);
  font-family: var(--font-util);
  font-size: var(--step--1);
  color: var(--color-cool);
}

/* ⚠️ **LA GARANTIE PORTE SES DEUX JEUX DE COULEURS.** Elle a changé de camp le
   13 août, quand l'ordre des sections a été revu : remontée juste après la
   galerie, elle est tombée sur un rang navy alors que ses couleurs étaient
   écrites pour le papier.

   Mesuré par `contraste.js` : **26 textes sous le seuil, dont « Structure et
   châssis » et les durées à 1,00** — du navy sur du navy. Le tableau de
   garantie, c'est-à-dire l'argument le plus fort de la page, était invisible.

   TROISIÈME occurrence du même défaut dans la même journée : la FAQ ce matin
   quand la galerie s'est remplie, puis la même FAQ quand les Séries sont
   parties, puis celle-ci. La règle du projet est donc à prendre au pied de la
   lettre — **toute section susceptible de changer de rang porte les deux
   jeux**, et on ne le découvre qu'en mesurant. */
:is(.band--navy, main > .band:nth-of-type(2n+3)) .warranty__figure { color: #fff; }
:is(.band--navy, main > .band:nth-of-type(2n+3)) .warranty__figure span { color: var(--color-on-navy-dim); }
:is(.band--navy, main > .band:nth-of-type(2n+3)) .warranty__row,
:is(.band--navy, main > .band:nth-of-type(2n+3)) .warranty__row:last-of-type {
  border-color: var(--rule-on-navy);
}
:is(.band--navy, main > .band:nth-of-type(2n+3)) .warranty__row dt { color: #fff; }
:is(.band--navy, main > .band:nth-of-type(2n+3)) .warranty__row dt span { color: var(--color-on-navy-dim); }
:is(.band--navy, main > .band:nth-of-type(2n+3)) .warranty__row dd { color: #fff; }
:is(.band--navy, main > .band:nth-of-type(2n+3)) .warranty__note { color: var(--color-on-navy-dim); }

/* =========================================================================
   LA PLAQUE SIGNALÉTIQUE
   Décrite au §12 du manuel : plaque inox gravée, fixée à l'arrière de
   l'appareil. C'est l'artefact qui prouve le sérieux mieux qu'une photo —
   donc on la reproduit telle quelle, pas un tableau de caractéristiques.
   ========================================================================= */

/* ⚠️ **LA PLAQUE S'INVERSE.** Elle était une plaque signalétique gravée —
   dégradé sombre, texte blanc, ombre portée intérieure — posée sur un premier
   écran navy. La direction 1a en fait une CARTE BLANCHE bordée, comme la
   planche photo : mêmes angles vifs, même filet d'un pixel.

   C'est la section qui portait à elle seule 18 des 19 défauts relevés par
   l'audit de contraste après la bascule : du blanc sur du blanc, à 1,1. Elle
   ne se corrige pas couleur par couleur, elle se retourne.

   Le dégradé, l'ombre interne et les `text-shadow` disparaissent : la
   direction ne porte AUCUNE ombre décorative. La seule ombre du site est
   désormais celle de l'en-tête, et elle n'est pas décorative — elle marque
   l'arête de la barre là où elle recouvre du contenu clair. Elle a remplacé
   celle du dock, retiré le 13 août. */
.nameplate {
  max-width: none;
  margin-top: 0;
  background: var(--color-surface);
  border: 1px solid var(--rule-firm);
  border-radius: 0;
  padding: clamp(1.5rem, 3vw, 2rem) clamp(1.5rem, 3.5vw, 2.25rem);
  color: var(--color-ink);
  font-family: var(--font-util);
  box-shadow: none;
}
/* Le filet sous l'en-tête est ÉPAIS (2 px) et navy : c'est le seul trait fort
   de la carte, il tient lieu de rivetage. */
.nameplate__head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  padding-bottom: var(--space-4);
  border-bottom: 2px solid var(--color-navy);
}
.nameplate__brand {
  font-family: var(--font-display);
  font-weight: 800; font-size: var(--step-3);
  letter-spacing: var(--tracking-block);
  color: var(--color-ink);
  text-shadow: none;
}
.nameplate__sub {
  display: inline;
  font-family: var(--font-body);
  font-style: italic;
  font-size: var(--step--1); font-weight: 400;
  letter-spacing: 0;
  color: var(--color-cool);
  margin-top: 0;
}
.nameplate__rows { margin: 0; }
.nameplate__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3) var(--space-5);
  padding-block: .6875rem;
  border-bottom: 1px solid rgba(14, 27, 44, .1);
}
.nameplate__row:last-child { border-bottom: 0; }
.nameplate__key {
  font-size: .9375rem; font-weight: 400;
  letter-spacing: 0; text-transform: none;
  color: var(--color-cool);
  margin: 0;
  flex: none;
}
.nameplate__val {
  font-size: .9375rem; font-weight: 600;
  color: var(--color-ink);
  text-shadow: none;
  text-align: right;
  margin: 0;
  min-width: 0;
}
/* Marquages réglementaires + adresse, comme sur une vraie plaque. */
.nameplate__marks {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-4);
  padding-top: var(--space-4);
}
/* ⚠️ **Les pictogrammes étaient BLANCS SUR BLANC.** Contraste 1,0 : invisibles.

   Ils avaient été dessinés pour la plaque gravée sombre — `color: #fff` et une
   ombre portée pour les détacher du navy. La plaque est devenue une carte
   blanche : le trait est resté blanc, l'ombre n'y peut rien.

   Aucun audit de contraste ne l'avait signalé, et pour une raison de fond : un
   SVG ne contient aucun nœud de texte. Un outil qui ne mesure que le texte est
   aveugle aux marques graphiques — or le marquage CE et le pictogramme DEEE
   sont des mentions RÉGLEMENTAIRES. Invisibles, elles ne sont pas apposées.

   `currentColor` plutôt qu'une valeur : le trait suit désormais la couleur du
   conteneur, donc reste juste si la plaque rebascule sur un fond sombre. */
.mark {
  display: block;
  width: auto;
  flex: none;
  color: currentColor;
  filter: none;
}
.mark--ce   { height: 1.5rem; }
.mark--weee { height: 1.5rem; }

.nameplate__foot {
  flex: 1 1 12rem;
  margin: 0;
  font-size: var(--step--2);
  color: var(--color-cool);
  line-height: 1.5;
}

/* =========================================================================
   LES BANDES-IMAGES — la photo bord à bord.

   Demande de Jeremy le 13 août : « il faut que les photos prennent toute la
   largeur ». Mesuré avant : la photo du premier écran faisait **244 px sur un
   écran de 390** — 63 %, avec 105 px de vide à droite — et 416 px sur 1280.
   Les bandes de couleur, elles, étaient déjà pleine largeur : c'était la photo
   qui était timide, pas la section.

   ⚠️ **Aucun `100vw` ici, et c'est délibéré.** C'est la recette habituelle du
   pleine largeur, et elle est fausse : `100vw` compte la barre de défilement,
   donc déborde de ~15 px sur tout navigateur qui en affiche une. Ces figures
   sont simplement placées HORS de `.shell` — le motif qu'employait `.keyspecs`,
   retirée depuis, et qui reste le seul échappement de gouttière du projet —
   le seul motif d'échappement du projet, et il ne coûte rien.

   ⚠️ **Le recadrage n'est pas cosmétique.** Sans lui, une photo carrée en
   pleine largeur ferait 1 920 px de haut sur un grand écran, et le visiteur
   devrait défiler trois écrans pour la dépasser. `aspect-ratio` + `cover`
   imposent la proportion et rognent au lieu d'étirer.
   ========================================================================= */

.bande-image { margin: 0; }

/* La photo du héros vit dans la grille du deck (1er septembre), donc DANS
   `.shell` : en mobile elle s'échappe de la gouttière par marges négatives —
   même pleine largeur qu'avant, sans `100vw` qui compte la barre de
   défilement. Au-delà de 60 rem la grille la reprend (voir plus bas). */
.deck__photo { margin-inline: calc(var(--page-pad) * -1); }

.bande-image__img {
  display: block;
  width: 100%;
  height: auto;
  /* Le fond couvre le temps de chargement : sur une image qui occupe toute la
     largeur, un trou blanc puis un aplat sombre se voit comme un clignotement. */
  background: var(--color-plate);
}

/* ⚠️ Le plafond s'applique à TOUTES les bandes, pas seulement au héros.
   Première version : il était posé sur `.bande-image--hero`, et la bande sans
   modificateur, placée avant la Réservation, s'est retrouvée à **1 920 × 1 071**
   sur un grand écran — un écran entier pour une seule photo, qu'il fallait
   franchir. Un défaut qui ne se voit qu'au-delà de 1 280 px, donc jamais pendant
   qu'on travaille. D'où la règle de base ici, et les variantes ensuite. */
.bande-image__img {
  aspect-ratio: 16 / 9;
  max-height: 72vh;
  object-fit: cover;
  /* Le rognage prend le HAUT, jamais le bas (28 août) : le système de levage
     — la raison d'être du produit — est au pied des bacs. Sur grand écran le
     cadre passe en 21/9 et le plafond 72vh mord encore : sans cet ancrage, le
     socle disparaissait le premier. */
  object-position: 50% 100%;
}

/* Le gros plan du clavier est CARRÉ. En pleine largeur il ferait la hauteur de
   l'écran ; on le rogne en bandeau, ce qui sert d'ailleurs le sujet — c'est un
   détail, pas un plan d'ensemble. */
.bande-image--detail .bande-image__img {
  /* Le clavier est légèrement à droite et sous le centre du cadre d'origine. */
  object-position: 60% 55%;
}

.bande-image__legende {
  margin: 0;
  padding: var(--space-3) var(--page-pad) 0;
  max-width: var(--measure);
  font-family: var(--font-util);
  font-size: var(--step--1);
  color: var(--color-cool);
}

@media (min-width: 60rem) {
  /* Sur grand écran le cadrage s'allonge : une photo d'ambiance y gagne, et la
     page ne se transforme pas en diaporama qu'il faut franchir. */
  .bande-image__img { aspect-ratio: 21 / 9; }
  .bande-image--detail .bande-image__img { aspect-ratio: 24 / 9; }
}

/* =========================================================================
   SECTIONS
   ========================================================================= */

/* Sur une page devenue claire, ce qui sépare deux sections est un FILET, plus
   un aplat. Les sections navy gardent leur fond — elles ne sont plus que deux,
   et c'est ce qui leur donne du poids. */
.band { padding-block: var(--section-y); border-top: 1px solid var(--rule); }
:is(.band--navy, main > .band:nth-of-type(2n+3)) {
  background: var(--color-navy);
  color: var(--color-on-navy-dim);
  border-top-color: transparent;
  padding-block: var(--section-y-navy);
}

/* Le kicker : accent assombri sur clair, bleu doux sur navy. */
.band .eyebrow { color: var(--color-volt-text); }
:is(.band--navy, main > .band:nth-of-type(2n+3)) .eyebrow { color: var(--color-soft-blue); }

.band__title {
  font-size: var(--title-s);
  font-weight: 800;
  letter-spacing: var(--tracking-snug);
  line-height: 1.1;
  margin: var(--space-4) 0 var(--space-5);
  max-width: 22ch;
  text-wrap: balance;
}
:is(.band--navy, main > .band:nth-of-type(2n+3)) .band__title { font-size: var(--title-m); color: #fff; }

.band__body {
  max-width: 56ch;
  font-family: var(--font-body);
  font-size: var(--step-2);
  line-height: 1.6;
  color: var(--color-ink-muted);
}
:is(.band--navy, main > .band:nth-of-type(2n+3)) .band__body { color: var(--color-on-navy-dim); }
.band__body > p + p { margin-top: var(--space-4); }

/* =========================================================================
   LA RÉVÉLATION À L'ENTRÉE — le cachet au défilement.

   Remplace le « magnet » (`scroll-snap`), écarté après mesure. Le calage était
   inapplicable ici pour une raison de géométrie, pas de réglage : **la moitié
   des sections est plus haute que l'écran** (le héros fait 1,87 écran en
   mobile) et le moteur exclut du calage toute section qu'il faut pouvoir
   parcourir. Le magnet n'aurait mordu qu'une section sur deux. Pire, mesuré à
   150 px par cran — le cran d'une souris — la page se bloquait sur la première
   bande et le bas devenait inatteignable, `proximity` se comportant exactement
   comme `mandatory`. Détail des relevés dans `docs/etat-du-projet.md`.

   Ici, rien ne retient le défilement : le contenu s'installe pendant qu'il
   entre. Amplitude courte et cascade discrète — le brief demande « le site
   respire, jamais il ne crie », et met les effets décoratifs aux interdits.

   ⚠️ **Tout est sous `@supports`, et l'état par défaut est VISIBLE.** C'est la
   seule chose vraiment dangereuse dans cette technique : posée sans garde, sur
   un navigateur sans `animation-timeline`, une règle `opacity: 0` d'attente ne
   serait jamais levée et la page s'afficherait VIDE. Ici l'opacité n'est
   jamais écrite hors du bloc ci-dessous : un navigateur qui ne comprend pas la
   règle affiche la page pleine, simplement sans le mouvement.

   Le héros est délibérément épargné — `.band .eyebrow` ne l'atteint pas, son
   kicker vit dans `.buy`. Ce qui est déjà à l'écran au chargement ne se révèle
   pas : on ne fait pas attendre le premier écran.

   Zéro JavaScript, conformément à la doctrine du site public. Le CSP
   (`style-src 'self'`) n'a rien à en dire : c'est une feuille servie.
   ========================================================================= */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .band .eyebrow,
    .band__title,
    .band__body {
      animation: entree-bande linear both;
      animation-timeline: view();
    }

    /* La cascade : l'intitulé, puis le titre, puis le corps.

       ⚠️ **Bornes en `cover`, et c'est une correction mesurée.** Écrites en
       `entry`, elles duraient la HAUTEUR DE L'ÉLÉMENT — 80 px pour un titre,
       soit une révélation expédiée en 140 px de défilement : un clignotement,
       pas une respiration. La plage `cover` s'étale sur la hauteur de l'écran
       PLUS celle de l'élément, donc environ 900 px : le mouvement a le temps
       d'exister.

       Les bornes hautes restent basses (≤ 38 %) délibérément. Une borne tardive
       n'est pas atteignable par la DERNIÈRE section de la page — elle ne sort
       jamais par le haut, faute de défilement restant — et le texte resterait
       définitivement à mi-opacité. Un texte à moitié transparent est un défaut
       de lisibilité, pas un effet. Un test vérifie que chacun atteint 1. */
    .band .eyebrow { animation-range: cover  4% cover 26%; }
    .band__title   { animation-range: cover  8% cover 32%; }
    .band__body    { animation-range: cover 12% cover 38%; }
  }
}

@keyframes entree-bande {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

/* --- Le parcours : un vrai enchaînement, donc numéroté ------------------- */

/* ⚠️ Le parcours FIPU devient une GRILLE DE CARTES, pas une liste bordée.
   La maquette en fait quatre pavés `#132438` posés sur le navy, chacun ouvert
   par son numéro en bleu doux. C'est le seul endroit du site où le numéro
   d'étape est mis en avant — et il le mérite : les quatre étapes sont un vrai
   enchaînement daté, pas une énumération décorative. */
.path {
  list-style: none;
  margin: var(--space-6) 0 0;
  padding: 0;
  border-top: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13.75rem), 1fr));
  gap: 1.25rem;
}
.path li {
  display: block;
  padding: 1.5rem;
  background: var(--color-navy-card);
  border: 1px solid var(--rule-on-navy);
  border-bottom: 1px solid var(--rule-on-navy);
}
.path__step {
  display: block;
  font-family: var(--font-display);
  font-size: 1.625rem; font-weight: 800;
  letter-spacing: 0;
  line-height: 1;
  color: var(--color-soft-blue);
  padding-top: 0;
}
.path__what {
  display: block;
  font-family: var(--font-util);
  font-size: var(--step-2); font-weight: 700;
  color: #fff;
  margin: .625rem 0 .375rem;
}
.path__why {
  display: block;
  font-family: var(--font-body);
  font-size: .875rem;
  line-height: 1.55;
  color: var(--color-on-navy-dim);
  margin-top: 0;
}

/* L'avertissement sur le crédit : filet bleu doux et fond légèrement éclairci,
   sur navy. C'est l'information qui évite une erreur irréversible — un achat
   à crédit ferme la porte du FIPU tant qu'il n'est pas soldé. */
.notice {
  margin-top: 1.75rem;
  padding: 1.25rem 1.5rem;
  border-left: 3px solid var(--color-soft-blue);
  background: rgba(255, 255, 255, .06);
  font-family: var(--font-body);
  font-size: .9375rem;
  line-height: 1.6;
  color: var(--color-on-navy-dim);
  max-width: 72ch;
}
.notice b { font-family: var(--font-util); color: var(--color-ink); font-weight: 600; }
/* L encart existe dans les DEUX contextes : prerequis sur clair, credit sur
   navy. Un `color: #fff` global rendait le premier invisible — ratio 1,0. */
:is(.band--navy, main > .band:nth-of-type(2n+3)) .notice b { color: #fff; }
.band:not(:is(.band--navy, main > .band:nth-of-type(2n+3))) .notice {
  border-left-color: var(--color-navy);
  background: var(--color-plate);
  color: var(--color-ink-muted);
}

/* --- Séries : RETIRÉES du site public le 13 août 2026 -------------------
   Elles restent le mécanisme interne — affectation des commandes, garde-fou
   de capacité, jauges d'administration — mais ne s'affichent plus. Leurs
   règles partent avec elles plutôt que de peser sur chaque visite.
   `produit/series.php` est conservé sans être requis : le jour où
   l'arbitrage s'inverse, ces règles se reprennent dans l'historique. */

/* =========================================================================
   CTA PERMANENT (mobile) — RETIRÉ le 13 août 2026

   Le §5.8 du brief le demandait ; Jeremy l'a tranché en sens inverse après
   l'avoir vu à l'écran, en connaissance de la contrepartie : plus aucun
   bouton sous la main entre le héros et la section Réservation, sur une page
   de 7 775 px en mobile.

   Il n'était affiché QU'EN MOBILE (masqué dès 60 rem) : le retirer là le
   retirait donc du site entier. Ses règles partent avec lui plutôt que de
   rester à peser sur chaque visite. Le partial `produit/dock.php` avait été
   conservé « au cas où » ; le dock est revenu le 1er septembre sous condition
   (caché sur le premier écran), puis retiré pour de bon le 10 septembre avec
   ses fichiers — le premier écran porte deux gestes, commander et recevoir
   un devis, et l'en-tête collante fait le reste.
   ========================================================================= */

/* --- Lien d'évitement ---------------------------------------------------- */
/* Invisible tant qu'il n'a pas le focus, mais présent dans le document : un
   utilisateur au clavier saute l'en-tête, les autres ne le voient jamais.
   `clip-path` plutôt que `display:none`, qui le retirerait aussi du parcours. */

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--color-volt);
  color: #fff;
  font-family: var(--font-util);
  font-size: var(--step--1);
  font-weight: 600;
  padding: var(--space-3) var(--space-4);
  text-decoration: none;
}
.skip:focus { left: 0; }

/* --- FAQ : <details> natif, aucun script -------------------------------- */
/* Fonctionne sans JavaScript — donc aussi quand un script est bloqué ou mal
   déployé — et reste accessible au clavier par construction. */

.faq { display: grid; gap: var(--space-7); }

.faq__cat {
  margin: 0 0 var(--space-3);
  font-family: var(--font-util);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-ink-muted);
}

.faq__item { border-top: 1px solid var(--rule); }
.faq__item:last-child { border-bottom: 1px solid var(--rule); }

.faq__q {
  display: flex;
  align-items: baseline;
  gap: var(--space-4);
  padding: var(--space-4) 0;
  cursor: pointer;
  font-family: var(--font-util);
  font-size: var(--step-1);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0;
  color: var(--color-ink);
  list-style: none;          /* Firefox */
}
.faq__q::-webkit-details-marker { display: none; }

/* Le signe est en ::after et non dans le balisage : un lecteur d'écran annonce
   déjà l'état plié ou déplié du <details>, il n'a pas besoin d'entendre « + ». */
.faq__q::after {
  content: "+";
  margin-left: auto;
  font-family: var(--font-util);
  font-size: 1.25rem;
  font-weight: 400;
  line-height: 1;
  color: var(--color-volt-text);
  transition: color .15s ease;
}
.faq__item[open] .faq__q::after { content: "−"; }
.faq__q:hover::after { color: var(--color-ink); }
.faq { max-width: 51rem; }   /* 820 px — largeur de la maquette */

.faq__a {
  padding: 0 var(--space-7) var(--space-5) 0;
  max-width: var(--measure);
  color: var(--color-ink-muted);
}

/* ⚠️ **LA FAQ PORTE SES DEUX JEUX DE COULEURS**, et ce n'est pas une précaution
   théorique : elle a changé de camp le 13 août, à la minute où la galerie s'est
   remplie.

   L'alternance se calcule par le RANG — `main > .band:nth-of-type(2n+3)`. La
   galerie est une section CONDITIONNELLE : vide, elle ne se rend pas et la FAQ
   tombe sur un rang clair ; remplie, elle décale tout d'un cran et la FAQ passe
   sur navy. Ses couleurs étaient écrites pour le papier seul.

   Le résultat, mesuré par `tests/outils/contraste.js` : **trente-huit textes
   au-dessous du seuil, dont les questions à 1,00** — du navy sur du navy,
   c'est-à-dire des questions parfaitement invisibles. Rien dans la feuille
   n'était « faux » : chaque jeton était juste, sur un fond qui avait changé.

   C'est la règle acquise du projet appliquée à la lettre : toute section
   susceptible de changer de camp doit porter les deux jeux. */
:is(.band--navy, main > .band:nth-of-type(2n+3)) .faq__cat { color: var(--color-soft-blue); }
:is(.band--navy, main > .band:nth-of-type(2n+3)) .faq__q { color: #fff; }
:is(.band--navy, main > .band:nth-of-type(2n+3)) .faq__a { color: var(--color-on-navy-dim); }
:is(.band--navy, main > .band:nth-of-type(2n+3)) .faq__item,
:is(.band--navy, main > .band:nth-of-type(2n+3)) .faq__item:last-child {
  border-color: var(--rule-on-navy);
}
:is(.band--navy, main > .band:nth-of-type(2n+3)) .faq__q::after { color: var(--color-soft-blue); }
:is(.band--navy, main > .band:nth-of-type(2n+3)) .faq__q:hover::after { color: #fff; }

/* --- Galerie ------------------------------------------------------------- */
/* Remplie le 13 août par la migration 016 : sept angles du LIBI LIFT. La
   section reste conditionnelle — vider `media` la fait disparaître. */

/* Depuis le 8 septembre la galerie mélange paysages (3:2) et portraits (2:3) du
   shooting Baptiste, et Jeremy ne veut NI recadrage NI rail horizontal : chaque
   photo entière, coins arrondis, défilement vers le bas.

   Une grille de QUATRE cases par rangée : un portrait prend une case, un paysage
   deux (`.gallery__item--paysage`, posée par galerie.php d'après width/height).
   Ainsi une rangée fait toujours la hauteur d'un portrait, et le paysage —
   légèrement moins haut sur deux cases (1,33 contre 1,5) — laisse 12 % de fond
   papier sous lui, invisible sur le fond de la page. L'ordre reste celui de la
   lecture, ligne par ligne. Première version en colonnes CSS écartée le même
   jour : le navigateur mettait 2 photos à gauche, 3 et 3 ailleurs — 570 px de
   trou sous la première colonne, relevé par le marcheur.

   Une colonne au téléphone ; deux cases entre 45 em et 60 rem (le paysage y est
   pleine largeur) ; quatre ensuite. */
.gallery {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  align-items: start;
}
.gallery__item { margin: 0; min-width: 0; }
.gallery__item img,
.gallery__item video {
  display: block;
  width: 100%;
  height: auto;
  background: var(--color-plate);
  border-radius: 14px;   /* demandé le 8 septembre — les cartes du site restent vives */
}
@media (min-width: 45em) {
  .gallery { grid-template-columns: repeat(2, 1fr); grid-auto-flow: dense; }
  .gallery__item--paysage { grid-column: span 2; }
}
@media (min-width: 60rem) {
  .gallery { grid-template-columns: repeat(4, 1fr); }
}
.gallery__item figcaption {
  margin-top: var(--space-2);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

/* --- Téléchargements ----------------------------------------------------- */

.downloads { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--rule); }
.downloads__item { border-bottom: 1px solid var(--rule); padding: var(--space-4) 0; }

.downloads__link {
  display: flex;
  align-items: baseline;
  gap: var(--space-4);
  color: inherit;
  text-decoration: none;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 500;
}
.downloads__link:hover .downloads__label { text-decoration: underline; }
/* Le poids à droite, en chiffres alignés : sur mobile, un document de 12 Mo
   ne se télécharge pas dans les mêmes conditions qu'un de 200 Ko. */
.downloads__meta {
  margin-left: auto;
  font-family: var(--font-util);
  font-size: var(--step--2);
  font-variant-numeric: tabular-nums;
  color: var(--color-ink-muted);
  white-space: nowrap;
}
.downloads__desc {
  margin: var(--space-2) 0 0;
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  max-width: var(--measure);
}

/* --- Pied de page -------------------------------------------------------- */

/* Le pied passe au clair lui aussi. La maquette le réduit à une ligne : logo à
   gauche, liens à droite, sans aplat. La section Réservation, juste au-dessus,
   est déjà navy — deux blocs sombres qui se suivent n'auraient fait qu'une
   grande zone sombre, et la Réservation y aurait perdu son relief. */
.site-foot {
  background: var(--color-paper);
  color: var(--color-cool);
  border-top: 1px solid var(--rule);
  padding-block: var(--space-6);
}
.site-foot__inner { display: grid; gap: var(--space-5); }

/* Le pied garde une plaque plus discrète — 26 px, valeur de la maquette —
   pour que l'en-tête reste le point d'entrée de la marque. */
.site-foot .wordmark__block { font-size: .9375rem; }   /* 15 × 1,68 ≈ 26 px */

.site-foot__by {
  margin: var(--space-4) 0 0;
  font-family: var(--font-util);
  font-size: var(--step--1);
  color: var(--color-cool);
  max-width: 34ch;
}

.site-foot__nav { display: grid; gap: var(--space-3); }
.site-foot__nav a,
.site-foot__contact a {
  color: var(--color-cool);
  text-decoration: none;
  font-family: var(--font-util);
  font-size: var(--step--1);
  font-weight: 400;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 2px;
  justify-self: start;
  transition: color .15s ease, border-color .15s ease;
}
.site-foot__nav a:hover,
.site-foot__contact a:hover { color: var(--color-volt-text); border-bottom-color: currentColor; }

.site-foot__contact { display: grid; gap: var(--space-3); }

.site-foot__pro {
  margin: 0;
  padding-top: var(--space-5);
  border-top: 1px solid var(--rule);
  font-family: var(--font-util);
  font-size: var(--step--2);
  letter-spacing: .04em;
  color: var(--color-cool);
}

/* --- Pages légales ------------------------------------------------------- */
/* Un texte légal illisible ne protège personne : il se survole, et une clause
   qu'on n'a pas lue se conteste. D'où une colonne étroite, un interlignage
   généreux et une hiérarchie nette — le même soin que sur une page qui vend. */

.legal { padding-block: var(--space-7) var(--space-9); }
.legal__inner { max-width: 42rem; }

.legal__title {
  margin: var(--space-2) 0 var(--space-5);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--title-s);
  letter-spacing: var(--tracking-tight);
  line-height: 1.15;
  text-wrap: balance;
}

.legal__lede {
  margin: 0 0 var(--space-7);
  padding-bottom: var(--space-6);
  border-bottom: 1px solid var(--rule);
  font-size: var(--step-1);
  color: var(--color-ink-muted);
}

.legal h2 {
  margin: var(--space-7) 0 var(--space-3);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-2);
  letter-spacing: var(--tracking-tight);
  line-height: 1.25;
}

.legal p { margin: 0 0 var(--space-4); max-width: var(--measure); }
.legal ul { margin: 0 0 var(--space-4); padding-left: 1.2em; max-width: var(--measure); }
.legal li { margin-bottom: var(--space-2); }

/* Le paragraphe qui porte l'engagement le plus lourd — l'acompte ferme — est
   signalé par un filet. Une clause décisive noyée dans le corps du texte est
   une clause qu'on pourra dire n'avoir pas vue. */
.legal__strong {
  padding: var(--space-4) var(--space-5);
  border-left: 3px solid var(--color-volt);
  background: var(--color-plate);
}

.legal__rows { margin: 0 0 var(--space-5); border-top: 1px solid var(--rule); }
.legal__rows > div {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  justify-content: space-between;
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--rule);
}
.legal__rows dt {
  font-family: var(--font-util);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-ink-muted);
}
.legal__rows dd { margin: 0; font-size: var(--step--1); text-align: right; }

/* Variante pour les blocs RGPD : la définition est un paragraphe, pas une
   valeur — elle a besoin de toute la largeur et d'un alignement à gauche. */
.legal__rows--wide > div { display: block; }
.legal__rows--wide dd { text-align: left; margin-top: var(--space-2); max-width: var(--measure); }

.legal__nowrap { white-space: nowrap; }

.legal__revision {
  margin-top: var(--space-8);
  padding-top: var(--space-4);
  border-top: 1px solid var(--rule);
  font-family: var(--font-util);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

/* =========================================================================
   DESKTOP — déclinaison
   ========================================================================= */

@media (min-width: 60rem) {
  .deck { padding-block: clamp(2rem, 5vw, 4rem) var(--section-y); }

  /* ⚠️ La grille du deck passe en `auto-fit` avec deux colonnes de poids
     comparable, comme la maquette : la photo n'est plus une vignette étroite
     à côté d'un long texte, elle tient la moitié de l'écran. Le `sticky` de
     la planche est retiré — la maquette aligne les deux colonnes en haut et
     les laisse défiler ensemble. */
  /* ⚠️ **Le héro est INVERSÉ par rapport au balisage** : le prototype 1a met
     le texte à GAUCHE et la photo à DROITE. C'est sa composition la plus
     reconnaissable — on lit le discours avant de voir l'objet.

     Fait en CSS, par `order`, plutôt qu'en déplaçant les blocs dans le
     gabarit : sur téléphone la grille repasse à une colonne et c'est alors la
     PHOTO qu'on veut voir en premier, avant de faire défiler. Un ordre inversé
     dans le HTML donnerait le bon rendu en bureau et le mauvais en mobile.
     L'ordre du document reste aussi celui que lit un lecteur d'écran. */
  /* ⚠️ **Le premier écran respire plus large que le reste du site** — 17 septembre.
     Relevé par Jeremy : « en plein écran sur ordi la photo reste petite ». Mesuré :
     la bande de contenu est plafonnée à 1280 px (`--content-max`, « la maquette
     cadre à 1280 px »), donc la photo restait figée à 536 px pendant que l'écran
     grandissait — 42 % de la largeur à 1280, et 21 % seulement à 2560.

     Le plafond GLOBAL n'est pas touché : une ligne de texte plus longue se lit
     moins bien, et les sections d'en dessous gardent le cadre de la maquette.
     Seul le deck s'élargit, et tout le surplus va à la photo — la colonne de
     texte est bornée à 28 rem — 448 px, environ soixante caractères, la bonne
     longueur de lecture — pour que tout le reste aille à la photo. Les proportions
     1.05/0.95 du prototype tenaient tant que la bande faisait 1280 ; au-delà
     elles figeaient les deux colonnes ensemble. */
  .deck .shell { max-width: 100rem; }

  .deck__grid {
    display: grid;
    grid-template-columns: minmax(18rem, 28rem) 1fr;
    gap: var(--gap-cols);
    /* `stretch` depuis que la colonne droite est la PHOTO (1er septembre) :
       elle remplit la hauteur que le bloc d'achat impose, au lieu de flotter
       dans un vide. La carte produit d'avant le 13 août préférait `start`. */
    align-items: stretch;
  }
  .deck__grid .buy { order: 1; }
  /* La photo du héros, colonne droite : elle reprend sa place de la maquette
     (texte à gauche, photo à droite). L'échappement de gouttière mobile est
     annulé et l'image garde ses PROPORTIONS NATURELLES, centrée dans la
     colonne — demande de Jeremy du 1er septembre : les deux bacs se voient
     en entier, aucun rognage. Le cadre 21/9 des bandes ne s'applique pas
     ici, il couperait un bac. */
  .deck__grid .deck__photo { order: 2; margin: 0; align-self: center; }
  .deck__grid .deck__photo .bande-image__img {
    width: 100%;
    height: auto;
    aspect-ratio: auto;
    max-height: none;
    object-fit: contain;
  }

  .band { padding-block: var(--space-10); }

  /* L'en-tête REDEVIENT collante ici, et seulement ici : au-delà de 60 rem la
     hauteur n'est plus une ressource rare, et une barre persistante est ce
     qu'on attend d'un grand écran. En mobile elle défile avec la page. */
  .masthead { position: sticky; top: 0; z-index: 20; }

  /* La FAQ en deux colonnes : une quinzaine de questions sur une seule colonne
     oblige à défiler pour rien sur un grand écran. Les groupes ne se coupent
     pas en deux — chaque catégorie reste d'un bloc. */
  .faq {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-8) var(--space-7);
    align-items: start;
  }

  .site-foot__inner {
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-7);
  }
  .site-foot__pro { grid-column: 1 / -1; }

  /* Les boutons ont été calibrés pour la colonne étroite du premier écran, où
     ils occupent toute la largeur à raison. Dans une section pleine largeur —
     showroom, réservation — un bouton de 1 100 px de long ne ressemble plus à
     un bouton. Ils reprennent leur taille naturelle. */
  .band .actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3) var(--space-4);
  }
  .band .actions .btn { flex: 0 0 auto; min-width: 14rem; }
}

/* ========================================================================= */

/* =========================================================================
   IMPRESSION — les pages légales finissent en PDF
   =========================================================================
   Des CGV se lisent, se signent et s'archivent sur papier ou en PDF. Une
   version imprimée qui embarque la barre de navigation, le bouton flottant et
   le menu du pied de page n'est pas un document contractuel, c'est une capture
   d'écran. Ces règles servent autant à Jeremy pour faire relire le texte qu'au
   client qui voudra le classer. */

@media print {
  /* Ce qui n'a aucun sens sur un document : navigation, appels à l'action. */
  .masthead, .skip, .site-foot__nav, .site-foot__contact,
  .actions, .faq__q::after { display: none !important; }

  /* Les couleurs sont posées ÉLÉMENT PAR ÉLÉMENT, et non par héritage depuis
     body. Le navy de la charte (#0E1B2C) ressort gris-bleu à l'impression :
     élégant à l'écran, pénible sur un document qu'on relit clause par clause et
     qu'on annote. Un contrat s'imprime en noir. */
  body,
  .legal, .legal h1, .legal h2, .legal p, .legal li,
  .legal dt, .legal dd, .legal a, .legal b, .legal strong {
    color: #000 !important;
    background: #fff;
  }

  body { font-size: 10.5pt; line-height: 1.5; }

  /* Les mentions secondaires restent lisibles sans concurrencer le corps. */
  .legal__lede, .legal__revision, .legal__rows dt { color: #333 !important; }

  .legal { padding: 0; }
  .legal__inner { max-width: none; }
  .legal p, .legal ul, .legal__rows dd, .legal__lede { max-width: none; }

  /* Un titre seul en bas de page, séparé de sa clause, rend le document
     pénible à relire — et c'est exactement ce qu'on demande à Jeremy de faire. */
  .legal h2 { break-after: avoid; page-break-after: avoid; margin-top: 14pt; }
  .legal__strong, .legal__rows > div { break-inside: avoid; page-break-inside: avoid; }

  /* L'encadré de la clause d'acompte doit rester visible en noir et blanc :
     un aplat de couleur disparaît sur une imprimante laser. */
  .legal__strong { background: none; border-left: 2pt solid #000; padding-left: 10pt; }

  .eyebrow::before { display: none; }
  .eyebrow { color: #000; }

  /* L'adresse des liens, en clair : un PDF ne se clique pas toujours. */
  .legal a[href^="http"]::after,
  .legal a[href^="mailto"]::after { content: " (" attr(href) ")"; font-size: 9pt; }

  /* Le pied de page reste — il identifie l'éditeur, ce qu'un document
     contractuel doit porter. Mais ses marges généreuses d'écran produisaient
     une page blanche supplémentaire : elles tombent à zéro. */
  .site-foot {
    background: none; color: #000;
    border-top: 1pt solid #000;
    padding: 10pt 0 0;
    margin: 0;
    break-inside: avoid;
  }
  .site-foot__inner { display: block; gap: 0; }
  .site-foot .wordmark__block { background: none; color: #000; padding: 0; }
  .site-foot__by, .site-foot__pro { margin: 4pt 0 0; padding: 0; border: 0; color: #333 !important; }

  @page { margin: 18mm 16mm; }
}

@media (prefers-reduced-motion: reduce) {
  .scale__rule { animation: none; transform: scaleY(1); }
  .scale__rule::before, .scale__rule::after {
    animation: none; opacity: 1; transform: translateX(-50%);
  }
  * { transition-duration: .01ms !important; }
}

/* =========================================================================
   EXPÉDITION — la page du logisticien (§7.7)
   Ouverte sur un téléphone, sur un quai : deux blocs, deux boutons. Elle vit
   hors du rythme des bandes — fond papier, largeur de lecture.
   ========================================================================= */
.page--expedition { background: var(--color-paper); }
.expedition { max-width: 34rem; padding-block: var(--space-7); }
.expedition__tete { margin-bottom: var(--space-6); }
.expedition__tete p { color: var(--color-ink-muted); line-height: 1.6; }
.expedition__tete b { color: var(--color-ink); }
.expedition__bloc {
  background: #fff;
  border: 1px solid var(--rule);
  padding: var(--space-5);
  margin-bottom: var(--space-5);
}
.expedition__bloc h2 { margin: 0 0 var(--space-4); font-size: var(--step-1); }
.expedition .alert {
  margin: 0 0 var(--space-5);
  padding: var(--space-3) var(--space-4);
  border-left: 3px solid #B4232A;
  background: #FBEDED;
  color: #7A1319;
}

/* =========================================================================
   DISTRIBUTEUR — la page de candidature (§5). Aucune promesse chiffrée :
   la page dit le cadre, le formulaire demande le terrain, rien d'autre.
   ========================================================================= */
.band__lead {
  max-width: var(--measure);
  color: var(--color-ink-muted);
  line-height: 1.65;
}
.points {
  margin: var(--space-5) 0 0;
  padding: 0;
  list-style: none;
  max-width: var(--measure);
}
.points li {
  position: relative;
  padding: var(--space-3) 0 var(--space-3) var(--space-5);
  border-bottom: 1px solid var(--rule);
  color: var(--color-ink-muted);
  line-height: 1.55;
}
.points li:last-child { border-bottom: 0; }
.points li::before {
  content: "";
  position: absolute;
  left: 0; top: 1.15em;
  width: .55rem; height: 2px;
  background: var(--color-volt);
}
.points b { color: var(--color-ink); }
.candidature { max-width: 34rem; margin-top: var(--space-5); }
.candidature .btn { margin-top: var(--space-4); }
.page--distributeur .alert {
  margin: 0 0 var(--space-5);
  padding: var(--space-3) var(--space-4);
  border-left: 3px solid #B4232A;
  background: #FBEDED;
  color: #7A1319;
  max-width: var(--measure);
}

/* --- Fenêtre de consentement (6 septembre, centrée le 10) -------------------
   `hidden` (posé par le gabarit, retiré par consent.js) prime sur `display` :
   sans cette règle, la fenêtre clignoterait avant que le script ne décide.
   Un voile plein écran, une carte au centre : la réponse se donne sur la page
   d'arrivée, avant que le visiteur bouge (l'attribution se lit à ce moment).
   Pas de verrou du défilement : le voile suffit, et `overflow: hidden` sur
   `body` casse la restitution du défilement sur iOS. */
#nq-consent[hidden] { display: none; }

.consent {
  position: fixed; inset: 0; z-index: 1000;
  display: grid; place-items: center;
  padding: var(--space-5);
  background: rgba(14, 27, 44, .58);
}
.consent__card {
  width: 100%; max-width: 24rem;
  padding: var(--space-6) var(--space-5);
  background: #fff; color: var(--color-ink);
  border-radius: var(--radius);
  box-shadow: 0 24px 64px rgba(14, 27, 44, .35);
}
.consent__title {
  margin: 0 0 var(--space-3);
  font-family: var(--font-display);
  font-size: var(--step-2);
  line-height: 1.1;
  color: var(--color-navy);
}
.consent__text {
  margin: 0 0 var(--space-5);
  font-family: var(--font-util); font-size: var(--step--1);
  line-height: 1.5; color: var(--color-ink);
}
.consent__lien { color: var(--color-navy); text-decoration: underline; white-space: nowrap; }

/* Deux vrais boutons, même taille, même texte en gras, l'un sous l'autre :
   accepter dans la couleur de la marque, refuser à bordure. Refuser doit
   rester aussi simple qu'accepter — un clic, le même écran, la même
   surface — mais rien n'oblige à le peindre de la même couleur. */
.consent__actions { display: grid; gap: var(--space-3); }
.consent__btn { width: 100%; min-height: 3rem; padding: .8rem 1.2rem; }
.consent .btn--ghost { border-color: var(--color-navy); color: var(--color-navy); }

/* =========================================================================
   SIMULATION D'AIDE — la fenêtre du bouton en tête (10 septembre)
   Un voile, une carte, cinq chiffres et trois lignes. Le vert ne sert qu'à
   une chose sur tout le site : l'argent que le salon ne paiera pas.
   Angles vifs : la charte réserve le rayon aux boutons.
   ========================================================================= */
#nq-simu[hidden] { display: none; }

.simu {
  position: fixed; inset: 0; z-index: 1000;
  display: grid; place-items: center;
  padding: var(--space-5);
  background: rgba(14, 27, 44, .58);
  overflow-y: auto;
}
.simu__card {
  position: relative;
  width: 100%; max-width: 27rem;
  padding: var(--space-6) var(--space-5) var(--space-5);
  background: #fff;
  border: 1px solid var(--rule);
  box-shadow: 0 24px 64px rgba(14, 27, 44, .35);
}
.simu__close {
  position: absolute; top: .35rem; right: .35rem;
  width: 2.75rem; height: 2.75rem;
  display: grid; place-items: center;
  border: 0; background: transparent; cursor: pointer;
  font-family: var(--font-util); font-size: 1.6rem; line-height: 1;
  color: var(--color-cool);
}
.simu__close:hover { color: var(--color-ink); }
.simu__close:focus-visible { outline: 2px solid var(--color-volt); outline-offset: -2px; }

.simu__eyebrow {
  margin: 0 0 .35rem;
  font-family: var(--font-util); font-size: var(--step--2); font-weight: 600;
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
  color: var(--color-cool);
}
.simu__title {
  margin: 0 0 var(--space-5);
  font-family: var(--font-display); font-size: var(--step-3); line-height: 1.05;
  color: var(--color-ink);
}

.simu__field { border: 0; padding: 0; margin: 0 0 var(--space-5); }
.simu__legend {
  padding: 0; margin: 0 0 .6rem;
  font-family: var(--font-util); font-size: var(--step--1); font-weight: 600;
  color: var(--color-ink);
}
.simu__chips { display: grid; grid-template-columns: repeat(5, 1fr); gap: .5rem; }
.simu__chip {
  display: grid; place-items: center;
  min-height: 3rem;
  border: 1px solid var(--rule-strong);
  background: #fff; cursor: pointer;
  font-family: var(--font-display); font-size: var(--step-1); font-weight: 700;
  color: var(--color-ink);
  transition: border-color .15s var(--ease), background-color .15s var(--ease);
}
.simu__input:checked + .simu__chip {
  background: var(--color-navy); border-color: var(--color-navy); color: #fff;
}
.simu__input:focus-visible + .simu__chip { outline: 2px solid var(--color-volt); outline-offset: 2px; }

/* Trois lignes, et la deuxième porte tout le message. */
.simu__ligne {
  display: grid; grid-template-columns: 1fr auto;
  gap: var(--space-4);
  align-items: baseline;
  padding: .7rem 0;
  border-top: 1px solid var(--rule);
  font-family: var(--font-util); font-size: var(--step--1);
  color: var(--color-cool);
}
.simu__ligne small {
  display: block; margin-top: .15rem;
  font-size: var(--step--2); line-height: 1.35; color: var(--color-cool);
}
.simu__montant { font-family: var(--font-util); font-weight: 600; color: var(--color-ink); white-space: nowrap; }

.simu__ligne--aide { align-items: center; }
.simu__ligne--aide > span:first-child { color: var(--color-ink); font-weight: 600; }
.simu__aide {
  font-family: var(--font-display); font-size: var(--step-2); font-weight: 700;
  line-height: 1; color: var(--color-aide); white-space: nowrap;
}

.simu__ligne--reste {
  border-top: 2px solid var(--color-navy);
  padding-top: .8rem;
  font-size: var(--step-0); color: var(--color-ink);
}
.simu__ligne--reste > span:first-child { font-weight: 700; }
.simu__ligne--reste .simu__montant { font-family: var(--font-display); font-size: var(--step-1); }

.simu__note {
  margin: var(--space-4) 0 var(--space-5);
  font-family: var(--font-util); font-size: var(--step--2); line-height: 1.5;
  color: var(--color-cool);
}
.simu__cta { width: 100%; }
