/* ==========================================================================
   SERRURIER RICHARD — feuille de style unique
   ==========================================================================

   Une seule feuille, aucune dépendance, aucune requête vers un domaine tiers.
   Les polices sont auto-hébergées : le texte s'affiche sans attendre un
   serveur extérieur, et la Content-Security-Policy peut rester stricte.

   Organisation du fichier
     1.  Polices
     2.  Jetons de design (couleurs, espacements, rayons, ombres, typo)
     3.  Base et réinitialisation
     4.  Utilitaires et accessibilité
     5.  Boutons et badges
     6.  En-tête et navigation
     7.  Héros
     8.  Sections et titres
     9.  Cartes
     10. Réassurance, chiffres, étapes
     11. Galerie et médias
     12. Bandeaux d'urgence et appels à l'action
     13. Tableaux et encadrés
     14. FAQ
     15. Formulaires
     16. Article et fil d'Ariane
     17. Pied de page
     18. Barre mobile et bandeau cookies
     19. Animations
     20. Impression
   ========================================================================== */

/* --- 1. Police ------------------------------------------------------------ */

/* Une seule police pour tout le site : INTER, en fichier variable.
   Un seul téléchargement de 34 Ko couvre les graisses 100 à 900 — les quatre
   fichiers précédents en pesaient 55 à eux quatre, pour deux graisses
   chacun.

   Inter est dessinée pour les écrans, et c'est ce qui la rend lisible ici :
   hauteur d'x généreuse, formes ouvertes, et des lettres qu'on ne confond
   pas — le I majuscule, le l minuscule et le chiffre 1 sont trois dessins
   distincts. Sur un site où l'on lit un numéro de téléphone et des prix,
   cela compte davantage que le caractère.

   « font-display: swap » : le texte s'affiche immédiatement dans la police
   système, puis bascule. Mieux vaut un texte lisible tout de suite qu'un
   blanc de trois secondes. */
@font-face {
  font-family: "Inter";
  src: url("/assets/fonts/inter-variable.woff2") format("woff2-variations"),
       url("/assets/fonts/inter-variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* --- 2. Jetons de design -------------------------------------------------
   Toute la charte tient ici. Changer --color-primary suffit à repeindre
   l'ensemble du site : aucune couleur n'est écrite en dur ailleurs.
   ------------------------------------------------------------------------ */

:root {
  /* ARDOISE — la couleur dominante du site.
     Cinq niveaux, et c'est le contraste qui décide de l'usage de chacun.
     Les deux plus clairs ne portent JAMAIS de texte : ils tracent, ils
     soulignent, ils encadrent. */
  --color-primary:        #475569;   /* texte secondaire, icônes  (7,07:1) */
  --color-primary-light:  #64748B;   /* traits marqués            (4,76:1) */
  --color-primary-lighter:#94A3B8;   /* traits fins — jamais de texte      */
  --color-primary-dark:   #334155;   /* titres, contours         (10,41:1) */
  --color-primary-deep:   #1E293B;   /* TEXTE, liens, fonds de bouton (14,6:1) */
  /* Sur un aplat ardoise très clair, on reste sur l'encre la plus dense :
     elle y tient 12,4:1, il n'y a donc aucune raison de descendre. */
  --color-primary-sur-clair: #1E293B;
  --color-primary-soft:   #E9EDF2;   /* aplat de section, pastilles */
  --color-primary-tint:   #F5F7F9;   /* voile le plus léger */

  /* Encre — la couleur du texte. Elle ne sert pas de fond. */
  --color-dark:           #0F172A;
  --color-dark-2:         #1E293B;
  --color-dark-3:         #334155;

  /* Orange — urgence uniquement, employé avec parcimonie.
     C'est la SEULE couleur du site : elle ne vaut que parce que rien
     d'autre ne vient la concurrencer. */
  --color-secondary:      #F97316;
  --color-secondary-dark: #C2410C;
  --color-secondary-soft: #FFF7ED;

  /* Neutres — blanc cassé, jamais de gris froid en aplat */
  --color-white:          #FFFFFF;
  --color-background:     #FAFAF9;   /* blanc cassé, surfaces alternées */
  --color-background-2:   #F4F4F2;
  --color-text:           #334155;   /* 10,41:1 sur blanc */
  --color-muted:          #64748B;   /* 4,76:1 sur blanc — blanc PUR seulement */
  --color-muted-light:    #94A3B8;
  --color-border:         #E4E4E1;
  --color-border-strong:  #CBCBC6;

  /* Sémantique */
  --color-success:        #059669;
  --color-success-soft:   #ECFDF5;
  --color-danger:         #DC2626;
  --color-danger-soft:    #FEF2F2;

  /* Typographie */
  /* Deux jetons, une seule famille : la distinction titre/texte se fait
     désormais par la GRAISSE et l'interlettrage, pas par un changement de
     dessin. C'est plus sobre, et plus solide — deux polices mal accordées se
     remarquent, une seule bien réglée ne se remarque pas. Les deux noms sont
     conservés : une centaine de règles s'y réfèrent. */
  --font-title: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body:  "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

  --text-xs:   0.8125rem;
  --text-sm:   0.9063rem;
  --text-base: 1rem;
  --text-lg:   1.125rem;
  --text-xl:   1.3125rem;
  --text-2xl:  clamp(1.375rem, 1.2rem + 0.7vw, 1.625rem);
  --text-3xl:  clamp(1.625rem, 1.35rem + 1.2vw, 2.125rem);
  --text-4xl:  clamp(2rem, 1.5rem + 2.2vw, 3.125rem);

  /* Espacements — échelle de 4 px */
  --space-1: 0.25rem;  --space-2: 0.5rem;   --space-3: 0.75rem;
  --space-4: 1rem;     --space-5: 1.5rem;   --space-6: 2rem;
  --space-7: 2.5rem;   --space-8: 3rem;     --space-9: 4rem;
  --space-10: 5rem;    --space-12: 7rem;

  /* Structure */
  --container: 1200px;
  --container-etroit: 760px;

  /* Rayons */
  /* Angles vifs, partout. Les jetons gardent leur nom — une centaine de
     règles s'y réfèrent — mais valent tous zéro : le site n'a plus un seul
     coin arrondi, boutons compris. Pour revenir à des angles adoucis, il
     suffit de redonner une valeur à ces cinq lignes. */
  --radius-sm: 0;
  --radius:    0;
  --radius-lg: 0;
  --radius-xl: 0;
  --radius-full: 0;

  /* Ombres — diffuses et colorées, jamais du gris neutre */
  --shadow-xs: 0 1px 2px rgba(15,23,42,.05);
  --shadow-sm: 0 1px 3px rgba(15,23,42,.07), 0 1px 2px rgba(15,23,42,.04);
  --shadow:    0 4px 16px rgba(15,23,42,.07), 0 1px 3px rgba(15,23,42,.05);
  --shadow-lg: 0 12px 32px rgba(15,23,42,.10), 0 4px 8px rgba(15,23,42,.04);
  --shadow-xl: 0 24px 56px rgba(15,23,42,.14), 0 8px 16px rgba(15,23,42,.05);
  /* Ombres portées nettes et neutres : un halo de couleur ramollirait
     l'arête vive des boutons. Décalage franc, très peu de flou. */
  --shadow-primary: 0 3px 0 rgba(15,23,42,.20);
  --shadow-secondary: 0 3px 0 rgba(120,53,15,.35);

  --transition: 180ms cubic-bezier(.4,0,.2,1);

  /* Le site est conçu clair. On le déclare, plutôt que de laisser le
     navigateur inverser des couleurs qui perdraient leur sens. */
  color-scheme: light;
}

/* --- 3. Base -------------------------------------------------------------- */

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

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

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.7;
  color: var(--color-text);
  background: var(--color-white);
  font-feature-settings: "kern" 1, "liga" 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

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

a { color: var(--color-primary-deep); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--color-primary); }

h1, h2, h3, h4, h5 {
  font-family: var(--font-title);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--color-dark);
  margin: 0 0 var(--space-4);
  text-wrap: balance;
}
h1 { font-size: var(--text-4xl); letter-spacing: -0.03em; }
h2 { font-size: var(--text-3xl); }
h3 { font-size: var(--text-xl); letter-spacing: -0.01em; }
h4 { font-size: var(--text-lg); }

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

/* 600 et non 700 : dans une phrase, le 700 d'Inter fait une tache noire qui
   attire l'œil hors de la ligne. 600 se distingue nettement du 400 sans
   casser le gris de lecture. Les titres, eux, restent en 700. */
strong, b { font-weight: 600; color: var(--color-dark); }

/* Un numéro de téléphone se lit chiffre par chiffre, pas comme un mot : les
   chiffres tabulaires lui donnent un rythme régulier. */
.btn-call, .barre-mobile-appel, .hero-vignette strong, .header-call-numero {
  font-variant-numeric: tabular-nums;
}

/* Toutes les sections du site sont désormais claires : un « strong » garde
   partout la couleur d'encre, il n'y a plus d'inversion à gérer. */

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

hr { border: 0; border-top: 1px solid var(--color-border); margin: var(--space-7) 0; }

::selection { background: var(--color-primary-soft); color: var(--color-primary-deep); }

/* --- 4. Utilitaires et accessibilité -------------------------------------- */

