/* =====================================================================
   Felix Garden — FEUILLE DE STYLE UNIQUE

   ⚠️ AUCUNE VALEUR EN DUR ICI. Ni couleur, ni taille, ni espacement, ni
   durée : tout passe par les jetons de `tokens.css`. Le seul endroit où
   un nombre nu est légitime est une valeur STRUCTURELLE qui n'appartient
   pas au thème (un `1px` de filet, un `100%`, un `50%`).

   ⚠️ MOBILE D'ABORD, STRICTEMENT. Tout ce qui est écrit hors media query
   décrit le téléphone à 375 px. Les `@media (min-width: …)` en fin de
   fichier ne font qu'ÉLARGIR. Jamais l'inverse.

   ⚠️ AUCUNE INTERACTION NE DÉPEND DU SURVOL. Le survol ajoute du confort,
   il ne débloque rien. Sur ce site le client appelle : les boutons d'appel
   sont accessibles au doigt, partout, tout le temps.

   Plan du fichier
     1.  Reset et base
     2.  Mise en page : conteneurs, sections
     3.  Typographie
     4.  Utilitaires
     5.  Boutons
     6.  En-tête et navigation
     7.  Menu mobile
     8.  Hauteur d'écran (hero)
     9.  Cartes de métier
    10.  Galerie et réalisations
    11.  Comparaison avant / après
    12.  FAQ
    13.  Pages de zone : fil d'Ariane, communes
    14.  Formulaire de devis
    15.  Pied de page
    16.  Pile de boutons flottants
    17.  Pop-up commun (ow-popup)
    18.  Apparition au défilement
    19.  Élargissement : tablette puis ordinateur
   ===================================================================== */

/* =====================================================================
   1. RESET ET BASE
   ===================================================================== */

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

html {
  /* Le défilement doux respecte le réglage système : voir §18. */
  scroll-behavior: smooth;
  /* Une ancre ne doit pas passer sous l'en-tête collant. */
  scroll-padding-top: calc(var(--header-h) + var(--space-4));
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--background);
  color: var(--foreground);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: var(--leading-body);
  font-weight: var(--weight-regular);
  -webkit-font-smoothing: antialiased;
  /* Aucune page ne doit défiler horizontalement. */
  overflow-x: hidden;
}

img,
picture,
video,
svg { display: block; max-width: 100%; }

img,
video {
  height: auto;
  /* ⚠️ Chaque <img> porte aussi `width` et `height` EN ATTRIBUTS dans le
     HTML : c'est ce qui réserve la place et évite le décalage de mise en
     page (CLS). Cette règle-ci ne fait que rendre l'image fluide. */
}

a {
  color: var(--primary);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  transition: color var(--duration-fast) var(--ease);
}
a:hover { color: var(--primary-strong); }

/* Anneau de focus visible partout : il ne se retire jamais. */
:focus-visible {
  outline: 3px solid var(--ring);
  outline-offset: 2px;
  border-radius: var(--radius);
}

button { font: inherit; color: inherit; }

hr {
  height: 1px;
  margin: var(--space-8) 0;
  border: 0;
  background: var(--border);
}

/* =====================================================================
   2. MISE EN PAGE
   ===================================================================== */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* La mesure de lecture : un paragraphe ne dépasse jamais 65-75 signes. */
.container-text {
  width: 100%;
  max-width: var(--container-text);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--section-y); }
.section--muted { background: var(--muted); }
.section--stone {
  background: var(--stone);
  color: var(--stone-foreground);
}
.section--stone a { color: var(--primary-soft); }
/* ⚠️ BUG CORRIGÉ LE 02/09/2026. `--muted-foreground` est un gris-bleu prévu
   pour le fond CLAIR : posé sur `--stone`, il mesurait 1,9:1, c'est-à-dire
   illisible. Tout ce qui est « secondaire » doit s'éclaircir sur fond
   sombre, pas s'assombrir. */
.section--stone .section-intro,
.section--stone .contrainte p,
.section--stone .faq-reponse,
.section--stone .champ-aide,
.section--stone .form-note,
.section--stone .fait-date {
  color: color-mix(in oklab, var(--stone-foreground) 80%, transparent);
}
.section--stone .contrainte { border-bottom-color: color-mix(in oklab, var(--stone-foreground) 18%, transparent); }

/* ⚠️ MÊME FAMILLE DE BUG, MÊME JOUR. Les titres portent `--foreground`, une
   couleur sombre écrite une fois pour toutes dans la règle générale : sur
   `--stone`, ils devenaient presque invisibles. Idem pour les libellés du
   formulaire, qui sont repris sur onze pages.
   La leçon : dès qu'une section renverse le fond, TOUT ce qui porte une
   couleur de texte fixe doit être renversé avec elle. Il n'y a pas de
   demi-mesure — un seul oubli et le bloc devient illisible. */
.section--stone h1,
.section--stone h2,
.section--stone h3,
.section--stone h4,
.section--stone .champ label,
.section--stone .form-devis { color: var(--stone-foreground); }

/* Le formulaire garde sa surface claire : c'est un formulaire, il doit se
   lire comme un formulaire, pas comme un bloc de la section. */
.section--stone .form-devis {
  background: var(--card);
  color: var(--card-foreground);
  border-color: transparent;
}
.section--stone .form-devis label,
.section--stone .form-devis .champ-aide,
.section--stone .form-devis .form-note { color: var(--card-foreground); }
.section--stone .form-devis .champ-aide,
.section--stone .form-devis .form-note { color: var(--muted-foreground); }

