/* ══════════════════════════════════════════════════════════════════════
   RX Counotte — feuille de style.

   Les jetons sont nommés par leur RÔLE (--fond, --texte, --accent), jamais
   par leur pigment. Les couleurs de marque n'alimentent que les jetons :
   aucune règle ne les emploie directement, si bien qu'une couleur peut
   changer — depuis l'administration — sans relire cette feuille.

   Les sections claires et sombres redéfinissent LES MÊMES jetons : un
   composant s'écrit une fois et fonctionne des deux côtés.
   ══════════════════════════════════════════════════════════════════════ */

:root {
  /* Les pigments de la marque, relevés dans le logo. Ils n'alimentent que
     les jetons ci-dessous — ne jamais les employer directement. */
  --p-anthracite: #0f1622;   /* l'anthracite du logo, TEINTÉ DE BLEU :
                                 sur un gris neutre, l'accent n'est qu'un
                                 liseré perdu — mesuré à 1,9 % du premier
                                 écran avant cette correction */
  --p-encre:      #0a1018;   /* le plus profond : pieds de page, voiles  */
  /* DEUX bleus, deux rôles distincts — c'est le dosage qui fait la
     différence, pas la teinte seule. L'électrique #013bff est celui du
     logo à l'écran : très saturé, il crie dès qu'il couvre une grande
     surface. Le marine est celui du logo IMPRIMÉ, sur leur carte de
     visite : c'est LUI qui porte les aplats.
       électrique → boutons, filets, liens, petits accents
       marine     → voiles, aplats, grandes surfaces */
  /* UN SEUL bleu, celui du logo IMPRIMÉ, relevé au pixel sur le cadre.
     L'électrique #013bff — la version écran du logo — est trop vif dès
     qu'il couvre les boutons de tout un site : il crie au lieu de guider.
     Il ne subsiste nulle part. */
  --p-bleu:        #084596;
  --p-bleu-surface:#084596;
  --p-bleu-clair:  #7ba4e8;   /* la variante lisible sur fond sombre */
  --p-blanc:      #ffffff;

  /* Les rôles, en clair (le réglage par défaut d'une section). */
  --fond:          var(--p-blanc);
  --fond-doux:     #eef2f8;   /* le fond clair porte lui aussi la teinte */
  --fond-carte:    var(--p-blanc);
  --texte:         var(--p-anthracite);
  --texte-doux:    #56636d;
  --texte-faible:  #626e78;   /* 4,6:1 sur le fond doux — #7d8892 tombait à 3,3 */
  --accent:        var(--p-bleu);
  --accent-lisible: var(--p-bleu);      /* la variante qui reste lisible sur le fond courant */
  --accent-texte:  var(--p-blanc);      /* le texte POSÉ SUR l'accent — un réglage, pas une constante */
  --lisere:        rgba(19, 25, 29, .12);
  --lisere-fort:   rgba(19, 25, 29, .22);
  --ombre:         0 1px 2px rgba(19, 25, 29, .05), 0 8px 24px rgba(19, 25, 29, .07);
  --ombre-forte:   0 2px 6px rgba(19, 25, 29, .09), 0 18px 48px rgba(19, 25, 29, .13);

  /* Rythme. Le rapport qui tient : héros 6rem, section 4,4rem, carte 2,3rem.
     Un titre de section timide face à un héros fait s'affaisser la page dès
     qu'on quitte le haut. */
  --t-hero:    clamp(2.25rem, 4.6vw, 4.7rem);
  --t-section: clamp(1.95rem, 3.9vw, 3.9rem);
  --t-carte:   clamp(1.2rem, 1.5vw, 1.45rem);
  --t-chapo:   clamp(1.04rem, 1.2vw, 1.25rem);

  --large:  1440px;
  --marge:  clamp(1.15rem, 4vw, 3.5rem);
  --section-y: clamp(4.5rem, 8vw, 8.5rem);
  --rayon:  14px;
  --rayon-s: 9px;

  /* Deux largeurs d'un même registre, pas deux familles qui se
     ressemblent : Barlow Condensed pour les titres (la signalétique
     d'atelier), Archivo pour le corps (un grotesque de panneau, robuste
     à petite taille). Le contraste se joue sur la LARGEUR, pas sur une
     opposition serif/sans qui n'aurait rien à dire ici.
     Inter, l'ancien corps, est la police par défaut de la génération
     automatique — elle ne porte aucune voix. */
  /* Jost : une géométrique à terminaisons horizontales, la plus proche
     de la police du LOGO (sofia-pro, que l'ancien site chargeait chez
     Typekit). Barlow Condensed, condensé, n'avait aucun rapport avec le
     lettrage de la marque — le logo et les titres ne se parlaient pas. */
  --titre-police: Jost, 'Century Gothic', system-ui, sans-serif;
  --texte-police: Archivo, system-ui, -apple-system, 'Segoe UI', sans-serif;

  --barre-appel: 0px;   /* la barre d'action du bas, en mobile seulement */
  --entete-min: 72px;   /* la hauteur voulue (min-height) */
  --haut-entete: 72px;  /* la hauteur MESURÉE, écrite par script.js — ne jamais l'utiliser en min-height */
}

/* La variante sombre : LES MÊMES jetons, d'autres valeurs. */
.section--sombre,
.pied,
.entete {
  --fond:         var(--p-anthracite);
  --fond-doux:    #16203040;
  --fond-carte:   #16202e;
  --texte:        var(--p-blanc);
  --texte-doux:   rgba(255, 255, 255, .72);
  --texte-faible: rgba(255, 255, 255, .5);
  /* Le bleu de marque tombe à 2,6:1 sur l'anthracite : illisible en texte.
     C'est sa variante claire qui sert de couleur de texte, l'accent plein
     restant pour les aplats et les filets. */
  --accent-lisible: var(--p-bleu-clair);
  --lisere:       rgba(255, 255, 255, .13);
  --lisere-fort:  rgba(255, 255, 255, .26);
  --ombre:        0 1px 2px rgba(0, 0, 0, .3), 0 10px 30px rgba(0, 0, 0, .32);
  --ombre-forte:  0 2px 8px rgba(0, 0, 0, .38), 0 22px 56px rgba(0, 0, 0, .46);
}


/* ── Les surfaces du navigateur ───────────────────────────────────────
   Ce que l'on n'a pas dessiné porte quand même le design. La sélection,
   le curseur, la barre de défilement, l'anneau de focus, le décalage des
   soulignements et les chiffres des tableaux arrivent tous avec les
   réglages par défaut du navigateur, qui n'appartiennent à aucune charte.
   Les habiller est ce qui distingue une page CONSTRUITE d'une page
   assemblée — et c'est ce qu'on oublie le plus souvent. */

/* La sélection prend la couleur de la marque, pas le bleu du système. */
::selection { background: color-mix(in srgb, var(--p-bleu) 82%, transparent); color: #fff; }
::-moz-selection { background: color-mix(in srgb, var(--p-bleu) 82%, transparent); color: #fff; }

/* Le curseur de saisie : la couleur de l'accent, pas le noir par défaut. */
input, textarea, select, [contenteditable] { caret-color: var(--p-bleu); }
.section--sombre input, .section--sombre textarea { caret-color: var(--p-bleu-clair); }

/* La barre de défilement, discrète et aux couleurs du site. Firefox
   d'abord, puis WebKit — les deux syntaxes cohabitent. */
html {
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--p-bleu) 55%, transparent) transparent;
}
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--p-anthracite) 28%, transparent);
  border: 3px solid transparent;
  border-radius: 999px;
  background-clip: padding-box;
}
@media (hover: hover) and (pointer: fine) {
  ::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--p-bleu) 55%, transparent); background-clip: padding-box; }
}
.section--sombre ::-webkit-scrollbar-thumb,
.tiroir ::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .22); background-clip: padding-box; }

/* Les soulignements : posés sous la ligne de base, pas collés au texte,
   et d'une épaisseur choisie. */
@media (hover: hover) and (pointer: fine) {
  a:where(:hover, :focus-visible) { text-underline-offset: 3px; text-decoration-thickness: 1.5px; }
}

/* Les chiffres s'alignent en colonne dans tout ce qui se compare : prix,
   kilométrages, horaires, notes. Sans cela les chiffres « dansent » d'une
   ligne à l'autre, parce qu'un 1 est plus étroit qu'un 8. */
.horaire dd, .vehicule__prix, .vehicule__faits li, .repere b,
.avis figcaption time, .fiche dd, .barre-filtres__compte,
.pagination button, .carte--tarif__prix {
  font-variant-numeric: tabular-nums;
}

/* Le fond derrière le rebond de défilement (iOS, macOS) : sans lui, un
   bandeau blanc apparaît au-dessus d'un haut de page sombre. */
html { background: var(--p-encre); }

/* Ce que le navigateur souligne en cas de faute d'orthographe, et la
   zone de survol tactile : neutralisés là où ils n'ont rien à dire. */
* { -webkit-tap-highlight-color: color-mix(in srgb, var(--p-bleu) 18%, transparent); }

/* ⚠ TOUTES les règles :hover de cette feuille sont enveloppées dans
   `@media (hover: hover) and (pointer: fine)`. Le tactile n'a pas de
   survol : le navigateur en simule un, qui RESTE COLLÉ après le tap —
   un bouton agrandi au survol reste agrandi une fois tapé. Les deux
   conditions comptent : `hover` dit que l'entrée peut survoler,
   `pointer: fine` qu'elle est précise (ce qui écarte les stylets).
   Le retour au doigt passe par `:active`, qui marche partout. */

/* ── Réinitialisation ─────────────────────────────────────────────────── */

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

html {
  -webkit-text-size-adjust: 100%;   /* pas de gonflement du texte en paysage */
  scroll-behavior: smooth;
  /* Le voile gris que le navigateur peint sur tout élément tapé : c'est le
     signal « ceci est un site web » le plus bruyant, et il se bat avec le
     retour au doigt qu'on a dessiné. On le supprime — et chaque élément
     tapable reçoit son propre :active en échange. */
  -webkit-tap-highlight-color: transparent;
  /* Le tirer-pour-rafraîchir et le rebond de page n'ont rien à faire ici :
     les zones qui défilent ont le leur. */
  overscroll-behavior: none;
  /* Coupe le double-tap qui zoome et les 300 ms avant chaque clic.
     Le pincement, lui, reste possible. */
  touch-action: manipulation;
  scroll-padding-top: calc(var(--haut-entete) + 1rem);
}

body {
  margin: 0;
  background: var(--p-blanc);
  color: var(--texte);
  font: 400 clamp(1.01rem, .97rem + .2vw, 1.09rem)/1.62 var(--texte-police);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

img, svg, video { display: block; max-width: 100%; }
img { height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }

/* Un appui long sur un bouton en sélectionnait le libellé, ou ouvrait le
   menu copier/partager sur un lien. Les contrôles ne sont pas du texte.
   ⚠ Jamais sur `body` : l'adresse, le numéro de TVA et les messages
   d'erreur doivent rester copiables. */
button, [role="button"], .bouton, .filtres button, .pagination button,
.tiroir-bascule, .mosaique__case, .hero__point, .choix-langue__bouton,
.select-habille__bouton, .barre-appel a, .tiroir__nav a {
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--titre-police);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -.018em;   /* une géométrique respire : on la resserre */
  text-wrap: balance;
}
p { margin: 0; text-wrap: pretty; }
ul, ol, dl, dd { margin: 0; padding: 0; }
ul, ol { list-style: none; }

a { color: inherit; text-decoration: none; }
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--accent-lisible);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Une icône dans un lien : la réinitialisation met les svg en `display:
   block`, ce qui est indispensable pour les photos et fatal pour les
   icônes en ligne — sans `inline-flex`, l'icône se retrouve SEULE sur sa
   ligne, au-dessus du texte. */
.ic { flex: none; display: inline-block; vertical-align: middle; }

.saut-contenu {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  padding: .8rem 1.3rem; background: var(--p-bleu); color: #fff; font-weight: 600;
}
.saut-contenu:focus { left: .5rem; top: .5rem; }

.conteneur {
  width: 100%;
  max-width: var(--large);
  margin-inline: auto;
  padding-inline: var(--marge);
}

.sans-coupure { white-space: nowrap; }
/* La mesure : 65–75 ch. Au-delà, l'œil perd la ligne en revenant à la
   gauche. Les mentions et les notes s'étalaient sur 93 ch. */