.wrap {
  width: min(100% - var(--space-6), var(--container));
  margin-inline: auto;
}
.wrap-etroit { width: min(100% - var(--space-6), var(--container-etroit)); margin-inline: auto; }

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

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--color-primary-deep); color: #fff;
  padding: var(--space-3) var(--space-5);
  font-weight: 700; border-radius: 0 0 var(--radius-sm) 0;
}
.skip-link:focus { left: 0; color: #fff; }

:focus-visible {
  outline: 3px solid var(--color-primary-light);
  outline-offset: 3px;
  border-radius: 0;
}

/* --- 5. Boutons et badges ------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-2);
  padding: 0.875rem 1.5rem;
  min-height: 48px;
  border-radius: var(--radius-full);
  font-family: var(--font-title);
  font-weight: 700; font-size: var(--text-base);
  letter-spacing: -0.01em;
  text-decoration: none;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform var(--transition), background-color var(--transition),
              box-shadow var(--transition), border-color var(--transition), color var(--transition);
  white-space: nowrap;
  max-width: 100%;
}
/* Sur un écran étroit, un libellé long — « Dépannage immédiat — 02 20 06 00 75 »
   par exemple — ne peut pas rester sur une ligne sans faire déborder la page.
   Le bouton passe alors sur deux lignes plutôt que de casser la mise en page. */
@media (max-width: 640px) {
  .btn { white-space: normal; text-align: center; line-height: 1.3; }
  .btn-large { padding: 0.9375rem 1.25rem; font-size: var(--text-base); }
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

/* Appel — l'action principale du site, toujours en orange d'urgence.
   Le texte est brun très sombre et non blanc : blanc sur cet orange ne donne
   que 2,80 de contraste, là où WCAG AA en exige 4,5 pour du texte de 16 px.
   Le brun atteint 6,63 sans rien perdre de la vivacité du bouton.
   Le survol éclaircit au lieu d'assombrir, ce qui augmente encore l'écart. */
.btn-call {
  background: var(--color-secondary); color: #1A1200;
  box-shadow: var(--shadow-secondary);
}
.btn-call:hover { background: #FB923C; color: #1A1200; box-shadow: 0 3px 0 rgba(120,53,15,.45); }

/* Devis — action secondaire, dans l'encre du site */
.btn-devis {
  background: var(--color-primary-deep); color: #fff;
  box-shadow: var(--shadow-primary);
}
.btn-devis:hover { background: var(--color-dark); color: #fff; }

.btn-urgence { background: var(--color-danger); color: #fff; }
.btn-urgence:hover { background: #B91C1C; color: #fff; }

.btn-ghost {
  border-color: var(--color-border-strong);
  color: var(--color-dark);
  background: var(--color-white);
}
.btn-ghost:hover { border-color: var(--color-primary); color: var(--color-primary-deep); background: var(--color-primary-tint); }

/* Dans le héros et les appels à l'action, le bouton fantôme est posé sur une
   surface claire : il garde son dessin, avec un contour un peu plus affirmé
   pour ne pas disparaître dans le fond. */
.hero .btn-ghost, .cta-final .btn-ghost, .bandeau-urgence .btn-ghost {
  background: var(--color-white);
  border-color: var(--color-border-strong);
  color: var(--color-dark);
}
.hero .btn-ghost:hover, .cta-final .btn-ghost:hover, .bandeau-urgence .btn-ghost:hover {
  border-color: var(--color-primary);
  color: var(--color-primary-dark);
  background: var(--color-primary-tint);
}

.btn-large { padding: 1.0625rem 2rem; font-size: var(--text-lg); min-height: 58px; }
.btn-bloc  { display: flex; width: 100%; }

.badge {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 0.375rem 0.875rem;
  border-radius: var(--radius-full);
  font-family: var(--font-title);
  font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  background: var(--color-primary-soft); color: var(--color-primary-sur-clair);
}
.badge-urgence { background: var(--color-secondary-soft); color: var(--color-secondary-dark); }

/* Badge du héros : une étiquette de contexte, pas un bouton. Elle est donc
   neutre — l'orange du site ne sert qu'à une chose, appeler. Le point orange
   clignotant qui l'ouvrait a été retiré : il suggérait un état « en ligne »
   que rien ne mesure. */
.urgence-badge {
  display: inline-flex; align-items: center; gap: var(--space-2);
  background: var(--color-white);
  color: var(--color-dark);             /* 16,1:1 sur blanc */
  border: 1px solid var(--color-border-strong);
  padding: 0.4375rem 1rem;
  border-radius: var(--radius-full);
  font-family: var(--font-title);
  font-size: var(--text-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .08em;
  margin-bottom: var(--space-5);
}

/* --- 6. En-tête et navigation ---------------------------------------------
   UNE seule ligne. Un rail à trois colonnes dont la colonne centrale est
   réellement centrée : « 1fr auto 1fr », la marque et les actions dans les
   colonnes latérales. C'est ce qui produit l'équilibre, et non un ajustement
   de marges à l'œil.

   La barre de service qui coiffait la page a été supprimée : elle répétait le
   téléphone et le devis, elle poussait le contenu vers le bas, et c'était le
   premier bloc que le visiteur voyait.

   Au défilement, le rail perd quelques pixels de hauteur — la baseline se
   replie — sans que la navigation ni l'appel ne disparaissent jamais.
   ------------------------------------------------------------------------ */

.site-header {
  position: sticky; top: 0; z-index: 100;
  background: var(--color-white);
  border-bottom: 1px solid var(--color-border);
  color: var(--color-dark);
  transition: box-shadow 220ms ease;
}
body.defile .site-header { box-shadow: 0 4px 20px rgba(15, 23, 42, .07); }

.header-inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-6);
  padding-block: var(--space-4);
  transition: padding-block 220ms ease;
}
body.defile .header-inner { padding-block: var(--space-3); }

/* --- La marque ------------------------------------------------------------
   Le logo est une image, pas du texte reconstitué : le mot-symbole a sa
   typographie propre, et la réécrire en CSS donnerait une imitation, pas la
   marque. La hauteur est imposée ici, la largeur suit — un logo étiré n'est
   plus un logo. « width » et « height » sont écrits dans la balise : la place
   est réservée avant même que le fichier arrive, la page ne saute pas.
   ------------------------------------------------------------------------ */
.brand {
  display: flex; align-items: center;
  text-decoration: none; min-height: 44px; justify-self: start;
}
.brand img {
  display: block; width: auto;
  height: 56px;
  transition: height 220ms ease;
}
/* Au défilement le rail se resserre : le logo suit, sans jamais disparaître. */
body.defile .brand img { height: 44px; }

.brand picture { display: block; }

/* --- Navigation, colonne centrale ---------------------------------------
   Le repère de la page courante et celui du survol sont le MÊME trait, sous
   le mot. Un aplat de couleur derrière sept entrées faisait sept blocs ;
   un trait sous une seule en fait une.
   ------------------------------------------------------------------------ */

.nav { min-width: 0; justify-self: center; }
.nav ul { display: flex; gap: var(--space-2); list-style: none; margin: 0; padding: 0; }
.nav li { margin: 0; }
.nav a {
  display: flex; align-items: center;
  position: relative;
  min-height: 40px;
  padding: 0 var(--space-3);
  color: var(--color-dark-3); text-decoration: none;
  font-family: var(--font-title);
  font-size: var(--text-sm); font-weight: 600;
  white-space: nowrap;
  transition: color var(--transition);
}
.nav a::after {
  content: ""; position: absolute;
  left: var(--space-3); right: var(--space-3); bottom: 4px;
  height: 2px;
  background: var(--color-dark);
  transform: scaleX(0); transform-origin: center;
  transition: transform var(--transition);
}
.nav a:hover { color: var(--color-dark); }
.nav a:hover::after { transform: scaleX(1); }
.nav a[aria-current="page"] { color: var(--color-dark); }
.nav a[aria-current="page"]::after {
  transform: scaleX(1);
  background: var(--color-secondary);
}

/* --- Actions, colonne de droite ----------------------------------------- */

.header-actions {
  display: flex; align-items: center; gap: var(--space-4);
  justify-self: end;
}
/* Le devis est un lien, pas un bouton : deux boutons côte à côte se
   concurrencent, et c'est l'appel qui doit gagner. */
.header-devis {
  display: inline-flex; align-items: center;
  min-height: 44px;
  color: var(--color-dark-3); text-decoration: none;
  font-family: var(--font-title);
  font-size: var(--text-sm); font-weight: 600;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
  transition: color var(--transition), border-color var(--transition);
}
.header-devis:hover {
  color: var(--color-dark);
  border-bottom-color: var(--color-dark);
}
.header-call {
  flex-direction: column; gap: 0; line-height: 1.15;
  padding: 0 var(--space-5); min-height: 46px;
  white-space: nowrap;
}
.header-call-libelle { font-size: var(--text-xs); font-weight: 600; opacity: .85; }
.header-call-numero { font-family: var(--font-title); font-size: 1.0625rem; }

.nav-toggle {
  display: none; align-items: center; justify-content: center;
  min-width: 46px; min-height: 46px;
  background: var(--color-white); border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm); padding: 0; cursor: pointer;
}
.nav-toggle-bars, .nav-toggle-bars::before, .nav-toggle-bars::after {
  display: block; width: 20px; height: 2px; background: var(--color-dark);
  content: ""; transition: transform var(--transition), opacity var(--transition);
}
.nav-toggle-bars::before { transform: translateY(-6px); }
.nav-toggle-bars::after  { transform: translateY(4px); }
/* Croix lorsque le panneau est ouvert : l'état du bouton doit être lisible. */
.nav-toggle[aria-expanded="true"] .nav-toggle-bars { background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::before { transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::after  { transform: translateY(-2px) rotate(-45deg); }

/* --- Bascule mobile ------------------------------------------------------
   En dessous de 1080 px, la navigation ne tient plus au centre. Elle devient
   un panneau qui glisse sous le header, avec des entrées assez hautes pour
   être touchées sans viser.
   ------------------------------------------------------------------------ */

@media (max-width: 1080px) {
  .header-inner { grid-template-columns: auto 1fr; gap: var(--space-4); }
  .nav-toggle { display: flex; }
  /* La ligne se réduit à : nom · appeler · menu. */
  .header-devis { display: none; }

  .nav {
    position: absolute; left: 0; right: 0; top: 100%;
    justify-self: stretch;
    background: var(--color-white);
    border-bottom: 1px solid var(--color-border);
    box-shadow: 0 18px 40px rgba(15, 23, 42, .12);
    display: none;
  }
  .nav[data-ouvert="true"] { display: block; }
  .nav ul {
    flex-direction: column; gap: 0;
    width: min(100% - var(--space-6), var(--container));
    margin-inline: auto;
    padding: var(--space-3) 0 var(--space-5);
  }
  .nav li + li { border-top: 1px solid var(--color-border); }
  .nav a {
    min-height: 54px; padding: 0 var(--space-2);
    font-size: var(--text-lg);
  }
  /* Dans le panneau, le trait passe à gauche du mot : sous le mot, il se
     confondrait avec la séparation entre deux entrées. */
  .nav a::after {
    left: calc(var(--space-2) * -1); right: auto; top: 12px; bottom: 12px;
    width: 3px; height: auto;
    transform: scaleY(0);
  }
  .nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleY(1); }
}

@media (max-width: 900px) {
  /* Le rail se réduit : le logo aussi, plutôt que d'écraser le bouton
     d'appel, qui est la raison d'être de cette ligne. */
  .brand img { height: 48px; }
  body.defile .brand img { height: 40px; }
}
@media (max-width: 560px) {
  .header-inner { padding-block: var(--space-3); gap: var(--space-3); }
  .header-call { padding: 0 var(--space-4); }
  /* C'est « picture » qui a déjà changé de fichier : il ne reste qu'à donner
     à la marque, bien plus haute que large, sa propre hauteur. */
  .brand img { height: 44px; }
  body.defile .brand img { height: 38px; }
}
@media (max-width: 400px) {
  .header-call { flex-direction: row; gap: var(--space-2); padding: 0 var(--space-3); }
  .header-call-numero { display: none; }
  .header-call-libelle { font-size: var(--text-sm); opacity: 1; }
  .nav-toggle { min-width: 42px; min-height: 42px; }
  .brand img { height: 40px; }
}

/* --- 7. Héros ------------------------------------------------------------- */

.hero {
  position: relative;
  /* Un seul dégradé, très léger : le fond doit se remarquer par sa clarté,
     pas par sa couleur. Le voile orange qui était ici n'existait que pour
     équilibrer le bleu ; sans bleu, il ne restait qu'une tache. */
  background:
    radial-gradient(1100px 520px at 78% 6%, var(--color-primary-soft), transparent 62%),
    linear-gradient(168deg, var(--color-primary-tint) 0%, var(--color-white) 52%, var(--color-background) 100%);
  color: var(--color-text);
  padding: var(--space-9) 0 var(--space-10);
  overflow: hidden;
}
/* Grille technique discrète, évoque le plan et la précision */
.hero::before {
  content: ""; position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(30,41,59,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(30,41,59,.05) 1px, transparent 1px);
  background-size: 56px 56px;
  mask-image: radial-gradient(circle at 50% 0%, #000 30%, transparent 72%);
  pointer-events: none;
}
.hero > * { position: relative; }

.hero h1 { margin-bottom: var(--space-5); }
.hero p { color: var(--color-dark-3); }
.hero .chapeau { font-size: var(--text-lg); color: var(--color-dark-3); max-width: 38ch; line-height: 1.65; }
.hero a:not(.btn) { color: var(--color-primary-deep); }

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
  gap: var(--space-8);
  /* « stretch » et non « center » : la photo occupe toute la hauteur de la
     colonne de texte. Centrée, elle laissait en dessous d'elle un vide plus
     haut qu'elle-même — le défaut le plus visible d'un héros à deux colonnes. */
  align-items: stretch;
}
.hero-grid > div:first-child { display: flex; flex-direction: column; justify-content: center; }
.hero-actions {
  display: flex; gap: var(--space-3); flex-wrap: wrap;
  margin-top: var(--space-6); margin-bottom: 0;
}

/* Réassurance du héros : liste à coches, pas des chiffres inventés.
   Elle occupe toute la largeur, sous les deux colonnes. */
/* Deux rangées explicites : tous les titres sur la première, toutes les
   descriptions sur la seconde. Sans cela, un titre qui passe sur deux lignes
   décalait sa description seule vers le bas et la rangée partait de travers.
   Les quatre entrées s'y accrochent par « subgrid ». */
.hero-preuves {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(4, minmax(0,1fr));
  grid-auto-rows: auto;
  gap: var(--space-2) var(--space-6);
  margin: var(--space-7) 0 0; padding: var(--space-6) 0 0;
  border-top: 1px solid var(--color-border);
  list-style: none;
}
.preuve {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  grid-template-rows: subgrid;
  grid-row: span 2;
  column-gap: var(--space-3);
  margin: 0;
}
/* Repli pour un navigateur sans « subgrid » : la mise en page reste correcte,
   seule la synchronisation des rangées est perdue. */
@supports not (grid-template-rows: subgrid) {
  .hero-preuves { align-items: start; }
  .preuve { grid-template-rows: auto auto; grid-row: auto; }
}
/* Le marqueur de liste est un caractère, pas un dessin vectoriel : il indique
   un point vérifié, il ne prétend pas illustrer quoi que ce soit. */
.preuve::before {
  content: "\2713";
  grid-column: 1; grid-row: 1;
  width: 22px; height: 22px; margin-top: 3px;
  display: grid; place-items: center;
  background: var(--color-primary-soft);
  color: var(--color-primary-deep);
  font-size: 13px; font-weight: 700; line-height: 1;
}
.preuve strong {
  grid-column: 2; grid-row: 1;
  font-family: var(--font-title); font-size: var(--text-base);
  line-height: 1.35;
}
.preuve span {
  grid-column: 2; grid-row: 2;
  font-size: var(--text-sm); color: var(--color-muted);
  line-height: 1.5;
}

/* Le visuel d'ouverture est traité comme une image de première page : le
   rapport est imposé par le conteneur, jamais laissé au fichier. Le fichier
   maître est en 16/9. Affiché sur toute la largeur, il est rendu tel quel,
   sans le moindre recadrage ; en deux colonnes il passe en 3/2, ce qui retire
   environ 16 % de largeur sur les bords — le technicien reste entier, la
   serrure reste au centre. Aucun recadrage plus agressif n'est appliqué : la
   colonne de texte, plus haute que l'image, ne l'étire plus pour la rejoindre,
   c'est la vignette placée dessous qui occupe le reste de la hauteur. */
.hero-media {
  display: flex; flex-direction: column; justify-content: center;
  gap: var(--space-4);
}
.hero-media img, .hero-media picture {
  display: block; width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover; object-position: 42% center;
  border-radius: var(--radius-lg);
  box-shadow: 0 28px 56px rgba(15, 23, 42, .18);
  border: 1px solid var(--color-border);
}

/* Vignette téléphone : un bloc posé sous la photo, jamais par-dessus. Rien
   n'est masqué du visuel, et le rapport de l'image reste intact. */
.hero-vignette {
  background: var(--color-white); color: var(--color-dark);
  border-radius: var(--radius); padding: var(--space-4) var(--space-5);
  box-shadow: var(--shadow-lg);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-secondary);
}
.hero-vignette strong { display: block; font-family: var(--font-title); font-size: var(--text-xl); line-height: 1.2; letter-spacing: -0.02em; }
.hero-vignette span { font-size: var(--text-xs); color: var(--color-muted); }

/* À partir de 1151 px la photo partage la ligne avec le texte : le 3/2 la
   rend plus haute sans la déformer et remplit la colonne. En dessous, elle
   occupe toute la largeur et garde le 16/9 du fichier. */
@media (min-width: 1151px) {
  .hero-media img, .hero-media picture { aspect-ratio: 3 / 2; }
}

@media (max-width: 1080px) {
  .hero-preuves { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 1150px) {
  .hero { padding: var(--space-7) 0 var(--space-8); }
  .hero-grid { grid-template-columns: 1fr; gap: var(--space-7); }
  .hero .chapeau { max-width: none; }
}
@media (max-width: 560px) {
  .hero-preuves { grid-template-columns: 1fr; }
  .hero-actions .btn { width: 100%; }
}

/* Héros compact des pages intérieures */
.hero-page { padding: var(--space-7) 0 var(--space-8); }
.hero-page h1 { margin-bottom: var(--space-4); }

/* --- 8. Sections et titres ------------------------------------------------ */

section { padding: var(--space-9) 0; }
section.alt { background: var(--color-background); }
/* Anciennement la seule section sombre du site. Elle reste une respiration
   visuelle — un aplat teinté entre deux sections blanches — mais en clair,
   comme le reste. Le nom de classe est conservé : il est employé dans les
   pages, et le renommer aurait modifié du contenu sans rien apporter. */
section.sombre {
  background:
    radial-gradient(900px 420px at 15% 0%, var(--color-primary-soft), transparent 62%),
    linear-gradient(170deg, var(--color-primary-tint), var(--color-background));
  border-block: 1px solid var(--color-border);
}

.section-titre { max-width: 46rem; margin-bottom: var(--space-7); }
.section-titre .badge { margin-bottom: var(--space-4); }
.section-titre h2 { margin-bottom: var(--space-3); }
/* « :not(.badge) » est indispensable : sans lui cette règle est plus
   spécifique que « .badge » et lui impose le gris des chapeaux — 4,15:1 sur
   l'aplat bleu clair, sous le seuil WCAG AA. */
.section-titre p:not(.badge) { color: var(--color-muted); font-size: var(--text-lg); }
.section-titre-centre { margin-inline: auto; text-align: center; }

.grille { display: grid; gap: var(--space-5); }
.grille-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); }
.grille-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.grille-4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); }

/* --- 9. Cartes ------------------------------------------------------------ */

.carte {
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}
.carte h3 { margin-bottom: var(--space-2); }
/* Idem : une pastille posée dans une carte doit garder sa couleur, sinon elle
   passe sous le seuil de contraste AA sur son fond bleu clair. */
.carte p:not(.badge) { color: var(--color-muted); }
.carte > :last-child { margin-bottom: 0; }

.carte-icone {
  width: 52px; height: 52px; border-radius: var(--radius-sm);
  background: linear-gradient(140deg, var(--color-primary-soft), #fff);
  border: 1px solid var(--color-border);
  color: var(--color-primary);
  display: grid; place-items: center;
  margin-bottom: var(--space-4);
}
.carte-icone svg { width: 26px; height: 26px; }

.lien-fleche {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-title); font-weight: 700;
  color: var(--color-primary-deep); text-decoration: none;
  min-height: 24px; padding: var(--space-1) 0;
}
.lien-fleche::after {
  content: "→"; transition: transform var(--transition); font-size: 1.1em;
}
.lien-fleche:hover { color: var(--color-primary); }
.lien-fleche:hover::after { transform: translateX(4px); }

/* Carte de prestation avec photo — le composant central du site */
.carte-service {
  display: flex; flex-direction: column;
  padding: 0; overflow: hidden;
}
/* Sans image, la carte redevient une carte de texte : c'est le corps qui
   porte les marges, et la pastille remplace le bandeau posé sur la photo. */
.carte-service .carte-corps { padding: var(--space-6); }
.carte-service .badge { align-self: flex-start; margin-bottom: var(--space-4); }
.carte-service:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
  border-color: var(--color-primary-lighter);
}
/* Cartes : 3/2, exactement le format des fichiers maîtres. Aucun recadrage,
   donc aucun risque de couper une main ou une tête, et toutes les cartes
   d'une grille ont la même hauteur d'image quelle que soit la photo. */