.section-head {
  max-width: var(--container-text);
  margin-bottom: var(--space-8);
}
.section-intro {
  margin-top: var(--space-3);
  color: var(--muted-foreground);
}

/* Une étiquette de section : petites capitales laiton au-dessus du titre.
   ⚠️ `inline-flex` et non `block` : certaines étiquettes portent une icône,
   qui passait à la ligne au-dessus du texte. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
  color: var(--accent);
  font-size: var(--text-xs);
  font-weight: var(--weight-semi);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* Grille générique. Une colonne sur téléphone, élargie au §19.
   `--2` reste à deux colonnes même sur grand écran : c'est le cas du bloc
   « appeler / formulaire », qui n'a que deux enfants et se retrouvait
   étalé sur trois colonnes. */
.grid {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: 1fr;
}

/* =====================================================================
   3. TYPOGRAPHIE
   ===================================================================== */

h1, h2, h3, h4 {
  margin: 0 0 var(--space-4);
  font-family: var(--font-display);
  /* Fraunces porte l'axe `opsz` : ses formes s'affinent d'elles-mêmes
     quand le titre grandit. Sans cette ligne, l'axe reste figé. */
  font-optical-sizing: auto;
  font-weight: var(--weight-semi);
  line-height: var(--leading-snug);
  color: var(--foreground);
  text-wrap: balance;
}

h1 {
  font-size: var(--step-3);
  line-height: var(--leading-tight);
  letter-spacing: -0.015em;
}
h2 { font-size: var(--step-2); }
h3 { font-size: var(--step-1); }
h4 { font-size: var(--text-lg); }

p { margin: 0 0 var(--space-4); text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

ul, ol { margin: 0 0 var(--space-4); padding-left: var(--space-5); }
li { margin-bottom: var(--space-2); }

strong { font-weight: var(--weight-semi); }

blockquote {
  margin: var(--space-6) 0;
  padding-left: var(--space-5);
  border-left: 3px solid var(--accent);
  color: var(--muted-foreground);
  font-style: italic;
}

/* =====================================================================
   4. UTILITAIRES
   ===================================================================== */

.u-muted { color: var(--muted-foreground); }
.u-accent { color: var(--accent); }
.u-center { text-align: center; }
.u-mt { margin-top: var(--space-6); }
.u-mb { margin-bottom: var(--space-6); }
.u-nowrap { white-space: nowrap; }

/* Réservé aux lecteurs d'écran. */
.u-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Lien d'évitement : premier élément focalisable de chaque page. */
.skip-link {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  z-index: var(--z-overlay);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius);
  background: var(--primary);
  color: var(--primary-foreground);
  transform: translateY(-200%);
  transition: transform var(--duration-fast) var(--ease);
}
.skip-link:focus { transform: translateY(0); }

/* Le sprite SVG inline : présent dans le flux, jamais visible. */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.icon {
  width: 1.25em;
  height: 1.25em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}

/* Le pot de miel anti-robot : hors écran, jamais masqué par `display`,
   qui le retirerait aussi du remplissage automatique des robots. */
.hp {
  position: absolute;
  left: -9999px;
  opacity: 0;
  pointer-events: none;
}

/* ⚠️ `sr-only` ET NON `.hp` : ce sont deux rôles différents sous des noms
   différents. `.hp` cache un PIÈGE que personne ne doit lire ; `sr-only`
   cache à l'œil un texte que les lecteurs d'écran DOIVENT lire. Les
   confondre reviendrait à faire disparaître les intitulés du formulaire
   pour les technologies d'assistance.
   Le nom vient de Bootstrap et de Tailwind, comme `--card` vient de shadcn :
   un nom que la communauté emploie déjà est un nom qu'on n'a pas à
   expliquer. La recette, elle, est celle qui fait consensus — surtout pas
   `display: none`, qui retirerait le texte de l'arbre d'accessibilité. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* =====================================================================
   5. BOUTONS
   ===================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  /* ⚠️ 48 px de haut, pas 44 : c'est le confort de l'audit Lighthouse, et
     sur ce site le bouton d'appel est le premier outil commercial. */
  min-height: var(--tap-target-comfort);
  padding: var(--space-3) var(--space-5);
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: var(--primary);
  color: var(--primary-foreground);
  font-weight: var(--weight-semi);
  font-size: var(--text-md);
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition:
    background var(--duration-fast) var(--ease),
    border-color var(--duration-fast) var(--ease),
    color var(--duration-fast) var(--ease);
}
.btn:hover {
  background: var(--primary-strong);
  color: var(--primary-foreground);
}

.btn-accent { background: var(--accent); color: var(--accent-foreground); }
.btn-accent:hover { background: var(--accent-strong); color: var(--accent-foreground); }

.btn-ghost {
  background: transparent;
  border-color: var(--border-strong);
  color: var(--foreground);
}
.btn-ghost:hover {
  background: var(--muted);
  border-color: var(--primary);
  color: var(--foreground);
}

/* Sur fond sombre : le contour se lit, le plein serait trop lourd. */
.section--stone .btn-ghost,
.site-hero .btn-ghost {
  border-color: color-mix(in oklab, var(--stone-foreground) 45%, transparent);
  color: var(--stone-foreground);
}
.section--stone .btn-ghost:hover,
.site-hero .btn-ghost:hover {
  background: color-mix(in oklab, var(--stone-foreground) 12%, transparent);
  color: var(--stone-foreground);
}

.btn-lg { font-size: var(--text-btn-lg); padding: var(--space-4) var(--space-7); }
.btn-block { display: flex; width: 100%; }

