/* =========================================================================
   SWISS PRO MOVING — base.css
   SOCLE COMMUN aux quatre pages : index, calculateur, merci, 404.

   Ce fichier a été rhabillé le 20.09.2026 par le lot L0 du cahier
   directions/site-swiss-pro-moving.md. Table de correspondance : §2.3.
   Scission de l'ancien jeton d'action : §2.4. Forme de l'erreur : §2.6.
   Titres et piles de polices : §2.2. En-tête et pied : §3.

   CE QUI VIENT DE LA MARQUE, ET QUI N'EST PAS REDIT ICI.
   Les deux @import ci-dessous apportent :
     tokens.css  — les trois couches de jetons, le socle minimal (corps,
                   .affiche/h1/h2/h3, l'anneau de focus, .coupe-rabat, .pli,
                   .puce, .chiffre, p/li { max-width }, le repli de
                   mouvement réduit) ;
     base.css    — remise à zéro, liens, listes, filets, .spm-mention,
                   .spm-chapeau, .spm-capitales, .spm-coque, .spm-section,
                   .spm-hors-ecran, .spm-evitement.
   Une règle, un seul code : si une valeur paraît manquer ici, elle est dans
   l'une de ces deux feuilles. On ne la recopie pas.

   Les quatre pages portent, DANS CET ORDRE (cahier §2.5) :
     <link rel="stylesheet" href="base.css">
     <link rel="stylesheet" href="marque/components.css">
     <link rel="stylesheet" href="marque/rayon-Composants.css">
     <link rel="stylesheet" href="marque/rayon-Marque.css">
   puis la feuille de la page : accueil.css · calculateur.css · pages.css.

   RÈGLES DE FABRICATION, contrôlées par le critère de fini de L0 :
     1. aucune couleur en dur — ni hexadécimal, ni fonction de couleur, ni
        mélange de couleurs, ni dans le code NI DANS LES COMMENTAIRES. Le
        contrôle balaie le fichier entier hors du bloc :root ; une valeur
        citée en commentaire le ferait rougir à juste titre, puisqu'elle
        serait une seconde source pour une valeur qui n'en a qu'une.
     2. aucune règle de mode sombre, sous aucune forme : le site est en mode
        clair et il y reste (§2.1). Le mode sombre de marque/tokens.css n'est
        ni supprimé ni modifié, il est simplement jamais déclenché, parce que
        les quatre pages portent <html lang="fr-CH" data-theme="light">.
     3. aucun rayon sur un rectangle : --rayon vaut 0. --rayon-rond est une
        AUTRE forme, réservée aux disques et aux anneaux du trajet (§1.6.4).
     4. aucune ombre : --ombre vaut none. La profondeur passe par
        --fond → --surface → --surface-enfoncee et par les trois filets.

   Aucune requête externe. Polices système, en attendant la licence (§2.2 et
   _A-REMPLACER.md §4).
   ========================================================================= */

/* Les deux feuilles de marque ne sont plus importées ici depuis le 21.09
   (audit mobile P2-5) : un @import ne part qu'une fois base.css reçue, et
   sur réseau lent tokens.css et marque/base.css ne démarraient qu'à 1,5 s.
   Chaque page les appelle désormais par deux <link> AVANT base.css, dans le
   même ordre : la cascade est inchangée.
     <link rel="stylesheet" href="marque/tokens.css">
     <link rel="stylesheet" href="marque/base.css"> */

/* --------------------------------------------------------------- 1. Jetons */

/* Il ne reste ICI que les propriétés LOCALES : une géométrie propre à ce
   site, que la marque ne connaît pas. Toutes les autres sont devenues des
   jetons de marque et se lisent dans marque/tokens.css.
   Ce bloc ne porte AUCUNE couleur : il n'y en a plus une seule à écrire. */

:root {
  /* Composant de la géométrie du rail, pas un pas d'espacement :
     56 = 10 + 20 + 6 + 16 + 4. Multiple de 4, donc conforme à §3.1. */
  --e20: 20px;

  /* Le couloir du calculateur n'est pas la marge de page de la marque : il
     porte le bandeau de trajet. Il reste local, et il lit l'échelle. */
  --gouttiere-calc-g: var(--e40);
  --gouttiere-calc-d: var(--e24);

  /* Grille de page. Alignée sur --marge-page de la marque (e16 / e40 /
     min(6vw, 96px)), MAIS la dissymétrie gauche-droite du palier reste sous
     768 px : la gouttière gauche est le couloir où court la ligne
     d'itinéraire, et c'est elle qui porte la ligne (§2.3). */
  --gouttiere-g: var(--e40);
  --gouttiere-d: var(--e16);

  --retrait-rail: 0px;
  --rail-in: -20px;

  /* Amplitude latérale des coudes du trajet : c'est la valeur de dx. La
     pente 2 : 1 impose dy = 2 × dx, posé par script.js (§1.4). */
  --amplitude: 10px;

  /* CORRECTION D'AXE SUR LES DEUX JETONS DE COUPE, mesurée au navigateur le
     20.09. Ce qui change est l'axe de référence, pas la forme.

     marque/tokens.css pose `--coupe-rabat: min(calc(100% / 8), 96px)` et
     `--pli-course: min(calc(100% / 6), 240px)`. Chacun de ces deux jetons
     sert à la fois de coordonnée X et de coordonnée Y dans un polygon() de
     clip-path — or un pourcentage y tombe sur la LARGEUR en X et sur la
     HAUTEUR en Y. La pente obtenue vaut donc hauteur ÷ (2 × largeur) : elle
     ne tombe sur le 1 : 2 exigé par le §1.2 du langage graphique que si
     l'élément est carré, ce qu'aucun ne sera jamais. Mesuré : 0,6173 sur le
     bloc rouge de l'accueil en 375 × 463, 0,4113 sur la photo du héros en
     375 × 309, 0,2533 et 0,2695 à 768 px. Aucune de ces valeurs n'est dans
     la liste close des pentes du §8.1.

     On échange `100%` contre `100vw` : une longueur de fenêtre vaut la même
     chose sur les deux axes, donc montée ÷ course vaut exactement 1 ÷ 2
     quelle que soit la boîte. Sur un bloc pleine largeur la course
     HORIZONTALE ne bouge pas d'un pixel — 375 ÷ 8 et 375 ÷ 6 sont ce que la
     page dessine déjà — et c'est la profondeur, seule fautive, qui se
     corrige. --pli-montee reste ce que la marque en a fait, la moitié de la
     course : il redevient juste du seul fait que sa course l'est.

     Les classes .coupe-rabat et .pli ne sont PAS recopiées ici : une règle,
     un seul code. Deux valeurs de jeton, et rien d'autre. */
  --coupe-rabat: min(calc(100vw / 8), 96px);
  --pli-course: min(calc(100vw / 6), 240px);
}