.note { margin-top: 1rem; color: var(--texte-faible); font-size: .92rem; max-width: 68ch; }
.texte { color: var(--texte-doux); max-width: 72ch; }
.texte + .texte { margin-top: 1rem; }

/* ── Titres et rythme ─────────────────────────────────────────────────
   filet → surtitre → titre → chapô : les MÊMES deux écarts dans toutes
   les sections. Le piège qui les fait exploser est de poser ces éléments
   comme des LIGNES d'une grille à deux colonnes — elles s'étirent alors
   sur la hauteur de la colonne voisine. D'où ce bloc, en flux normal. */

/*
 * ⚠ PAS de max-width ici. Il y en avait un — `46rem`, soit 736 px fixes —
 *   et il étranglait ce qu'il était censé protéger. Chaque enfant porte
 *   déjà SA mesure, et ces mesures-là suivent la police :
 *     .titre-section  17em   .titre-hero  14em   .chapo  44ch
 *   Un plafond en `rem` ne suit rien. La police des titres, elle, grandit
 *   avec l'écran (clamp : 40 px à 1024, 62 px à 1680). Au-delà de 1500 px
 *   le titre devenait donc plus gros DANS une boîte inchangée : « Le prêt
 *   pendant la réparation, ou la location libre » passait de deux lignes à
 *   trois, avec 39 % de la boîte laissée vide. Plus l'écran était grand,
 *   plus le titre était à l'étroit.
 */
.bloc-titre { }
.bloc-titre--centre { margin-inline: auto; text-align: center; }
.bloc-titre--centre .filet { margin-inline: auto; }

/* Le filet subsiste pour les usages ponctuels (héros, séparations), mais
   il n'est plus posé au-dessus de chaque titre : accolé à un surtitre
   répété de section en section, il formait le gabarit que toute page
   engendrée porte. */
.filet {
  display: block;
  width: 72px; height: 5px;
  background: var(--accent);
  border-radius: 3px;
  margin-bottom: .5rem;
}

/* Le MARQUEUR, là où il apprend quelque chose — jamais en ornement
   systématique. Un trait court le précède sur la même ligne : il se lit
   comme une étiquette d'atelier, pas comme un chapeau de magazine. */
.marqueur {
  display: flex; align-items: center; gap: .6rem;
  margin: 0 0 .7rem;
  font: 600 .8rem/1.3 var(--texte-police);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent-lisible);
}
.marqueur::before {
  content: ''; flex: none;
  width: 28px; height: 3px; border-radius: 2px;
  background: currentColor;
}
.bloc-titre--centre .marqueur { justify-content: center; }
.marqueur--hero { color: rgba(255, 255, 255, .92); min-height: 2.6em; align-items: flex-end; }
.marqueur--hero::before { background: var(--p-blanc); margin-bottom: .42em; }

/* Le titre porte seul la hiérarchie, puisque rien ne l'annonce plus :
   il monte d'un cran. */
.titre-section { font-size: var(--t-section); max-width: 17em; }
.bloc-titre--centre .titre-section { margin-inline: auto; }

.titre-hero { font-size: var(--t-hero); max-width: 14em; font-weight: 700; }

.chapo {
  margin-top: 1.15rem;
  font-size: var(--t-chapo);
  line-height: 1.6;
  color: var(--texte-doux);
  max-width: 44ch;
}
.bloc-titre--centre .chapo { margin-inline: auto; }

.section {
  background: var(--fond);
  color: var(--texte);
  padding-block: var(--section-y);
}

/* Le héros clair ne doit jamais toucher une section du même fond : la
   limite entre les deux s'effacerait. */
.section--sombre + .section--sombre { padding-top: 0; }

.section__tete {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem 2.5rem;
  margin-bottom: 3rem;
}
.section__tete .bloc-titre { margin: 0; }

/* ── Boutons ──────────────────────────────────────────────────────────
   `nowrap` : un bouton cassé en deux lignes perd sa forme de pilule et
   décentre son texte. D'où la contrainte de rédaction — des libellés
   courts, et sous 420 px un bouton pleine largeur plutôt que tronqué. */

.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  padding: .82rem 1.5rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font: 600 .95rem/1 var(--texte-police);
  white-space: nowrap;
  cursor: pointer;
  transition: background .18s, color .18s, border-color .18s, transform .18s;
}
/* Le retour se donne à l'APPUI. Un bouton qui ne change qu'au `click`
   répond quand le doigt PART : cela se lit comme un retard, même à 0 ms. */
.bouton:active { transform: scale(.975); }
.bouton--grand { padding: 1rem 1.9rem; font-size: 1rem; }