.btn-wa { background: var(--whatsapp); color: var(--whatsapp-foreground); }
.btn-wa:hover {
  background: color-mix(in oklab, var(--whatsapp) 82%, black);
  color: var(--whatsapp-foreground);
}

/* Un groupe de boutons : empilés au doigt, en ligne dès qu'il y a la place. */
.btn-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* =====================================================================
   6. EN-TÊTE ET NAVIGATION
   ===================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--stone);
  color: var(--stone-foreground);
  border-bottom: 1px solid color-mix(in oklab, var(--stone-foreground) 14%, transparent);
}

/* ⚠️ `justify-content: flex-start` et non `space-between` : le menu doit
   rester COLLÉ à la marque, à gauche. C'est le téléphone qui est poussé à
   droite, par son propre `margin-left: auto`. Un `space-between` étalerait
   le menu au milieu de la barre. */
.site-header > .container {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: var(--header-h);
}

/* Le nom tient SUR UNE SEULE LIGNE, à côté de la feuille. Un lockup sur deux
   lignes oblige à grandir la barre pour rester lisible, et il se lit moins
   vite qu'un nom écrit d'un trait. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  flex: none;
  /* Le lockup est un LIEN vers l'accueil : c'est une cible tactile, pas un
     ornement. Mesuré à 40 px de haut le 02/09/2026, sous le plancher. */
  min-height: var(--tap-target-min);
  color: var(--stone-foreground);
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: var(--weight-semi);
  font-size: var(--text-md);
  text-decoration: none;
  letter-spacing: -0.01em;
}
.brand:hover { color: var(--stone-foreground); }
.brand-logo {
  width: 2.4em;
  height: 2.4em;
  object-fit: contain;
}
.brand-nom { white-space: nowrap; }

/* La navigation d'ordinateur est masquée au doigt : le menu passe par le
   bouton hamburger. Elle réapparaît au §19. */
.main-nav { display: none; }

/* Le téléphone dans l'en-tête : visible À TOUTES LES LARGEURS. C'est le
   canal principal du métier, il ne se replie pas dans un menu. */
/* ⚠️ C'EST `.header-actions` QUI POUSSE À DROITE, plus le lien lui-même.
   Le menu reste aligné à gauche contre la marque : règle de l'écosystème.
   Déplacer ce `margin-left: auto` sur un autre élément étalerait le menu. */
.header-actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* Le numéro est un LIEN, pas un bouton : fond transparent, demandé le
   24/09/2026. Il garde sa hauteur de cible tactile — c'est ce qu'on appelle
   le plus souvent sur ce site, et un lien qui ne se touche pas ne sert à
   rien. */
.header-call {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--tap-target-comfort);
  min-width: var(--tap-target-comfort);
  padding-inline: var(--space-2);
  border-radius: var(--radius);
  background: transparent;
  color: var(--stone-foreground);
  font-weight: var(--weight-semi);
  font-size: var(--text-sm);
  text-decoration: none;
}
.header-call:hover {
  background: color-mix(in oklab, var(--stone-foreground) 12%, transparent);
  color: var(--stone-foreground);
}

/* Le bouton d'appel à l'action. ⚠️ Masqué sous la tablette : à 375 px,
   l'en-tête porte déjà la marque, le numéro et le menu, et la barre
   flottante du bas offre déjà appel, WhatsApp et courriel. */
.header-cta { display: none; }
/* Le numéro écrit en toutes lettres n'apparaît qu'à partir de la tablette :
   au doigt, l'icône suffit et la place manque. */
.header-call span { display: none; }

.burger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap-target-comfort);
  height: var(--tap-target-comfort);
  padding: 0;
  border: 1px solid color-mix(in oklab, var(--stone-foreground) 30%, transparent);
  border-radius: var(--radius);
  background: transparent;
  color: var(--stone-foreground);
  cursor: pointer;
}
.burger .icon { width: 1.4em; height: 1.4em; }

/* =====================================================================
   7. MENU MOBILE
   ===================================================================== */

.mobmenu {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  display: flex;
  flex-direction: column;
  padding: var(--space-4) 0 var(--space-10);
  background: var(--stone);
  color: var(--stone-foreground);
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Fermé : hors du flux ET hors de l'ordre de tabulation. */
  visibility: hidden;
  opacity: 0;
  transform: translateY(-1rem);
  transition:
    opacity var(--duration-base) var(--ease),
    transform var(--duration-base) var(--ease),
    visibility var(--duration-base) var(--ease);
}
.mobmenu[data-ouvert="1"] {
  visibility: visible;
  opacity: 1;
  transform: translateY(0);
}

.mobmenu-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: var(--header-h);
}

.mobmenu-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap-target-comfort);
  height: var(--tap-target-comfort);
  padding: 0;
  border: 1px solid color-mix(in oklab, var(--stone-foreground) 30%, transparent);
  border-radius: var(--radius);
  background: transparent;
  color: var(--stone-foreground);
  cursor: pointer;
}

.mobmenu-nav { display: flex; flex-direction: column; margin-top: var(--space-6); }
.mobmenu-nav a {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--tap-target-comfort);
  padding: var(--space-2) 0;
  border-bottom: 1px solid color-mix(in oklab, var(--stone-foreground) 12%, transparent);
  color: var(--stone-foreground);
  font-size: var(--text-lg);
  text-decoration: none;
}
.mobmenu-nav a:hover { color: var(--primary-soft); }
.mobmenu-nav a .icon { color: var(--primary-soft); }