@media (min-width: 768px) {
  :root {
    --gouttiere-g: var(--e40);
    --gouttiere-d: var(--e40);
    --gouttiere-calc-g: var(--e40);
    --gouttiere-calc-d: var(--e40);
    --retrait-rail: 56px;
    --rail-in: 16px;
    --amplitude: 28px;
  }
}

@media (min-width: 1080px) {
  :root {
    --gouttiere-g: min(6vw, 96px);
    --gouttiere-d: min(6vw, 96px);
    --gouttiere-calc-g: min(6vw, 96px);
    --gouttiere-calc-d: min(6vw, 96px);
    --retrait-rail: 64px;
    --amplitude: 36px;
  }
}

/* ---------------------------------------------------------------- 2. Socle */

/* La remise à zéro, le corps, les titres, les liens, les listes et l'anneau
   de focus viennent des deux feuilles de marque. Ne restent ici que les
   règles que ce site ajoute, et le garde-fou du point d'atterrissage. */

/* Un attribut du HTML ne doit pas dépendre de la feuille de page qui se
   charge ensuite : la règle est commune aux quatre pages. */
[hidden] { display: none !important; }

/* Un titre d'arrêt porte tabindex="-1" pour recevoir le focus quand le
   script change d'écran : c'est un point d'atterrissage pour le lecteur
   d'écran, pas une commande. Chrome lui applique pourtant :focus-visible.
   Le box-shadow part avec l'outline, sinon un halo de --focus-contre de 4 px
   entoure chaque titre d'arrêt (§2.4).
   Déclarée AVANT .onglet:focus-visible (§9), de même spécificité (0,2,0) :
   l'onglet, qui est un vrai contrôle, garde son anneau par l'ordre. */
[tabindex="-1"]:focus { outline: none; box-shadow: none; }

/* RÉPARATION D'UN ÉCRASEMENT SILENCIEUX, mesurée au navigateur le 20.09.
   marque/components.css pose `box-shadow: var(--ombre)` sur .spm-btn pour
   qu'aucun défaut de navigateur ne réintroduise une ombre sous un bouton.
   Mais cette feuille se charge APRÈS marque/tokens.css, à spécificité égale
   (0,1,0) : elle emportait aussi le CONTRE-ANNEAU de l'anneau de focus, sur
   tous les boutons du site. Relevé au navigateur : anneau de 2 px présent,
   contre-anneau `none`, sur le bouton principal — là où §2.4 décrit un
   anneau doublé.
   L'anneau noir restait visible — il se pose en dehors du bouton, sur le
   fond blanc — donc ce n'était pas une rupture d'accessibilité ici. Mais le
   contre-anneau est ce qui fait tenir le focus sur une surface teintée, et
   c'est écrit dans le cahier. On le rend, au seul état où il sert.
   ⚠️ À remonter au design system : le défaut est dans components.css, que ce
   site copie sans le toucher (contrôle md5). Signalé, pas corrigé là-bas. */
.spm-btn:focus-visible {
  box-shadow: 0 0 0 calc(var(--focus-epaisseur) + var(--focus-decalage))
              var(--focus-contre);
}

/* address n'est pas en italique (§3.3 point 5). La feuille documents.css de
   la marque le corrige, mais le site ne la charge pas. */
address { font-style: normal; }

/* Micro-texte du site. C'est --t-petit de la marque (0,875 rem), et NON son
   --t-micro, qui vaut 0,8125 rem et sert aux mentions légales. */
.micro {
  font-size: var(--t-petit);
  line-height: var(--interligne-petit);
  color: var(--texte-secondaire);
}

/* Forme locale de .spm-hors-ecran, employée par le balisage des quatre
   pages. Les deux font le même travail : on met l'une OU l'autre sur un
   élément, jamais les deux. */