.bouton--accent { background: var(--accent); color: var(--accent-texte); }
@media (hover: hover) and (pointer: fine) {
  .bouton--accent:hover { background: color-mix(in srgb, var(--accent) 85%, #000); }
}

.bouton--clair { background: var(--p-blanc); color: var(--p-anthracite); }
@media (hover: hover) and (pointer: fine) {
  .bouton--clair:hover { background: #e8ecef; }
}

.bouton--contour {
  background: transparent;
  color: var(--texte);
  border-color: var(--lisere-fort);
}
@media (hover: hover) and (pointer: fine) {
  .bouton--contour:hover { border-color: var(--accent); color: var(--accent-lisible); }
}

.lien-fleche {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  font-weight: 600;
  color: var(--accent-lisible);
}
@media (hover: hover) and (pointer: fine) {
  .lien-fleche:hover { text-decoration: underline; text-underline-offset: 3px; }
}

/* ── En-tête ──────────────────────────────────────────────────────────── */

.entete {
  position: sticky; top: 0; z-index: 90;
  background: color-mix(in srgb, var(--p-anthracite) 97%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 2px solid var(--p-bleu);
  color: var(--texte);
  transition: padding .2s;
}
.entete__dedans {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  max-width: var(--large);
  margin-inline: auto;
  padding: .7rem var(--marge);
  min-height: var(--entete-min);
}

.marque { display: inline-flex; align-items: center; gap: .7rem; flex: none; min-width: 0; }

/* Le LETTRAGE, pas la vignette : le signe carré porte son propre fond et
   son propre cadre, qui font un double encadrement sur l'en-tête sombre —
   et à 44 px son texte gravé est illisible. Le lettrage suit la couleur
   du texte, donc le thème. */
/* Le VRAI logo, détouré : son fond anthracite est transparent, donc il se
   pose sur l'en-tête sans traîner son propre rectangle — c'était ce qui le
   faisait paraître « collé ». La version à fond plein (marque-plaque)
   reste pour les contextes clairs : favicon, mails, documents. */
.marque__signe {
  width: clamp(40px, 9vw, 52px); height: auto;
  flex: none;
}
.marque__mot { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.marque__mot b {
  font-family: var(--titre-police);
  font-size: 1.32rem; font-weight: 700; letter-spacing: .01em;
}
.marque__mot i {
  font-style: normal; font-size: .72rem; letter-spacing: .04em;
  color: var(--texte-faible);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Dans l'en-tête, le lettrage EST le nom : la baseline seule l'accompagne. */
.entete .marque__mot b { font-size: 1.24rem; }
.entete .marque__mot i { font-size: .68rem; }

/* ⚠ La poussée vit sur .entete__actions, PAS sur .menu : celui-ci passe
   en `display: none` sous 1240 px et emporterait sa marge avec lui —
   tout le bloc de droite se recollait alors à gauche. */
.menu { margin-left: auto; }
.menu ul { display: flex; gap: .3rem; }
.menu a {
  display: block;
  padding: .55rem .82rem;
  border-radius: 999px;
  font-weight: 500; font-size: .95rem;
  color: var(--texte-doux);
  transition: color .16s, background .16s;
}
@media (hover: hover) and (pointer: fine) {
  .menu a:hover { color: var(--texte); background: rgba(255, 255, 255, .07); }
}
.menu a.est-actif { color: var(--texte); }
.menu a.est-actif::after {
  content: ''; display: block; height: 2px; margin-top: .3rem;
  background: var(--accent); border-radius: 2px;
}

.entete__actions { display: flex; align-items: center; gap: .55rem; margin-left: auto; }
.entete__appel { padding: .68rem 1.15rem; font-size: .92rem; }

/* Le sélecteur de langue. Le `<select>` natif est banni de l'écran : son
   menu est dessiné par le système, gris et carré, et différent sur chaque
   machine. Ici, un simple menu maison — il n'emporte aucune donnée de
   formulaire, seulement des liens. */
.choix-langue { position: relative; }
/* Pas d'icône de globe : à 17 px ses méridiens se rendaient en tache
   pleine. Le code de langue suffit, et il est plus court à lire. */
.choix-langue__bouton {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .6rem .8rem;
  background: transparent; border: 1px solid var(--lisere-fort);
  border-radius: 999px; color: var(--texte-doux);
  font-size: .85rem; font-weight: 600;
}
@media (hover: hover) and (pointer: fine) {
  .choix-langue__bouton:hover { color: var(--texte); border-color: var(--accent); }
}
.choix-langue__liste {
  position: absolute; top: calc(100% + .4rem); right: 0; z-index: 20;
  display: none; flex-direction: column; min-width: 10rem;
  padding: .35rem;
  background: #1b2228; border: 1px solid var(--lisere);
  border-radius: var(--rayon-s); box-shadow: var(--ombre-forte);
}
.choix-langue[data-ouvert] .choix-langue__liste { display: flex; }
.choix-langue__liste a,
.choix-langue__liste span {
  padding: .55rem .75rem; border-radius: 6px;
  font-size: .9rem; color: rgba(255, 255, 255, .78);
}
@media (hover: hover) and (pointer: fine) {
  .choix-langue__liste a:hover { background: rgba(255, 255, 255, .09); color: #fff; }
}
.choix-langue__liste span { color: #fff; font-weight: 600; background: rgba(255, 255, 255, .07); }

/* Le bouton porte LES DEUX icônes : sans croix, rien ne dit comment
   refermer le tiroir — le visiteur cherche, et certains quittent la page. */
.tiroir-bascule {
  display: none;
  position: relative;
  width: 42px; height: 42px;
  padding: 0; background: transparent;
  border: 1px solid var(--lisere-fort); border-radius: var(--rayon-s);
  color: var(--texte);
}
.tiroir-bascule > span {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  transition: opacity .2s, transform .25s cubic-bezier(.25, 1, .5, 1);
}
.tiroir-bascule__croix { opacity: 0; transform: rotate(-90deg); }
.tiroir-bascule[aria-expanded="true"] .tiroir-bascule__menu { opacity: 0; transform: rotate(90deg); }
.tiroir-bascule[aria-expanded="true"] .tiroir-bascule__croix { opacity: 1; transform: none; }
.tiroir-bascule[aria-expanded="true"] { border-color: var(--accent); }

/* ── Le tiroir ────────────────────────────────────────────────────────
   Premier essai : des liens à 1,85 rem séparés de filets pleine largeur,
   un gros bouton bleu et trois pastilles de langue. Chaque élément criait
   aussi fort que les autres, et l'ensemble faisait brouillon.

   Ici la navigation porte seule, à une taille lisible mais tenue ; le
   pied regroupe l'appel, l'adresse et la langue — ce qu'on cherche sur
   un téléphone. */

.tiroir {
  position: fixed; inset: var(--haut-entete) 0 0; z-index: 89;
  display: flex; flex-direction: column;
  padding: .5rem var(--marge) calc(1.5rem + env(safe-area-inset-bottom));
  background: var(--p-encre); color: #fff;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.tiroir[hidden] { display: none; }

.tiroir__nav { flex: 1; }
.tiroir__nav ul { display: flex; flex-direction: column; }
.tiroir__nav a {
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.05rem .2rem;
  border-bottom: 1px solid rgba(255, 255, 255, .09);
  font-family: var(--titre-police);
  font-size: 1.42rem; font-weight: 500; letter-spacing: -.01em;
  color: rgba(255, 255, 255, .92);
}
/* Un chevron discret dit que la ligne mène quelque part. */
.tiroir__nav a::after {
  content: '';
  width: 7px; height: 7px;
  border-right: 1.6px solid rgba(255, 255, 255, .3);
  border-bottom: 1.6px solid rgba(255, 255, 255, .3);
  transform: rotate(-45deg);
}
.tiroir__nav a.est-actif { color: var(--p-bleu-clair); font-weight: 600; }
.tiroir__nav a.est-actif::after { border-color: var(--p-bleu-clair); }

.tiroir__pied { display: flex; flex-direction: column; gap: 1.1rem; margin-top: 1.8rem; }

/* L'appel : une ligne, pas une pilule géante. Le numéro se lit, le mot
   « Appeler » dit ce qui va se passer. */
.tiroir__appel {
  display: flex; align-items: center; gap: .85rem;
  padding: .85rem 1rem;
  background: color-mix(in srgb, var(--p-bleu) 18%, transparent);
  border: 1px solid color-mix(in srgb, var(--p-bleu-clair) 40%, transparent);
  border-radius: var(--rayon);
}
.tiroir__appel-icone {
  display: grid; place-items: center;
  width: 38px; height: 38px; flex: none;
  background: var(--p-bleu); color: #fff;
  border-radius: 50%;
}
.tiroir__appel-texte { display: flex; flex-direction: column; line-height: 1.2; }
.tiroir__appel-texte i {
  font-style: normal; font-size: .72rem; letter-spacing: .1em;
  text-transform: uppercase; color: rgba(255, 255, 255, .55);
}
.tiroir__appel-texte b { font-size: 1.12rem; font-weight: 600; white-space: nowrap; }

.tiroir__adresse { font-size: .88rem; line-height: 1.5; color: rgba(255, 255, 255, .6); }

.tiroir__langues { display: flex; gap: .4rem; flex-wrap: wrap; }
.tiroir__langues a, .tiroir__langues span {
  padding: .45rem .85rem;
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 999px;
  font-size: .82rem; font-weight: 500;
  color: rgba(255, 255, 255, .68);
}
@media (hover: hover) and (pointer: fine) {
  .tiroir__langues a:hover { border-color: rgba(255, 255, 255, .4); color: #fff; }
}
.tiroir__langues span {
  background: rgba(255, 255, 255, .1); border-color: transparent;
  color: #fff; font-weight: 600;
}

/* ── Bandeau d'annonce ────────────────────────────────────────────────── */

.annonce { background: var(--p-bleu-surface); color: #fff; }
.annonce__dedans {
  display: flex; align-items: center; gap: .7rem;
  padding-block: .65rem;
  font-size: .92rem;
}
.annonce__dedans p { margin: 0; }
.annonce__dedans a { font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
.annonce__fermer {
  margin-left: auto; padding: .3rem;
  background: transparent; border: 0; color: inherit; opacity: .8;
}
@media (hover: hover) and (pointer: fine) {
  .annonce__fermer:hover { opacity: 1; }
}

/* ── Héros ────────────────────────────────────────────────────────────
   100 vh, ET PLEIN. Un haut de page qui prend tout l'écran pour n'y mettre
   qu'un titre et deux boutons oblige le visiteur à défiler avant la
   première information. Les repères chiffrés vont DONC dans le héros, en
   pied d'écran.

   `grid`, jamais `flex` : avec flex sur le héros et flex:1 sur le dedans,
   la largeur de celui-ci est écrasée, les marges disparaissent et le
   contenu colle aux bords — sans que rien ne déborde, donc sans qu'aucun
   contrôle automatique ne le voie. */

.hero {
  position: relative;
  display: grid;
  /* Le haut de page passe SOUS l'encoche depuis viewport-fit=cover : son
     contenu s'en écarte. */
  padding-left: env(safe-area-inset-left, 0px);
  padding-right: env(safe-area-inset-right, 0px);
  min-height: calc(100svh - var(--haut-entete) - var(--barre-appel));
  padding-top: clamp(2rem, 5vh, 4.5rem);
  padding-bottom: clamp(1.5rem, 3vh, 2.5rem);
  background: var(--p-anthracite);
  color: #fff;
  isolation: isolate;
  overflow: hidden;
}
.hero--compact { min-height: calc(74svh - var(--haut-entete) - var(--barre-appel)); }

.hero__fond { position: absolute; inset: 0; z-index: -2; }
.hero__fond img { width: 100%; height: 100%; object-fit: cover; }

/* Les vues du carrousel. Elles sont TOUTES dans la page : sans
   JavaScript, la première reste affichée et le haut de page est complet.
   Le fondu porte sur l'opacité seule — jamais sur une propriété de mise
   en page, qui ferait trembler la photo. */
.hero__fond--suite .hero__vue {
  position: absolute; inset: 0; margin: 0;
  opacity: 0;
  transition: opacity 1.1s cubic-bezier(.4, 0, .2, 1);
}
.hero__fond--suite .hero__vue.est-active { opacity: 1; }
/* Sans script, la première vue est la seule visible. */
html:not(.js) .hero__fond--suite .hero__vue:first-child { opacity: 1; }
/* Un lent rapprochement pendant que la vue est à l'écran : la photo
   respire, sans que rien ne bouge autour. */
.js .hero__fond--suite .hero__vue.est-active img { animation: hero-souffle 9s linear forwards; }
@keyframes hero-souffle { from { transform: scale(1); } to { transform: scale(1.045); } }

/* ⚠ Dans le FLUX, juste au-dessus des repères. Posée en absolu au pied du
   héros, la commande passait par-dessus eux : la légende recouvrait
   « Véhicule prêté ». */
/* ⚠ Les points et la légende s'alignent sur la même LIGNE DE BASE
   optique. `align-items: center` les décalait : un trait de 3 px et un
   texte de 13 px n'ont pas le même centre visuel. On aligne les boîtes
   par leur milieu ET on donne aux points la hauteur d'une ligne de
   texte, pour qu'ils tombent au même endroit. */
.hero__commande {
  align-self: end;
  display: flex; align-items: center; justify-content: flex-end; gap: .95rem;
  padding-bottom: .9rem;
}
/* ⚠ Pas de `height: 1em` sur le texte : la boîte devient plus courte que
   la ligne, les jambages débordent par le bas et le mot paraît descendu
   sous les traits. On laisse chaque élément prendre sa hauteur, et le
   `center` du conteneur les aligne vraiment. */
/* ⚠ Les <li> héritent d'une hauteur de ligne et rendent la liste plus
   haute que les traits qu'elle contient : le bloc entier se décalait de
   quelques pixels sous le texte voisin. Chaque <li> colle donc à son
   bouton. */
.hero__points { align-items: center; line-height: 0; }
.hero__points li { display: flex; }
.hero__points { display: flex; gap: .4rem; pointer-events: auto; }
.hero__point {
  position: relative;
  width: 34px; height: 3px;
  padding: 0; border: 0; border-radius: 2px;
  background: rgba(255, 255, 255, .34);
  overflow: hidden;
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  .hero__point:hover { background: rgba(255, 255, 255, .5); }
}
/* La jauge dit combien de temps il reste sur la vue : un point qui ne
   bouge pas ne dit pas qu'un défilement est en cours. */
.hero__jauge {
  position: absolute; inset: 0;
  background: #fff;
  transform: scaleX(0); transform-origin: left center;
}
.hero__point.est-active .hero__jauge { animation: hero-jauge var(--duree, 6s) linear forwards; }
@keyframes hero-jauge { from { transform: scaleX(0); } to { transform: scaleX(1); } }
/* Variante au doigt : la jauge y est recentrée par translateY, qu'une
   animation sur `transform` effacerait si elle ne le reportait pas. */
@keyframes hero-jauge-tactile {
  from { transform: translateY(-50%) scaleX(0); }
  to   { transform: translateY(-50%) scaleX(1); }
}

.hero__legende {
  font-size: .82rem; line-height: 1.2; letter-spacing: .04em;
  color: rgba(255, 255, 255, .8);
  text-shadow: 0 1px 4px rgba(0, 0, 0, .55);
}

@media (max-width: 760px) {
  .hero__commande { justify-content: flex-start; padding-bottom: .7rem; }
  .hero__legende { display: none; }
  .hero__point { width: 26px; }
}
@media (prefers-reduced-motion: reduce) {
  .js .hero__fond--suite .hero__vue.est-active img { animation: none; }
  .hero__point.est-active .hero__jauge { animation: none; transform: scaleX(1); }
  @media (pointer: coarse) {
    .hero__point.est-active .hero__jauge { transform: translateY(-50%) scaleX(1); }
  }
  .hero__fond--suite .hero__vue { transition: none; }
}
.hero__voile {
  position: absolute; inset: 0; z-index: -1;
  /* ⚠ AUCUNE teinte de couleur sur la photo. Un filtre bleu posé sur une
     image la date immédiatement : c'est un traitement des années 2010, et
     il abîme la photo au lieu de la servir. Le voile ne fait qu'UNE
     chose — assombrir là où le texte se pose, et nulle part ailleurs.
     La photo reste elle-même. */
  background:
    linear-gradient(to right, rgba(9, 13, 20, .88) 0%, rgba(9, 13, 20, .62) 38%, rgba(9, 13, 20, .18) 66%, transparent 88%),
    linear-gradient(to top, rgba(9, 13, 20, .90) 0%, rgba(9, 13, 20, .30) 26%, transparent 52%);
}

.hero__dedans {
  display: grid;
  grid-template-rows: 1fr auto auto;   /* le texte, la commande, les repères */
  gap: clamp(2rem, 5vh, 3.5rem);
  width: 100%;
  max-width: var(--large);
  margin-inline: auto;
  padding-inline: var(--marge);
}

/* Ancré en HAUT, avec un padding constant : le titre tombe alors toujours
   à la même hauteur d'une page à l'autre, quel que soit le nombre de
   lignes du chapô. Ancré en bas, un héros plus haut décalerait son titre
   de 150 px par rapport aux autres. */
/* Sur grand écran, la colonne du titre s'élargit : à 40 rem fixes, un mot
   composé allemand casse le titre en six lignes. */
/*
 * ⚠ C'était `min(46rem, 50vw)`. Le `46rem` est un plafond FIXE (736 px) :
 *   au-delà de ~1470 px de large, c'est lui qui gagnait, alors que la
 *   police du titre continuait de grandir (clamp : jusqu'à 66 px). Le H1
 *   « 40 ans de carrosserie, de père en fils. » passait donc à trois
 *   lignes sur les grands écrans — plus l'écran était large, plus le titre
 *   était à l'étroit.
 *
 *   Le `50vw` reste, lui : il a une raison d'être, garder le texte du côté
 *   qui lui revient sans empiéter sur la photo. Et le titre porte déjà sa
 *   propre mesure (`.titre-hero { max-width: 14em }`), qui suit la police.
 */
.hero__texte { align-self: start; max-width: 50vw; }
@media (max-width: 900px) { .hero__texte { max-width: 40rem; } }
/* ⚠ Le surtitre du héros est BLANC, pas bleu. Depuis que le voile porte
   la teinte de marque, un texte bleu clair sur un fond bleu profond tombe
   à 3,0–3,8:1 — mesuré sur les pixels rendus, sur les six pages et deux
   largeurs. Le contrôle général écarte les textes sur photo : ce défaut-là
   ne se voit qu'en mesurant le héros à part. */

/*
 * 36ch était trop court : sous la plage lisible (45–75 caractères), le
 * chapô tombait à QUATRE lignes à toutes les largeurs en n'occupant que
 * 43 % de son bloc sur grand écran — 412 px offerts sur 960 disponibles.
 * Quatre lignes courtes sous un titre de deux lignes pleines, cela se voit.
 *
 * 46ch ramène le chapô à trois lignes partout, français, néerlandais et
 * allemand compris (l'allemand est le plus long des trois : c'est lui qui
 * a fixé la valeur, pas le français). Sur téléphone, le bloc est plus
 * étroit que 46ch de toute façon — rien n'y change.
 */
.hero__texte .chapo--hero { color: rgba(255, 255, 255, .82); max-width: 46ch; }

.hero__boutons { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 2rem; }

/* ⚠ PAS de `background` sur le conteneur. Il servait à dessiner les
   séparateurs de 1 px via `gap: 1px` — mais dès que l'écart grandit (en
   mobile), ce fond se voit en grand rectangle gris. Les séparations sont
   de vraies bordures. */
.reperes {
  align-self: end;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  padding-top: 1.5rem;
  border-top: 1px solid rgba(255, 255, 255, .26);
}
.repere {
  padding: .2rem 1.4rem;
  border-left: 1px solid rgba(255, 255, 255, .18);
}
.repere:first-child { border-left: 0; padding-left: 0; }
.repere > b {
  display: block;
  font-family: var(--titre-police);
  font-size: clamp(1.5rem, 2.1vw, 2.15rem);
  font-weight: 700; line-height: 1.05;
  white-space: nowrap;           /* une valeur courte ne se coupe jamais */
}
/* ⚠ `> span` et non `span` : le sélecteur large attrapait aussi les
   <span> posés À L'INTÉRIEUR de la valeur pour la rendre modifiable, les
   passait en bloc, et le « /5 » de la note tombait à la ligne — avec la
   taille et la marge du libellé. Un défaut créé par l'annotation CMS
   elle-même, invisible à la relecture du HTML. */
.repere > span {
  display: block; margin-top: .3rem;
  font-size: .82rem; line-height: 1.35;
  color: rgba(255, 255, 255, .64);
}
.repere__note { display: inline-flex !important; align-items: baseline; gap: .3rem; }
.repere__note .ic { color: var(--p-bleu-clair); align-self: center; }
.repere__note i { font-style: normal; font-size: .62em; color: rgba(255, 255, 255, .55); }


/* ── Tuiles ───────────────────────────────────────────────────────────
   Les quatre métiers. La photo PORTE la tuile : le garage se montre au
   lieu de se décrire. Premier essai : des bandes fines à vignette — elles
   faisaient timbre-poste, avec du vide partout.

   ⚠ Aucun `padding` ni aucune dimension n'est animé au survol : animer
   une propriété de mise en page fait glisser le contenu sous le curseur,
   et c'est ce qui donne l'impression d'amateurisme. Seuls l'échelle de la
   photo et l'opacité du voile bougent. */

/* ⚠ DEUX colonnes fixes, pas `auto-fit` : avec quatre tuiles, l'auto-fit
   en pose trois sur la première rangée et laisse la quatrième orpheline —
   un pavage bancal. Quatre tuiles veulent deux rangées de deux. */
.tuiles {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(.7rem, 1.2vw, 1.1rem);
  margin-top: 3rem;
}
@media (max-width: 760px) { .tuiles { grid-template-columns: 1fr; } }

.tuile {
  position: relative;
  display: block;
  aspect-ratio: 16 / 10;
  border-radius: var(--rayon);
  overflow: hidden;
  isolation: isolate;
  background: var(--p-encre);
}
.tuile__photo { position: absolute; inset: 0; z-index: -2; }
.tuile__photo img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .7s cubic-bezier(.2, .7, .3, 1);
}
@media (hover: hover) and (pointer: fine) {
  .tuile:hover .tuile__photo img { transform: scale(1.05); }
}

.tuile__voile {
  position: absolute; inset: 0; z-index: -1;
  /* Fort au pied, où le texte se pose ; effacé au-dessus, où la photo
     doit se voir. Un voile uniforme éteint la photo et la tuile devient
     un rectangle sombre. */
  background:
    linear-gradient(to top, rgba(10, 16, 24, .95) 0%, rgba(10, 16, 24, .72) 34%, rgba(10, 16, 24, .18) 62%, transparent 82%),
    linear-gradient(to top, rgba(9, 13, 20, .55) 0%, transparent 40%);
  transition: opacity .35s;
}
@media (hover: hover) and (pointer: fine) {
  .tuile:hover .tuile__voile { opacity: .88; }
}

.tuile__corps {
  position: absolute; inset: auto 0 0 0;
  display: flex; flex-direction: column; gap: .25rem;
  padding: clamp(1.2rem, 2.2vw, 1.9rem);
  color: #fff;
}
.tuile__rang {
  font-family: var(--titre-police);
  font-size: .95rem; font-weight: 600; letter-spacing: .1em;
  color: rgba(255, 255, 255, .62);
  font-variant-numeric: tabular-nums;
}
.tuile__corps b {
  font-family: var(--titre-police);
  font-size: clamp(1.7rem, 3vw, 2.5rem); font-weight: 600; line-height: 1.02;
}
.tuile__corps i {
  font-style: normal; font-size: .95rem; line-height: 1.5;
  color: rgba(255, 255, 255, .82);
  max-width: 34ch;
}
.tuile__lien {
  display: inline-flex; align-items: center; gap: .45rem;
  margin-top: .7rem;
  font-weight: 600; font-size: .93rem;
  color: #fff;
}
.tuile__lien .ic { transition: transform .25s cubic-bezier(.2, .7, .3, 1); }
@media (hover: hover) and (pointer: fine) {
  .tuile:hover .tuile__lien .ic { transform: translateX(5px); }
}

@media (max-width: 520px) {
  .tuile { aspect-ratio: 4 / 3; }
  .tuile__corps b { font-size: 1.6rem; }
}

/* ── Fiche d'atelier ──────────────────────────────────────────────────
   Les douze prestations. La liste affichée au mur d'un garage : un rang,
   un intitulé, une précision. Se lit d'un coup d'œil, là où douze cartes
   imposeraient douze arrêts. Les numéros sont une NOMENCLATURE — pas un
   ornement de section. */

.fiche-atelier {
  margin-top: 3rem;
  border-top: 2px solid var(--texte);
  columns: 2;
  column-gap: clamp(2rem, 5vw, 5rem);
}
@media (max-width: 860px) { .fiche-atelier { columns: 1; } }

.ligne-fiche {
  break-inside: avoid;
  display: grid;
  grid-template-columns: 2.6rem 1fr;
  gap: .1rem .9rem;
  padding: 1rem 0;
  border-bottom: 1px solid var(--lisere);
}
.ligne-fiche__rang {
  grid-row: 1 / 3;
  font-family: var(--titre-police);
  font-size: 1.05rem; font-weight: 600;
  color: var(--accent-lisible);
  font-variant-numeric: tabular-nums;
  padding-top: .15rem;
}
.ligne-fiche__nom {
  font-family: var(--titre-police);
  font-size: clamp(1.2rem, 1.7vw, 1.4rem); font-weight: 600; line-height: 1.15;
}
.ligne-fiche__detail { color: var(--texte-doux); font-size: .93rem; line-height: 1.55; }

/* ── Atouts ───────────────────────────────────────────────────────────
   Les quatre « plus ». Une rangée séparée par des filets : quatre cartes
   de plus en auraient fait seize sur la même page. */

.atouts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  margin-top: 3rem;
  border-top: 1px solid var(--lisere);
}
.atout {
  display: flex; flex-direction: column; gap: .45rem;
  padding: 1.6rem clamp(1rem, 2vw, 1.8rem);
  border-left: 1px solid var(--lisere);
  border-bottom: 1px solid var(--lisere);
}
.atout:first-child { border-left: 0; padding-left: 0; }
.atout__icone { color: var(--accent-lisible); margin-bottom: .35rem; opacity: .9; }
.atout b { font-family: var(--titre-police); font-size: 1.25rem; font-weight: 600; line-height: 1.15; }
.atout > span { color: var(--texte-doux); font-size: .9rem; line-height: 1.5; }
@media (max-width: 620px) {
  .atout { border-left: 0; padding-left: 0; padding-right: 0; }
}

/* ── Grilles et cartes ────────────────────────────────────────────────── */

.grille { display: grid; gap: clamp(1rem, 1.6vw, 1.5rem); }
.grille--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr)); }
.grille--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr)); }
.grille--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 15.5rem), 1fr)); }