.mobmenu-titre {
  margin: var(--space-6) 0 var(--space-2);
  color: var(--primary-soft);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-semi);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.mobmenu-actions { display: flex; flex-direction: column; gap: var(--space-3); margin-top: var(--space-8); }

/* La page derrière un menu ouvert ne défile pas. */
.no-scroll { overflow: hidden; }

/* =====================================================================
   8. HAUTEUR D'ÉCRAN (HERO)
   ---------------------------------------------------------------------
   ⚠️ PEU DE TEXTE AU-DESSUS DE LA LIGNE DE FLOTTAISON. Ce site se vend par
   la photo : un titre, une phrase, deux boutons. Rien d'autre.
   ===================================================================== */

/* ⚠️ 58svh au doigt, 66svh sur ordinateur. Elle faisait 78svh et 84svh : le
   premier contenu utile arrivait trop bas, et un visiteur qui doit défiler
   pour comprendre ce qu'on lui vend est un visiteur qu'on a déjà perdu. */
.site-hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: 58svh;
  padding-block: var(--space-12) var(--space-8);
  background: var(--stone);
  color: var(--stone-foreground);
  overflow: hidden;
}

.site-hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.site-hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Le voile : c'est lui qui rend le titre lisible sur un chantier
   ensoleillé. Dégradé plutôt qu'aplat, pour que la photo respire en haut.
   ⚠️ RÉÉQUILIBRÉ le 02/09/2026, après avoir raccourci la hauteur d'écran :
   le même dégradé qui allait sur 78svh noircissait toute la photo sur 58svh.
   Un voile se règle SUR LA HAUTEUR RÉELLE du bloc, pas dans l'absolu.
   ⚠️ `--overlay-fort` en pied, et non `--overlay` : mesuré le 01/09/2026,
   l'étiquette et le titre passaient mal sur une photo claire. Le voile doit
   garantir la lisibilité SANS CONNAÎTRE LA PHOTO, parce que Félix en
   changera.
   ⚠️ IL NE FINIT PLUS EN `transparent`, mais sur `--overlay-plancher`. Deux
   réglages de ce dégradé en deux jours, tous deux déclenchés par un texte
   dont la longueur avait changé : un voile réglé sur la hauteur d'un texte
   se dérègle au premier mot ajouté. Le plancher supprime la classe entière
   de ce défaut, au lieu de la corriger une troisième fois. */
.site-hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    var(--overlay-fort) 0%,
    var(--overlay-fort) 42%,
    var(--overlay) 62%,
    var(--overlay-soft) 82%,
    var(--overlay-plancher) 100%
  );
}

.site-hero > .container { position: relative; z-index: var(--z-base); }

/* ⚠️ L'OMBRE PORTÉE N'EST PAS UN EFFET, C'EST LE GARDE-FOU DE LISIBILITÉ.
   Le voile seul ne suffit pas : il s'applique à toute la hauteur du hero,
   alors que le texte, lui, se déplace — un titre plus long, une intro plus
   courte, et l'étiquette se retrouve sur le ciel. C'est arrivé deux fois en
   deux jours, chaque fois corrigé en re-réglant le dégradé, chaque fois
   recassé au texte suivant.
   L'ombre, elle, suit le texte. C'est la réponse standard pour du texte posé
   sur une photo qu'on ne choisit pas — et Félix changera la photo.
   Réglage : assez pour tenir sur un ciel blanc, assez peu pour rester
   invisible sur la partie sombre. */
.site-hero .eyebrow,
.site-hero h1,
.site-hero p {
  text-shadow: 0 1px 2px oklch(0.15 0.01 223 / 0.55),
               0 2px 12px oklch(0.15 0.01 223 / 0.35);
}

.site-hero h1 {
  max-width: 18ch;
  color: var(--stone-foreground);
  font-size: var(--step-4);
}
.site-hero p {
  max-width: 46ch;
  color: var(--stone-foreground);
  font-size: var(--step-1);
}
/* ⚠️ Blanc, et non `--primary-soft` comme ailleurs sur fond sombre : ici le
   fond n'est pas un aplat mais une PHOTO qu'on ne choisit pas. Un olive
   clair sur une photo claire disparaît, mesuré le 01/09/2026. */
.site-hero .eyebrow { color: var(--stone-foreground); }

/* Le bandeau de preuves, juste sous la hauteur d'écran. */
.proof {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  padding-block: var(--space-6);
  border-bottom: 1px solid var(--border);
}
.proof-item { display: flex; align-items: flex-start; gap: var(--space-3); }
.proof-item .icon { width: 1.5em; height: 1.5em; color: var(--accent); }
.proof-item strong { display: block; font-family: var(--font-display); font-optical-sizing: auto; }
.proof-item span { color: var(--muted-foreground); font-size: var(--text-sm); }

/* =====================================================================
   9. CARTES DE MÉTIER
   ===================================================================== */

.carte {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--card);
  color: var(--card-foreground);
  overflow: hidden;
  transition:
    border-color var(--duration-base) var(--ease),
    box-shadow var(--duration-base) var(--ease);
}

/* ⚠️ TITRES, TEXTES ET LIENS ALIGNÉS D'UNE CARTE À L'AUTRE.
   `subgrid` a été essayé et retiré le 02/09/2026 : il n'aligne QUE les
   cartes d'une même rangée, donc avec huit cartes sur deux rangées la
   rangée du bas se réglait toute seule. Il se battait en plus avec les
   hauteurs réservées ci-dessous, qui suffisent et se raisonnent.

   La recette qui marche : on RÉSERVE deux lignes de titre et trois lignes
   de texte, et le lien est poussé en bas par `margin-top: auto`. Les huit
   cartes ont alors exactement la même anatomie.
   ⚠️ Un texte qui déborde des trois lignes se raccourcit. C'est le contenu
   qui s'adapte à la grille, pas la grille au contenu. */