.visuellement-cache {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Lien d'évitement. Position fixe, donc calée sur la fenêtre quoi qu'il
   arrive, et un déplacement de 200 % de sa propre hauteur vers le haut au
   repos. Aucune transition : rien à replier sous prefers-reduced-motion.
   Forme locale de .spm-evitement ; même remarque que ci-dessus. */
.saut {
  position: fixed;
  left: var(--e8);
  top: var(--e8);
  z-index: calc(var(--z-bandeau) + 1);
  padding: var(--e12) var(--e16);
  background: var(--fond);
  border: var(--filet-epaisseur) solid var(--filet-fort);
  border-radius: var(--rayon);
  color: var(--texte);
  font-size: var(--t-petit);
  font-weight: var(--graisse-gras);
  text-decoration: none;
  transform: translateY(-200%);
  /* Opacité nulle au repos EN PLUS du déplacement (DA 29.09, D1) : une
     capture « au-delà de la fenêtre » (Playwright, élément plus haut que
     l'écran) peint aussi ce qui est au-dessus du bord haut, et la boîte
     apparaissait sur les 13 captures de #carte sans jamais avoir le focus.
     Toujours focalisable : l'opacité ne retire rien au clavier. */
  opacity: 0;
}

.saut:focus-visible { transform: translateY(0); opacity: 1; }

/* ------------------------------------------------------- 3. Grille de page */

.bande {
  display: grid;
  grid-template-columns:
    [pleine-d] minmax(var(--gouttiere-g), 1fr)
    [texte-d] minmax(0, var(--largeur-max))
    [texte-f] minmax(var(--gouttiere-d), 1fr)
    [pleine-f];
}

.bande > * {
  grid-column: texte-d / texte-f;
  padding-left: var(--retrait-rail);
}

.bande > .bord-droit { grid-column: texte-d / pleine-f; }

.bande > .pleine-largeur {
  grid-column: pleine-d / pleine-f;
  padding-left: 0;
}

/* ------------------------------------------------------------- 4. Surfaces */

/* La seule profondeur du site : le passage --fond vers --surface.
   Aucune ombre, aucun flou, aucun dégradé, aucun rayon. */
.panneau {
  position: relative;
  max-width: 520px;
  padding: var(--e24);
  background: var(--surface);
  border-radius: var(--rayon);
}

@media (min-width: 768px) { .panneau { padding: var(--e32); } }

/* --------------------------------------------------------------- 5. Champs */

/* SECTION SUPPRIMÉE au rhabillage. Les champs du site sont désormais ceux du
   paquet de marque : .spm-formulaire, .spm-groupe, .spm-etiquette,
   .spm-champ (+ --erreur, --nombre), .spm-aide, .spm-facultatif, .spm-case,
   .spm-nlpd, dans marque/components.css §2. Règle de non-recouvrement du
   cahier §2.5 : une classe spm-* et une classe locale ne portent jamais la
   même propriété sur le même élément ; quand le besoin se recouvre, c'est la
   classe spm-* qui gagne et la locale disparaît.
   Le numéro de section est conservé pour que _COMPOSANTS.md continue de
   renvoyer aux sections par leur numéro. Idem pour 7 bis et 8. */

/* ---------------------------------------------------- 6. Messages d'erreur */

/* L'erreur change de FORME en même temps que de couleur, et c'est le point :
   dans une marque rouge, la couleur seule ne distingue plus une alerte d'un
   appel à l'action (§2.6, fondations.md §1.4). Trois signaux, pas un :
     aplat rouge plein    marque oui · erreur JAMAIS
     filet gauche de 3 px marque jamais · erreur OUI, c'est sa forme
     porte du blanc       marque oui · erreur jamais
     pictogramme          marque aucun · erreur TRIANGLE, et il est seul
   Le triangle est #i-int-alerte dans icones.svg, l. 87. Il existe déjà, il
   est le seul du jeu de 92, on n'en dessine pas un second et on ne renomme
   pas celui-là.
   Garde-fou de mise en page : aucun message d'erreur ne partage son bloc
   avec un bouton rouge. Le résumé d'erreurs est AU-DESSUS du formulaire, le
   bouton principal est dans la barre basse. */

/* Message sous un champ. Forme locale de .spm-erreur-champ, avec en plus la
   mise en ligne du triangle. Une seule des deux classes par élément. */
.message-erreur {
  display: flex;
  align-items: flex-start;
  gap: var(--e8);
  margin-top: var(--e8);
  max-width: var(--mesure);
  font-size: var(--t-petit);
  line-height: var(--interligne-petit);
  font-weight: var(--graisse-medium);
  color: var(--erreur);
}

.message-erreur .picto {
  flex: none;
  width: 14px;
  height: 14px;
  margin-top: .2em;
  fill: none;
  stroke: currentColor;
  stroke-width: var(--icone-trait);
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Résumé d'erreurs, en tête de formulaire. Cette classe ne porte QUE la mise
   en page et la liste : la surface, l'encre et le filet gauche de 3 px
   viennent de .spm-alerte--erreur, qu'elle accompagne.
   L'idiome est donc :
     <div class="spm-alerte spm-alerte--erreur resume-erreurs" role="alert">
   Aucune propriété n'est écrite deux fois sur le même élément. */
.resume-erreurs {
  display: block;
  margin-bottom: var(--e24);
}

.resume-erreurs p { font-size: var(--t-petit); color: inherit; }

.resume-erreurs ul { margin-top: var(--e8); padding-left: 0; list-style: none; }

.resume-erreurs li + li { margin-top: var(--e4); }

.resume-erreurs a {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  font-size: var(--t-petit);
  color: inherit;
  text-underline-offset: .22em;
}

/* --------------------------------------------------- 7. Groupe de pastilles */

/* Sert au nombre de pièces, à l'étage, à l'ascenseur. Le rond a disparu avec
   le rhabillage : --rayon vaut 0 et --rayon-rond est réservé aux disques et
   aux anneaux du trajet (§1.6.4). Ce qui distingue une pastille d'un onglet
   n'est plus sa forme mais sa surface pleine une fois choisie. */

.pastilles { min-width: 0; margin: 0; padding: 0; border: 0; }

/* --cols vaut 4 par défaut (l'étage : 4 x 52 + 3 x 10 = 238 px sur 311
   utiles à 375 px). --cols-large reprend --cols au-delà de 768 px si rien
   n'est dit. */
.pastilles-liste {
  display: grid;
  grid-template-columns: repeat(var(--cols, 4), 52px);
  gap: 10px;
  justify-content: start;
  margin: 0;
  padding-left: 0;
  list-style: none;
}

.pastilles-liste > li + li { margin-top: 0; }

/* Le nombre de pièces garde ses deux rangées de trois sous 768 px. */
.pastilles-pieces { --cols: 3; --cols-large: 6; }

/* Pastilles larges (« Avec ascenseur ») : jamais plus de quatre par rangée. */
.pastilles-liste-large {
  display: flex;
  flex-wrap: wrap;
  grid-template-columns: none;
}

@media (min-width: 768px) {
  .pastilles-liste { grid-template-columns: repeat(var(--cols-large, var(--cols, 4)), 52px); }
  .pastilles-liste-large { grid-template-columns: none; }
}

.pastille { position: relative; }

.pastille input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}

.pastille label {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  width: 52px;
  height: 52px;
  border: var(--filet-epaisseur) solid var(--filet-fort);
  border-radius: var(--rayon);
  color: var(--texte);
  cursor: pointer;
  transition:
    border-color var(--duree-instant) var(--entree),
    background-color var(--duree-instant) var(--entree);
}

.pastille-large label {
  width: auto;
  height: 52px;
  padding: 0 var(--e20);
  font-size: 15px;
  font-weight: var(--graisse-gras);
  white-space: nowrap;
}

.pastille-chiffre {
  font-family: var(--police-chiffre);
  font-size: 17px;
  line-height: 1;
  letter-spacing: .02em;
}

/* Grille 3 x 2 de carrés de 5 unités, SVG de 14 px de haut, trait de 1,25 px
   d'écran (non-scaling-stroke, sinon l'échelle du viewBox l'épaissit). */
.pastille-icone { display: block; height: 14px; width: auto; }
.pastille-icone .carre-plein { fill: currentColor; }

.pastille-icone .carre-vide {
  fill: none;
  stroke: var(--filet-fort);
  stroke-width: 1.25;
  vector-effect: non-scaling-stroke;
}

.pastille-icone .plus {
  fill: none;
  stroke: currentColor;
  stroke-width: var(--icone-trait);
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.pastille label:hover { border-color: var(--texte); }

/* Choisie : surface de marque, encre de contre-marque. C'est l'un des emplois
   de --marque hors bouton que §2.4 autorise. */
.pastille input:checked + label {
  background: var(--marque);
  border-color: var(--marque);
  color: var(--sur-marque);
}

.pastille input:checked + label .carre-vide { stroke: var(--sur-marque); }

/* L'anneau sans teinte de la marque, recopié parce qu'il se pose ici sur le
   label et non sur le contrôle, qui est hors écran. */
.pastille input:focus-visible + label {
  outline: var(--focus-epaisseur) solid var(--focus);
  outline-offset: var(--focus-decalage);
  box-shadow: 0 0 0 calc(var(--focus-epaisseur) + var(--focus-decalage)) var(--focus-contre);
}

.pastille input:disabled + label { opacity: .5; cursor: not-allowed; }

/* ---------------------------------------------------- 7 bis. Case à cocher */

/* SECTION SUPPRIMÉE au rhabillage : c'est .spm-case de marque/components.css,
   avec sa case de 20 px teintée par accent-color et son étiquette cliquable.
   Numéro conservé, voir la note du §5. */

/* -------------------------------------------------------------- 8. Boutons */

/* SECTION SUPPRIMÉE au rhabillage : ce sont .spm-btn et ses variantes
   --primaire, --secondaire, --fantome, --petit, --grand, --bloc, plus le
   groupe .spm-btns, dans marque/components.css §1.
   Un seul bouton principal par fenêtre, et c'est le seul aplat rouge de la
   fenêtre : il ne coexiste jamais avec le grand aplat de marque (§1.5).
   Numéro conservé, voir la note du §5. */

/* ----------------------------------------------------- 9. Onglets de pièce */

/* Le rail est un trait, l'onglet choisi porte un trait intérieur, et jamais
   une ombre portée. Le trait intérieur passe en --marque : un seul onglet est
   choisi à la fois, donc un seul rouge (§2.4). */

.onglets {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  margin: 0;
  padding-left: 0;
  list-style: none;
  border-bottom: var(--filet-epaisseur) solid var(--filet-fort);
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.onglets::-webkit-scrollbar { display: none; }

.onglets > li + li { margin-top: 0; }

.onglet {
  flex: none;
  scroll-snap-align: start;
  display: inline-flex;
  align-items: center;
  gap: var(--e8);
  height: 44px;
  padding: 0 var(--e16);
  background: none;
  border: 0;
  border-radius: var(--rayon);
  color: var(--texte-secondaire);
  font-family: var(--police-texte);
  font-size: 15px;
  font-weight: var(--graisse-gras);
  white-space: nowrap;
  cursor: pointer;
}

.onglet[aria-selected="true"] {
  color: var(--texte);
  box-shadow: inset 0 -2px 0 var(--marque);
}

/* Zéro objet : pas de nombre du tout, plutôt qu'un « 0 ». */
.onglet-compte {
  font-family: var(--police-chiffre);
  font-size: 13px;
  letter-spacing: .04em;
  color: var(--texte-secondaire);
}

/* Vers l'intérieur, sinon l'anneau déborde du rail. Le contre-anneau blanc
   de la marque est retiré ici : posé en négatif il masquerait le trait de
   l'onglet choisi, qui passe juste dessous. */
.onglet:focus-visible {
  outline: var(--focus-epaisseur) solid var(--focus);
  outline-offset: calc(var(--focus-decalage) * -4);
  box-shadow: none;
}

/* Les sept onglets mesurent ensemble environ 950 px et la colonne de
   formulaire 792 px : à 1440 px, le dernier s'affichait réduit à une lettre
   suivie d'un chevron. Une deuxième rangée de 44 px, prise sur le vide déjà
   présent sous le formulaire. */
@media (min-width: 1080px) {
  .onglets { flex-wrap: wrap; overflow-x: visible; }
}

/* --------------------------------------------- 10. Case d'objet et compteur */

/* Chaque case est un contrôle, il y en a dix à seize par onglet : c'est un
   sélecteur, pas une grille de cartes clonées. Le rhabillage remplace les
   pictogrammes au trait par les images d'objet (§5.3) ; la hauteur de la
   tuile et la grille de la planche sont reprises par calculateur.css, qui
   est propriété de L2. Ici ne restent que le cadre, le nom, le volume et le
   compteur, communs à toute page qui afficherait une case. */

.planche {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--e12);
  margin: 0;
  padding-left: 0;
  list-style: none;
}

.planche > li + li { margin-top: 0; }

@media (min-width: 768px) {
  .planche { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--e16); }
}

@media (min-width: 1080px) {
  .planche { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

.case-objet {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: var(--e12);
  background: transparent;
  border: var(--filet-epaisseur) solid var(--filet-fort);
  border-radius: var(--rayon);
  transition: border-color var(--duree-instant) var(--entree);
}

.case-objet .picto {
  flex: none;
  width: 36px;
  height: 36px;
  color: var(--texte-secondaire);
  fill: none;
  stroke: currentColor;
  stroke-width: var(--icone-trait);
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Deux lignes réservées pour que toutes les cases s'alignent quel que soit
   le nom, et coupe par des points de suspension au-delà. */
.case-nom {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  margin-top: var(--e8);
  min-height: 38px;
  max-width: none;
  font-size: 15px;
  line-height: 1.25;
  color: var(--texte-secondaire);
}

.case-volume {
  margin-top: 2px;
  max-width: none;
  font-family: var(--police-chiffre);
  font-size: 12px;
  line-height: 15px;
  letter-spacing: .03em;
  color: var(--texte-secondaire);
}

.case-objet .compteur { margin-top: auto; }

.case-objet.est-comptee { border-color: var(--marque); }
.case-objet.est-comptee .case-nom { color: var(--texte); }

/* Le repère de ce qui est chargé dans le camion. L'information n'est jamais
   portée par la seule couleur : le compteur affiche aussi un nombre.
   Un carré, pas un disque : --rayon-rond appartient au trajet (§1.6.4). */
.case-objet.est-comptee::after {
  content: "";
  position: absolute;
  top: var(--e8);
  right: var(--e8);
  width: 6px;
  height: 6px;
  border-radius: var(--rayon);
  background: var(--marque);
}

.case-libre { border-style: dashed; }
.case-libre .picto { color: var(--filet-fort); }

.case-onglet {
  position: absolute;
  top: var(--e8);
  right: var(--e12);
  max-width: none;
  font-family: var(--police-chiffre);
  font-size: 12px;
  letter-spacing: .03em;
  color: var(--texte-secondaire);
}

.compteur {
  display: grid;
  grid-template-columns: 40px 1fr 40px;
  align-items: center;
  height: 44px;
}

.compteur-moins,
.compteur-plus {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  background: none;
  border: var(--filet-epaisseur) solid var(--filet-fort);
  border-radius: var(--rayon);
  color: var(--texte);
  cursor: pointer;
  transition: border-color var(--duree-instant) var(--entree);
}

/* Zone tactile portée à 44 x 44 px sans changer le carré visible. */
.compteur-moins::after,
.compteur-plus::after { content: ""; position: absolute; inset: -2px; }

.compteur-moins:hover,
.compteur-plus:hover { border-color: var(--texte); }

.compteur-moins .picto,
.compteur-plus .picto {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: var(--icone-trait);
  stroke-linecap: round;
}

.compteur-moins[aria-disabled="true"],
.compteur-plus[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }

.compteur-valeur {
  width: 100%;
  height: 40px;
  padding: 0;
  background: transparent;
  border: 0;
  color: var(--texte);
  font-family: var(--police-chiffre);
  font-size: 20px;
  letter-spacing: .02em;
  text-align: center;
  -moz-appearance: textfield;
  appearance: textfield;
}

.compteur-valeur::-webkit-outer-spin-button,
.compteur-valeur::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* ----------------------------------------------- 11. Zone de dépôt d'images */

/* Maquette : URL.createObjectURL et affichage seulement. Aucun envoi, aucun
   fetch, aucun domaine externe. */

.depot {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--e12);
  min-height: 140px;
  padding: var(--e24);
  background: transparent;
  border: var(--filet-epaisseur) dashed var(--filet-fort);
  border-radius: var(--rayon);
}

/* Aucun changement de taille au survol du dépôt. */
.depot.est-survole {
  border-style: solid;
  border-color: var(--marque);
  background: var(--surface);
}

.depot .picto {
  width: 40px;
  height: 40px;
  color: var(--filet-fort);
  fill: none;
  stroke: currentColor;
  stroke-width: var(--icone-trait);
  stroke-linecap: round;
  stroke-linejoin: round;
}

.depot-titre { font-size: 17px; color: var(--texte); }
.depot-ou { font-size: var(--t-petit); color: var(--texte-secondaire); }

.vignettes {
  display: grid;
  grid-template-columns: repeat(auto-fill, 72px);
  gap: var(--e12);
  margin: var(--e16) 0 0;
  padding-left: 0;
  list-style: none;
}

.vignettes > li + li { margin-top: 0; }

.vignette { position: relative; width: 72px; height: 72px; }

.vignette img {
  width: 72px;
  height: 72px;
  object-fit: cover;
  border: var(--filet-epaisseur) solid var(--filet-fort);
  border-radius: var(--rayon);
}

/* Repli du HEIC : Safari l'affiche, Chrome et Firefox non. Même encombrement,
   le nom du fichier à la place de l'image. La photo reste comptée. */
.vignette-repli {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--e4);
  width: 72px;
  height: 72px;
  padding: var(--e4);
  border: var(--filet-epaisseur) solid var(--filet-fort);
  border-radius: var(--rayon);
}

.vignette-repli .picto { width: 20px; height: 20px; }

.vignette-nom {
  max-width: 100%;
  overflow: hidden;
  font-family: var(--police-chiffre);
  font-size: 11px;
  line-height: 1.2;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--texte-secondaire);
}

.vignette-retrait {
  position: absolute;
  top: -6px;
  right: -6px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  background: var(--fond);
  border: var(--filet-epaisseur) solid var(--filet-fort);
  border-radius: var(--rayon);
  color: var(--texte);
  cursor: pointer;
}

.vignette-retrait .picto {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: var(--icone-trait);
  stroke-linecap: round;
}

/* ------------------------------------------ 12. Bandeau de progression A à B */

/* C'est la ligne d'itinéraire de l'accueil, couchée. Pas de pastille
   numérotée. Hauteur 56 px partout : 10 + 20 + 6 + 16 + 4.
   merci.html et 404.html en affichent une version figée.
   Les tailles viennent des jetons de composant --trajet-* de la marque, et
   les deux couleurs sont celles de §1.4 : --trajet-parcouru pour la part
   faite, --trajet-restant pour ce qui reste. Deux jetons, pas trois. */

.bandeau-trajet {
  position: sticky;
  top: 0;
  z-index: var(--z-bandeau);
  height: 56px;
  padding: 10px var(--gouttiere-calc-d) 4px var(--gouttiere-calc-g);
  background: var(--fond);
  border-bottom: var(--filet-epaisseur) solid var(--filet-fort);
}

.rail { position: relative; height: var(--e20); }

/* 24 px de marge de chaque côté. */
.rail-piste {
  position: absolute;
  left: 24px;
  right: 24px;
  top: 9px;
  height: var(--trajet-trait);
  background: var(--trajet-restant);
}

.rail-parcouru {
  display: block;
  width: calc(var(--avancement, 0) * 100%);
  height: var(--trajet-trait);
  background: var(--trajet-parcouru);
  transition: width var(--trajet-duree) var(--trajet-courbe);
}

.rail-depart {
  position: absolute;
  left: 24px;
  top: 10px;
  width: var(--trajet-depart-taille);
  height: var(--trajet-depart-taille);
  margin: calc(var(--trajet-depart-taille) / -2) 0 0 calc(var(--trajet-depart-taille) / -2);
  border-radius: var(--rayon-rond);
  background: var(--trajet-parcouru);
}

/* Chaque arrêt porte sa position sur le rail par --t, de 0 à 1. */
.rail-arret {
  position: absolute;
  top: 10px;
  left: calc(24px + var(--t, 0) * (100% - 48px));
  transform: translate(-50%, -50%);
  width: 44px;
  height: 44px;
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
}

.rail-arret::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--trajet-arret-taille);
  height: var(--trajet-arret-taille);
  margin: calc(var(--trajet-arret-taille) / -2) 0 0 calc(var(--trajet-arret-taille) / -2);
  background: var(--fond);
  border: 2px solid var(--trajet-parcouru);
  border-radius: var(--rayon-rond);
}