.carte-media {
  position: relative; aspect-ratio: 3 / 2;
  background: var(--color-background-2); overflow: hidden;
}
.carte-media img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  transition: transform 420ms cubic-bezier(.4,0,.2,1);
}
.carte-service:hover .carte-media img { transform: scale(1.045); }
.carte-media .badge {
  position: absolute; top: var(--space-3); left: var(--space-3);
  background: rgba(255,255,255,.94); color: var(--color-primary-deep);
  box-shadow: var(--shadow-sm); backdrop-filter: blur(6px);
}
.carte-corps { padding: var(--space-5); display: flex; flex-direction: column; flex: 1; }
.carte-corps h3 { margin-bottom: var(--space-2); }
.carte-service .probleme {
  font-size: var(--text-sm); color: var(--color-muted);
  background: var(--color-background); border-radius: var(--radius-sm);
  padding: var(--space-3); margin: 0 0 var(--space-3);
  border-left: 3px solid var(--color-primary-lighter);
}
.carte-service .probleme strong { color: var(--color-dark); }
.carte-service .carte-pied {
  margin: auto 0 0; padding-top: var(--space-4);
  display: flex; gap: var(--space-3); flex-wrap: wrap; align-items: center;
}
.carte-service .carte-pied .btn { padding: 0.5rem 1rem; min-height: 40px; font-size: var(--text-sm); }
/* Le bouton d'appel des cartes passe en contour. Six pastilles orange pleines
   dans un même écran ne se lisent plus comme un accent mais comme un motif :
   l'aplat reste réservé aux appels principaux — en-tête, héros, bandeau
   d'urgence, barre fixe du mobile. Le geste, lui, est identique. */
.carte-service .carte-pied .btn-call {
  background: var(--color-white);
  color: var(--color-secondary-dark);      /* 5,15:1 sur blanc */
  border: 1.5px solid var(--color-secondary);
  box-shadow: none;
}
.carte-service .carte-pied .btn-call:hover {
  background: var(--color-secondary);
  color: var(--color-dark);
}

/* --- 10. Réassurance, chiffres, étapes ------------------------------------ */

/* Réassurance — du texte, pas d'image. Les photos qui s'y trouvaient
   reprenaient celles des cartes de prestation situées juste en dessous :
   l'accueil affichait 26 images pour 14 visuels distincts. Un fait chiffré
   convainc mieux qu'une photo vue trois fois sur la même page. */