.carte {
  display: flex;
  flex-direction: column;
  gap: .7rem;
  padding: clamp(1.4rem, 2vw, 1.9rem);
  background: var(--fond-carte);
  border: 1px solid var(--lisere);
  border-radius: var(--rayon);
  transition: border-color .18s, transform .18s, box-shadow .18s;
}
.carte h3 { font-size: var(--t-carte); }
.carte p { color: var(--texte-doux); font-size: .96rem; }

.carte__icone {
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px;
  margin-bottom: .3rem;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent-lisible);
  border-radius: 11px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 34%, transparent);
}

/* Le dernier bloc d'une carte s'aligne sur celui de ses voisines, quelle
   que soit la longueur du texte au-dessus. Sans `margin-top: auto`, le
   lien de chacune s'arrête où finit SON texte. */
.carte__lien {
  display: inline-flex; align-items: center; gap: .4rem;
  margin-top: auto; padding-top: .5rem;
  font-weight: 600; font-size: .92rem;
  color: var(--accent-lisible);
}
@media (hover: hover) and (pointer: fine) {
  a.carte:hover { border-color: var(--accent); transform: translateY(-3px); box-shadow: var(--ombre); }
}
@media (hover: hover) and (pointer: fine) {
  a.carte:hover .carte__lien { gap: .65rem; }
}

.carte--agrement { align-items: flex-start; }
/* Les logos vont du très allongé (3,2:1) au presque carré (1,2:1). Bornés
   sur les DEUX côtés, chacun est retenu par sa dimension dominante — sinon
   le carré occupe trois fois moins de largeur et paraît minuscule. */
.carte--agrement__logo {
  display: flex; align-items: center; justify-content: center;
  width: 84px; height: 62px; margin-bottom: .5rem;
  background: #fff; border-radius: 9px; padding: .45rem;
}
.carte--agrement__logo img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; }

.carte--formule .liste-check { margin-top: auto; padding-top: .6rem; }
.carte--tarif__prix {
  font-family: var(--titre-police);
  font-size: clamp(1.8rem, 2.4vw, 2.4rem); font-weight: 700;
  color: var(--accent-lisible) !important;
}

.liste-check { display: flex; flex-direction: column; gap: .6rem; margin-top: 1.4rem; }
.liste-check li { display: flex; align-items: flex-start; gap: .6rem; font-size: .96rem; color: var(--texte-doux); }
.liste-check .ic { color: var(--accent-lisible); margin-top: .22rem; }

/* ── Agréments ────────────────────────────────────────────────────────
   Le logo PORTE l'agrément : c'est lui que le visiteur reconnaît. Dans
   une carte, réduit à 84 px sous un titre, il ne servait à rien. */

.agrements {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: clamp(1.4rem, 2.5vw, 2.6rem);
  margin-top: 3rem;
}
.agrement { display: flex; flex-direction: column; gap: 1rem; }
/* Fond blanc : ces logos sont dessinés pour le papier et disparaissent
   sur un fond sombre. Bornés sur LES DEUX côtés — du 3,2:1 au 1,2:1, à
   hauteur libre le presque-carré paraîtrait minuscule. */
.agrement__logo {
  display: flex; align-items: center; justify-content: center;
  height: 96px; padding: .9rem 1.2rem;
  background: #fff; border-radius: var(--rayon-s);
}
.agrement__logo img {
  /* Bornés sur LES DEUX côtés, et la largeur serrée : AlphaCredit est en
     3,2:1, Febelcar en 1:1 — à largeur libre le premier occupait 3,6× la
     surface du second. Le rapport doit rester sous 2. */
  max-width: 150px; max-height: 100%;
  width: auto; height: auto; object-fit: contain;
}
.agrement__texte { display: flex; flex-direction: column; gap: .35rem; }
.agrement__texte b {
  font-family: var(--titre-police);
  font-size: 1.3rem; font-weight: 600; line-height: 1.15;
}
.agrement__texte span { color: var(--texte-doux); font-size: .93rem; line-height: 1.55; }

/* ── Bloc image + texte ───────────────────────────────────────────────
   La photo remplit la hauteur : sans `height: 100%`, un grand vide se
   forme sous elle dès que le texte est long. */

.duo__dedans {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr));
  gap: clamp(2rem, 4vw, 4.5rem);
  align-items: center;   /* légitime ici : texte + IMAGE, jamais texte + texte */
}
.duo--inverse .duo__image { order: 2; }
.duo__dedans--inverse .duo__image { order: 2; }
@media (max-width: 860px) {
  .duo--inverse .duo__image,
  .duo__dedans--inverse .duo__image { order: 0; }
}

.duo__image { border-radius: var(--rayon); overflow: hidden; box-shadow: var(--ombre); }
.duo__image img { width: 100%; height: 100%; min-height: 18rem; object-fit: cover; }
.duo__texte .bouton { margin-top: 1.8rem; }

/* ── Étapes ───────────────────────────────────────────────────────────── */

/* ── Le déroulé d'un sinistre ─────────────────────────────────────────
   Un VRAI stepper : les étapes sont reliées par un trait qui passe par
   les numéros. Sans ce lien, ce ne sont que des blocs empilés — et le
   lecteur ne voit pas qu'il s'agit d'une séquence.

   ⚠ `auto-fit` posait cinq étapes dans quatre colonnes et laissait la
   cinquième orpheline. Une séquence de cinq veut cinq colonnes. */