.rail-arret.est-franchi::before { background: var(--trajet-parcouru); }
.rail-arret:disabled { cursor: default; }

.rail-arret:focus-visible {
  outline: var(--focus-epaisseur) solid var(--focus);
  outline-offset: -8px;
  box-shadow: none;
}

/* L'anneau d'arrivée se ferme par stroke-dashoffset : il lui faut un SVG. */
.rail-arrivee {
  position: absolute;
  top: 10px;
  right: 24px;
  width: var(--trajet-arrivee-taille);
  height: var(--trajet-arrivee-taille);
  margin: calc(var(--trajet-arrivee-taille) / -2) calc(var(--trajet-arrivee-taille) / -2) 0 0;
  overflow: visible;
}

.rail-arrivee circle {
  fill: none;
  stroke: var(--trajet-parcouru);
  stroke-width: var(--trajet-arrivee-trait);
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  transition: stroke-dashoffset 400ms var(--trajet-courbe);
}

.rail-arrivee.est-complet circle { stroke-dashoffset: 0; }

/* Un décalage de tiret égal à la longueur du tracé ne dessine rien : sans ce
   cercle de repos l'anneau d'arrivée restait invisible pendant TOUT le
   remplissage, et le rail s'arrêtait net sur rien alors que la page vend un
   trajet de A vers B. Le cercle de repos dit « l'arrivée est là » en
   --trajet-restant ; le rouge dit « vous y êtes ».
   Le balisage qui va avec, dans calculateur.html et les deux pages :
     <circle class="rail-arrivee-repos" cx="10" cy="10" r="8"/>
   posé AVANT le cercle animé, dans le même <svg class="rail-arrivee">. */