.reassurance {
  display: grid; gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
  list-style: none; margin: 0; padding: 0;
}
.reassurance li {
  margin: 0;
  padding: var(--space-6);
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-top: 3px solid var(--color-primary);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.reassurance strong {
  display: block; font-family: var(--font-title);
  color: var(--color-dark); font-size: var(--text-lg);
  margin-bottom: var(--space-3);
}
.reassurance li > span { font-size: var(--text-sm); color: var(--color-muted); line-height: 1.65; }

.engagements { list-style: none; margin: var(--space-5) 0 0; padding: 0; display: grid; gap: var(--space-4); }
.engagements li {
  margin: 0;
  padding: var(--space-4) 0 var(--space-4) var(--space-5);
  border-left: 3px solid var(--color-primary-light);
}
.engagements strong {
  display: block; font-family: var(--font-title);
  color: var(--color-dark); font-size: var(--text-lg); margin-bottom: var(--space-1);
}
.engagements li { color: var(--color-muted); font-size: var(--text-sm); line-height: 1.65; }

.chiffres {
  list-style: none; padding: 0; margin: 0;
  display: grid; gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 170px), 1fr));
}
.chiffres li {
  background: var(--color-white); border: 1px solid var(--color-border);
  border-radius: var(--radius); padding: var(--space-5) var(--space-4);
  text-align: center; margin: 0; box-shadow: var(--shadow-xs);
}
.chiffres strong {
  display: block; font-family: var(--font-title);
  font-size: 1.875rem; line-height: 1.1; color: var(--color-primary-dark);
  letter-spacing: -0.03em;
}
.chiffres span { font-size: var(--text-sm); color: var(--color-muted); }
/* « à partir de », posé AVANT le montant : c'est dans cet ordre qu'on le lit.
   Placé après, il se lisait comme un commentaire de la ligne suivante. */
.chiffres small {
  display: block;
  font-size: var(--text-xs); font-weight: 600;
  text-transform: uppercase; letter-spacing: .08em;
  color: var(--color-muted);
  margin-bottom: var(--space-1);
}

.etapes {
  counter-reset: etape; list-style: none; padding: 0; margin: 0;
  display: grid; gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
}
.etapes li { counter-increment: etape; position: relative; padding-top: var(--space-8); margin: 0; }
.etapes li::before {
  content: counter(etape, decimal-leading-zero);
  position: absolute; top: 0; left: 0;
  font-family: var(--font-title); font-weight: 700;
  font-size: 1.5rem; line-height: 1;
  color: var(--color-primary);
  background: var(--color-primary-soft);
  border-radius: var(--radius-sm);
  padding: 0.5rem 0.75rem;
  letter-spacing: -0.03em;
}
.etapes h3 { margin-bottom: var(--space-2); font-size: var(--text-lg); }
.etapes p { color: var(--color-muted); font-size: var(--text-sm); margin: 0; }
section.sombre .etapes li::before { background: var(--color-primary-soft); color: var(--color-primary-deep); }

/* Carte de prestation locale : le gabarit d'une carte de service, sans
   image. Sur une page de zone, les six cartes reprenaient les visuels du
   héros et des cas d'intervention de la même page. Un titre, un texte de
   contexte local et un lien suffisent, et la page cesse de tourner en rond. */
.carte-locale {
  display: flex; flex-direction: column;
  padding: var(--space-6);
}
.carte-locale .badge { align-self: flex-start; margin-bottom: var(--space-4); }
.carte-locale h3 { margin-bottom: var(--space-3); }
/* « :not(.badge) » est indispensable : sans lui ce sélecteur, plus spécifique
   que .badge, repeignait les pastilles en gris et les faisait tomber sous le
   seuil AA. */
.carte-locale p:not(.badge) { color: var(--color-muted); font-size: var(--text-sm); line-height: 1.65; }
.carte-locale .carte-pied { margin-top: auto; padding-top: var(--space-4); }

/* --- 11. Galerie et médias ------------------------------------------------ */

/* --- Galerie — en sommeil ------------------------------------------------
   La section « Nos interventions » a quitté l'accueil : elle réunissait, sur
   un même écran, les photographies déjà présentes sur les pages de service.
   C'était exactement la répétition à supprimer.

   Le mécanisme reste entier — src/galerie.conf, les deux jetons GALERIE et
   GALERIE_FILTRES, les filtres, la visionneuse. Il suffit de remettre la
   section dans src/pages/index.html pour la rallumer. À faire le jour où des
   photographies existeront qui n'ont pas déjà leur place ailleurs : sans
   quoi la galerie recréerait le doublon qu'on vient de retirer.
   ------------------------------------------------------------------------ */
.galerie {
  display: grid; gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  list-style: none; padding: 0; margin: 0;
}
.galerie figure {
  margin: 0; border-radius: var(--radius);
  overflow: hidden; background: var(--color-background-2);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition), box-shadow var(--transition);
}
.galerie figure:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.galerie img { display: block; width: 100%; aspect-ratio: 3 / 2; object-fit: cover; object-position: center; }
.galerie figcaption {
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm); color: var(--color-muted);
  background: var(--color-white);
}
.galerie figcaption strong { display: block; color: var(--color-dark); font-family: var(--font-title); }

/* Grande illustration en pleine largeur de colonne */
/* Image principale d'une page service. Elle a droit à de l'air : collée au
   texte qui la précède, elle se lit comme l'illustration d'un paragraphe et
   non comme le sujet de la page. */
.media-large {
  border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: var(--shadow-lg); border: 1px solid var(--color-border);
  margin: var(--space-7) 0 var(--space-3);
}
.media-large img {
  display: block; width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover; object-position: center;
}
.media-legende {
  font-size: var(--text-sm); color: var(--color-muted);
  margin-top: calc(var(--space-6) * -1 + var(--space-3));
  margin-bottom: var(--space-6);
}

/* Bloc alterné texte / image */
.duo {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: var(--space-8); align-items: center;
}
.duo-inverse .duo-media { order: -1; }
.duo-media img { border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); }
@media (max-width: 900px) {
  .duo { grid-template-columns: 1fr; gap: var(--space-6); }
  .duo-inverse .duo-media { order: 0; }
}

/* --- 12. Urgence et appels à l'action ------------------------------------- */

/* L'urgence se signale par la couleur, pas par l'obscurité : un aplat chaud
   très clair, un liseré orange, et le bouton d'appel qui reste le seul
   élément pleinement saturé de la section. */
.bandeau-urgence {
  background:
    radial-gradient(700px 320px at 85% 15%, rgba(249,115,22,.16), transparent 62%),
    linear-gradient(150deg, #FFF7ED 0%, #FFEDD5 60%, #FFF7ED 100%);
  color: var(--color-text);
  border-block: 1px solid #FDBA74;
  padding: var(--space-8) 0;
}
.bandeau-urgence p { color: #7C2D12; }
/* Ce lien est un appel à l'action à part entière, pas un lien noyé dans un
   paragraphe : il doit respecter la taille minimale de cible tactile
   demandée par WCAG 2.5.8 (24 px). */
.bandeau-urgence a:not(.btn) {
  color: #9A3412;
  display: inline-block; padding: var(--space-2) var(--space-1); min-height: 24px;
}

.urgence-inner { display: grid; grid-template-columns: 1.5fr 0.5fr; gap: var(--space-7); align-items: center; }
@media (max-width: 900px) { .urgence-inner { grid-template-columns: 1fr; } }

.liste-situations {
  list-style: none; padding: 0; margin: var(--space-5) 0 0;
  display: grid; gap: var(--space-2) var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr));
}
.liste-situations li {
  position: relative; padding-left: 1.75rem; font-size: var(--text-sm); margin: 0;
}
.liste-situations li::before {
  content: ""; position: absolute; left: 0; top: .5em;
  width: 6px; height: 6px;
  background: currentColor; opacity: .6;
}

.cta-final {
  background:
    radial-gradient(800px 380px at 50% 0%, var(--color-primary-soft), transparent 64%),
    linear-gradient(165deg, var(--color-primary-tint), var(--color-background));
  border-top: 1px solid var(--color-border);
  text-align: center; padding: var(--space-9) 0;
}
.cta-final p { color: var(--color-dark-3); max-width: 44rem; margin-inline: auto; font-size: var(--text-lg); }
.cta-final a:not(.btn) { color: var(--color-primary-deep); }
.cta-final .hero-actions { justify-content: center; }

/* --- 13. Tableaux et encadrés --------------------------------------------- */

.tableau-wrap {
  overflow-x: auto; border: 1px solid var(--color-border);
  border-radius: var(--radius); background: var(--color-white);
  box-shadow: var(--shadow-xs);
  -webkit-overflow-scrolling: touch;
}
table { width: 100%; border-collapse: collapse; min-width: 520px; }
caption {
  text-align: left; padding: var(--space-4) var(--space-5) var(--space-2);
  font-size: var(--text-sm); color: var(--color-muted);
}
th, td { padding: var(--space-4) var(--space-5); text-align: left; border-bottom: 1px solid var(--color-border); }
thead th {
  background: var(--color-background);
  font-family: var(--font-title); font-size: var(--text-xs);
  text-transform: uppercase; letter-spacing: .07em; color: var(--color-muted);
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--color-primary-tint); }
/* Chiffres tabulaires : toutes les figures ont alors la même largeur, donc
   les prix s'alignent verticalement dans la colonne. Avec des chiffres
   proportionnels, un « 1 » étroit décale la ligne et l'œil ne peut plus
   comparer deux tarifs d'un coup. */