/* ⚠️ `subgrid` n'aligne QUE les cartes d'une même rangée. Avec huit cartes
   sur deux rangées, la rangée du bas se réglait toute seule et ne tombait
   pas sur la rangée du haut. On RÉSERVE donc la place : deux lignes de
   titre, trois lignes de texte, mesurés sur la carte la plus longue.
   Le texte d'une carte qui dépasserait ces trois lignes doit être
   raccourci — c'est le contenu qui s'adapte à la grille, pas l'inverse. */
.grid--cartes .carte-corps h3 { min-height: calc(2 * var(--leading-snug) * 1em); }
.grid--cartes .carte-corps > p { min-height: calc(3 * var(--leading-body) * 1em); }

.carte:hover { border-color: var(--primary); box-shadow: var(--shadow-md); }

.carte-media { aspect-ratio: 3 / 2; background: var(--muted); }
.carte-media img { width: 100%; height: 100%; object-fit: cover; }

.carte-corps { display: flex; flex-direction: column; flex: 1; padding: var(--space-5); }
.carte-corps h3 { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-2); }
.carte-corps h3 .icon { color: var(--accent); }
.carte-corps p { color: var(--muted-foreground); font-size: var(--text-sm); }

/* Le lien de carte couvre toute la carte : au doigt, on ne vise pas un mot.
   Le texte du lien reste explicite pour les lecteurs d'écran.
   ⚠️ `min-height` malgré le `::before` qui couvre la carte : mesuré à 375 px
   le 01/09/2026, le lien lui-même faisait 40 px. Un audit de cibles
   tactiles mesure l'élément, pas son pseudo-élément. */
.carte-lien {
  display: flex;
  align-items: center;
  min-height: var(--tap-target-min);
  margin-top: auto;
  padding-top: var(--space-4);
  color: var(--primary);
  font-weight: var(--weight-semi);
  font-size: var(--text-sm);
  text-decoration: none;
}
.carte-lien::after { content: " →"; }
.carte-lien::before {
  content: "";
  position: absolute;
  inset: 0;
}
/* ⚠️ `.chantier` EST DANS CETTE REGLE, et ce n'est pas cosmetique : le
   `::before` de `.carte-lien` se positionne sur le premier ancetre positionne.
   Sans elle, la zone cliquable deborderait sur toute la page.
   Les cartes de chantier partagent ce lien plutot que d'avoir le leur : mesure
   le 02/09/2026, leur ancien `<p><a>` faisait 17 px de haut, 27 fois sur la
   page realisations. */
.carte,
.chantier { position: relative; }

/* =====================================================================
   10. GALERIE ET RÉALISATIONS
   ---------------------------------------------------------------------
   ⚠️ CHAQUE PHOTO PORTE SON CONTEXTE : commune, métier, matériau. C'est
   exactement ce qu'aucun concurrent du panel ne fait — leurs galeries sont
   des murs d'images sans un mot. Voir docs/AUDIT-CONCURRENCE.md §5.
   ===================================================================== */

.chantier {
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--card);
  overflow: hidden;
}
.chantier-media { aspect-ratio: 3 / 2; background: var(--muted); }
.chantier-media img { width: 100%; height: 100%; object-fit: cover; }

.chantier-corps { padding: var(--space-5); }
.chantier-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
  padding: 0;
  list-style: none;
}
.chantier-meta li {
  margin: 0;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--muted);
  color: var(--muted-foreground);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.chantier-corps p { color: var(--muted-foreground); font-size: var(--text-sm); }

/* =====================================================================
   11. COMPARAISON AVANT / APRÈS
   ---------------------------------------------------------------------
   Deux images côte à côte, étiquetées. ⚠️ PAS de curseur à faire glisser :
   ce serait une interaction au geste, sans équivalent au clavier, et sur
   une photo de chantier elle apporte moins qu'elle ne coûte.
   ===================================================================== */

.avant-apres {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
}
.avant-apres figure { position: relative; margin: 0; }
.avant-apres img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--radius);
}
.avant-apres figcaption {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--overlay);
  color: var(--stone-foreground);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semi);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* =====================================================================
   12. FAQ
   ---------------------------------------------------------------------
   ⚠️ <details>/<summary> et non un accordéon JavaScript : le contenu est
   dans le HTML, donc lu par les moteurs et par les IA, ouvert ou fermé.
   C'est ce qui fait fonctionner le JSON-LD FAQPage de la page.
   ===================================================================== */

.faq { border-top: 1px solid var(--border); }

.faq details {
  border-bottom: 1px solid var(--border);
}
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: var(--tap-target-comfort);
  padding: var(--space-4) 0;
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: var(--weight-semi);
  font-size: var(--text-lg);
  cursor: pointer;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "";
  flex: none;
  width: 0.6em;
  height: 0.6em;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(45deg) translate(-0.15em, -0.15em);
  transition: transform var(--duration-fast) var(--ease);
}
.faq details[open] summary::after {
  transform: rotate(-135deg) translate(-0.15em, -0.15em);
}
.faq-reponse {
  padding-bottom: var(--space-5);
  color: var(--muted-foreground);
}
/* ⚠️ LA RÉPONSE TIENT DANS SES DEUX PREMIÈRES PHRASES. C'est ce qu'une IA
   ou un extrait enrichi reprend ; le reste est du confort de lecture. */