.rail-arrivee .rail-arrivee-repos {
  fill: var(--fond);
  stroke: var(--trajet-restant);
  stroke-width: var(--trajet-arrivee-trait);
  stroke-dasharray: none;
  stroke-dashoffset: 0;
  transition: none;
}

.rail-libelles {
  position: relative;
  height: var(--e16);
  margin-top: 6px;
  max-width: none;
  font-family: var(--police-chiffre);
  font-size: 12px;
  line-height: var(--e16);
  letter-spacing: .03em;
  color: var(--texte-secondaire);
}

.rail-lieu { position: absolute; top: 0; white-space: nowrap; }
.rail-lieu-depart { left: 0; }
.rail-lieu-arrivee { right: 0; }

/* Sous 768 px, seules les deux communes restent : les noms d'arrêt seraient
   illisibles à 311 px et ils sont déjà dans le <h2> juste en dessous. */
.rail-nom {
  position: absolute;
  top: 0;
  left: calc(24px + var(--t, 0) * (100% - 48px));
  transform: translateX(-50%);
  white-space: nowrap;
  display: none;
}

@media (min-width: 768px) {
  .rail-nom { display: block; }
  .rail-nom.est-courant { color: var(--texte); }
}

/* --------------------------------------------------------- 13. Récapitulatif */