/* ⚠ Le bloc est BORNÉ et CENTRÉ. Étalé sur toute la largeur, chaque
   colonne recevait 440 px pour deux lignes de texte : les blocs
   flottaient, et l'ensemble ne se centrait plus sous son titre — le
   dernier texte s'arrêtant bien avant le bord de sa colonne, le stepper
   paraissait poussé à gauche. */
.etapes {
  --rang: 42px;
  --ecart: clamp(1rem, 1.8vw, 1.8rem);
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--ecart);
  margin-top: 3.2rem;
  margin-inline: auto;
  max-width: 78rem;
}
.etapes--trois {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  max-width: 58rem;
}

/* Le numéro est CENTRÉ sur la colonne, donc sur le bloc de texte qu'il
   coiffe. Aligné à gauche, il flottait au-dessus du début de la première
   ligne et ne coiffait rien. */
.etape {
  position: relative;
  display: flex; flex-direction: column; align-items: center;
  gap: .85rem;
  text-align: center;
}

/* Le trait relie le bord droit d'un numéro au bord gauche du suivant.
   Les numéros étant centrés sur leur colonne, il part de
   « 50 % + rayon » et court jusqu'à la colonne d'après — d'où le `right`
   négatif, qui déborde de l'écart entre colonnes. */
.etape::after {
  content: '';
  position: absolute;
  top: calc(var(--rang) / 2 - 1px);
  left: calc(50% + var(--rang) / 2 + 10px);
  right: calc(-50% - var(--ecart) + var(--rang) / 2 + 10px);
  height: 2px;
  background: var(--lisere-fort);
}
.etape:last-child::after { display: none; }

.etape__rang {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--rang); height: var(--rang);
  flex: none;
  background: var(--accent); color: var(--accent-texte);
  border-radius: 50%;
  font-family: var(--titre-police); font-size: 1.3rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
  /* Le numéro passe AU-DESSUS du trait qu'il interrompt. */
  position: relative; z-index: 1;
  box-shadow: 0 0 0 6px var(--fond);
}
.etape h3 { font-size: var(--t-carte); margin-bottom: .35rem; }
.etape p { color: var(--texte-doux); font-size: .95rem; }

@media (max-width: 1080px) {
  .etapes { grid-template-columns: repeat(3, 1fr); }
  /* En trois colonnes, le trait ne doit pas courir au bout d'une rangée. */
  .etape:nth-child(3n)::after { display: none; }
  .etapes--trois .etape:nth-child(3n)::after { display: none; }
}

/* Sous 760 px : un stepper VERTICAL. Le trait descend le long des
   numéros, et chaque étape s'y accroche — c'est ce qui fait lire la
   suite comme un déroulé, et non comme cinq blocs. */
@media (max-width: 760px) {
  .etapes, .etapes--trois {
    grid-template-columns: 1fr;
    gap: 0;
  }
  .etape {
    flex-direction: row;
    align-items: flex-start;
    text-align: left;
    gap: 1.1rem;
    padding-bottom: 1.8rem;
  }
  .etape:last-child { padding-bottom: 0; }
  .etape::after {
    top: var(--rang); bottom: 0; left: calc(var(--rang) / 2 - 1px);
    right: auto;
    width: 2px; height: auto;
  }
  .etape__rang { box-shadow: none; }
  .etape > div { padding-top: .35rem; }
  .etape h3 { margin-bottom: .3rem; }
}

/* ── Avis ─────────────────────────────────────────────────────────────── */

.avis__grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
  gap: clamp(1rem, 1.6vw, 1.4rem);
  margin-top: 3rem;
}
.avis {
  display: flex; flex-direction: column; gap: .9rem;
  margin: 0; padding: clamp(1.4rem, 2vw, 1.8rem);
  background: var(--fond-carte);
  border: 1px solid var(--lisere);
  border-radius: var(--rayon);
}
.avis__notes { display: flex; gap: .14rem; color: var(--accent-lisible); }
/* Une étoile de notation se lit PLEINE : en contour, elle passe pour une
   étoile « non acquise ». C'est la seule icône du jeu qui garde son aplat. */
.avis__notes .ic, .repere__note .ic { fill: currentColor; stroke: none; }
.avis blockquote { margin: 0; }
.avis blockquote p { color: var(--texte-doux); font-size: .97rem; }
/* Le bas de la carte s'aligne d'un avis à l'autre, quelle que soit la
   longueur de la citation. */
.avis figcaption {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .2rem .6rem;
  margin-top: auto; padding-top: .8rem;
  border-top: 1px solid var(--lisere);
}
.avis figcaption b { font-weight: 600; }
.avis figcaption time { font-size: .84rem; color: var(--texte-faible); }
.avis__source { margin-top: 2rem; text-align: center; }

/* ── Pagination ───────────────────────────────────────────────────────
   Posée d'emblée même quand elle ne se voit pas : le client PEUT ajouter
   des avis, c'est tout l'intérêt du CMS. Une classe à part pour masquer
   hors-page — jamais `hidden`, qui appartient au contenu et dit ce que le
   client a choisi de cacher. */

.hors-page { display: none !important; }
.pagination {
  display: flex; justify-content: center; align-items: center; gap: .4rem;
  margin-top: 2.2rem;
}
.pagination[hidden] { display: none; }
.pagination button {
  min-width: 40px; padding: .5rem .75rem;
  background: transparent; border: 1px solid var(--lisere-fort);
  border-radius: 8px; color: var(--texte-doux);
  font-size: .9rem; font-weight: 600;
}
.pagination button[aria-current="true"] {
  background: var(--accent); border-color: var(--accent); color: var(--accent-texte);
}
.pagination button:disabled { opacity: .35; cursor: default; }

/* ── Partenaires ──────────────────────────────────────────────────────── */

.partenaires { padding-block: clamp(2.5rem, 4vw, 4rem); background: var(--fond-doux); }
/* Un titre court et centré : la mesure ne s'y applique pas, mais on le
   borne pour qu'il ne s'étire pas sur toute la largeur. */
.partenaires__titre {
  text-align: center; margin-bottom: 1.6rem; max-width: 40ch; margin-inline: auto;
  font: 600 .8rem/1.3 var(--texte-police);
  letter-spacing: .13em; text-transform: uppercase; color: var(--texte-faible);
}
.partenaires__liste {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: clamp(1.5rem, 4vw, 3.5rem);
}
/* Le conteneur RÉSERVE la place : sans hauteur, un logo pas encore chargé
   mesure 0 × 0 et le bandeau se replie à rien. */
.partenaire {
  display: flex; align-items: center; justify-content: center;
  width: clamp(92px, 10vw, 118px); height: 72px;
}
/* Bornés sur les deux côtés : le rapport de surface entre le plus grand et
   le plus petit doit rester sous 2. */
.partenaire__logo {
  /* Bornés sur les DEUX côtés, avec une hauteur minimale : sans elle, un
     logo très allongé n'occupe qu'un tiers de la surface du carré voisin. */
  max-width: 100%; max-height: 100%;
  min-height: 42px;
  width: auto; height: auto;
  object-fit: contain;
  filter: grayscale(1); opacity: .68;
  transition: filter .2s, opacity .2s;
}
@media (hover: hover) and (pointer: fine) {
  .partenaire:hover .partenaire__logo { filter: none; opacity: 1; }
}

/* ── Occasions ────────────────────────────────────────────────────────── */

.occasions__grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19.5rem), 1fr));
  gap: clamp(1rem, 1.6vw, 1.5rem);
  margin-top: 2.5rem;
}
.occasions__attente,
.occasions__vide {
  grid-column: 1 / -1;
  padding: 2.5rem 1rem; text-align: center;
  color: var(--texte-faible);
}
.occasions__vide a { color: var(--accent-lisible); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }

.vehicule {
  display: flex; flex-direction: column;
  background: var(--fond-carte);
  border: 1px solid var(--lisere);
  border-radius: var(--rayon);
  overflow: hidden;
  transition: border-color .18s, transform .18s, box-shadow .18s;
}
@media (hover: hover) and (pointer: fine) {
  .vehicule:hover { border-color: var(--accent); transform: translateY(-3px); box-shadow: var(--ombre); }
}
.vehicule__photo { position: relative; aspect-ratio: 4 / 3; background: var(--fond-doux); }
.vehicule__photo img { width: 100%; height: 100%; object-fit: cover; }
/* Un badge OPAQUE, pas un dégradé : sur une carrosserie claire, un texte
   blanc sur dégradé disparaît. */
.vehicule__prix {
  position: absolute; left: .7rem; bottom: .7rem;
  padding: .35rem .75rem;
  background: rgba(19, 25, 29, .92);
  backdrop-filter: blur(4px);
  border-radius: 8px;
  color: #fff;
  font-family: var(--titre-police); font-size: 1.3rem; font-weight: 700;
  white-space: nowrap;
}
.vehicule__corps { display: flex; flex-direction: column; gap: .5rem; padding: 1.1rem 1.2rem 1.2rem; flex: 1; }
.vehicule__titre { font-size: 1.28rem; }
.vehicule__version { font-size: .88rem; color: var(--texte-faible); }
.vehicule__faits {
  display: flex; flex-wrap: wrap; gap: .35rem .5rem;
  margin-top: .3rem;
}
.vehicule__faits li {
  padding: .25rem .6rem;
  background: color-mix(in srgb, var(--texte) 7%, transparent);
  border-radius: 999px;
  font-size: .8rem; color: var(--texte-doux);
  white-space: nowrap;
}
.vehicule__lien {
  display: inline-flex; align-items: center; gap: .4rem;
  margin-top: auto; padding-top: .8rem;
  font-weight: 600; font-size: .92rem; color: var(--accent-lisible);
}
@media (hover: hover) and (pointer: fine) {
  .vehicule:hover .vehicule__lien { gap: .65rem; }
}
.occasions__source { margin-top: 2rem; text-align: center; }

/* La barre de filtres. Le fond est quasi opaque (97 %) : des photos
   défilent dessous, et à 88 % les libellés deviennent illisibles. Il ne
   se pose QU'UNE FOIS COLLÉE — posé d'emblée, il forme une pastille grise
   flottant sur rien. */
.barre-filtres {
  position: sticky; top: var(--haut-entete); z-index: 40;
  margin: 2.5rem 0 0;
  padding-block: .7rem;
  transition: background .2s, box-shadow .2s, border-color .2s;
  border-bottom: 1px solid transparent;
}
.barre-filtres[hidden] { display: none; }
.barre-filtres.est-collee {
  background: color-mix(in srgb, var(--fond) 97%, transparent);
  backdrop-filter: blur(8px);
  border-bottom-color: var(--lisere);
  box-shadow: 0 6px 20px rgba(19, 25, 29, .06);
}
/* ⚠ Une GRILLE, pas un flex-wrap. En flex avec `flex: 1; min-width: 0`,
   la zone des filtres se laissait écraser par le tri et le compteur : elle
   tombait à 15 px de large pour 483 px de contenu, et TOUS les boutons
   passaient hors écran en mobile. Une grille donne à chaque zone sa
   largeur, sans négociation. */
.barre-filtres__dedans {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: .75rem 1rem;
}
.filtres { display: flex; gap: .4rem; min-width: 0; }

@media (max-width: 860px) {
  /* Les filtres prennent toute la largeur sur leur propre ligne ; le tri
     et le compte passent dessous. */
  .barre-filtres__dedans { grid-template-columns: minmax(0, 1fr) auto; }
  .filtres { grid-column: 1 / -1; }
  /* Défilement horizontal plutôt que trois rangées collantes qui
     mangeraient l'écran. Un dégradé dit qu'il reste des filtres à droite. */
  .filtres {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    padding-bottom: .15rem;
    /* Le geste horizontal appartient à la bande, le vertical reste au
       navigateur : sans cela il devine, et la page saute pendant le
       glissement. */
    touch-action: pan-y;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 28px), transparent 100%);
  }
  .filtres::-webkit-scrollbar { display: none; }
  .filtres button { scroll-snap-align: start; }
  .barre-filtres__compte { justify-self: end; }
}
.filtres button {
  padding: .5rem .95rem;
  background: transparent; border: 1px solid var(--lisere-fort);
  border-radius: 999px; color: var(--texte-doux);
  font-size: .88rem; font-weight: 600; white-space: nowrap;
}
.filtres button[aria-pressed="true"] {
  background: var(--accent); border-color: var(--accent); color: var(--accent-texte);
}
.barre-filtres__compte { font-size: .88rem; color: var(--texte-faible); white-space: nowrap; }