.faq-reponse > p:first-child { color: var(--foreground); }

/* =====================================================================
   13. PAGES DE ZONE
   ===================================================================== */

.ariane {
  padding-block: var(--space-4);
  color: var(--muted-foreground);
  font-size: var(--text-sm);
}
.ariane ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.ariane li { margin: 0; }
.ariane li + li::before { content: "› "; color: var(--border-strong); }

/* La liste des communes : EN DUR dans le HTML, jamais dans un menu
   déroulant. C'est elle qui rend la page trouvable sur
   « <métier> <commune> » sans créer une page par commune. */
.communes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-1) var(--space-4);
  margin: 0 0 var(--space-5);
  padding: 0;
  list-style: none;
}
.communes li {
  margin: 0;
  padding-left: var(--space-4);
  font-size: var(--text-sm);
  text-indent: calc(-1 * var(--space-4));
}
.communes li::before { content: "· "; color: var(--accent); }

/* La note d'échappement, juste après la liste : elle transforme en contact
   ce qui serait une sortie de site. */
.communes-note {
  padding: var(--space-4);
  border-left: 3px solid var(--accent);
  background: var(--muted);
  color: var(--muted-foreground);
  font-size: var(--text-sm);
}

/* « Ce qui change ici » : les contraintes propres à la zone. */
.contrainte {
  display: flex;
  gap: var(--space-4);
  padding-block: var(--space-5);
  border-bottom: 1px solid var(--border);
}
.contrainte .icon { width: 1.6em; height: 1.6em; color: var(--accent); }
.contrainte h3 { margin-bottom: var(--space-2); font-size: var(--text-lg); }
.contrainte p { margin: 0; color: var(--muted-foreground); font-size: var(--text-sm); }

/* Un fait juridique daté. ⚠️ La date n'est pas décorative : une règle
   d'urbanisme change, et un site qui ne dit pas quand il a vérifié ment
   par omission. */
.fait-date {
  display: block;
  margin-top: var(--space-2);
  color: var(--muted-foreground);
  font-size: var(--text-xs);
}

/* =====================================================================
   14. FORMULAIRE DE DEVIS
   ===================================================================== */

.form-devis {
  padding: var(--space-6);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--card);
}

/* Resserré le 24/09/2026 en même temps que la hauteur des champs : six
   champs à 20 px d'écart faisaient une colonne inutilement longue. */
.champ { margin-bottom: var(--space-3); }
.champ label {
  display: block;
  margin-bottom: var(--space-2);
  font-weight: var(--weight-medium);
  font-size: var(--text-sm);
}
.champ .oblig { color: var(--accent); }

.champ input,
.champ select,
.champ textarea {
  width: 100%;
  /* ⚠️ HAUTEUR RAMENÉE AU PLANCHER TACTILE le 24/09/2026 : les champs
     faisaient 48 px plus 24 px de rembourrage vertical, ce qui donnait un
     formulaire très haut pour six lignes. On descend au plancher de 44 px et
     on resserre le rembourrage. ⚠️ Pas plus bas : sous 44 px on rate le
     champ au doigt, et le formulaire est le second canal du site.
     ⚠️ `font-size` reste à 16 px : en dessous, iOS zoome au premier appui. */
  min-height: var(--tap-target-min);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--input);
  border-radius: var(--radius);
  background: var(--background);
  color: var(--foreground);
  font: inherit;
  font-size: var(--step-0);
}
.champ textarea { min-height: calc(var(--space-24) + var(--space-8)); resize: vertical; }
.champ input:focus-visible,
.champ select:focus-visible,
.champ textarea:focus-visible {
  outline: none;
  border-color: var(--ring);
  box-shadow: var(--shadow-focus);
}

.champ-aide {
  margin-top: var(--space-2);
  color: var(--muted-foreground);
  font-size: var(--text-xs);
}
/* L'erreur se pose SOUS le champ concerné, jamais en haut de formulaire. */
.champ-erreur {
  margin-top: var(--space-2);
  color: var(--destructive);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}
.champ[data-erreur="1"] input,
.champ[data-erreur="1"] select,
.champ[data-erreur="1"] textarea { border-color: var(--destructive); }

.form-note { margin-top: var(--space-4); color: var(--muted-foreground); font-size: var(--text-xs); }

/* =====================================================================
   15. PIED DE PAGE
   ===================================================================== */

.site-footer {
  padding-block: var(--space-12) var(--space-20);
  background: var(--stone);
  color: var(--stone-foreground);
  font-size: var(--text-sm);
}
.site-footer a { color: var(--stone-foreground); text-decoration: none; }
.site-footer a:hover { color: var(--primary-soft); }

.footer-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-8); }

.footer-titre {
  margin-bottom: var(--space-3);
  color: var(--primary-soft);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-semi);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.footer-liste { margin: 0; padding: 0; list-style: none; }
.footer-liste li { margin: 0; }

/* ⚠️ LA HAUTEUR DES LIENS DÉPEND DU POINTEUR, et c'est le fond du sujet.
   Le plancher de 44 px existe pour un DOIGT, pas pour une souris : au
   clavier et à la souris il ne protège rien et il étire le pied de page,
   ce que Quentin a relevé le 24/09/2026. On sert donc 32 px par défaut,
   et le plancher revient entier dès que le pointeur est grossier.
   ⚠️ Ne pas revenir à une valeur unique : sur un site dont le téléphone est
   le canal principal, 18 liens de pied à 19 px de haut passent Lighthouse
   avec 100 en accessibilité — l'outil ne mesure pas les cibles tactiles. */