td.prix {
  font-family: var(--font-title); font-weight: 700;
  color: var(--color-primary-sur-clair); white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* #059669 ne donne que 3,77:1 sur le blanc du tableau : un cran plus foncé
   suffit à passer les 4,5:1 sans changer la lecture « c'est bon ». */
.comparatif td.oui { color: #047857; font-weight: 700; }
.comparatif td.non { color: var(--color-muted); }

.encadre {
  border-left: 4px solid var(--color-primary);
  background: var(--color-primary-tint);
  padding: var(--space-5) var(--space-6);
  border-radius: 0 var(--radius) var(--radius) 0;
  margin: var(--space-6) 0;
}
.encadre h2, .encadre h3 { font-size: var(--text-lg); margin-bottom: var(--space-2); }
.encadre.alerte { border-left-color: var(--color-danger); background: var(--color-danger-soft); }
.encadre.ok { border-left-color: var(--color-success); background: var(--color-success-soft); }

/* ---------------------------------------------------------------------------
   Réponse directe, sous le titre de chaque page.

   Ce bloc existe pour être cité hors de son contexte : par un moteur de
   réponse génératif, par un extrait Google, par un assistant vocal (il est
   désigné par « speakable » dans le balisage). Il est donc placé juste après
   le <h1>, avant tout le reste, et reste aligné à gauche même dans un
   en-tête centré — un paragraphe de fait se lit en drapeau, pas en centré.
   --------------------------------------------------------------------------- */
.reponse-ia {
  border-left: 4px solid var(--color-primary);
  background: var(--color-primary-tint);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: var(--space-5) var(--space-6);
  margin: var(--space-5) 0 var(--space-6);
  text-align: left;
  max-width: 68ch;
}
.section-titre .reponse-ia { margin-inline: auto; }
/* La règle « .section-titre p:not(.badge) » est plus spécifique et repeignait
   ce paragraphe en --color-muted : 4,43:1 sur le voile, sous le seuil AA de
   4,5:1. Le sélecteur ci-dessous reprend la main sur la couleur ET sur la
   taille. Un passage destiné à être cité doit d'abord être lisible. */
.reponse-ia p,
.section-titre .reponse-ia p:not(.badge) {
  margin: 0;
  font-size: var(--text-base);
  color: var(--color-text);
}

/* ---------------------------------------------------------------------------
   Avis clients.

   Les témoignages sont des <figure> : le texte est la citation, la légende
   porte l'auteur, la commune et la date. Les étoiles sont purement
   décoratives et masquées aux lecteurs d'écran, qui reçoivent la note en
   toutes lettres via aria-label.
   --------------------------------------------------------------------------- */
.section-avis { padding: var(--space-9) 0; background: var(--color-surface, var(--color-primary-tint)); }
.avis-bloc { margin: var(--space-6) 0; }
.avis-entete { margin-bottom: var(--space-6); }
.avis-entete h2, .avis-entete h3 { margin-bottom: var(--space-2); }
/* --color-muted (#64748B) tient sur blanc pur (4,76:1) mais tombe à 4,43:1
   sur le voile de .section-avis, sous le seuil AA de 4,5. --color-primary
   (#475569) garde l'effet « texte secondaire » en restant confortable sur
   les deux fonds. Même raison pour la mention de provenance. */
.avis-entete p { color: var(--color-primary); margin: 0; }

.avis-carte {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
}
.avis-note { font-size: var(--text-lg); color: #B45309; letter-spacing: 0.08em; line-height: 1; }
.avis-carte blockquote { margin: 0; border: 0; padding: 0; background: none; }
.avis-carte blockquote p {
  margin: 0;
  font-style: normal;
  color: var(--color-text);
}
.avis-carte blockquote p::before { content: "\00AB\00A0"; }
.avis-carte blockquote p::after  { content: "\00A0\00BB"; }
.avis-carte figcaption {
  margin-top: auto;
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
}
.avis-auteur { font-weight: 700; color: var(--color-text); }
.avis-lieu, .avis-date { color: var(--color-muted); }
.avis-provenance {
  margin-top: var(--space-5);
  font-size: var(--text-sm);
  color: var(--color-primary);
  max-width: 78ch;
}

/* ---------------------------------------------------------------------------
   Pagination des listes d'articles.

   Les numéros sont de vrais liens et la page courante n'en est pas un : un
   lecteur au clavier comme un robot doivent pouvoir parcourir la série. Les
   zones cliquables font au moins 44 px pour rester utilisables au doigt.
   --------------------------------------------------------------------------- */
.pagination {
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px solid var(--color-border);
  text-align: center;
}
.pagination-etat {
  margin: 0 0 var(--space-4);
  font-size: var(--text-sm);
  color: var(--color-muted);
}
.pagination-liens {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--space-2);
}
.pagination-liens a,
.pagination-liens .page-courante {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0 var(--space-3);
  border-radius: var(--radius);
  border: 1px solid var(--color-border);
  font-weight: 600;
  text-decoration: none;
}
.pagination-liens a { color: var(--color-text); background: var(--color-white); }
.pagination-liens a:hover,
.pagination-liens a:focus-visible {
  border-color: var(--color-primary);
  background: var(--color-primary-tint);
}
.pagination-liens .page-courante {
  color: var(--color-white);
  background: var(--color-primary);
  border-color: var(--color-primary);
  cursor: default;
}
/* Sur mobile, les libellés complets passent à la ligne et prennent toute la
   largeur : c'est plus lisible que de les tronquer. */
.pagination-liens .page-prec,
.pagination-liens .page-suiv { padding: 0 var(--space-4); }
@media (max-width: 30rem) {
  .pagination-liens .page-prec,
  .pagination-liens .page-suiv { flex-basis: 100%; }
}

/* Emplacement d'avis, tant qu'aucun avis réel n'est publié */
.avis-vide {
  border: 2px dashed var(--color-border-strong);
  border-radius: var(--radius-lg);
  padding: var(--space-7) var(--space-6);
  text-align: center; color: var(--color-muted);
  background: var(--color-white);
}
/* Grille des témoignages. Le minimum est fixé à 260 px pour qu'une sélection
   de quatre avis tienne sur une seule ligne en grand écran : à 300 px elle se
   cassait en trois plus un, ce qui déséquilibrait visiblement la section.
   Les anciennes règles « .avis blockquote » ont été retirées : elles dessinaient
   un cadre autour de la citation ALORS QUE la carte en dessine déjà un, et
   imposaient un italique peu lisible sur des témoignages de cette longueur. */
.avis {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}

/* --- 14. FAQ -------------------------------------------------------------- */

.faq { max-width: 56rem; }
.faq details {
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-white);
  margin-bottom: var(--space-3);
  overflow: hidden;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.faq details[open] { border-color: var(--color-primary-lighter); box-shadow: var(--shadow); }
.faq summary {
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  font-family: var(--font-title); font-weight: 700; font-size: var(--text-lg);
  color: var(--color-dark); cursor: pointer; list-style: none;
  min-height: 44px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--color-primary-deep); }
/* Le « + » d'ouverture est un caractère, comme les autres marqueurs du site :
   plus aucun dessin vectoriel n'est embarqué dans la feuille de style. */
.faq summary::after {
  content: "+"; flex: none; width: 26px; height: 26px;
  display: grid; place-items: center;
  background: var(--color-primary-soft);
  color: var(--color-primary-deep);
  font-family: var(--font-title); font-size: 1.125rem; font-weight: 700; line-height: 1;
  transition: transform var(--transition), background-color var(--transition),
              color var(--transition);
}
.faq details[open] summary::after {
  transform: rotate(45deg);
  background-color: var(--color-primary-deep);
  color: var(--color-white);
}
.faq details > *:not(summary) { padding: 0 var(--space-6) var(--space-5); margin: 0; }
.faq details p { color: var(--color-muted); }
.faq details p + p { padding-top: var(--space-3); }
.faq h2 { margin-bottom: var(--space-5); }
.faq h2:not(:first-child) { margin-top: var(--space-8); }

/* --- 15. Formulaires ------------------------------------------------------ */

.formulaire {
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow);
}
.champs { display: grid; gap: var(--space-5); grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr)); }
.champ { display: flex; flex-direction: column; gap: var(--space-2); margin: 0; }
.champ-large { grid-column: 1 / -1; }
.champ label { font-family: var(--font-title); font-weight: 700; font-size: var(--text-sm); color: var(--color-dark); }
.champ .aide { font-size: var(--text-xs); color: var(--color-muted); font-weight: 400; line-height: 1.55; }
/* L'astérisque de champ obligatoire est une information, pas une décoration :
   l'orange vif ne donne que 2,80 de contraste sur blanc, l'orange foncé 4,89. */
.champ .requis { color: var(--color-secondary-dark); }