/* ── Mosaïque ─────────────────────────────────────────────────────────
   Un pavage qui REMPLIT exactement ses rangées, jamais une vedette suivie
   de restes. Dix cases, quatre colonnes, quatre rangées pleines :

     ┌───────┬───┬───┐   1      : 2×2
     │   1   │ 2 │ 3 │   6,9,10 : 2×1
     │       ├───┼───┤   le reste : 1×1
     │       │ 4 │ 5 │   aucune case orpheline
     ├───────┼───┼───┤
     │   6   │ 7 │ 8 │
     ├───────┼───┴───┤
     │   9   │  10   │
     └───────┴───────┘

   Les légendes sont TOUJOURS lisibles, sur un dégradé posé au pied de
   chaque case. Cachées derrière un survol, elles n'existent pas sur une
   tablette — et le visiteur ne sait pas ce qu'il regarde. */

.mosaique {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: minmax(0, clamp(9rem, 13vw, 13.5rem));
  gap: .5rem;
  margin-top: 3rem;
}

.mosaique__case {
  position: relative;
  padding: 0; border: 0;
  border-radius: 10px;
  overflow: hidden;
  background: var(--fond-doux);
  cursor: zoom-in;
  isolation: isolate;
}
.mosaique__case img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .8s cubic-bezier(.22, 1, .36, 1);
}
@media (hover: hover) and (pointer: fine) {
  .mosaique__case:hover img { transform: scale(1.06); }
}
.mosaique__case:focus-visible img { transform: scale(1.06); }

/* Le dégradé qui porte la légende. Il vit dans un pseudo-élément pour ne
   pas alourdir le HTML de dix cases. */
.mosaique__case::after {
  content: '';
  position: absolute; inset: auto 0 0 0; height: 62%;
  background: linear-gradient(to top, rgba(10, 16, 24, .88) 0%, rgba(10, 16, 24, .42) 44%, transparent 100%);
  opacity: .92;
  transition: opacity .35s;
  pointer-events: none;
}
@media (hover: hover) and (pointer: fine) {
  .mosaique__case:hover::after { opacity: 1; }
}

.mosaique__legende {
  position: absolute; left: .85rem; right: .85rem; bottom: .75rem;
  z-index: 1;
  color: #fff;
  font-size: .82rem; font-weight: 500; line-height: 1.3;
  text-align: left;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .5);
  transform: translateY(2px);
  transition: transform .35s cubic-bezier(.22, 1, .36, 1);
}
@media (hover: hover) and (pointer: fine) {
  .mosaique__case:hover .mosaique__legende { transform: none; }
}

/* La loupe, discrète, qui dit que la case s'ouvre. */
.mosaique__case::before {
  content: '';
  position: absolute; top: .7rem; right: .7rem; z-index: 2;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .16) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.8' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='m15.5 15.5 4 4M10.5 7.6v5.8M7.6 10.5h5.8'/%3E%3C/svg%3E") center / 17px no-repeat;
  backdrop-filter: blur(6px);
  opacity: 0; transform: scale(.85);
  transition: opacity .3s, transform .3s cubic-bezier(.22, 1, .36, 1);
}
@media (hover: hover) and (pointer: fine) {
  .mosaique__case:hover::before { opacity: 1; transform: none; }
}
.mosaique__case:focus-visible::before { opacity: 1; transform: none; }

.mosaique__case--1  { grid-column: span 2; grid-row: span 2; }
.mosaique__case--6  { grid-column: span 2; }
.mosaique__case--9  { grid-column: span 2; }
.mosaique__case--10 { grid-column: span 2; }

/* La grande case mérite une légende plus grande. */
.mosaique__case--1 .mosaique__legende { font-size: .95rem; }

@media (max-width: 880px) {
  .mosaique { grid-template-columns: repeat(2, 1fr); grid-auto-rows: minmax(0, 10rem); }
  .mosaique__case--1 { grid-column: span 2; grid-row: span 1; }
  .mosaique__case--6, .mosaique__case--9, .mosaique__case--10 { grid-column: span 2; }
  .mosaique__case::before { opacity: 1; transform: none; }   /* pas de survol au doigt */
}
@media (max-width: 520px) {
  .mosaique { grid-template-columns: 1fr; grid-auto-rows: minmax(0, 11rem); }
  .mosaique__case, .mosaique__case--1 { grid-column: span 1; }
}

/* ── Visionneuse ──────────────────────────────────────────────────────
   ⚠ `display` CONDITIONNÉ à [open]. Un <dialog> fermé est masqué par la
   feuille du navigateur ; toute règle `display` posée sans condition
   l'écrase, et il reste un panneau noir vide que rien ne peut fermer. */

.visionneuse:not([open]) { display: none; }
.visionneuse[open] {
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-rows: 1fr auto;
  gap: .6rem;
  position: fixed; inset: 0;
  width: 100%; max-width: 100%; height: 100%; max-height: 100%;
  margin: 0; padding: clamp(.8rem, 3vw, 2rem);
  border: 0; background: rgba(10, 13, 16, .97);
  color: #fff;
  overscroll-behavior: contain;
}
.visionneuse::backdrop { background: rgba(10, 13, 16, .9); }

/* La zone d'affichage est IDENTIQUE pour tous les clichés : l'image est
   sortie du flux et centrée, si bien que ce n'est plus elle qui dicte la
   hauteur du cadre. `max-width/height` seuls laisseraient un portrait
   déborder et une vignette flotter au milieu du noir. */
.visionneuse__cadre { position: relative; grid-area: 1 / 2; min-height: 0; }
.visionneuse__cadre img {
  position: absolute; inset: 0; margin: auto;
  width: auto; height: auto;
  max-width: 100%; max-height: 100%;
  border-radius: 12px;    /* sur les vrais bords du cliché, pas sur la zone */
}

.visionneuse__fermer {
  position: absolute; top: clamp(.8rem, 3vw, 2rem); right: clamp(.8rem, 3vw, 2rem);
  z-index: 2;
  display: inline-flex; padding: .55rem;
  background: rgba(255, 255, 255, .12); border: 0; border-radius: 50%; color: #fff;
}
@media (hover: hover) and (pointer: fine) {
  .visionneuse__fermer:hover { background: rgba(255, 255, 255, .22); }
}

.visionneuse__nav {
  align-self: center;
  display: inline-flex; padding: .7rem;
  background: rgba(255, 255, 255, .1); border: 0; border-radius: 50%; color: #fff;
}
@media (hover: hover) and (pointer: fine) {
  .visionneuse__nav:hover { background: rgba(255, 255, 255, .2); }
}
.visionneuse__nav--avant { grid-area: 1 / 1; }
.visionneuse__nav--avant .ic { transform: rotate(180deg); }
.visionneuse__nav--apres { grid-area: 1 / 3; }

/* Le pied a une hauteur FIXE, pas une min-height : une légende de trois
   lignes raboterait sinon la zone du cliché. Trois colonnes, dont une
   fantôme de la largeur du compteur — sans quoi « centré » voudrait dire
   « décalé de la largeur du compteur ». */