.footer-liste a {
  display: flex;
  align-items: center;
  min-height: var(--space-8);
}
@media (pointer: coarse) {
  .footer-liste a { min-height: var(--tap-target-min); }
}

/* Le bloc de marque, sorti de la grille de liens : il est l'identité du
   site, pas une colonne de menu parmi quatre. */
.footer-marque {
  padding-bottom: var(--space-8);
  margin-bottom: var(--space-10);
  border-bottom: 1px solid color-mix(in oklab, var(--stone-foreground) 16%, transparent);
}
.footer-resume {
  max-width: 48ch;
  margin-top: var(--space-4);
  color: color-mix(in oklab, var(--stone-foreground) 80%, transparent);
}
.footer-contact {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-6);
  margin-top: var(--space-2);
}

/* ⚠️ Les liens légaux sur UNE LIGNE, demandé le 24/09/2026. C'est la liste
   elle-même qui passe en ligne : `.footer-bas` empilait déjà la mention de
   copyright au-dessus, mais les deux liens restaient l'un sous l'autre. */
.footer-bas .footer-liste {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-6);
}

.footer-bas {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-top: var(--space-10);
  padding-top: var(--space-6);
  border-top: 1px solid color-mix(in oklab, var(--stone-foreground) 16%, transparent);
  color: color-mix(in oklab, var(--stone-foreground) 72%, transparent);
  font-size: var(--text-xs);
}

/* =====================================================================
   16. PILE DE BOUTONS FLOTTANTS
   ---------------------------------------------------------------------
   ⚠️ Le téléphone est le canal principal de ce métier : la pastille
   d'appel est présente sur TOUTES les pages, y compris celles qui n'ont
   ni en-tête ni pied de page.
   ===================================================================== */

/* ⚠️ AU DOIGT, C'EST UNE BARRE, PAS UNE PILE DANS UN COIN.
   Mesuré le 01/09/2026 à 375 px : la pile flottante recouvrait le bouton
   « Devis gratuit après visite » de la hauteur d'écran. Un appel à l'action
   masqué par un bouton d'appel est un défaut commercial, pas un détail de
   mise en page.

   La barre occupe toute la largeur en bas, et `body` reçoit un
   remplissage de sa hauteur : rien n'est jamais recouvert. Au-dessus de
   48 rem, elle redevient la pile dans le coin, où il y a la place. */
.float-actions {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-float);
  display: flex;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--gutter);
  /* La marge de sécurité du bas d'écran des téléphones sans bouton. */
  padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom, 0px));
  background: color-mix(in oklab, var(--background) 92%, transparent);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--border);
}

/* La hauteur reservee sous la page : bouton + ses deux remplissages. */
body {
  padding-bottom: calc(var(--tap-target-comfort) + var(--space-6)
                       + env(safe-area-inset-bottom, 0px));
}

.float-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap-target-comfort);
  height: var(--tap-target-comfort);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-md);
  text-decoration: none;
  transition: transform var(--duration-fast) var(--ease);
}
.float-btn:hover { transform: translateY(-2px); }
.float-btn .icon { width: 1.35em; height: 1.35em; }

.float-call { background: var(--primary); color: var(--primary-foreground); }
.float-call:hover { color: var(--primary-foreground); }
.float-devis { background: var(--accent); color: var(--accent-foreground); }
.float-devis:hover { color: var(--accent-foreground); }
/* ⚠️ Vert de marque : cette pastille n'affiche QU'UNE ICÔNE. Y poser un
   libellé blanc donnerait 1,98:1, un échec AA. */
.float-wa { background: var(--whatsapp-brand); color: var(--stone); }
.float-wa:hover { color: var(--stone); }

/* =====================================================================
   17. POP-UP COMMUN (ow-popup)
   ---------------------------------------------------------------------
   Collé depuis `code/popup/ow-popup.css` du skill onlyway_standards_web,
   HORS de toute media query : le pop-up existe à toutes les largeurs.
   ⚠️ Ne pas le modifier ici. Il se corrige dans le skill, puis se recopie.
   ===================================================================== */

/* ⚠️ Le `display` se pose sur `[open]`, JAMAIS sur `.ow-modal` : la règle
   de navigateur `dialog:not([open]) { display: none }` a une spécificité
   plus faible, et le pop-up resterait affiché en permanence. */
.ow-modal[open] { display: flex; }

.ow-modal {
  flex-direction: column;
  width: 100%;
  max-width: min(34rem, calc(100vw - 2rem));
  max-height: 88vh;
  max-height: 88dvh;
  margin: auto;
  padding: 0;
  border: 0;
  border-radius: var(--radius-card);
  background: var(--card);
  color: var(--card-foreground);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

.ow-modal::backdrop {
  background: var(--overlay);
  backdrop-filter: blur(3px);
}

.ow-modal-close {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: color-mix(in oklab, var(--primary) 75%, transparent);
  color: var(--primary-foreground);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease);
}
.ow-modal-close:hover { background: var(--primary); }
.ow-modal-close svg { width: 20px; height: 20px; }

.ow-modal:focus,
.ow-modal:focus-visible { outline: none; }

.ow-modal-close:focus-visible {
  outline: 3px solid var(--ring);
  outline-offset: -3px;
}

.ow-modal-body {
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 0;
}

.ow-modal-titre {
  margin: 0;
  padding: var(--space-5) var(--space-6) 0;
  font-weight: 700;
  font-size: var(--text-lg);
  color: var(--card-foreground);
}