.champ input, .champ select, .champ textarea {
  font-family: var(--font-body); font-size: var(--text-base);
  color: var(--color-text); background: var(--color-white);
  border: 1.5px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  padding: 0.8125rem 1rem; width: 100%; min-height: 50px;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.champ input::placeholder, .champ textarea::placeholder { color: var(--color-muted-light); }
.champ textarea { min-height: 150px; resize: vertical; line-height: 1.65; }
.champ input:focus, .champ select:focus, .champ textarea:focus {
  outline: none; border-color: var(--color-primary);
  box-shadow: 0 0 0 4px rgba(30,41,59,.13);
}
.champ input[aria-invalid="true"], .champ select[aria-invalid="true"], .champ textarea[aria-invalid="true"] {
  border-color: var(--color-danger); background: var(--color-danger-soft);
}
.champ input[type="file"] { padding: 0.625rem; background: var(--color-background); cursor: pointer; }

/* Cases et boutons radio : le contrôle natif fait 13 px, très en dessous des
   24 px demandés par WCAG 2.5.8. On agrandit le contrôle lui-même et on rend
   toute la ligne d'intitulé cliquable, ce qui aide autant à la souris qu'au
   doigt — un doigt vise mal une cible de la taille d'une tête d'épingle. */
input[type="radio"], input[type="checkbox"] {
  width: 24px; height: 24px; flex: none; margin: 0;
  accent-color: var(--color-primary-deep);
  cursor: pointer;
}
.champ-radio label,
label:has(> input[type="radio"]),
label:has(> input[type="checkbox"]) {
  display: flex; align-items: center; gap: var(--space-3);
  min-height: 44px; cursor: pointer;
}
/* La case de consentement est hors du label : c'est le libellé associé par
   « for » qui l'active. La case reste alignée en haut du paragraphe, qui fait
   plusieurs lignes. */
.champ-case { display: flex; align-items: flex-start; gap: var(--space-3); }
.champ-case input[type="checkbox"] { margin-top: 2px; }
.champ-case label { cursor: pointer; }
.champ .erreur { font-size: var(--text-sm); color: var(--color-danger); font-weight: 700; }

.champ-radio { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.champ-radio label { color: var(--color-text);
  display: flex; align-items: center; gap: var(--space-2);
  border: 1.5px solid var(--color-border-strong); border-radius: var(--radius-full);
  padding: 0.625rem 1.125rem; cursor: pointer;
  font-family: var(--font-body); font-weight: 500; font-size: var(--text-sm);
  min-height: 46px; transition: all var(--transition);
}
.champ-radio label:hover { border-color: var(--color-primary-lighter); background: var(--color-primary-tint); }
/* « width: auto » remettait le contrôle natif à 13 px de large et annulait
   la règle ci-dessus : la case redevenait deux fois trop petite. */
.champ-radio input { width: 24px; height: 24px; min-height: 0; margin: 0; accent-color: var(--color-primary-deep); }
.champ-radio label:has(input:checked) {
  border-color: var(--color-primary); background: var(--color-primary-soft);
  color: var(--color-primary-sur-clair); font-weight: 700;
}

.champ-case { flex-direction: row; align-items: flex-start; gap: var(--space-3); }
.champ-case input { width: 24px; height: 24px; min-height: 0; margin-top: 4px; accent-color: var(--color-primary-deep); flex: none; }
.champ-case label { font-family: var(--font-body); font-weight: 400; font-size: var(--text-sm); color: var(--color-muted); line-height: 1.6; }

/* Piège à robots : hors écran, ni display:none ni hidden, que des automates
   savent détecter. */
.pot-de-miel { position: absolute !important; left: -9999px !important; width: 1px; height: 1px; overflow: hidden; }

.formulaire-actions { margin-top: var(--space-6); display: flex; gap: var(--space-4); align-items: center; flex-wrap: wrap; }
.formulaire-note { font-size: var(--text-sm); color: var(--color-muted); margin: var(--space-5) 0 0; padding-top: var(--space-4); border-top: 1px solid var(--color-border); }

.message-etat {
  border-radius: var(--radius); padding: var(--space-5) var(--space-6);
  margin-bottom: var(--space-6); border-left: 4px solid;
}
.message-etat.ok { border-color: var(--color-success); background: var(--color-success-soft); }
.message-etat.echec { border-color: var(--color-danger); background: var(--color-danger-soft); }
.message-etat ul { margin: var(--space-3) 0 0; }

/* --- 16. Article et fil d'Ariane ------------------------------------------ */

.fil { font-size: var(--text-sm); color: var(--color-muted); padding: var(--space-4) 0 0; }
.fil ol { list-style: none; display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0; padding: 0; }
.fil li { margin: 0; }
.fil li:not(:last-child)::after { content: "›"; margin-left: var(--space-2); color: var(--color-border-strong); }
/* Le fil d'Ariane est une navigation autonome, pas un lien dans une phrase :
   l'exception « inline » de WCAG 2.5.8 ne s'y applique pas et ses liens
   doivent atteindre 24 px de haut. Le rembourrage vertical est compensé par
   une marge négative pour ne pas décaler la mise en page. */
.fil a {
  color: var(--color-muted); text-decoration: none;
  display: inline-block; padding: var(--space-2) 0; min-height: 24px;
}
.fil ol { margin-block: calc(var(--space-2) * -1); }
.fil a:hover { color: var(--color-primary-deep); text-decoration: underline; }

.article { max-width: 46rem; margin-inline: auto; font-size: var(--text-lg); }
.article h2 { margin-top: var(--space-8); }
.article h3 { margin-top: var(--space-6); }
.article ul, .article ol { margin-bottom: var(--space-5); }
.article img { border-radius: var(--radius); margin: var(--space-6) 0; }
.article-meta { color: var(--color-muted); font-size: var(--text-sm); margin-bottom: var(--space-6); }

.sommaire {
  background: var(--color-background); border: 1px solid var(--color-border);
  border-radius: var(--radius); padding: var(--space-5) var(--space-6);
  margin-bottom: var(--space-7);
}
.sommaire h2 {
  font-size: var(--text-xs); text-transform: uppercase; letter-spacing: .08em;
  color: var(--color-muted); margin: 0 0 var(--space-3);
}
.sommaire ol { margin: 0; padding-left: 1.2em; }
/* Le sommaire est une navigation : ses entrées doivent atteindre 24 px de
   haut, l'exception « inline » de WCAG 2.5.8 ne s'applique pas à une liste
   de liens autonomes. */
.sommaire a {
  color: var(--color-primary-deep); text-decoration: none;
  display: inline-block; padding: var(--space-1) 0; min-height: 24px;
}
.sommaire a:hover { text-decoration: underline; }

.liens-connexes { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: var(--space-2); }
.liens-connexes li { margin: 0; }
.liens-connexes a {
  display: inline-block; text-decoration: none;
  border: 1px solid var(--color-border-strong); border-radius: var(--radius-full);
  padding: 0.5rem 1.125rem; font-size: var(--text-sm); font-weight: 500;
  background: var(--color-white); color: var(--color-dark);
  min-height: 24px; transition: all var(--transition);
}
.liens-connexes a:hover {
  border-color: var(--color-primary); background: var(--color-primary-soft);
  color: var(--color-primary-deep);
}

/* Guides locaux des pages de zone : une liste de titres avec leur résumé, et
   non des pastilles. Les pastilles conviennent à un mot, pas à une phrase. */
.liens-guides { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
.liens-guides a {
  display: block; padding: var(--space-3); border-radius: 0;
  border: 1px solid var(--color-border); background: var(--color-white);
  font-weight: 400; font-size: var(--text-base); height: 100%;
}
.liens-guides a strong {
  display: block; color: var(--color-primary-deep);
  font-size: var(--text-base); font-weight: 700; margin-bottom: 0.35rem;
}
.liens-guides a span {
  display: block; color: var(--color-primary); font-size: var(--text-sm);
  line-height: 1.55;
}
.liens-guides a:hover { border-color: var(--color-primary-dark); background: var(--color-primary-tint); }
.liens-guides a:hover strong,
.liens-guides a:hover span { color: var(--color-primary-deep); }
@media (max-width: 720px) {
  .liens-guides { grid-template-columns: 1fr; }
}
.lien-tous-guides {
  display: inline-block; min-height: 24px;
  padding: 0.5rem 0; font-weight: 500;
}

:target { scroll-margin-top: 6rem; }

/* --- 17. Pied de page ----------------------------------------------------- */

/* Le pied de page est posé sur un aplat gris : --color-muted n'y donne que
   4,34:1, il n'est lisible que sur blanc pur. Toutes les mentions discrètes
   du pied passent donc en --color-dark-3. */
.site-footer {
  background: var(--color-background-2);
  border-top: 1px solid var(--color-border);
  color: var(--color-dark-3); padding: var(--space-9) 0 var(--space-5);
}
.site-footer .footer-horaires,
.site-footer .footer-legal,
.site-footer .copyright { color: var(--color-dark-3); }
.footer-grid { display: grid; gap: var(--space-7); grid-template-columns: 1.6fr 1fr 1fr 1fr 1fr; }
@media (max-width: 1080px) { .footer-grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr)); } }

.footer-col h2 {
  font-family: var(--font-title); font-size: var(--text-xs);
  text-transform: uppercase; letter-spacing: .09em;
  color: var(--color-dark); margin-bottom: var(--space-4);
}
.footer-col ul { list-style: none; margin: 0; padding: 0; }
.footer-col li { margin-bottom: var(--space-1); }
/* « :not(.btn) » est indispensable : sans lui, cette règle est plus
   spécifique que .btn et écrase display, padding et taille de police du
   bouton d'appel du pied de page, dont le libellé chevauche alors l'icône. */
.footer-col a:not(.btn) {
  color: var(--color-dark-3); text-decoration: none; font-size: var(--text-sm);
  display: inline-block; padding: var(--space-1) 0; min-height: 24px;
  transition: color var(--transition);
}
.footer-col a:not(.btn):hover { color: var(--color-primary-deep); }
.footer-h2-suite { margin-top: var(--space-6); }

.footer-brand strong {
  color: var(--color-dark); display: block; margin-bottom: var(--space-3);
  font-family: var(--font-title); font-size: var(--text-xl);
}
.footer-brand p { font-size: var(--text-sm); line-height: 1.7; }
.footer-brand .btn { margin-top: var(--space-4); }
.footer-horaires { font-size: var(--text-xs); margin-top: var(--space-4); }

.footer-legal {
  border-top: 1px solid var(--color-border-strong);
  margin-top: var(--space-8); padding-top: var(--space-5);
  font-size: var(--text-xs);
}
.footer-legal p { margin-bottom: var(--space-2); }
.copyright { opacity: 1; }

/* --- 18. Barre mobile et bandeau cookies ---------------------------------- */

.barre-mobile { display: none; }