.visionneuse__pied {
  grid-area: 2 / 1 / 3 / 4;
  display: grid;
  grid-template-columns: 4.5rem 1fr 4.5rem;
  align-items: center;
  height: 3.2rem;
}
.visionneuse__legende {
  text-align: center; font-size: .92rem; color: rgba(255, 255, 255, .82);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.visionneuse__compteur { text-align: right; font-size: .85rem; color: rgba(255, 255, 255, .55); white-space: nowrap; }

@media (max-width: 640px) {
  .visionneuse__nav { display: none; }
  .visionneuse[open] { grid-template-columns: 1fr; }
  .visionneuse__cadre { grid-area: 1 / 1; }
  .visionneuse__pied { grid-area: 2 / 1 / 3 / 2; grid-template-columns: 3rem 1fr 3rem; }
}

/* ── Appel à l'action ─────────────────────────────────────────────────── */

/* Le seul GRAND aplat de couleur du site : sans lui, l'accent ne se voit
   jamais autrement qu'en filets et en pilules. */
.appel {
  background: var(--p-bleu-surface);
  color: var(--p-blanc);
  padding-block: clamp(3.5rem, 6vw, 6rem);
}
.appel .titre-section { color: var(--p-blanc); }
.appel .chapo { color: rgba(255, 255, 255, .86); }
.appel .bouton--accent { background: var(--p-blanc); color: var(--p-bleu-surface); }
@media (hover: hover) and (pointer: fine) {
  .appel .bouton--accent:hover { background: #e6ecff; }
}
.appel .bouton--contour { color: #fff; border-color: rgba(255, 255, 255, .5); }
@media (hover: hover) and (pointer: fine) {
  .appel .bouton--contour:hover { border-color: #fff; color: #fff; background: rgba(255, 255, 255, .12); }
}
.appel__dedans {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 2rem 3rem;
}
.appel__dedans .chapo { margin-top: .8rem; }
.appel__boutons { display: flex; flex-wrap: wrap; gap: .75rem; }

/* ── Contact ──────────────────────────────────────────────────────────── */

.contact__grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr));
  gap: clamp(2.5rem, 5vw, 5rem);
  align-items: start;   /* deux colonnes de TEXTE : jamais `center` */
}

/* Une vraie grille à deux colonnes. Un `min-width` sur la clé ne suffit
   pas : chaque valeur démarrerait où finit sa clé. */
.fiche { display: grid; gap: 0; margin-top: 2rem; }
.fiche__ligne {
  display: grid;
  grid-template-columns: minmax(11rem, 15rem) 1fr;
  gap: .5rem 1.5rem;
  padding: .95rem 0;
  border-bottom: 1px solid var(--lisere);
}
.fiche dt { display: flex; align-items: center; gap: .55rem; font-weight: 600; font-size: .93rem; }
.fiche dt .ic { color: var(--accent-lisible); }
.fiche dd { color: var(--texte-doux); }
@media (hover: hover) and (pointer: fine) {
  .fiche dd a:hover { color: var(--accent-lisible); text-decoration: underline; text-underline-offset: 3px; }
}

.horaires { display: grid; margin-top: 2rem; }
.horaire {
  display: grid;
  grid-template-columns: minmax(10rem, 14rem) 1fr;
  gap: .3rem 1.5rem;
  padding: .75rem 0;
  border-bottom: 1px solid var(--lisere);
}
.horaire dt { font-weight: 600; font-size: .93rem; }
.horaire dd { display: flex; flex-wrap: wrap; gap: .25rem 1rem; color: var(--texte-doux); }
.horaire dd span { white-space: nowrap; }   /* « 8h – 12h30 » ne se coupe jamais */
.horaire .ferme { font-style: normal; color: var(--texte-faible); }

/* ── Formulaire ───────────────────────────────────────────────────────── */

.formulaire { display: flex; flex-direction: column; gap: 1.1rem; margin-top: 2.2rem; }
.formulaire__rangee {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
  gap: 1.1rem;
}

.champ { display: flex; flex-direction: column; gap: .4rem; }
/* Les libellés d'une même rangée s'alignent : un libellé long plie sur deux
   lignes, son voisin non, et les deux champs ne tombent plus à la même
   hauteur. Deux lignes de haut, texte aligné en bas. */
.champ__libelle {
  display: flex; align-items: flex-end; min-height: 2.4em;
  font-size: .88rem; font-weight: 600;
}
.champ input,
.champ textarea,
.champ select {
  width: 100%;
  /* ⚠ 16 px MINIMUM : en dessous, iOS zoome la page à la mise au point et
     ne revient jamais en arrière. La parade n'est pas `maximum-scale=1`
     (qui interdit le zoom, donc un défaut d'accessibilité) mais la
     taille du texte elle-même. */
  font-size: max(16px, 1rem);
  padding: .82rem 1rem;
  background: color-mix(in srgb, var(--fond-carte) 100%, transparent);
  border: 1px solid var(--lisere-fort);
  border-radius: var(--rayon-s);
  color: var(--texte);
  transition: border-color .16s, box-shadow .16s;
}
.champ textarea { resize: vertical; min-height: 8rem; line-height: 1.6; }
.champ input:focus, .champ textarea:focus, .champ select:focus {
  outline: 0;
  border-color: var(--accent-lisible);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}
.champ__aide { font-size: .82rem; color: var(--texte-faible); }
.champ__erreur { display: none; font-size: .82rem; color: #ff7b7b; }
.champ.est-fautif input,
.champ.est-fautif textarea { border-color: #ff7b7b; }
.champ.est-fautif .champ__erreur { display: block; }

.champ--tri { flex-direction: row; align-items: center; gap: .55rem; }
.champ--tri .champ__libelle { min-height: 0; font-size: .85rem; color: var(--texte-faible); white-space: nowrap; }

/* ⚠ Dans la barre de filtres, le select habillé héritait du gabarit des
   champs de FORMULAIRE : même padding, même corps de texte. À côté de
   pastilles de filtre de 34 px, il paraissait deux fois trop gros. Ici
   c'est un contrôle de barre, pas un champ de saisie : il s'aligne sur
   les pastilles voisines. */
.champ--tri .select-habille__bouton {
  padding: .5rem .8rem;
  font-size: .88rem; font-weight: 600;
  border-radius: 999px;
  min-height: 34px;
  gap: .4rem;
}
.champ--tri .select-habille__bouton .ic { width: 14px; height: 14px; }
.champ--tri .select-habille__liste { min-width: 12rem; }
.champ--tri .select-habille__liste button { font-size: .88rem; padding: .5rem .7rem; }

/* Le <select> natif, gardé hors de vue MAIS dans la page : c'est lui que
   le formulaire envoie, lui que le clavier pilote, lui que les lecteurs
   d'écran annoncent. L'habillage n'est qu'une couche par-dessus.
   ⚠ Les dimensions sont FORCÉES : un `width: 100%` posé sur les champs du
   formulaire l'emporterait, et le select resterait sous le doigt. */
.select-habille { position: relative; }
.select-habille > select {
  position: absolute !important;
  width: 1px !important; height: 1px !important;
  padding: 0 !important; margin: 0 !important; border: 0 !important;
  opacity: 0; pointer-events: none;
}
.select-habille__bouton {
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  width: 100%;
  padding: .82rem 1rem;
  background: var(--fond-carte);
  border: 1px solid var(--lisere-fort);
  border-radius: var(--rayon-s);
  color: var(--texte);
  text-align: left;
}
/* L'icône ne capte pas le doigt : sans cela, elementFromPoint au centre
   du bouton renvoie le chevron, et une cible de 16 px se glisse entre le
   doigt et le bouton. */
.select-habille__bouton .ic {
  color: var(--texte-faible);
  transform: rotate(90deg); transition: transform .18s;
  pointer-events: none;
}
.select-habille__bouton > span { pointer-events: none; }
.select-habille[data-ouvert] .select-habille__bouton .ic { transform: rotate(-90deg); }
.select-habille[data-ouvert] .select-habille__bouton { border-color: var(--accent-lisible); }
.select-habille__liste {
  position: absolute; left: 0; right: 0; top: calc(100% + .35rem); z-index: 30;
  display: none; flex-direction: column;
  max-height: 16rem; overflow-y: auto;
  overscroll-behavior: contain;   /* le défilement ne file pas à la page */
  padding: .3rem;
  background: var(--fond-carte);
  border: 1px solid var(--lisere-fort);
  border-radius: var(--rayon-s);
  box-shadow: var(--ombre-forte);
}
.select-habille[data-ouvert] .select-habille__liste { display: flex; }
/* Une liste qui sortirait de la fenêtre s'ouvre vers le haut. */
.select-habille[data-vers-haut] .select-habille__liste { top: auto; bottom: calc(100% + .35rem); }
.select-habille__liste button {
  padding: .6rem .75rem; border: 0; border-radius: 6px;
  background: transparent; color: var(--texte-doux);
  text-align: left; font-size: .94rem;
}
@media (hover: hover) and (pointer: fine) {
  .select-habille__liste button:hover { background: color-mix(in srgb, var(--texte) 8%, transparent); color: var(--texte); }
}
.select-habille__liste button[aria-selected="true"] { color: var(--accent-lisible); font-weight: 600; }

/* Le même composant, en sombre : le bandeau d'édition est posé sur fond
   noir, et les jetons clairs y seraient illisibles. */
.select-habille--sombre .select-habille__bouton {
  background: rgba(255, 255, 255, .08);
  border-color: rgba(255, 255, 255, .22);
  color: #fff;
}
.select-habille--sombre .select-habille__bouton .ic { color: rgba(255, 255, 255, .6); }
.select-habille--sombre .select-habille__liste {
  background: #1b2430; border-color: rgba(255, 255, 255, .18);
}
.select-habille--sombre .select-habille__liste button { color: rgba(255, 255, 255, .8); }
@media (hover: hover) and (pointer: fine) {
  .select-habille--sombre .select-habille__liste button:hover { background: rgba(255, 255, 255, .1); color: #fff; }
}
.select-habille--sombre .select-habille__liste button[aria-selected="true"] { color: var(--p-bleu-clair); }
.select-habille--sombre.choix--court { min-width: 5.2rem; }

.piege { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.formulaire__mention { font-size: .84rem; color: var(--texte-faible); max-width: 68ch; }
.formulaire__retour { padding: .9rem 1.1rem; border-radius: var(--rayon-s); font-size: .94rem; }
.formulaire__retour[hidden] { display: none; }
.formulaire__retour.est-reussi { background: rgba(46, 160, 96, .15); color: #7ee2a8; }
.formulaire__retour.est-echoue { background: rgba(224, 62, 62, .15); color: #ff9d9d; }

/* ── Carte ────────────────────────────────────────────────────────────── */

.carte-lieu {
  position: relative;
  margin-top: 2rem;
  aspect-ratio: 16 / 10;
  border-radius: var(--rayon);
  overflow: hidden;
  background: var(--fond-doux);
  border: 1px solid var(--lisere);
}
.carte-lieu iframe { width: 100%; height: 100%; border: 0; }
.carte-lieu__facade {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  background:
    radial-gradient(circle at 42% 44%, color-mix(in srgb, var(--accent) 20%, transparent) 0, transparent 46%),
    repeating-linear-gradient(45deg, color-mix(in srgb, var(--texte) 4%, transparent) 0 14px, transparent 14px 28px),
    var(--fond-doux);
}
.carte-lieu__epingle {
  position: absolute; top: 38%; left: 42%;
  color: var(--accent);
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, .3));
}
.carte-lieu__boite {
  display: flex; flex-direction: column; align-items: center; gap: .7rem;
  max-width: 22rem; margin-top: 4.5rem; padding: 1.3rem;
  background: var(--fond-carte);
  border: 1px solid var(--lisere);
  border-radius: var(--rayon-s);
  box-shadow: var(--ombre);
  text-align: center;
}
.carte-lieu__boite p { font-weight: 600; font-size: .95rem; }
.carte-lieu__boite small { font-size: .78rem; color: var(--texte-faible); line-height: 1.4; }
.carte-lieu + .bouton { margin-top: 1rem; }

/* ── Erreur 404 ───────────────────────────────────────────────────────── */

.erreur { min-height: 62svh; display: grid; place-items: center; }
.erreur__dedans { max-width: 44rem; text-align: center; }
.erreur__dedans .filet { margin-inline: auto; }
.erreur__liens { display: flex; flex-wrap: wrap; justify-content: center; gap: .6rem; margin-top: 2.5rem; }

/* ── Pied de page ─────────────────────────────────────────────────────── */

.pied { background: var(--fond); color: var(--texte); }
.pied__dedans {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: clamp(2rem, 4vw, 3.5rem);
  max-width: var(--large);
  margin-inline: auto;
  padding: clamp(3rem, 6vw, 5rem) var(--marge);
}
.pied__bloc--marque { grid-column: span 1; }
.marque--pied { margin-bottom: 1.1rem; }
.marque--pied img { width: 52px; height: 52px; border-radius: 8px; }
.pied__apropos { color: var(--texte-doux); font-size: .93rem; max-width: 26rem; }

.pied h2 {
  margin-bottom: 1.1rem;
  font: 600 .8rem/1.3 var(--texte-police);
  letter-spacing: .13em; text-transform: uppercase; color: var(--texte-faible);
}
.pied__liens { display: flex; flex-direction: column; gap: .55rem; }
.pied__liens a { font-size: .95rem; color: var(--texte-doux); }
@media (hover: hover) and (pointer: fine) {
  .pied__liens a:hover { color: var(--texte); }
}

.pied__coordonnees { display: flex; flex-direction: column; gap: .8rem; }
.pied__coordonnees li { display: flex; align-items: flex-start; gap: .6rem; font-size: .93rem; color: var(--texte-doux); }
.pied__coordonnees .ic { color: var(--accent-lisible); margin-top: .18rem; }
@media (hover: hover) and (pointer: fine) {
  .pied__coordonnees a:hover { color: var(--texte); }
}

.pied__horaires { display: grid; gap: .1rem; }
.pied__horaires .horaire { grid-template-columns: 1fr auto; padding: .45rem 0; border-color: var(--lisere); }
.pied__horaires dt { font-size: .88rem; font-weight: 500; color: var(--texte-doux); }
.pied__horaires dd { display: flex; flex-direction: column; align-items: flex-end; gap: .1rem; font-size: .85rem; }
.pied__horaires dd span { white-space: nowrap; }
.pied__horaires em { font-style: normal; color: var(--texte-faible); }

.pied__bas {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: .6rem 2rem;
  max-width: var(--large);
  margin-inline: auto;
  padding: 1.4rem var(--marge);
  border-top: 1px solid var(--lisere);
  font-size: .84rem; color: var(--texte-faible);
}
.pied__signature a { color: var(--texte-doux); }
@media (hover: hover) and (pointer: fine) {
  .pied__signature a:hover { color: var(--accent-lisible); text-decoration: underline; text-underline-offset: 3px; }
}

/* ── Barre d'action mobile ────────────────────────────────────────────
   Fond OPAQUE et séparateurs en `border-left` : avec un `gap` sur un fond
   translucide, la page défile dans les interstices. `min-height` commune
   et `nowrap` pour que les trois entrées s'alignent — d'où des libellés
   d'un seul mot. */

.barre-appel {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 80;
  display: none;
  background: var(--p-anthracite);
  border-top: 1px solid rgba(255, 255, 255, .13);
  padding-bottom: env(safe-area-inset-bottom);
}
.barre-appel a {
  flex: 1 1 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .2rem;
  min-height: 60px; padding: .55rem .3rem;
  border-left: 1px solid rgba(255, 255, 255, .13);
  color: rgba(255, 255, 255, .86);
  font-size: .76rem; font-weight: 600; white-space: nowrap;
}
.barre-appel a:first-child { border-left: 0; }
.barre-appel a:last-child { color: var(--p-bleu-clair); }

/* ── Entrées ──────────────────────────────────────────────────────────
   Seules les SUITES entrent, et chaque élément à son tour : le retard est
   posé par le script, qui seul connaît le rang.

   ⚠ L'opacité de départ n'est posée QUE si le script a démarré (html.js).
   Sans cette garde, un échec du JavaScript — ou un rendu sans JS — livre
   une page vide : la transition ne se déclenche jamais et rien
   n'apparaît. */

.js [data-entre] {
  opacity: 0;
  transform: translateY(14px);
}
.js [data-entre].est-vue {
  opacity: 1;
  transform: none;
  /* ease-out-quart : le mouvement finit doucement, sans rebond. */
  transition: opacity .5s cubic-bezier(.25, 1, .5, 1),
              transform .55s cubic-bezier(.25, 1, .5, 1);
}

/* Le trait du stepper se dessine avec la suite : il part du premier
   numéro et court vers le suivant, ce qui donne à voir l'enchaînement. */
.js .etape::after { transform-origin: left center; transform: scaleX(0); }
.js .etape.est-vue::after {
  transform: scaleX(1);
  transition: transform .5s cubic-bezier(.25, 1, .5, 1) .12s;
}
@media (max-width: 760px) {
  .js .etape::after { transform-origin: center top; transform: scaleY(0); }
  .js .etape.est-vue::after { transform: scaleY(1); }
}

/* ── L'entrée du héros ───────────────────────────────────────────────
 *
 * Le héros arrivait figé : le fond respirait, la jauge avançait, mais le
 * titre, le chapô et les boutons étaient simplement là. C'est le seul
 * endroit du site où le mouvement est attendu — la première image — et les
 * trois éléments forment une vraie suite : on dit qui on est, puis quoi,
 * puis ce qu'on peut faire. Ce n'est pas le « fondu montant sur chaque
 * section » qui signe une page engendrée.
 *
 * ── Trois décisions, et leurs raisons ───────────────────────────────
 *
 * 1. Une ANIMATION, pas une transition déclenchée par une classe. Le
 *    héros est au-dessus de la ligne de flottaison : passer par
 *    l'observateur d'intersection, c'est risquer qu'il ne se déclenche
 *    jamais (onglet caché, rendu sans fenêtre) et livrer un héros vide.
 *    Une animation CSS part toute seule, ou ne part pas du tout — et
 *    `backwards` fait que l'état de départ ne s'applique QUE pendant le
 *    délai. Sans CSS, le texte est à sa place.
 *
 * 2. Le bloc, pas les mots. Découper le titre en <span> par mot donnerait
 *    une entrée plus léchée — et casserait l'édition en ligne et le
 *    chargeur de contenu, qui écrivent le `textContent` du H1 entier.
 *    Un effet qui casse le CMS n'est pas un effet, c'est une régression.
 *
 * 3. Court. 0,62 s, décalage de 90 ms, ease-out-quart — le mouvement finit
 *    doucement, sans rebond, et tout est fini avant qu'on ait lu la
 *    deuxième ligne. Le total des délais reste sous 300 ms.
 */
@keyframes hero-entree {
  from { opacity: 0; transform: translateY(16px); }
}

.hero__texte > *,
.hero .reperes {
  animation: hero-entree .62s cubic-bezier(.25, 1, .5, 1) backwards;
}
.hero__texte > .titre-hero   { animation-delay: .05s; }
.hero__texte > .chapo        { animation-delay: .14s; }
.hero__texte > .hero__boutons{ animation-delay: .23s; }
.hero .reperes               { animation-delay: .30s; }

/* La commande du carrousel arrive en dernier : elle ne sert à rien tant
   que la première vue n'est pas lue. */
.hero__commande { animation: hero-entree .62s cubic-bezier(.25, 1, .5, 1) .38s backwards; }

@media (prefers-reduced-motion: reduce) {
  .js [data-entre],
  .js [data-entre].est-vue { opacity: 1; transform: none; transition: none; }
  .js .etape::after,
  .js .etape.est-vue::after { transform: none; transition: none; }
  .hero__texte > *,
  .hero .reperes,
  .hero__commande { animation: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  .js [data-apparait] { opacity: 1; transform: none; }
}

/* ── Paliers ──────────────────────────────────────────────────────────── */

@media (max-width: 1240px) {
  .menu { display: none; }
  .tiroir-bascule { display: inline-flex; }
}

/* Palier intermédiaire : sur une fenêtre basse (1024 × 768), les textes
   allemands poussaient les repères 9 px sous le bord. Les écarts cèdent
   avant le contenu. */
@media (max-height: 820px) and (min-width: 761px) {
  .hero { padding-top: clamp(1.4rem, 3vh, 2.4rem); }
  .hero__dedans { gap: 1.2rem; }
  .hero__boutons { margin-top: 1.3rem; }
  .hero__commande { padding-bottom: .6rem; }
  .reperes { padding-top: 1.1rem; }
}

/* Entre 1080 et 1240, le libellé du bouton d'appel part avant le menu :
   il vaut 160 px à lui seul. */
@media (max-width: 1360px) {
  .entete__appel span { display: none; }
  .entete__appel { padding: .68rem .85rem; }
}

/* Sous 900 px, seul le signe reste : le nom écrit prenait la place du
   bouton d'appel. */
@media (max-width: 900px) {
  .entete .marque__mot { display: none; }
}

/* Sous 640 px, le choix de langue quitte l'en-tête : il occupait 67 px et
   poussait le logotype hors de l'écran. Il reste accessible dans le
   tiroir, où il a sa place et de la largeur. */
@media (max-width: 640px) {
  .entete .choix-langue { display: none; }
}

@media (max-width: 860px) {
  /* La barre d'action existe : le héros doit en tenir compte, sinon ses
     repères chiffrés passent dessous. */
  :root { --barre-appel: 60px; }
  body { padding-bottom: 60px; }
  .barre-appel { display: flex; }
  /* DEUX colonnes jusqu'en bas : passés en colonne unique, quatre repères
     empilés mangent 300 px et tombent hors du premier écran.
     Les séparations sont de vraies bordures, et chaque repère garde sa
     marge intérieure — sans elle, le texte colle au bord de l'écran. */
  /* ⚠ Le voile est pensé pour le DESKTOP : sa dominante bleue est à
     GAUCHE, là où vit le texte. En mobile le texte occupe toute la
     largeur — la même dominante noie alors la photo entière et laisse un
     creux au milieu du héros. On bascule le dégradé à la VERTICALE :
     fort en haut sous le texte, effacé au centre où la photo respire,
     profond en bas sous les repères. */
  .hero__voile {
    background:
      linear-gradient(to bottom, rgba(9, 13, 20, .88) 0%, rgba(9, 13, 20, .56) 30%, rgba(9, 13, 20, .12) 52%, rgba(9, 13, 20, .92) 100%);
  }

  .reperes { grid-template-columns: repeat(2, 1fr); padding-top: 1.2rem; }
  .repere { padding: .55rem 1rem; }
  .repere:nth-child(odd) { border-left: 0; padding-left: 0; }
  .repere:nth-child(n+3) { border-top: 1px solid rgba(255, 255, 255, .13); }
  .repere b { font-size: clamp(1.15rem, 4.4vw, 1.55rem); }
  .repere > span { font-size: .74rem; margin-top: .18rem; }
  .hero__dedans { gap: 1.6rem; }
  .hero__boutons { margin-top: 1.5rem; }
}

@media (max-width: 560px) {
  .fiche__ligne, .horaire { grid-template-columns: 1fr; }
  .fiche__ligne { padding: .8rem 0; }
  .pied__horaires .horaire { grid-template-columns: 1fr auto; }
}

/* Sous 420 px, un bouton passe pleine largeur plutôt que de tronquer. */
@media (max-width: 420px) {
  .hero__boutons, .appel__boutons, .erreur__liens { flex-direction: column; align-items: stretch; }
  .hero__boutons .bouton, .appel__boutons .bouton { width: 100%; }
}

/* Sous 400 px, seul le signe de la marque reste : le nom écrit prenait
   188 px sur les 323 disponibles, et l'en-tête débordait. */
@media (max-width: 400px) {
  /* Le héros se resserre : en allemand, un surtitre sur deux lignes et un
     chapô plus long poussaient les repères 11 px sous la barre d'action.
     Les écarts cèdent avant le contenu. */
  .hero { padding-top: clamp(1.2rem, 3vh, 2rem); }
  .hero__dedans { gap: 1.1rem; }
  .hero__boutons { margin-top: 1.1rem; gap: .55rem; }
  .hero__texte .chapo--hero { margin-top: .8rem; font-size: 1rem; }
  .reperes { padding-top: .9rem; gap: .7rem 0; }
}

/* ── Cibles tactiles : 44 px au doigt ────────────────────────────────── */
/*
 * Mesuré au téléphone, pas déduit : 24 éléments cliquables tombaient sous
 * 44 px — les liens du pied à 16 px, les pastilles du carrousel à 3 px.
 * Un doigt couvre environ 9 mm ; sous 44 px on vise, on rate, on
 * recommence. La souris n'a pas ce problème, d'où le `pointer: coarse`.
 *
 * ⚠ La première version listait des CLASSES. Elle a laissé passer les
 *   liens du pied de contact, la signature, les pastilles du carrousel et
 *   la pagination — tout ce qui n'était pas dans la liste. On raisonne
 *   donc sur la STRUCTURE : un lien seul dans son conteneur est un
 *   contrôle, un lien au fil d'une phrase n'en est pas un (et WCAG 2.5.8
 *   l'exempte justement, parce que l'agrandir ferait chevaucher les
 *   lignes).
 *
 * Deux outils, et le choix n'est pas cosmétique :
 *   — REMBOURRAGE quand l'élément peut grandir sans rien déplacer ;
 *   — zone invisible en ::after quand il ne peut pas — une pastille de
 *     3 px doit RESTER de 3 px à l'œil.
 */
@media (pointer: coarse) {

  /*
   * Tous les boutons, par EXCLUSION : ainsi un bouton ajouté demain est
   * couvert d'office. Seules sortent les commandes dont la taille EST le
   * dessin — elles reçoivent une zone invisible plus bas.
   */
  /* `.bouton` compte autant que `<button>` : l'appel de l'en-tête est un
     <a class="bouton"> et échappait à la règle. */
  button:not(.hero__point):not(.select-habille__liste button),
  .bouton { min-height: 44px; }

  /* `.champ--tri .select-habille__bouton` plafonne à 34 px avec une
     spécificité de 0,2,0 : il faut la même pour la lever. */
  .champ--tri .select-habille__bouton,
  .select-habille .select-habille__bouton { min-height: 44px; }

  .select-habille__liste button { min-height: 44px; padding-block: .7rem; }
  .filtres button { padding-block: .7rem; }
  .tiroir-bascule { min-width: 44px; }
  .marque { min-height: 44px; }

  /*
   * Les liens AUTONOMES — seuls dans leur `li`, `dd`, `span`, `p` ou
   * `dt`. La zone déborde en ::after avec `content: ''` : invisible,
   * non sélectionnable, et elle ne déplace RIEN. On n'ancre en
   * `relative` que ce qui est encore `static`, sinon on délogerait un
   * élément déjà positionné.
   */
  li > a:only-child,
  dd > a:only-child,
  dt > a:only-child,
  span > a:only-child,
  p > a:only-child,
  .lien-fleche {
    position: relative;
  }
  li > a:only-child::after,
  dd > a:only-child::after,
  dt > a:only-child::after,
  span > a:only-child::after,
  p > a:only-child::after,
  .lien-fleche::after {
    content: '';
    position: absolute;
    inset: 50% 0 auto 0;
    height: 44px;
    transform: translateY(-50%);
  }
  /*
   * La pastille du carrousel : une zone en ::after y était INUTILE, parce
   * que `overflow: hidden` (qui sert à rogner la jauge) la rognait avec le
   * reste — vérifié à l'écran avec elementFromPoint, qui renvoyait le fond
   * du héros à 14 px du centre. Le CSS disait 44 px, le doigt touchait 3.
   *
   * On inverse donc : le BOUTON devient une boîte transparente de 44 px,
   * et la barre visible de 3 px descend dans un ::before qui, lui, rogne
   * la jauge. Ce qu'on voit ne change pas d'un pixel ; ce qu'on touche
   * passe de 3 px à 44.
   */
  .hero__point {
    height: 44px;
    overflow: visible;
    background: none;
    display: grid;
    align-items: center;
  }
  .hero__point::before {
    content: '';
    display: block;
    height: 3px;
    border-radius: 2px;
    background: rgba(255, 255, 255, .34);
  }
  .hero__jauge {
    inset: 50% 0 auto 0;
    height: 3px;
    border-radius: 2px;
    transform: translateY(-50%) scaleX(0);
  }
  .hero__point.est-active .hero__jauge { animation-name: hero-jauge-tactile; }

  /*
   * Une zone de 44 px sur un texte de 16 px déborde de 14 px en haut et
   * en bas : sans air entre les lignes, deux zones se chevauchent et un
   * doigt posé entre deux liens active le mauvais. On écarte donc les
   * lignes des listes de liens jusqu'à ce que les zones ne se touchent
   * plus — mesuré, pas estimé.
   */
  /*
   * Le pied n'a PAS de prose : tous ses liens sont des contrôles. On les
   * couvre donc par RÉGION et non un par un — c'est ce qui a rattrapé la
   * signature « Site refait par ReFreshWeb », où le lien n'est pas
   * `:only-child` et passait à travers la règle structurelle.
   */
  .pied a { position: relative; }
  .pied a::after {
    content: '';
    position: absolute;
    inset: 50% 0 auto 0;
    height: 44px;
    transform: translateY(-50%);
  }
  .pied__signature { padding-block: .6rem; }

  .pied__liens { gap: .4rem 1.2rem; }
  .pied__liens li,
  .pied__coordonnees li { padding-block: .5rem; }
  .contact__liste dd,
  .contact__liste dt { padding-block: .45rem; }

  /* Une case à cocher : c'est l'étiquette entière qui reçoit le doigt. */
  label:has(> input[type="checkbox"]),
  .champ--case label { min-height: 44px; display: flex; align-items: center; }
  input[type="checkbox"], input[type="radio"] { min-width: 22px; min-height: 22px; }
}