/* Aucune ombre, aucun rayon. Ce panneau est désormais sur --surface : la
   paire --texte-secondaire sur --surface est l'une des paires NOUVELLES que
   le chantier crée, et le banc de L4 la mesure (§2.7).
   Ce que le récapitulatif rend n'est plus un montant : c'est un volume, une
   équipe, un camion, et « Prix sur devis » (§1.3 et §5.5). */

.recap {
  background: var(--surface);
  border-radius: var(--rayon);
  padding: var(--e24);
}

@media (min-width: 768px) { .recap { padding: var(--e32); } }

.recap-titre { font-size: var(--t-h3); color: var(--texte); }

.recap-lignes { margin: var(--e16) 0 0; padding-left: 0; list-style: none; }

.recap-ligne {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e16);
  margin-top: 0;
  padding: var(--e12) 0;
  border-top: var(--filet-epaisseur) solid var(--filet);
}

.recap-libelle { max-width: none; font-size: 15px; color: var(--texte-secondaire); }

/* Huit des libellés du récapitulatif sont des boutons de texte qui ramènent
   à leur arrêt ; les autres sont calculés. Les onze partagent une taille,
   une graisse et une couleur, sinon les libellés modifiables crient plus
   fort que les valeurs qu'ils décrivent. Réglage CONTEXTUEL du composant :
   il ne vit que dans le récapitulatif, et .spm-btn--fantome garde partout
   ailleurs son encre de marque. */
.recap-libelle .spm-btn--fantome {
  min-height: 32px;
  padding: 0;
  font-size: 15px;
  font-weight: var(--graisse-normale);
  color: var(--texte-secondaire);
  text-decoration: underline;
  text-decoration-color: var(--filet-fort);
  text-underline-offset: .22em;
}

.recap-libelle .spm-btn--fantome:hover,
.recap-libelle .spm-btn--fantome:focus-visible {
  color: var(--texte);
  text-decoration-color: var(--marque);
}

.recap-valeur {
  max-width: none;
  font-family: var(--police-chiffre);
  font-size: var(--e16);
  letter-spacing: .02em;
  text-align: right;
  color: var(--texte);
}

.recap-valeur-note {
  display: block;
  font-size: 13px;
  color: var(--texte-secondaire);
}

/* Le récapitulatif redit le trajet : un trait de 1 px court entre le repère
   du départ et celui de l'arrivée. C'est le seul autre endroit, avec le
   rail, où --rayon-rond a le droit de servir. */
.recap-trajet { position: relative; }

.recap-trajet::before {
  content: "";
  position: absolute;
  left: 3px;
  top: calc(var(--e12) + .7em);
  bottom: calc(var(--e12) + .7em);
  width: var(--filet-epaisseur);
  background: var(--trajet-restant);
}

.recap-trajet .recap-libelle {
  display: flex;
  align-items: baseline;
  gap: var(--e12);
}

.recap-point,
.recap-anneau {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: var(--rayon-rond);
  transform: translateY(-1px);
}

.recap-point { background: var(--trajet-parcouru); }

.recap-anneau {
  background: var(--fond);
  border: var(--trajet-arrivee-trait) solid var(--trajet-parcouru);
}

.recap-total {
  margin-top: var(--e16);
  padding-top: var(--e16);
  border-top: var(--filet-epaisseur) solid var(--filet-fort);
}