@media (max-width: 860px) {
  .barre-mobile {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 200;
    display: grid; grid-template-columns: 1.9fr 1fr;
    gap: 1px; background: var(--color-border-strong);
    box-shadow: 0 -6px 24px rgba(20,35,31,.18);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .barre-mobile a {
    display: flex; align-items: center; justify-content: center; gap: var(--space-2);
    min-height: 60px; padding: var(--space-3);
    font-family: var(--font-title); font-weight: 700; font-size: var(--text-base);
    text-decoration: none; line-height: 1.2;
  }
  .barre-mobile-appel { background: var(--color-secondary); color: #1A1200; }
  .barre-mobile-devis { background: var(--color-primary-deep); color: #fff; }
  body { padding-bottom: calc(60px + env(safe-area-inset-bottom)); }
}

.cookie-bandeau {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 300;
  background: var(--color-white); color: var(--color-dark-3);
  padding: var(--space-5); box-shadow: 0 -8px 32px rgba(20,35,31,.16);
  border-top: 1px solid var(--color-border-strong);
}
.cookie-inner {
  display: flex; align-items: center; gap: var(--space-5);
  flex-wrap: wrap; justify-content: center;
  width: min(100% - var(--space-6), var(--container)); margin-inline: auto;
}
.cookie-inner p { margin: 0; font-size: var(--text-sm); max-width: 46rem; }
.cookie-inner a { color: var(--color-primary-deep); }
.cookie-actions { display: flex; gap: var(--space-3); }
.cookie-actions .btn { padding: 0.625rem 1.25rem; min-height: 44px; font-size: var(--text-sm); }
.cookie-actions .btn-ghost { background: var(--color-white); border-color: var(--color-border-strong); color: var(--color-dark); }
@media (max-width: 860px) { .cookie-bandeau { bottom: calc(60px + env(safe-area-inset-bottom)); } }

/* --- 19. Animations ------------------------------------------------------- */

/* Apparition au défilement. La classe est posée par le JavaScript ; sans
   JavaScript, les éléments restent simplement visibles. */
.apparait { opacity: 0; transform: translateY(18px); }
.apparait.visible {
  opacity: 1; transform: none;
  transition: opacity 560ms ease, transform 560ms cubic-bezier(.22,1,.36,1);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .apparait { opacity: 1; transform: none; }
  .btn:hover, .carte-service:hover, .galerie figure:hover { transform: none; }
}

/* --- 20. Impression ------------------------------------------------------- */

@media print {
  .site-header, .barre-mobile, .cookie-bandeau, .nav, .skip-link,
  .bandeau-urgence, .cta-final { display: none !important; }
  body { padding-bottom: 0; font-size: 11pt; background: #fff; }
  .hero { background: none !important; color: #000 !important; padding: 0; }
  .hero h1, .hero p { color: #000 !important; }
  a[href^="/"]::after { content: " (serrurier-richard.fr" attr(href) ")"; font-size: .8em; color: #555; }
  .carte, .encadre, .faq details { break-inside: avoid; }
}

/* --- Visionneuse de galerie ----------------------------------------------
   Créée par le JavaScript au clic sur une image. Sans JavaScript, la galerie
   reste une grille d'images parfaitement consultable.
   ------------------------------------------------------------------------ */

.visionneuse {
  position: fixed; inset: 0; z-index: 400;
  background: rgba(15,23,42,.92);
  backdrop-filter: blur(6px);
  display: grid; place-items: center;
  padding: var(--space-6);
  animation: voile-entre 200ms ease;
}
@keyframes voile-entre { from { opacity: 0; } to { opacity: 1; } }
.visionneuse img {
  max-width: min(100%, 1100px); max-height: 86vh;
  border-radius: var(--radius); box-shadow: var(--shadow-xl);
}
.visionneuse-fermer {
  position: absolute; top: var(--space-5); right: var(--space-5);
  width: 48px; height: 48px;
  background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.25);
  color: #fff; font-size: 1.75rem; line-height: 1; cursor: pointer;
}
.visionneuse-fermer:hover { background: rgba(255,255,255,.22); }
.galerie figure:focus-visible { outline: 3px solid var(--color-primary-light); outline-offset: 3px; }

/* ==========================================================================
   18. CARTE DES ZONES D'INTERVENTION
   --------------------------------------------------------------------------
   Le tracé est un SVG servi par le site : pas de requête vers un service
   extérieur, pas d'adresse IP transmise à un tiers, pas de consentement à
   demander, et un affichage instantané. La carte à tuiles n'apparaît que si
   le visiteur clique sur « Afficher la carte détaillée ».
   ========================================================================== */

.carte-zones {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: var(--space-6);
  align-items: start;
  margin-bottom: var(--space-7);
}

.carte-figure {
  margin: 0;
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-4) var(--space-4) var(--space-3);
  overflow: hidden;
}
.carte-figure figcaption {
  font-size: var(--text-sm);
  color: var(--color-muted);
  padding: var(--space-3) var(--space-2) var(--space-1);
  border-top: 1px solid var(--color-border);
  margin-top: var(--space-3);
}

.carte-svg { display: block; width: 100%; height: auto; }

/* Les départements sont des liens : ils réagissent au survol comme au clavier,
   et restent parfaitement lisibles sans JavaScript. */
/* Six teintes d'une même famille : deux départements voisins ne peuvent pas
   se confondre, et l'ensemble reste une seule couleur, pas un arc-en-ciel.
   Le numéro de teinte est posé par scripts/generer-carte.py ; la CSS ne
   connaît donc aucun département en particulier. */
.carte-svg .zone[data-teinte="1"] path { fill: #B6BFCC; }
.carte-svg .zone[data-teinte="2"] path { fill: #E4E9EF; }
.carte-svg .zone[data-teinte="3"] path { fill: #A0ABBB; }
.carte-svg .zone[data-teinte="4"] path { fill: #D2D9E2; }
.carte-svg .zone[data-teinte="5"] path { fill: #8B98AA; }
.carte-svg .zone[data-teinte="6"] path { fill: #F1F3F6; }

.carte-svg .zone path {
  stroke: var(--color-white);
  stroke-width: 1.6;
  stroke-linejoin: round;
  transition: fill 180ms ease;
  cursor: pointer;
}
.carte-svg .zone:hover path,
.carte-svg .zone:focus path,
.carte-svg .zone.active path {
  fill: var(--color-primary-light);
}
.carte-svg .zone:focus { outline: none; }
.carte-svg .zone:focus-visible path {
  stroke: var(--color-dark);
  stroke-width: 2.6;
}

.carte-svg .ville { fill: var(--color-dark-3); }
.carte-svg .ville-forte {
  fill: var(--color-secondary);
  stroke: var(--color-white);
  stroke-width: 2;
}
.carte-svg .etiquette {
  font-family: var(--font-title);
  font-size: 15px;
  font-weight: 600;
  fill: var(--color-dark);
  paint-order: stroke;
  stroke: rgba(255, 255, 255, .85);
  stroke-width: 3.5px;
  stroke-linejoin: round;
}

/* --- Panneau latéral : liste des départements ---------------------------- */

.carte-liste { list-style: none; margin: 0 0 var(--space-4); padding: 0; }
.carte-liste li { margin: 0 0 var(--space-2); }
.carte-liste a {
  display: block;
  padding: var(--space-3) var(--space-4);
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-primary-soft);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: border-color var(--transition), transform var(--transition),
              box-shadow var(--transition);
}
.carte-liste a:hover,
.carte-liste a:focus-visible {
  border-left-color: var(--color-secondary);
  transform: translateX(3px);
  box-shadow: var(--shadow-sm);
}
.carte-liste strong {
  display: block;
  font-family: var(--font-title);
  color: var(--color-dark);
  font-size: var(--text-base);
}
.carte-liste strong span { color: var(--color-primary-deep); font-weight: 600; }
.carte-villes {
  display: block;
  font-size: var(--text-xs);
  color: var(--color-muted);
  line-height: 1.45;
  margin-top: 2px;
}

/* --- Carte détaillée, chargée à la demande ------------------------------- */

.carte-detail {
  background: var(--color-primary-tint);
  border: 1px solid var(--color-primary-soft);
  border-radius: var(--radius);
  padding: var(--space-4);
}
.carte-detail-texte {
  font-size: var(--text-xs);
  color: var(--color-dark-3);
  margin-bottom: var(--space-3);
}
.carte-detail .btn { width: 100%; justify-content: center; }

/* Conteneur Leaflet. La hauteur est fixée avant le chargement : la page ne
   saute pas au moment où la carte apparaît. */
.carte-tuiles {
  height: 380px;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--color-border);
  background: var(--color-background-2);
}
.carte-tuiles-etat {
  display: grid;
  place-items: center;
  height: 100%;
  font-size: var(--text-sm);
  color: var(--color-muted);
  padding: var(--space-4);
  text-align: center;
}

@media (max-width: 900px) {
  .carte-zones { grid-template-columns: 1fr; }
  .carte-svg .etiquette { font-size: 19px; }
  .carte-tuiles { height: 320px; }
}

/* ==========================================================================
   19. GALERIE FILTRABLE
   ========================================================================== */

.galerie-filtres {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
}
.filtre {
  font: 600 var(--text-sm)/1 var(--font-title);
  /* 44 px de haut : la cible reste confortable au doigt (WCAG 2.5.8). */
  min-height: 44px;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border-strong);
  background: var(--color-white);
  color: var(--color-dark-3);
  cursor: pointer;
  transition: background var(--transition), color var(--transition),
              border-color var(--transition);
}
.filtre:hover { border-color: var(--color-primary); color: var(--color-primary-sur-clair); }
.filtre.actif {
  background: var(--color-primary-deep);
  border-color: var(--color-primary-deep);
  color: var(--color-white);
}
.galerie figure[hidden] { display: none; }
.galerie-vide {
  text-align: center;
  color: var(--color-muted);
  padding: var(--space-6);
}

/* La photographie se rapproche légèrement au survol : le mouvement se produit
   à l'intérieur du cadre, la mise en page n'est donc jamais déplacée. */
.galerie figure img { transition: transform 420ms ease; }
.galerie figure:hover img { transform: scale(1.04); }

/* Chaque vignette dit ce qu'elle est. L'attribut est posé par le build selon
   le fichier réellement trouvé sur le disque : une illustration ne peut donc
   pas être présentée comme un chantier réel, même par inadvertance. */
.galerie figure { position: relative; }
.galerie figure img[data-visuel="illustration"] + figcaption::before,
.galerie figure > img[data-visuel="illustration"] ~ figcaption::before {
  content: "Illustration";
  display: inline-block;
  margin-bottom: var(--space-2);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--color-background-2);
  color: var(--color-muted);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: .02em;
}

/* ==========================================================================
   20. FRISE DU DÉROULÉ D'INTERVENTION
   --------------------------------------------------------------------------
   Reprend la liste numérotée existante et la relie par un fil continu. Sur
   mobile la frise bascule à la verticale, ce qui reste lisible au pouce.
   ========================================================================== */

/* Le fil de liaison déborde volontairement dans la gouttière de la grille,
   pour relier deux colonnes voisines. « overflow: hidden » l'arrête au bord
   de la liste : sans lui, le dernier fil de chaque rangée pousserait la page
   de 8 px vers la droite lorsque la grille passe sur deux rangées. */
.etapes.frise { position: relative; counter-reset: etape; overflow: hidden; }
.etapes.frise li { padding-top: calc(var(--space-8) + var(--space-3)); }

/* Le fil relie les pastilles ; il s'arrête à la dernière. */
.etapes.frise li::after {
  content: "";
  position: absolute;
  top: 22px;
  left: 3.2rem;
  right: calc(var(--space-5) * -1);
  height: 2px;
  background: linear-gradient(90deg, var(--color-primary-soft), transparent);
}
.etapes.frise li:last-child::after { display: none; }

.etapes.frise li::before {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  font-size: var(--text-lg);
}
section.sombre .etapes.frise li::after {
  background: linear-gradient(90deg, #CBD5E1, transparent);
}

@media (max-width: 760px) {
  .etapes.frise li::after {
    top: 44px;
    bottom: calc(var(--space-5) * -1);
    left: 21px;
    right: auto;
    width: 2px;
    height: auto;
    background: linear-gradient(180deg, var(--color-primary-soft), transparent);
  }
  .etapes.frise li { padding-left: calc(44px + var(--space-4)); padding-top: 0; min-height: 44px; }
  .etapes.frise li::before { top: 0; }
  section.sombre .etapes.frise li::after {
    background: linear-gradient(180deg, #CBD5E1, transparent);
  }
}

/* ==========================================================================
   21. AVIS — RENVOI VERS LA FICHE RÉELLE
   --------------------------------------------------------------------------
   Aucune note, aucune étoile, aucun témoignage n'est mis en forme ici : il
   n'y en a pas dans le HTML. Ce bloc n'est qu'un renvoi vers la source.
   ========================================================================== */

.avis-fiche {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: var(--space-5);
  align-items: stretch;
}
.avis-fiche-texte,
.avis-appel {
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
}
.avis-appel {
  background: var(--color-primary-tint);
  border-color: var(--color-primary-soft);
}
.avis-fiche h3 { font-size: var(--text-xl); margin-bottom: var(--space-3); }
.avis-actions { margin: var(--space-5) 0 0; }

@media (max-width: 760px) {
  .avis-fiche { grid-template-columns: 1fr; }
}

/* ==========================================================================
   22. BANDEAU D'URGENCE — COLONNE MÉDIA
   ========================================================================== */

.urgence-media { display: grid; gap: var(--space-4); }
.urgence-photo {
  margin: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 2px solid rgba(255, 255, 255, .28);
  box-shadow: var(--shadow-lg);
}
.urgence-photo img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

@media (max-width: 900px) {
  /* Sur mobile le bouton d'appel doit rester au-dessus de la ligne de
     flottaison : la photo passe donc après lui. */
  .urgence-photo { order: 2; }
  .urgence-media .btn { order: 1; }
}

/* ==========================================================================
   23. MICRO-INTERACTIONS
   --------------------------------------------------------------------------
   Toutes sont désactivées par la requête « prefers-reduced-motion » traitée
   plus bas : elles ajoutent du confort, elles ne portent aucune information.
   ========================================================================== */

/* Décalage d'apparition entre voisins d'une même grille. Le retard est posé
   en CSS et non en JavaScript : il ne coûte aucune tâche au fil principal. */
.apparait { transition-delay: 0ms; }
.grille > .apparait:nth-child(3n + 2),
.galerie > .apparait:nth-child(3n + 2) { transition-delay: 70ms; }
.grille > .apparait:nth-child(3n + 3),
.galerie > .apparait:nth-child(3n + 3) { transition-delay: 140ms; }

@media (prefers-reduced-motion: reduce) {
  .apparait { transition-delay: 0ms !important; }
  .galerie figure:hover img { transform: none; }
  .carte-liste a:hover, .carte-liste a:focus-visible { transform: none; }
  .carte-svg .zone path { transition: none; }
}

/* ==========================================================================
   24. COMPOSANTS DE LANDING PAGE LOCALE
   --------------------------------------------------------------------------
   Ces blocs servent aux pages de zone, qui ne sont pas des pages SEO mais des
   pages commerciales : un visiteur qui arrive de Google doit y trouver son
   problème, la solution, le déroulé, les preuves et le moyen d'appeler, sans
   avoir à naviguer ailleurs.
   ========================================================================== */

/* --- Héros local ---------------------------------------------------------- */

.hero-local {
  position: relative;
  background:
    radial-gradient(1000px 480px at 80% 8%, var(--color-primary-soft), transparent 62%),
    linear-gradient(168deg, var(--color-primary-tint), var(--color-white) 62%, var(--color-background));
  border-bottom: 1px solid var(--color-border);
  padding: var(--space-8) 0 var(--space-9);
  overflow: hidden;
}
/* La photo a quitté ce héros : elle vivait déjà sur sa page de service, et la
   répéter ici était précisément le défaut à corriger. Sa colonne accueille
   maintenant la liste des communes — une information que le visiteur cherche
   vraiment, et qui répond à la seule question qu'il se pose en arrivant :
   « est-ce qu'ils viennent chez moi ? ». */
.hero-local-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: var(--space-8);
  align-items: start;
}
.hero-local-communes {
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
}
.communes-titre {
  margin: 0 0 var(--space-4);
  font-family: var(--font-title);
  font-size: var(--text-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .08em;
  color: var(--color-dark-3);
}
@media (max-width: 900px) {
  .hero-local-grid { grid-template-columns: 1fr; gap: var(--space-6); }
}
.hero-local h1 { margin-bottom: var(--space-4); }
.hero-local .chapeau {
  font-size: var(--text-lg);
  color: var(--color-dark-3);
  line-height: 1.65;
  max-width: 46ch;
}
/* Héros des pages locales : 3/2, le format des fichiers maîtres. */
.hero-local-media img {
  display: block; width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover; object-position: center;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  box-shadow: 0 24px 52px rgba(15, 23, 42, .16);
}

/* Liste de communes en pastilles : elle répond en un coup d'œil à la seule
   question que se pose le visiteur — « est-ce qu'ils viennent chez moi ? » */
.communes {
  display: flex; flex-wrap: wrap; gap: var(--space-2);
  list-style: none; margin: var(--space-5) 0 0; padding: 0;
}
.communes li {
  margin: 0;
  padding: 0.375rem 0.875rem;
  border-radius: var(--radius-full);
  background: var(--color-white);
  border: 1px solid var(--color-border-strong);
  font-size: var(--text-sm);
  color: var(--color-dark-3);
}
.communes li.principale {
  background: var(--color-primary-soft);
  border-color: var(--color-primary-light);
  color: var(--color-primary-deep);
  font-weight: 600;
}

/* --- Bloc « quel est votre problème ? » ----------------------------------- */

.problemes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
  gap: var(--space-3);
  list-style: none; margin: 0 0 var(--space-6); padding: 0;
}
.problemes li { margin: 0; }
.problemes a {
  display: block; position: relative;
  height: 100%;
  padding: var(--space-4) var(--space-6) var(--space-4) var(--space-5);
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-primary-light);
  border-radius: var(--radius);
  text-decoration: none;
  transition: border-color var(--transition), box-shadow var(--transition),
              transform var(--transition);
}
/* La flèche est un caractère, pas un dessin : elle indique une direction,
   elle ne prétend rien illustrer. */
.problemes a::after {
  content: "→"; position: absolute; right: var(--space-4); top: var(--space-4);
  color: var(--color-primary-deep); font-size: 1.1em;
  transition: transform var(--transition);
}
.problemes a:hover::after { transform: translateX(3px); }
.problemes a:hover, .problemes a:focus-visible {
  border-left-color: var(--color-secondary);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}
.problemes strong {
  display: block;
  font-family: var(--font-title);
  color: var(--color-dark);
  font-size: var(--text-base);
  margin-bottom: 2px;
}
.problemes span { font-size: var(--text-sm); color: var(--color-muted); }

/* --- Intervention détaillée : problème, diagnostic, méthode, résultat ------ */

.interventions { display: grid; gap: var(--space-6); }
.intervention {
  display: block;
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
/* Une intervention sur deux inverse ses colonnes : la page respire au lieu
   d'aligner six blocs strictement identiques. */
.intervention:nth-child(even) .intervention-media { order: 2; }
.intervention-media { margin: 0; align-self: stretch; }
/* Bloc d'intervention : 4/3. Le fichier est en 3/2, « cover » retire donc
   environ 11 % de largeur — à parts égales à droite et à gauche, sur des
   photos où le sujet est central. */
.intervention-media img {
  display: block; width: 100%; height: 100%;
  min-height: 280px;
  object-fit: cover; object-position: center;
}
.intervention-corps { padding: var(--space-6); }
.intervention-corps h3 { font-size: var(--text-xl); margin-bottom: var(--space-4); }
.intervention dl { margin: 0; }
.intervention dt {
  font-family: var(--font-title);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--color-primary-deep);
  margin-top: var(--space-4);
}
.intervention dt:first-of-type { margin-top: 0; }
.intervention dd {
  margin: var(--space-1) 0 0;
  font-size: var(--text-sm);
  color: var(--color-dark-3);
  line-height: 1.6;
}

@media (max-width: 860px) {
  .intervention { grid-template-columns: 1fr; }
  .intervention:nth-child(even) .intervention-media { order: 0; }
  .intervention-media img { min-height: 0; height: auto; aspect-ratio: 4 / 3; }
}

/* --- Avant / après -------------------------------------------------------- */

.avant-apres {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: var(--space-4);
}
.avant-apres figure {
  margin: 0; border-radius: var(--radius);
  overflow: hidden; border: 1px solid var(--color-border);
  background: var(--color-white);
}
.avant-apres img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.avant-apres figcaption {
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm); color: var(--color-muted);
}
.avant-apres figcaption strong {
  display: block; font-family: var(--font-title); color: var(--color-dark);
}

/* --- Réponses courtes, lisibles par un moteur comme par un humain --------- */

.geo-reponses {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: var(--space-4);
}
.geo-reponse {
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-primary);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: var(--space-5);
}
.geo-reponse h3 {
  font-size: var(--text-base);
  color: var(--color-primary-deep);
  margin-bottom: var(--space-2);
}
.geo-reponse p { font-size: var(--text-sm); color: var(--color-dark-3); margin: 0; }
.geo-reponse p + p { margin-top: var(--space-2); }

/* --- Bande d'appel à l'action intermédiaire ------------------------------- */

.cta-bande {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: var(--space-5);
  background: linear-gradient(135deg, var(--color-primary-tint), var(--color-primary-soft));
  border: 1px solid var(--color-primary-light);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  margin: var(--space-7) 0;
}
.cta-bande-texte { flex: 1 1 22rem; }
.cta-bande h2, .cta-bande h3 {
  font-size: var(--text-xl); margin-bottom: var(--space-2);
}
.cta-bande p { margin: 0; color: var(--color-dark-3); font-size: var(--text-sm); }
.cta-bande-actions { display: flex; gap: var(--space-3); flex-wrap: wrap; }

@media (max-width: 560px) {
  .cta-bande-actions { width: 100%; }
  .cta-bande-actions .btn { flex: 1 1 100%; }
}

/* --- Grille de villes ----------------------------------------------------- */

.villes-grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
  gap: var(--space-3);
  list-style: none; margin: 0; padding: 0;
}
.villes-grille li { margin: 0; }
.villes-grille a, .villes-grille span {
  display: block;
  padding: var(--space-3) var(--space-4);
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  color: var(--color-dark-3);
  text-decoration: none;
}
.villes-grille a { border-left: 3px solid var(--color-primary-light); }
.villes-grille a:hover, .villes-grille a:focus-visible {
  border-left-color: var(--color-secondary);
  color: var(--color-primary-deep);
}
.villes-grille strong { display: block; font-family: var(--font-title); color: var(--color-dark); }

/* --- Facteurs de prix ----------------------------------------------------- */

.facteurs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  gap: var(--space-4);
  list-style: none; margin: var(--space-5) 0 0; padding: 0;
}
.facteurs li {
  margin: 0; padding: var(--space-4);
  background: var(--color-background);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm); color: var(--color-dark-3);
}
.facteurs strong { display: block; font-family: var(--font-title); color: var(--color-dark); margin-bottom: 2px; }

@media (max-width: 900px) {
  .hero-local-grid { grid-template-columns: 1fr; }
  .hero-local .chapeau { max-width: none; }
}

/* ==========================================================================
   25. GRILLE COMPLÈTE DES PRESTATIONS
   --------------------------------------------------------------------------
   Toutes les prestations du métier y figurent, regroupées par famille, et
   chacune renvoie à la page qui la traite réellement. Plusieurs entrées
   peuvent viser la même page : « porte claquée » et « porte verrouillée »
   relèvent l'une et l'autre de l'ouverture de porte. C'est délibéré — mieux
   vaut deux entrées honnêtes vers une page solide que deux pages creuses
   créées pour occuper une requête.
   ========================================================================== */

.prestations-groupes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: var(--space-6);
}
.prestation-groupe h3 {
  font-size: var(--text-base);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--color-primary-deep);
  padding-bottom: var(--space-3);
  border-bottom: 2px solid var(--color-primary-soft);
  margin-bottom: var(--space-4);
}
.prestation-groupe ul { list-style: none; margin: 0; padding: 0; }
.prestation-groupe li { margin: 0 0 var(--space-1); }
.prestation-groupe a {
  display: block;
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background-color var(--transition);
}
.prestation-groupe a:hover, .prestation-groupe a:focus-visible {
  background: var(--color-primary-tint);
}
.prestation-groupe strong {
  display: block;
  font-family: var(--font-title);
  color: var(--color-dark);
  font-size: var(--text-base);
}
.prestation-groupe a > :not(strong),
.prestation-groupe a { color: var(--color-muted); font-size: var(--text-sm); line-height: 1.5; }