.ow-modal-ouvert { overflow: hidden; }

/* =====================================================================
   18. APPARITION AU DÉFILEMENT
   ===================================================================== */

.reveal {
  opacity: 0;
  transform: translateY(var(--space-4));
  transition:
    opacity var(--duration-slow) var(--ease),
    transform var(--duration-slow) var(--ease);
}
.reveal[data-vu="1"] { opacity: 1; transform: none; }

/* ⚠️ Le réglage système prime sur tout le reste. Un site qui ignore
   `prefers-reduced-motion` rend malade une partie de ses visiteurs. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { opacity: 1; transform: none; }
}

/* =====================================================================
   19. ÉLARGISSEMENT
   ---------------------------------------------------------------------
   ⚠️ Ces blocs ne font QU'AJOUTER. Aucune règle du haut du fichier n'y est
   annulée : si une valeur doit être défaite ici, c'est qu'elle était
   fausse en haut.
   ===================================================================== */

/* La grille des étapes de la méthode : 4 sur une ligne dès l'ordinateur. */
.grid--4 { grid-template-columns: 1fr; }
.grid--2 { grid-template-columns: 1fr; }

/* --- Tablette ------------------------------------------------------- */
@media (min-width: 48rem) {
  .grid--4 { grid-template-columns: repeat(2, 1fr); }
  .grid--2 { grid-template-columns: repeat(2, 1fr); }
  /* La barre d'actions redevient une pile dans le coin : il y a la place,
     et la barre pleine largeur mangerait de la hauteur pour rien. */
  .float-actions {
    left: auto;
    right: var(--gutter);
    bottom: var(--gutter);
    flex-direction: column;
    padding: 0;
    padding-bottom: 0;
    background: transparent;
    backdrop-filter: none;
    border-top: 0;
  }
  body { padding-bottom: 0; }

  .grid { grid-template-columns: repeat(2, 1fr); }
  .proof { grid-template-columns: repeat(3, 1fr); gap: var(--space-6); }
  .btn-row { flex-direction: row; flex-wrap: wrap; }
  .communes { grid-template-columns: repeat(3, 1fr); }
  .footer-grid { grid-template-columns: repeat(2, 1fr); }
  .footer-bas { flex-direction: row; justify-content: space-between; align-items: center; }
  .header-call span { display: inline; }
  /* Le bouton d'appel à l'action apparaît avec la place : sous la tablette,
     l'en-tête porte déjà marque, numéro et menu, et la barre flottante du
     bas offre appel, WhatsApp et courriel. */
  .header-cta { display: inline-flex; }
  .avant-apres img { aspect-ratio: 4 / 3; }
}

/* --- Ordinateur ----------------------------------------------------- */
@media (min-width: 64rem) {
  .grid { grid-template-columns: repeat(3, 1fr); }
  /* ⚠️ QUATRE par ligne, donc huit métiers sur DEUX lignes pleines. En trois
     colonnes, la deuxième ligne finissait par deux cartes et un trou. */
  .grid--4 { grid-template-columns: repeat(4, 1fr); }
  /* ⚠️ DEUX colonnes, pas trois : ce bloc n'a que deux enfants, et la grille
     générique à trois colonnes laissait le formulaire décentré avec le texte
     à cheval. Bug signalé le 02/09/2026. */
  .grid--2 { grid-template-columns: 1fr 1fr; }
  .communes { grid-template-columns: repeat(4, 1fr); }
  .footer-grid { grid-template-columns: 1.4fr 1fr 1fr 1fr; }

  /* La navigation d'ordinateur remplace le hamburger. */
  .burger { display: none; }
  .main-nav {
    display: flex;
    align-items: center;
    gap: var(--space-5);
  }
  .main-nav a {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap-target-min);
    color: var(--stone-foreground);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    text-decoration: none;
  }
  .main-nav a:hover { color: var(--primary-soft); }
  /* La page en cours se marque, elle ne se devine pas. */
  .main-nav a[aria-current="page"] {
    color: var(--primary-soft);
    text-decoration: underline;
    text-underline-offset: 0.35em;
  }

  .site-hero { min-height: 66svh; }
  .contrainte { padding-block: var(--space-6); }
}

/* ---------------------------------------------------------------------
   POINTEUR GROSSIER — téléphones et tablettes tactiles.
   ⚠️ Ce bloc ne dépend PAS de la largeur : une tablette large reste un
   écran tactile. Il agrandit ce que la souris seule tolérerait.
   --------------------------------------------------------------------- */
@media (pointer: coarse) {
  /* ⚠️ `display: inline-flex` EST INDISPENSABLE ICI, pas décoratif :
     `min-height` est SILENCIEUSEMENT IGNORÉ sur un élément `inline`, et un
     lien l'est par défaut. La règle existait depuis le 01/09/2026 et ne
     faisait rien : les liens du fil d'Ariane mesuraient toujours 17 px,
     émulation tactile activée. Mesuré, puis corrigé le 02/09/2026. */
  .footer-liste a,
  .ariane a,
  .ariane li,
  .communes a {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap-target-min);
  }
  /* Les listes du pied de page et des communes contiennent des libelles d'un
     seul mot court : « Gazon » mesurait 43 px de large pour un plancher a 44.
     Le texte reste cale a gauche (justify-content par defaut), donc la boite
     s'elargit sans que le libelle bouge ni que le souligne s'etende. */
  .footer-liste a,
  .communes a { min-width: var(--tap-target-min); }
  .carte:hover { box-shadow: none; }
}