.recap-total-libelle { font-size: 15px; color: var(--texte-secondaire); }

/* Aucune transition : pas de compteur qui défile, pas de fondu. La valeur
   change, c'est tout. */
.recap-montant {
  margin-top: var(--e4);
  max-width: none;
  font-family: var(--police-chiffre);
  font-size: 32px;
  line-height: 1.1;
  letter-spacing: .01em;
  color: var(--texte);
}

.recap-notes { margin: var(--e12) 0 0; padding-left: 0; list-style: none; }
.recap-notes li + li { margin-top: var(--e8); }

.recap-notes li {
  max-width: var(--mesure);
  font-size: var(--t-petit);
  line-height: var(--interligne-petit);
  color: var(--texte-secondaire);
}

/* ------------------------------------------------------------ 14. État vide */

/* Aucune boîte, aucun cadre plein. Aligné à gauche comme tout le reste.
   Une invitation à agir, pas une humeur. */

.etat-vide {
  padding: var(--e40) 0;
  border-top: var(--filet-epaisseur) dashed var(--filet-fort);
  border-bottom: var(--filet-epaisseur) dashed var(--filet-fort);
}

.etat-vide .picto {
  width: 40px;
  height: 40px;
  color: var(--filet-fort);
  fill: none;
  stroke: currentColor;
  stroke-width: var(--icone-trait);
  stroke-linecap: round;
  stroke-linejoin: round;
}

.etat-vide-titre { margin-top: var(--e16); font-size: 18px; color: var(--texte); }
.etat-vide-texte { margin-top: var(--e8); font-size: 15px; color: var(--texte-secondaire); }
.etat-vide .spm-btn { margin-top: var(--e24); }

/* ------------------------------------------------- 15. En-tête et pied de page */

/* Les quatre pages portent le même pied, au caractère près, et un en-tête à
   quatre variantes dont seule la dernière balise <a> change (§3).
   Le balisage prêt à coller est dans _SOCLE.md. */

/* .spm-entete et .spm-pied posent une surface, un filet et un rythme ; la
   classe .bande pose la grille de page qui centre la colonne de 1240 px.
   Les deux portent « display », et la feuille de marque se charge APRÈS
   base.css : sans cette ligne, le flex de la marque écraserait la grille et
   l'en-tête perdrait son alignement sur le reste de la page.
   C'est la seule dérogation déclarée à la règle de non-recouvrement du §2.5,
   et elle est étroite : trois propriétés, sur deux éléments, nommés.
   La gouttière de grille repasse à zéro (le couloir du trajet ne traverse ni
   l'en-tête ni le pied), et --retrait-rail aussi. */
.spm-entete.bande,
.spm-pied.bande {
  display: grid;
  gap: 0;
  --retrait-rail: 0px;
}

/* La rangée de l'en-tête. À partir de 600 px : logo à gauche, navigation et
   action à droite, tout passe à la ligne sans script.

   ⚠️ SOUS 600 px l'en-tête se REPLIE — corrigé le 20.09 après mesure.
   « Tout passe à la ligne » ne repliait rien du tout : à 375 px le flex
   empilait le logo (81 px), les trois liens sur deux lignes ragées (74 px)
   et l'action (53 px), séparés par deux gouttières de 24 px — 290 px
   d'en-tête sur les 812 px du premier écran, mesuré au navigateur sur les
   quatre pages avant correction. L'accueil n'ouvrait plus sur sa photo, et
   sur le calculateur la première question arrivait sous le pli.

   La forme repliée est celle arbitrée par le chef de chantier : le logo, et
   l'action de la page. Rien d'autre.

   Pourquoi les trois liens sortent au lieu de se resserrer : mis bout à
   bout ils mesurent 364 px à 14 px, pour une colonne de 319 px à 375 px.
   Ils tiennent donc sur deux lignes à toute taille encore lisible, et deux
   lignes serrées ne rendent qu'une trentaine de pixels sur les 74 — la
   hauteur reste, et les cibles tactiles tombent sous les 24 px. Un menu qui
   s'ouvre est exclu par §2.2 point 2 (aucun script, aucun hamburger,
   aucun aria-expanded), et un <details> demanderait du balisage, qui
   appartient à L1, L2 et L3.
   Les trois destinations se retrouvent au pied — SAUF « Comment ça se
   passe » (index.html#etapes), qui n'est écrit nulle part ailleurs sur
   aucune des quatre pages : signalé à L1, L2 et L3, L0 n'y touche pas. */
/* Inspection du chef, 20.09 17h : la grille empilait d'office le logo et
   l'action (164 px d'en-tête, « Estimer » seul sur sa rangée). En flex qui
   passe à la ligne, ils partagent une rangée quand ils tiennent côte à côte
   (accueil : logo + « Estimer ») et ne s'empilent que si l'action est longue
   (calculateur : « Retour à l'accueil »). */
.entete-corps {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--e8) var(--e12);
}

/* La navigation n'est pas masquée par un état : à cette largeur elle n'est
   pas là. Aucun bouton n'en promet l'ouverture, donc rien ne ment. */
.entete-corps > nav { display: none; }

/* L'en-tête se resserre, la cible tactile non : 44 px de haut, au-dessus des
   24 px exigés. */
.entete-corps > .spm-btn { min-height: 44px; }

@media (min-width: 600px) {
  .entete-corps {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--e24);
  }

  .entete-corps > nav { display: block; }
  .entete-corps > .spm-btn { min-height: 48px; }
}

/* Le filet de l'en-tête ouvre sur 16 px en haut et en bas (components.css) ;
   sous 600 px il passe à 12 px. Le sélecteur porte DEUX classes pour la même
   raison que celui du logo ci-dessous : components.css écrit `.spm-entete`
   et se charge après base.css. Les quatre pages portent `bande` sur leur
   en-tête (§3.2). */
.spm-entete.bande { padding-block: var(--e12); }

@media (min-width: 600px) {
  .spm-entete.bande { padding-block: var(--e16); }
}