/* Bloc de prestations associées en pied de page service. Titre discret : ce
   n'est pas une section éditoriale, c'est un relais de navigation. */
.services-associes h2 { font-size: var(--text-xl); }
.services-associes p { color: var(--color-muted); margin-bottom: var(--space-4); }
.services-associes { padding-block: var(--space-8); }

/* ==========================================================================
   25 bis. RESPIRATION AUTOUR DES IMAGES
   --------------------------------------------------------------------------
   Une hiérarchie constante, quel que soit le composant :

       titre  →  24 px  →  description  →  32 px  →  image
                        →  12 px  →  légende  →  24 px  →  action

   C'est la régularité d'un bloc à l'autre, plus que les valeurs elles-mêmes,
   qui donne l'impression d'une page composée.
   ========================================================================== */

.section-titre + .media-large,
.section-titre + .galerie,
.section-titre + .galerie-filtres,
.section-titre + .interventions,
.section-titre + .grille { margin-top: var(--space-7); }

.media-legende,
.galerie figcaption { margin-top: var(--space-3); }

.media-large + p,
.media-large + .btn,
.galerie + p { margin-top: var(--space-5); }

/* Une image ne touche jamais le texte qui la suit. */
figure + p, figure + h2, figure + h3 { margin-top: var(--space-5); }

/* ==========================================================================
   26. SCHÉMAS EXPLICATIFS
   --------------------------------------------------------------------------
   Une planche pédagogique porte son sens dans sa mise en page : la recadrer
   au format d'une carte couperait ses légendes. Elle garde donc ses
   proportions natives et occupe la largeur d'une colonne de lecture.
   ========================================================================== */

.schema {
  margin: var(--space-7) auto;
  max-width: 46rem;
}
.schema img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-md);
}
.schema figcaption {
  margin-top: var(--space-3);
  padding-left: var(--space-4);
  border-left: 3px solid var(--color-primary-light);
  font-size: var(--text-sm);
  color: var(--color-muted);
  line-height: 1.6;
}
.schema figcaption strong { color: var(--color-dark-3); }