/* Zone de protection du logo. Z vaut 21,4 % de la hauteur du signe. Rien
   n'entre dans cette bande : ni texte, ni filet, ni bord de bloc, ni autre
   logo. Z est un MINIMUM : une bande plus large reste conforme, une bande
   plus étroite non.
   Sous 600 px le verrouillage est à son minimum écran — `clamp(200px, 18vw,
   260px)` rend 200 px tant que 18vw reste sous 200, donc sur tout téléphone.
   À 200 px de large le signe fait 49,5 px de haut, Z vaut 10,6 px, soit
   12 px au pas de 4 : exactement le calcul du logo du pied, quelques lignes
   plus bas. À partir de 600 px la bande repasse à 16 px, la valeur écrite
   pour un logo de 240 px (59 px de haut, Z = 12,7 px arrondi à 16).
   ⚠️ Le sélecteur porte DEUX classes, et ce n'est pas un ornement : le
   var(--e8) de components.css est écrit `.spm-entete__logo`, à spécificité
   égale, dans une feuille qui se charge après base.css. Mesuré au navigateur
   le 20.09 avec un sélecteur simple : le padding rendu valait 8 px, pas 16.
   La combinaison .spm-entete + .spm-entete__logo (0,2,0) tranche, et elle ne
   déborde pas sur un autre contexte. */
.spm-entete .spm-entete__logo { padding: var(--e12); }

@media (min-width: 600px) {
  .spm-entete .spm-entete__logo { padding: var(--e16); }
}

/* Le pied. Colonne « qui nous sommes » : le verrouillage, sa signature, puis
   la portée en forme courte.
   Le logo du pied fait 200 px de large, le minimum écran du verrouillage
   horizontal : à cette largeur il fait 49,5 px de haut et Z vaut 10,6 px,
   soit 12 px au pas de 4. La gouttière de .spm-pied__colonnes vaut au moins
   16 px à toutes les largeurs, et le pied ouvre sur 64 px : la zone est
   dégagée sans qu'il faille l'écrire. La signature, elle, fait partie du
   verrouillage : elle a le droit d'être là. */
.pied-marque {
  display: flex;
  flex-direction: column;
  gap: var(--e8);
  align-items: flex-start;
}

.pied-marque img { width: 200px; height: auto; }

/* « Jamais plus large que le mot-symbole au-dessus d'elle. » Si elle déborde,
   on réduit le corps — on ne la met JAMAIS sur deux lignes (§3.3 point 1). */
.pied-marque .spm-signature { max-width: 200px; }

.pied-marque .spm-mention { margin-top: var(--e4); }

/* Un titre de colonne de pied n'est pas un titre de section : il reprend la
   famille de texte, jamais la condensée noire, qui ferme ses contre-poinçons
   sous 24 px (§2.2). */
.pied-titre {
  font-family: var(--police-texte);
  font-weight: var(--graisse-gras);
  font-size: var(--t-texte);
  line-height: var(--interligne-h3);
  letter-spacing: 0;
  margin: 0 0 var(--e12);
}

.pied-liens {
  display: grid;
  margin: 0;
  padding-left: 0;
  list-style: none;
  font-size: var(--t-petit);
}

/* LA RESPIRATION AUTOUR DU FILET N'EST PAS DU CONFORT, mesurée le 20.09.
   Les liens du pied étaient séparés par le seul filet d'un pixel, sans
   aucun retrait vertical : deux cibles de 44 px à 1 px l'une de l'autre.
   L'anneau de focus se dessine à +4 px de la boîte (§2.4), donc l'anneau
   du lien courant mordait le lien voisin sur 3 px de haut et sur toute la
   largeur — 957 px² relevés entre les boîtes 40, 429, 319, 44 et
   40, 384, 319, 44. Le pied étant commun aux quatre pages, le défaut s'y
   répétait partout et aux trois largeurs.
   On écarte donc les <li> de --e8 de part et d'autre du filet : 17 px entre
   deux boîtes de lien, le filet reste à équidistance des deux libellés, la
   cible tactile reste à 44 px, et l'anneau a la place de se fermer. */
.pied-liens li { margin-top: 0; padding-bottom: var(--e8); }

.pied-liens li + li {
  border-top: var(--filet-epaisseur) solid var(--filet);
  padding-top: var(--e8);
}

.pied-liens a {
  display: flex;
  align-items: center;
  min-height: 44px;
  /* LA PLACE DE L'ANNEAU SE RÉSERVE AUSSI AU DÉFILEMENT, mesuré le 20.09.
     Le dernier lien du pied est le dernier contrôle de la page. Tant que la
     page finissait juste après lui, le défilement butait sur le bas du
     document et le laissait 36 px au-dessus du bord — l'anneau passait par
     chance, et à 1440 px il ne restait que 3 px de marge. Dès que le pied
     grandit, le navigateur n'est plus bloqué : il amène le lien À RAS du bord
     bas, et les 4 px de l'anneau tombent hors fenêtre. Relevé : boîte
     396, 980, 332, 44 dans une fenêtre de 768 × 1024, bas + 4 = 1028.
     scroll-margin dit au navigateur de compter --e8 autour de ce lien quand
     il l'amène à l'écran : l'anneau a sa place quelle que soit la hauteur du
     pied, et rien ne bouge à l'œil. */
  scroll-margin-block: var(--e8);
}

.pied-adresse {
  max-width: var(--mesure);
  font-size: var(--t-petit);
  line-height: 1.7;
}

/* « Mentions légales » et « Protection des données » : les deux pages n'ont
   pas été commandées et n'existent pas. Le libellé reste pour dire ce qui
   viendra, mais ce n'est plus un lien : un <span class="lien-inerte"> avec
   aria-disabled="true". Pas de soulignement, pas de curseur de main : rien
   ne se clique, et il n'y a AUCUN lien mort sur le site. Dès que les deux
   pages existent, on remet des <a href> dans les QUATRE pieds, pas dans un
   seul. Les deux libellés sont listés dans _A-REMPLACER.md. */
.lien-inerte {
  color: inherit;
  text-decoration: none;
  cursor: default;
}

/* --------------------------------------------------- 16. Mouvement réduit */

/* Le repli commun vient de marque/tokens.css §4, qui coupe les animations et
   réintroduit le changement de couleur d'état. Ne restent ici que les
   mouvements propres à ce site. Toute retouche ajoute son repli ou n'est pas
   livrée. */

@media (prefers-reduced-motion: reduce) {
  /* Le tracé du rail change de largeur sans transition, l'anneau d'arrivée
     est dessiné d'emblée. On supprime le mouvement, pas l'information. */
  .rail-parcouru { transition: none; }

  .rail-arrivee circle {
    stroke-dasharray: none;
    stroke-dashoffset: 0;
    transition: none;
  }
}
