/* assets/01-fondations/dist/spacing.css */
:root {
  --space-xs: 8px;
  --space-sm: 16px;
  --space-md: 24px;
  --space-lg: 40px;
  --space-xl: 64px;

  --radius-sm: 4px;
  --radius-md: 10px;
  --radius-lg: 20px;
  --radius-pill: 999px;
}


/* assets/01-fondations/dist/colors.css */
/* Filtré à l'empaquetage par 03-assemblage/package-site.js — ce site
   n'utilise qu'une seule palette, les autres ont été retirées. Ne pas
   éditer à la main. */
[data-palette="bordeaux-vintage"] {
  --color-bg: #FAFAF9;
  --color-surface: #F5F5F4;
  --color-text: #1C1917;
  --color-text-muted: #57534E;
  --color-primary: #881337;
  --color-primary-contrast: #FFFFFF;
  --color-accent: #F59E0B;
  --color-border: #E7E5E4;
}


/* assets/01-fondations/dist/typography.css */
/* Filtré à l'empaquetage par 03-assemblage/package-site.js — ce site
   n'utilise qu'une seule typographie, les autres ont été retirées. Ne pas
   éditer à la main. */
[data-typo="luxe-contraste"] {
  --font-heading: 'Bodoni Moda', serif;
  --font-heading-weight: 700;
  --font-body: 'Jost', sans-serif;
  --font-body-weight: 400;
}


/* assets/02-composants/cookies/cookies.css */
/* Bandeau cookies — persistant en bas d'écran tant qu'aucun choix n'est fait.
   N'utilise que les tokens de la Couche 1. Accessibilité : role="region" +
   aria-label, boutons natifs (clavier OK par défaut), jamais bloquant (pas de
   fond assombri derrière, l'utilisateur peut continuer à lire la page). */

.cookies-bandeau {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 200;
  background: var(--color-text);
  color: var(--color-bg);
  padding: var(--space-sm) var(--space-lg);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  flex-wrap: wrap;
  font-family: var(--font-body);
  box-shadow: 0 -2px 12px rgba(0,0,0,0.15);
}
.cookies-bandeau[hidden] { display: none; }
.cookies-bandeau__texte { font-size: 13.5px; max-width: 560px; line-height: 1.5; }
.cookies-bandeau__texte a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.cookies-bandeau__actions { display: flex; gap: var(--space-sm); flex-wrap: wrap; }
.cookies-bandeau__btn {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 13px;
  border-radius: var(--radius-pill);
  padding: 9px 18px;
  /* 44px : cible tactile confortable (au-delà du minimum WCAG 2.2 de 24px) —
     ce bandeau est le seul élément que TOUT visiteur mobile est obligé de
     toucher pour continuer à naviguer normalement. Trouvé en audit,
     2026-08-15. */
  min-height: 44px;
  border: none;
  cursor: pointer;
}
.cookies-bandeau__btn--accepter { background: var(--color-primary); color: var(--color-primary-contrast); }
.cookies-bandeau__btn--refuser { background: transparent; color: inherit; border: 1px solid rgba(255,255,255,0.4); }


/* assets/02-composants/pages-secondaires/pages-secondaires.css */
/* Pages secondaires (mentions légales, confidentialité, remerciement, 404).
   N'utilise que les tokens de la Couche 1 — même famille visuelle que le site
   principal, mais mise en page simple centrée sur le texte (ce sont des pages de
   lecture, pas de conversion). */

.page-secondaire {
  font-family: var(--font-body);
  background: var(--color-bg);
  color: var(--color-text);
  min-height: 60vh;
  padding: var(--space-xl) var(--space-lg);
}
.page-secondaire__inner { max-width: 720px; margin: 0 auto; }
.page-secondaire__titre {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: clamp(28px, 4vw, 40px);
  color: var(--color-text);
  margin: 0 0 var(--space-md) 0;
}
.page-secondaire__retour {
  display: inline-block;
  font-size: 13.5px;
  color: var(--color-primary);
  text-decoration: underline;
  text-underline-offset: 3px;
  margin-bottom: var(--space-md);
}
.page-secondaire h2 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 19px;
  color: var(--color-text);
  margin: var(--space-lg) 0 var(--space-xs) 0;
}
.page-secondaire p, .page-secondaire li {
  font-size: 15px;
  line-height: 1.65;
  color: var(--color-text-muted);
}
.page-secondaire strong { color: var(--color-text); }
.page-secondaire a { color: var(--color-primary); text-decoration: underline; text-underline-offset: 2px; }

/* --- remerciement / 404 : contenu centré, un seul CTA de retour --- */
.page-secondaire--centree { text-align: center; }
.page-secondaire--centree .page-secondaire__inner { max-width: 480px; }
.page-secondaire--centree .page-secondaire__code {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: clamp(48px, 10vw, 88px);
  color: var(--color-primary);
  line-height: 1;
  margin: 0 0 var(--space-sm) 0;
}
.page-secondaire--centree .page-secondaire__message {
  font-size: 15px;
  color: var(--color-text-muted);
  margin: 0 0 var(--space-lg) 0;
}
.page-secondaire--centree .page-secondaire__cta {
  display: inline-block;
  font-family: var(--font-body);
  font-weight: 600;
  border-radius: var(--radius-pill);
  padding: 12px 28px;
  font-size: 14px;
  text-decoration: none;
  background: var(--color-primary);
  color: var(--color-primary-contrast);

  transition: filter 0.15s ease, transform 0.1s ease;
}
.page-secondaire__cta:hover { filter: brightness(0.93); }
.page-secondaire__cta:active { transform: scale(0.97); }


/* assets/02-composants/_shared/a11y.css */
/* Couche 5 — Accessibilité transversale. À charger sur CHAQUE page assemblée, en plus
   du CSS des composants utilisés (le moteur d'assemblage l'inclut automatiquement).
   Deux règles RGAA structurelles gérées ici :
   1. Focus clavier toujours visible, avec un style cohérent basé sur les tokens
      (jamais de outline:none sans remplacement — testé au clavier, pas juste à la souris).
   2. Utilitaire .sr-only pour donner un nom accessible à un élément sans l'afficher
      visuellement (labels de formulaire, etc.), sans changer le rendu visuel voulu.
*/

*:focus-visible {
  outline: 2px solid var(--color-primary, #1a1a1a);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Certains navigateurs appliquent un focus non-visible par défaut sur les liens/boutons
   au clic souris ; on ne supprime jamais l'outline par défaut sans le remplacer ici. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--color-primary, #1a1a1a);
  outline-offset: 2px;
}

/* 3. Lien d'évitement (RGAA 12.7) : premier élément focusable de la page, invisible
      tant qu'il n'a pas le focus clavier. Permet de sauter la navigation répétée
      d'une page à l'autre pour aller droit au contenu. */
.skip-link {
  /* `fixed`, pas `absolute` : en `absolute` le lien est ancré au DOCUMENT, donc
     un visiteur ayant déjà fait défiler la page le verrait apparaître hors écran
     au moment où il prend le focus — c'est-à-dire jamais (constaté en test). */
  position: fixed;
  left: 8px;
  top: -100px;
  z-index: 1000;
  padding: 10px 16px;
  border-radius: var(--radius-sm, 4px);
  background: var(--color-primary, #1a1a1a);
  color: var(--color-on-primary, #fff);
  font-family: var(--font-body, sans-serif);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  transition: top 0.15s ease;
}
.skip-link:focus {
  top: 8px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* 4. Champ piège anti-spam (honeypot) des formulaires de contact, voir
   02-composants/_shared/contact-mailer.template.php. VOLONTAIREMENT différent
   de .sr-only : .sr-only garde le contenu lisible par un lecteur d'écran (utile
   pour un vrai label), alors qu'un honeypot doit être invisible pour TOUT
   humain, y compris un utilisateur de lecteur d'écran — sinon un visiteur
   aveugle légitime pourrait le remplir et voir son message silencieusement
   ignoré. D'où `aria-hidden` sur le conteneur (retire tout du parcours
   d'accessibilité) en plus du masquage visuel, et un positionnement hors
   écran plutôt qu'une taille nulle (certains lecteurs d'écran ignorent
   display:none mais pas aria-hidden — la double protection est volontaire). */
.hp-field {
  position: absolute;
  left: -9999px;
  top: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* 5. Impression — un client artisan imprime volontiers sa page horaires ou
   adresse (2026-08-15). Trois problèmes concrets sans ces règles :
   - le bandeau cookies, en `position: fixed`, s'imprime flottant PAR-DESSUS
     le contenu de chaque page ;
   - le header, en `position: sticky`, se recale en haut de chaque page
     imprimée séparément, au lieu de rester une seule fois en tête de
     document ;
   - le bouton menu mobile (hamburger) n'a aucun sens sur papier — rien à
     déplier.
   Volontairement minimal : ne touche à AUCUNE couleur de fond ni typographie
   des composants (chaque bloc reste namespacé à lui-même, voir
   docs/regles-css.md) — seulement la structure, universelle sur tout le
   site quels que soient les blocs actifs. */
@media print {
  .skip-link,
  .cookies-bandeau,
  .site-header__toggle {
    display: none !important;
  }
  .site-header {
    position: static !important;
  }
}


/* assets/02-composants/_shared/scroll-reveal.css */
/* Révélation au scroll — chaque bloc de la page (repéré via [data-component], déjà
   présent sur tous les fragments) apparaît en fondu léger. Entièrement dans un bloc
   @media (prefers-reduced-motion: no-preference) : les utilisateurs qui ont demandé
   moins de mouvement voient le contenu directement, sans aucune animation ni délai.
   Dégradation : sans JS, la classe .reveal-init n'est jamais posée, donc tout reste
   visible par défaut (progressive enhancement, jamais de contenu caché si JS échoue). */

@media (prefers-reduced-motion: no-preference) {
  [data-component].reveal-init {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 0.5s ease, transform 0.5s ease;
  }
  [data-component].reveal-init.is-visible {
    opacity: 1;
    transform: none;
  }
}


/* assets/02-composants/apropos/apropos.css */
/* Bloc /apropos — 3 variantes. N'utilise que les tokens de la Couche 1. */

.apropos { font-family: var(--font-body); padding: var(--space-xl) var(--space-lg); background: var(--color-bg); }
.apropos__titre {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  color: var(--color-text);
  font-size: clamp(24px, 3.5vw, 32px);
  margin: 0 0 var(--space-sm) 0;
}
.apropos__texte { font-size: 15px; color: var(--color-text-muted); line-height: 1.6; margin: 0; }

/* --- personnel : photo + bio, ton individuel --- */
.apropos--personnel .apropos__inner {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: var(--space-lg);
  align-items: center;
  max-width: 780px;
  margin: 0 auto;
}
@media (max-width: 640px) {
  .apropos--personnel .apropos__inner { grid-template-columns: 1fr; }
  .apropos--personnel .apropos__photo { margin: 0 auto; }
}
.apropos--personnel .apropos__photo {
  position: relative;
  width: 200px; height: 200px;
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  background-size: cover;
  background-position: center;
  border: 1px solid var(--color-border);
}
.apropos--personnel .apropos__photo[style="background-image:url('');"]::after,
.apropos--personnel .apropos__photo[style="background-image:url('photo_src');"]::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--color-text-muted);
  opacity: .35;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5zm2 0v14h14V5H5z'/%3E%3Ccircle cx='8.5' cy='8.5' r='1.6'/%3E%3Cpath d='M6 17l4.2-4.6a1 1 0 0 1 1.4-.08l.1.1L15 16l1.7-1.9a1 1 0 0 1 1.4-.06l.1.1L20 17v.5a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5V17z'/%3E%3C/svg%3E") center / 38% no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5zm2 0v14h14V5H5z'/%3E%3Ccircle cx='8.5' cy='8.5' r='1.6'/%3E%3Cpath d='M6 17l4.2-4.6a1 1 0 0 1 1.4-.08l.1.1L15 16l1.7-1.9a1 1 0 0 1 1.4-.06l.1.1L20 17v.5a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5V17z'/%3E%3C/svg%3E") center / 38% no-repeat;
}
.apropos--personnel .apropos__nom {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 15px;
  color: var(--color-primary);
  margin: var(--space-sm) 0 0 0;
}

/* --- entreprise : institutionnel, repères chiffrés + description ---
   La carte de repères doit se centrer sur le PARAGRAPHE seul, jamais sur le
   titre au-dessus — un titre fait toujours une ligne ou deux, sa hauteur ne
   doit jamais peser dans le calcul, quel que soit le site généré. Un simple
   align-items:center sur toute la colonne de gauche (titre+texte ensemble)
   centre la carte sur les DEUX, ce qui la décale encore un peu vers le haut
   par rapport au paragraphe seul (constaté le 2026-09-02, ~30px d'écart
   avec la vraie moyenne du texte) — correct pour un premier correctif, mais
   pas exact.
   Le titre et le paragraphe sont ici deux enfants DIRECTS de la grille
   (plus un `<div>` autour des deux, voir entreprise.html) : le titre occupe
   sa PROPRE ligne de grille (`grid-row: 1`), le paragraphe et la carte
   partagent la ligne suivante (`grid-row: 2`). La hauteur de cette 2e ligne
   est alors dictée par le plus grand des deux (presque toujours le
   paragraphe) et `align-self: center` y centre la carte — sans JS, sans
   mesure, automatiquement juste pour n'importe quel texte/titre de
   n'importe quel site, puisque c'est la grille elle-même qui calcule les
   hauteurs à l'assemblage du navigateur, jamais une valeur figée ici. */
.apropos--entreprise .apropos__grid { display: grid; grid-template-columns: 1.3fr 1fr; gap: var(--space-lg); }
.apropos--entreprise .apropos__titre { grid-column: 1; grid-row: 1; }
.apropos--entreprise .apropos__texte { grid-column: 1; grid-row: 2; }
.apropos--entreprise .apropos__reperes { grid-column: 2; grid-row: 2; align-self: center; }
@media (max-width: 640px) {
  .apropos--entreprise .apropos__grid { grid-template-columns: 1fr; }
  /* Retour à l'ordre naturel du DOM (titre → texte → repères) une fois
     empilé — les placements explicites ci-dessus n'ont plus de sens sur
     une seule colonne. */
  .apropos--entreprise .apropos__titre,
  .apropos--entreprise .apropos__texte,
  .apropos--entreprise .apropos__reperes { grid-column: 1; grid-row: auto; align-self: stretch; }
}
.apropos--entreprise .apropos__reperes { display: flex; flex-direction: column; gap: var(--space-sm); background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--space-md); }
.apropos--entreprise .apropos__repere { display: flex; justify-content: space-between; gap: var(--space-sm); font-size: 14px; color: var(--color-text); }
.apropos--entreprise .apropos__repere strong { color: var(--color-primary); }

/* --- mission : citation centrale + valeurs --- */
.apropos--mission { text-align: center; }
.apropos--mission .apropos__inner { max-width: 640px; margin: 0 auto; }
.apropos--mission .apropos__citation {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: clamp(22px, 3.5vw, 30px);
  color: var(--color-text);
  line-height: 1.35;
  margin: 0 0 var(--space-lg) 0;
}
.apropos--mission .apropos__valeurs { display: flex; justify-content: center; gap: var(--space-lg); flex-wrap: wrap; }
.apropos--mission .apropos__valeur { font-size: 13.5px; font-weight: 600; color: var(--color-primary); }


/* assets/02-composants/confiance/confiance.css */
/* Bloc /confiance — 5 modes de preuve de confiance. N'utilise que les tokens de la
   Couche 1, jamais de valeur en dur. */

.confiance { font-family: var(--font-body); padding: var(--space-xl) var(--space-lg); background: var(--color-surface); }
.confiance__header { margin-bottom: var(--space-lg); }
.confiance__titre {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  color: var(--color-text);
  font-size: clamp(24px, 3.5vw, 32px);
  margin: 0 0 var(--space-xs) 0;
}
.confiance__accroche { font-size: 14.5px; color: var(--color-text-muted); margin: 0; max-width: 600px; }

/* --- avis : cartes de témoignages avec note ---
   4 avis par ligne maximum (max réel 3, voir REPEAT_GROUP) — même mécanisme
   que galerie/offre--catalogue, voir docs/composants.md#listes-à-nombre-variable. */
.confiance--avis .confiance__grid {
  display: grid;
  gap: var(--space-md);
  justify-content: center;
  grid-template-columns: repeat(1, minmax(240px, 340px));
}
@media (min-width: 620px) {
  .confiance--avis .confiance__grid--n2 { grid-template-columns: repeat(2, minmax(240px, 340px)); }
  .confiance--avis .confiance__grid--n3 { grid-template-columns: repeat(2, minmax(240px, 340px)); }
  .confiance--avis .confiance__grid--n4 { grid-template-columns: repeat(2, minmax(240px, 340px)); }
}
/* Paliers calculés (Règle 10) — MIN=240px, gap=--space-md (24px) : 3 col →
   3×240+2×24+80 = 848px (700px ne passe pas) ; 4 col → 4×240+3×24+80 =
   1112px (n4 jamais atteint en pratique, max réel 3 avis, mais gardé
   cohérent). Voir docs/CHANGELOG.md, 2026-08-08. */
@media (min-width: 860px) {
  .confiance--avis .confiance__grid--n3 { grid-template-columns: repeat(3, minmax(240px, 340px)); }
}
@media (min-width: 1120px) {
  .confiance--avis .confiance__grid--n4 { grid-template-columns: repeat(4, minmax(240px, 340px)); }
}
.confiance--avis .confiance__carte {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-md);
}
/* Couleur volontairement FIXE (jamais var(--color-accent)) : le jaune/or est
   une convention universelle de notation, le client s'attend à la retrouver
   identique quelle que soit la palette du site — retour utilisateur.
   #A16707 (pas #F5A623, trop clair — 2.03:1 sur blanc, sous le seuil AA
   4.5:1) depuis le 2026-08-15 : même teinte (or/ambre), assombrie pour
   rester confortable en basse vision — 4.33:1 dans le pire cas mesuré parmi
   les 48 palettes + la palette personnalisée (fond le plus clair,
   `blanc-absolu`), 4.71:1 sur blanc pur. Élément aria-hidden (le nombre
   d'étoiles reste annoncé via .sr-only juste après), donc pas un manquement
   RGAA au sens strict, mais rester lisible reste un vrai gain de confort —
   voir docs/CHANGELOG.md. */
.confiance--avis .confiance__etoiles { color: #A16707; font-size: 15px; letter-spacing: 2px; margin-bottom: var(--space-xs); }
.confiance--avis .confiance__citation { font-size: 14.5px; color: var(--color-text); line-height: 1.5; margin: 0 0 var(--space-sm) 0; font-style: italic; }
.confiance--avis .confiance__auteur { font-size: 13px; font-weight: 600; color: var(--color-text); }
.confiance--avis .confiance__role { font-size: 12px; color: var(--color-text-muted); }

/* --- certifications : badges en grille ---
   4 badges par ligne maximum — même mécanisme que galerie/offre--catalogue,
   voir docs/composants.md#listes-à-nombre-variable. */
.confiance--certifications .confiance__grid {
  display: grid;
  gap: var(--space-sm);
  justify-content: center;
  grid-template-columns: repeat(1, minmax(150px, 200px));
}
@media (min-width: 420px) {
  .confiance--certifications .confiance__grid--n2 { grid-template-columns: repeat(2, minmax(150px, 200px)); }
  .confiance--certifications .confiance__grid--n3 { grid-template-columns: repeat(2, minmax(150px, 200px)); }
  .confiance--certifications .confiance__grid--n4 { grid-template-columns: repeat(2, minmax(150px, 200px)); }
}
/* Paliers calculés (Règle 10) — MIN=150px, gap=--space-sm (16px) : 3 col →
   3×150+2×16+80 = 562px (700px passe) ; 4 col → 4×150+3×16+80 = 728px
   (700px ne passe pas). Voir docs/CHANGELOG.md, 2026-08-08. */
@media (min-width: 700px) {
  .confiance--certifications .confiance__grid--n3 { grid-template-columns: repeat(3, minmax(150px, 200px)); }
}
@media (min-width: 740px) {
  .confiance--certifications .confiance__grid--n4 { grid-template-columns: repeat(4, minmax(150px, 200px)); }
}
.confiance--certifications .confiance__badge {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-md);
  text-align: center;
}
.confiance--certifications .confiance__badge-icone {
  width: 36px; height: 36px;
  margin: 0 auto var(--space-xs) auto;
  border-radius: 50%;
  background: var(--color-primary);
}
.confiance--certifications .confiance__badge h3 { font-size: 13.5px; color: var(--color-text); margin: 0; font-weight: 600; }

/* --- experience : gros chiffres alignés ---
   Grille (jamais flex + space-between) : avec 3 blocs de largeur fixe et
   flex-wrap, dès que ça ne tient plus sur une ligne (mobile), space-between
   répartit CHAQUE ligne indépendamment — 2 blocs collés aux bords sur la
   première ligne, le 3e seul et plaqué à gauche sur la seconde. Rien n'est
   cassé au sens CSS (pas de débordement), mais rien n'est aligné non plus —
   trouvé par l'utilisateur en test réel (capture d'écran), Règle 10 pour le
   mécanisme de calcul du palier. Toujours exactement 3 stats (pas une liste
   à nombre variable) : un seul palier suffit, 1 colonne empilée en dessous,
   3 colonnes égales au-dessus — jamais l'état intermédiaire "2 sur une
   ligne, 1 sur l'autre" que produisait flex-wrap. Palier calculé : 3×MIN +
   2×gap + 80px (padding de section) = 3×140 + 2×40 + 80 = 580px. */
.confiance--experience .confiance__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
}
@media (min-width: 580px) {
  .confiance--experience .confiance__grid { grid-template-columns: repeat(3, minmax(140px, 1fr)); }
}
.confiance--experience .confiance__stat { text-align: center; }
.confiance--experience .confiance__chiffre {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: clamp(32px, 5vw, 48px);
  color: var(--color-primary);
  line-height: 1;
  margin: 0 0 6px 0;
}
.confiance--experience .confiance__label { font-size: 13.5px; color: var(--color-text-muted); }

/* --- avant_apres : deux colonnes comparatives --- */
.confiance--avant-apres .confiance__comparaison {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-md);
  max-width: 620px;
  margin: 0 auto;
}
@media (max-width: 480px) {
  .confiance--avant-apres .confiance__comparaison { grid-template-columns: 1fr; }
}
.confiance--avant-apres .confiance__panneau {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.confiance--avant-apres .confiance__panneau-image {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--color-border);
  background-size: cover;
  background-position: center;
}
.confiance--avant-apres .confiance__panneau-image[style="background-image:url('');"]::after,
.confiance--avant-apres .confiance__panneau-image[style="background-image:url('photo_avant');"]::after,
.confiance--avant-apres .confiance__panneau-image[style="background-image:url('photo_apres');"]::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--color-text-muted);
  opacity: .35;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5zm2 0v14h14V5H5z'/%3E%3Ccircle cx='8.5' cy='8.5' r='1.6'/%3E%3Cpath d='M6 17l4.2-4.6a1 1 0 0 1 1.4-.08l.1.1L15 16l1.7-1.9a1 1 0 0 1 1.4-.06l.1.1L20 17v.5a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5V17z'/%3E%3C/svg%3E") center / 38% no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5zm2 0v14h14V5H5z'/%3E%3Ccircle cx='8.5' cy='8.5' r='1.6'/%3E%3Cpath d='M6 17l4.2-4.6a1 1 0 0 1 1.4-.08l.1.1L15 16l1.7-1.9a1 1 0 0 1 1.4-.06l.1.1L20 17v.5a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5V17z'/%3E%3C/svg%3E") center / 38% no-repeat;
}
.confiance--avant-apres .confiance__panneau-label {
  padding: var(--space-sm);
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text);
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* --- partenaires : bande de logos discrète --- */
.confiance--partenaires { background: var(--color-bg); }
.confiance--partenaires .confiance__bande {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-lg);
  align-items: center;
  padding-top: var(--space-sm);
}
.confiance--partenaires .confiance__logo {
  height: 32px;
  min-width: 96px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  color: var(--color-text-muted);
  font-weight: 600;
  padding: 0 var(--space-sm);
}


/* assets/02-composants/contact/contact.css */
/* Bloc /contact — 4 variantes. N'utilise que les tokens de la Couche 1. */

.contact { font-family: var(--font-body); padding: var(--space-xl) var(--space-lg); background: var(--color-surface); }
.contact__titre {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  color: var(--color-text);
  font-size: clamp(24px, 3.5vw, 32px);
  margin: 0 0 var(--space-xs) 0;
}
.contact__accroche { font-size: 14.5px; color: var(--color-text-muted); margin: 0 0 var(--space-md) 0; max-width: 560px; }
.contact__cta {
  display: inline-block;
  font-family: var(--font-body);
  font-weight: 600;
  border-radius: var(--radius-pill);
  padding: 14px 28px;
  font-size: 15px;
  text-decoration: none;
  background: var(--color-primary);
  color: var(--color-primary-contrast);
  border: none;
  cursor: pointer;

  transition: filter 0.15s ease, transform 0.1s ease;
}
.contact__cta:hover { filter: brightness(0.93); }
.contact__cta:active { transform: scale(0.97); }

/* --- appel_direct : numéro géant, un seul geste --- */
.contact--appel-direct { text-align: center; }
.contact--appel-direct .contact__inner { max-width: 640px; margin: 0 auto; }
.contact--appel-direct .contact__accroche { margin-left: auto; margin-right: auto; }
.contact--appel-direct .contact__numero {
  display: block;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: clamp(36px, 6vw, 56px);
  color: var(--color-primary);
  text-decoration: none;
  margin: var(--space-md) 0;
}
.contact--appel-direct .contact__disponibilite { font-size: 13px; color: var(--color-text-muted); }

/* --- formulaire : champs classiques --- */
.contact--formulaire .contact__inner { max-width: 460px; margin: 0 auto; }
.contact--formulaire .contact__champs { display: flex; flex-direction: column; gap: var(--space-sm); }
.contact--formulaire .contact__champ {
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  background: var(--color-bg);
  font-size: 14px;
  color: var(--color-text);
  font-family: var(--font-body);
  transition: border-color 0.15s ease;
}
.contact--formulaire textarea.contact__champ { min-height: 90px; resize: vertical; }

/* --- rdv_ligne : bloc prise de rendez-vous en ligne --- */
.contact--rdv-ligne .contact__inner { display: flex; align-items: center; gap: var(--space-lg); flex-wrap: wrap; max-width: 780px; margin: 0 auto; }
.contact--rdv-ligne .contact__calendrier {
  position: relative;
  width: 96px; height: 96px;
  border-radius: var(--radius-md);
  background: var(--color-bg);
  background-size: cover;
  background-position: center;
  border: 2px solid var(--color-primary);
  flex-shrink: 0;
}
.contact--rdv-ligne .contact__calendrier[style="background-image:url('');"]::after,
.contact--rdv-ligne .contact__calendrier[style="background-image:url('photo_contact');"]::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--color-text-muted);
  opacity: .35;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5zm2 0v14h14V5H5z'/%3E%3Ccircle cx='8.5' cy='8.5' r='1.6'/%3E%3Cpath d='M6 17l4.2-4.6a1 1 0 0 1 1.4-.08l.1.1L15 16l1.7-1.9a1 1 0 0 1 1.4-.06l.1.1L20 17v.5a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5V17z'/%3E%3C/svg%3E") center / 38% no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5zm2 0v14h14V5H5z'/%3E%3Ccircle cx='8.5' cy='8.5' r='1.6'/%3E%3Cpath d='M6 17l4.2-4.6a1 1 0 0 1 1.4-.08l.1.1L15 16l1.7-1.9a1 1 0 0 1 1.4-.06l.1.1L20 17v.5a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5V17z'/%3E%3C/svg%3E") center / 38% no-repeat;
}

/* --- devis : formulaire + réassurance en deux colonnes --- */
.contact--devis .contact__inner { max-width: 900px; margin: 0 auto; }
.contact--devis .contact__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-lg); }
@media (max-width: 640px) {
  .contact--devis .contact__grid { grid-template-columns: 1fr; }
}
.contact--devis .contact__rassurance { background: var(--color-bg); border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--space-md); }
.contact--devis .contact__rassurance-item { font-size: 13.5px; color: var(--color-text); padding: 8px 0; border-top: 1px solid var(--color-border); }
.contact--devis .contact__rassurance-item:first-child { border-top: none; }
.contact--devis .contact__champs { display: flex; flex-direction: column; gap: var(--space-sm); }
.contact--devis .contact__champ {
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  background: var(--color-bg);
  font-size: 14px;
  color: var(--color-text);
  font-family: var(--font-body);
  transition: border-color 0.15s ease;
}

/* Focus + erreur — partagés par les deux variantes à champs (formulaire, devis). */
.contact__champ:focus { border-color: var(--color-primary); }
.contact__champ[aria-invalid="true"] { border-color: #C0392B; }
.contact__erreur {
  font-size: 12.5px;
  color: #C0392B;
  margin: -4px 0 0 0;
}
.contact__erreur:empty { display: none; }


/* assets/02-composants/disponibilite/disponibilite.css */
/* Bloc optionnel /disponibilite — indicateur "ouvert/fermé maintenant", calculé côté
   client à partir des horaires (mêmes données que le JSON-LD de la Couche 5 SEO).
   N'utilise que les tokens de la Couche 1.

   Positionné juste après le hero (voir PAGE_ORDER) — c'est une petite puce de
   statut, pas une section à part entière : contrairement à tous les autres
   blocs, l'élément racine (.disponibilite, data-component) ne porte PAS de
   fond coloré, juste un espacement vertical léger pour centrer la puce sans
   ajouter une nouvelle bande de couleur entre le hero et le reste de la page
   (qui alourdirait visuellement). C'est .disponibilite-badge, à l'intérieur,
   qui porte l'habillage visuel (fond, bordure, forme de pilule). */

.disponibilite {
  display: flex;
  justify-content: center;
  padding: var(--space-lg) var(--space-lg);
}

.disponibilite-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  padding: 8px 16px;
}
.disponibilite-badge__point {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--color-text-muted);
  flex-shrink: 0;
}
.disponibilite-badge.is-open .disponibilite-badge__point { background: #2E8B57; }
.disponibilite-badge.is-closed .disponibilite-badge__point { background: #C0392B; }


/* assets/02-composants/footer/footer.css */
/* Bloc /footer — 2 variantes. N'utilise que les tokens de la Couche 1. */

.footer-block { font-family: var(--font-body); background: var(--color-text); color: var(--color-bg); padding: var(--space-lg) var(--space-lg) var(--space-md); }
/* RGAA : un lien ne doit jamais être signalé par la couleur/opacité seule — le
   soulignement reste visible en permanence, pas seulement au survol. */
.footer-block a { color: inherit; text-decoration: underline; text-underline-offset: 3px; opacity: 0.85; }
.footer-block__nom {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 18px;
  margin: 0 0 var(--space-xs) 0;
}

/* --- standard : nom + nav + mentions --- */
.footer-block--standard .footer-block__row {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-md);
  padding-bottom: var(--space-md);
  border-bottom: 1px solid rgba(255,255,255,0.15);
  margin-bottom: var(--space-sm);
}
.footer-block--standard .footer-block__nav { display: flex; gap: var(--space-md); flex-wrap: wrap; font-size: 13.5px; }
.footer-block--standard .footer-block__bas { display: flex; justify-content: space-between; flex-wrap: wrap; gap: var(--space-xs); font-size: 12px; opacity: 0.7; }

/* --- zone : met en avant la zone d'intervention — les deux blocs sont poussés
   chacun vers leur bord (comme la variante standard), pas alignés au milieu
   d'une colonne à 50% qui les laissait "perdus" loin du bord droit. */
.footer-block--zone .footer-block__row {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-lg);
  padding-bottom: var(--space-md);
  border-bottom: 1px solid rgba(255,255,255,0.15);
  margin-bottom: var(--space-sm);
}
.footer-block--zone .footer-block__zones { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; max-width: 320px; }
.footer-block--zone .footer-block__zone-tag {
  font-size: 12.5px;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  background: rgba(255,255,255,0.12);
}
.footer-block--zone .footer-block__bas { display: flex; justify-content: space-between; flex-wrap: wrap; gap: var(--space-xs); font-size: 12px; opacity: 0.7; }


/* assets/02-composants/header/header.css */
/* Bloc /header — nav scindée en deux (2026-08-15, décision explicite de
   l'utilisateur) : `.site-header__epingles` (Accueil/Nos services/Contact,
   voir NAV_EPINGLES_KEYS dans assemble-site.js) reste TOUJOURS visible en
   ligne, sur toutes les tailles d'écran ; `.site-header__nav` (tout le
   reste — réalisations, tarifs, équipe, localisation, FAQ, à propos, page
   informations...) vit derrière le bouton hamburger `.site-header__toggle`,
   également sur toutes les tailles d'écran, plus seulement en dessous d'un
   seuil mobile comme avant cette date. N'utilise que les tokens de la
   Couche 1. */

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding: var(--space-sm) var(--space-lg);
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-border);
  position: sticky;
  top: 0;
  z-index: 100;
  font-family: var(--font-body);
}
.site-header__nom {
  display: flex;
  align-items: center;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 18px;
  color: var(--color-text);
  text-decoration: none;
}
/* Logo facultatif (voir docs/CHANGELOG.md, 2026-08-14) — même pattern que les
   autres slots photo à fond vide (apropos__photo, confiance__panneau-image...) :
   un `background-image:url('')` reste invisible tant qu'aucun logo n'est
   fourni, jamais une balise <img src=""> (qui redéclenche une requête vers la
   page courante dans certains navigateurs). Remplace visuellement le texte du
   nom quand présent — le texte reste dans le DOM pour l'accessibilité/le SEO. */
.site-header__logo {
  display: none;
  height: 32px; width: auto; aspect-ratio: auto;
  background-size: contain; background-repeat: no-repeat; background-position: left center;
}
.site-header__logo:not([style="background-image:url('');"]) {
  display: block;
  width: 120px; /* largeur de référence pour background-size:contain — le logo garde ses proportions dans cette boîte */
}
.site-header__logo:not([style="background-image:url('');"]) + .site-header__nom-texte {
  /* mêmes propriétés que .sr-only (02-composants/_shared/a11y.css) — pas la
     classe elle-même, un gabarit statique ne peut pas la poser
     conditionnellement selon que le logo est fourni ou non. */
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Liens épinglés — au plus 3 (Accueil/Nos services/Contact), jamais tous les
   candidats comme avant : un simple `flex-wrap` suffit à absorber les
   écrans étroits (au pire "Contact" passe à la ligne), plus besoin du
   défilement horizontal ni du filet flex-shrink:0 que l'ancienne nav à ~9
   liens exigeait. */
.site-header__epingles {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs) var(--space-md);
  margin-left: auto;
}
/* En dessous de 480px (vérifié à 375px), le nom de l'entreprise + le bouton
   hamburger occupent déjà l'essentiel de la largeur : sans ce palier, les 3
   liens épinglés se retrouvent chacun seul sur sa ligne (une colonne étroite
   coincée entre les deux), un header inutilement haut. Ici la nav épinglée
   passe sur sa propre ligne pleine largeur, sous le nom/logo — les 3 liens
   peuvent alors tenir côte à côte normalement. */
@media (max-width: 480px) {
  .site-header { flex-wrap: wrap; row-gap: var(--space-xs); }
  .site-header__epingles { order: 3; width: 100%; margin-left: 0; }
}
.site-header__epingles a {
  font-size: 14px;
  color: var(--color-text);
  text-decoration: none;
  padding: 4px 2px;
  border-bottom: 2px solid transparent;
  transition: border-color 0.15s ease;
  white-space: nowrap;
}
.site-header__epingles a:hover { border-color: var(--color-primary); }

.site-header__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  width: 44px;
  height: 44px;
  margin-left: var(--space-sm);
  cursor: pointer;
  font-size: 18px;
  color: var(--color-text);
  flex-shrink: 0;
}

/* Panneau déroulant des sections secondaires — un vrai menu ancré sous le
   bouton (pas une bande pleine largeur), cohérent qu'il s'ouvre sur mobile
   ou sur un grand écran, puisque son déclenchement n'est plus une question
   de largeur de fenêtre. `.site-header` est déjà `position: sticky` (donc
   positionné) : sert de bloc de référence à cet `absolute` sans wrapper
   supplémentaire. */
.site-header__nav {
  display: none;
  flex-direction: column;
  position: absolute;
  top: calc(100% + 6px);
  right: var(--space-lg);
  min-width: 200px;
  max-width: calc(100vw - 2 * var(--space-lg));
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
  padding: var(--space-xs);
  gap: 2px;
  z-index: 10;
}
.site-header__nav.is-open { display: flex; }
.site-header__nav a {
  display: block;
  font-size: 14px;
  color: var(--color-text);
  text-decoration: none;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
}
.site-header__nav a:hover { background: var(--color-surface); }


/* assets/02-composants/hero/hero.css */
/* Bloc /hero — 5 variantes par registre émotionnel. Structure différente à chaque
   fois (pas juste une couleur qui change) ; n'utilise que les tokens de la Couche 1
   (--color-*, --font-*, --space-*, --radius-*), jamais de valeur en dur. */

.hero { font-family: var(--font-body); }
.hero a { text-decoration: none; }
.hero__cta {
  display: inline-block;
  font-family: var(--font-body);
  font-weight: 600;
  border-radius: var(--radius-pill);
  padding: 14px 28px;
  font-size: 15px;

  transition: filter 0.15s ease, transform 0.1s ease;
}
.hero__cta:hover { filter: brightness(0.93); }
.hero__cta:active { transform: scale(0.97); }
.hero__cta--primary { background: var(--color-primary); color: var(--color-primary-contrast); }
.hero__cta--ghost { background: transparent; color: var(--color-text); border: 1px solid var(--color-border); }

/* Emplacement du bloc /disponibilite (badge "ouvert/fermé" calculé en
   direct) quand ce bloc est actif — réservé sur les 5 variantes de hero,
   vide/invisible sinon (voir AUTO_FIELD_COMPUTERS.hero dans
   03-assemblage/assemble-site.js). Remplace l'ancien "hero__badge" en texte
   libre, qui faisait doublon avec ce même statut calculé (retour
   utilisateur). Le style de base (fond, forme pilule, puce colorée) vient
   de .disponibilite-badge (02-composants/disponibilite/disponibilite.css) ;
   ces règles ne font qu'ajuster l'espacement et, par variante, le
   fond/couleur pour rester cohérentes avec le registre émotionnel du hero
   (fond translucide blanc sur urgence qui a déjà un fond coloré, style
   par défaut de .disponibilite-badge sur les 4 autres qui ont un fond
   clair). */
.hero__disponibilite:empty { display: none; }
.hero__disponibilite .disponibilite-badge { margin-bottom: var(--space-sm); }

/* --- Urgence : bandeau compact, CTA téléphone proéminent, badge de disponibilité --- */
.hero--urgence {
  background: var(--color-primary);
  color: var(--color-primary-contrast);
  padding: var(--space-xl) var(--space-lg);
}
.hero--urgence .hero__disponibilite .disponibilite-badge { background: rgba(255,255,255,0.15); border-color: rgba(255,255,255,0.35); color: var(--color-primary-contrast); }
.hero--urgence .hero__titre {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: clamp(32px, 5vw, 52px);
  margin: 0 0 var(--space-xs) 0;
  line-height: 1.05;
}
.hero--urgence .hero__accroche { font-size: 17px; margin: 0 0 var(--space-md) 0; opacity: 0.95; max-width: 520px; }
.hero--urgence .hero__actions { display: flex; gap: var(--space-sm); flex-wrap: wrap; }
.hero--urgence .hero__cta--primary { background: var(--color-primary-contrast); color: var(--color-primary); }
.hero--urgence .hero__cta--ghost { border-color: rgba(255,255,255,0.5); color: var(--color-primary-contrast); }

/* --- Sérénité : centré, spacieux, ton doux, un seul CTA --- */
.hero--serenite {
  background: var(--color-bg);
  padding: var(--space-xl) var(--space-lg);
  text-align: center;
}
.hero--serenite .hero__inner { max-width: 620px; margin: 0 auto; }
.hero--serenite .hero__titre {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: clamp(30px, 4.5vw, 44px);
  color: var(--color-text);
  margin: 0 0 var(--space-sm) 0;
  line-height: 1.15;
}
.hero--serenite .hero__accroche { font-size: 16px; color: var(--color-text-muted); margin: 0 0 var(--space-lg) 0; }
.hero--serenite .hero__cta--primary { background: var(--color-primary); color: var(--color-primary-contrast); }

/* --- Technique : deux colonnes, texte + trio de repères chiffrés --- */
.hero--technique {
  background: var(--color-bg);
  padding: var(--space-xl) var(--space-lg);
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: var(--space-lg);
  align-items: center;
}
@media (max-width: 640px) {
  .hero--technique { grid-template-columns: 1fr; }
}
.hero--technique .hero__titre {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: clamp(28px, 4vw, 40px);
  color: var(--color-text);
  margin: 0 0 var(--space-xs) 0;
  line-height: 1.15;
}
.hero--technique .hero__accroche { font-size: 15px; color: var(--color-text-muted); margin: 0 0 var(--space-md) 0; }
.hero--technique .hero__cta--primary { background: var(--color-primary); color: var(--color-primary-contrast); }
.hero--technique .hero__reperes {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-md);
}
.hero--technique .hero__repere { display: flex; justify-content: space-between; gap: var(--space-sm); font-size: 14px; color: var(--color-text); }
.hero--technique .hero__repere strong { color: var(--color-primary); }

/* --- Confidentiel : minimal, texte seul, aucune emphase visuelle forte --- */
.hero--confidentiel {
  background: var(--color-bg);
  padding: var(--space-xl) var(--space-lg);
}
.hero--confidentiel .hero__inner { max-width: 620px; margin: 0 auto; }
.hero--confidentiel .hero__titre {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: clamp(26px, 3.5vw, 34px);
  color: var(--color-text);
  margin: 0 0 var(--space-sm) 0;
  line-height: 1.2;
}
.hero--confidentiel .hero__accroche { font-size: 15px; color: var(--color-text-muted); margin: 0 0 var(--space-sm) 0; }
.hero--confidentiel .hero__rassurance { font-size: 13px; color: var(--color-text-muted); margin: 0 0 var(--space-md) 0; }
.hero--confidentiel .hero__cta--ghost { border-color: var(--color-border); color: var(--color-text); }

/* --- Premium : grande typo, espace généreux, ligne d'accent --- */
.hero--premium {
  background: var(--color-bg);
  padding: calc(var(--space-xl) * 1.4) var(--space-lg);
}
.hero--premium .hero__inner { max-width: 680px; margin: 0 auto; }
.hero--premium .hero__accent-line { width: 48px; height: 2px; background: var(--color-accent); margin-bottom: var(--space-md); }
.hero--premium .hero__titre {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: clamp(34px, 5.5vw, 56px);
  color: var(--color-text);
  margin: 0 0 var(--space-sm) 0;
  line-height: 1.08;
}
.hero--premium .hero__accroche { font-size: 17px; color: var(--color-text-muted); margin: 0 0 var(--space-lg) 0; }
.hero--premium .hero__cta--primary { background: var(--color-primary); color: var(--color-primary-contrast); padding: 16px 32px; }


/* assets/02-composants/offre/offre.css */
/* Bloc /offre — 5 variantes de structure de l'offre. N'utilise que les tokens de la
   Couche 1, jamais de valeur en dur. */

.offre { font-family: var(--font-body); padding: var(--space-xl) var(--space-lg); background: var(--color-bg); }
.offre__header { margin-bottom: var(--space-lg); }
.offre__titre {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  color: var(--color-text);
  font-size: clamp(26px, 4vw, 36px);
  margin: 0 0 var(--space-xs) 0;
}
.offre__accroche { font-size: 15px; color: var(--color-text-muted); margin: 0; max-width: 620px; }
.offre__cta {
  display: inline-block;
  font-family: var(--font-body);
  font-weight: 600;
  border-radius: var(--radius-pill);
  padding: 12px 26px;
  font-size: 14px;
  text-decoration: none;
  background: var(--color-primary);
  color: var(--color-primary-contrast);

  transition: filter 0.15s ease, transform 0.1s ease;
}
.offre__cta:hover { filter: brightness(0.93); }
.offre__cta:active { transform: scale(0.97); }

/* --- liste_services : grille de cartes simples, photo + titre + description ---
   4 services par ligne maximum — même mécanisme que galerie/offre--catalogue,
   voir docs/composants.md#listes-à-nombre-variable. */
.offre--liste-services .offre__grid {
  display: grid;
  gap: var(--space-md);
  justify-content: center;
  grid-template-columns: repeat(1, minmax(220px, 320px));
}
@media (min-width: 580px) {
  .offre--liste-services .offre__grid--n2 { grid-template-columns: repeat(2, minmax(220px, 320px)); }
  .offre--liste-services .offre__grid--n3 { grid-template-columns: repeat(2, minmax(220px, 320px)); }
  .offre--liste-services .offre__grid--n4 { grid-template-columns: repeat(2, minmax(220px, 320px)); }
}
/* Paliers 3/4 colonnes calculés (Règle 10, docs/regles-css.md) — MIN=220px,
   gap=--space-md (24px), padding=2×--space-lg (80px) — jamais 700px pour
   tous les blocs à la fois, ce chiffre ne dépend que du MIN de CE bloc :
   3 col → 3×220+2×24+80 = 788px ; 4 col → 4×220+3×24+80 = 1032px. Trouvé en
   déficit à 768px (tablette portrait) lors d'un passage systématique, voir
   docs/CHANGELOG.md, 2026-08-08. */
@media (min-width: 800px) {
  .offre--liste-services .offre__grid--n3 { grid-template-columns: repeat(3, minmax(220px, 320px)); }
}
@media (min-width: 1040px) {
  .offre--liste-services .offre__grid--n4 { grid-template-columns: repeat(4, minmax(220px, 320px)); }
}
.offre--liste-services .offre__carte {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-top: 3px solid var(--color-accent);
  border-radius: var(--radius-md);
  padding: var(--space-md);
}
.offre--liste-services .offre__photo {
  position: relative;
  aspect-ratio: 16 / 10;
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  background-size: cover;
  background-position: center;
  border: 1px solid var(--color-border);
  margin: 0 0 var(--space-sm) 0;
}
.offre--liste-services .offre__photo[style="background-image:url('');"]::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--color-text-muted);
  opacity: .35;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5zm2 0v14h14V5H5z'/%3E%3Ccircle cx='8.5' cy='8.5' r='1.6'/%3E%3Cpath d='M6 17l4.2-4.6a1 1 0 0 1 1.4-.08l.1.1L15 16l1.7-1.9a1 1 0 0 1 1.4-.06l.1.1L20 17v.5a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5V17z'/%3E%3C/svg%3E") center / 34% no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5zm2 0v14h14V5H5z'/%3E%3Ccircle cx='8.5' cy='8.5' r='1.6'/%3E%3Cpath d='M6 17l4.2-4.6a1 1 0 0 1 1.4-.08l.1.1L15 16l1.7-1.9a1 1 0 0 1 1.4-.06l.1.1L20 17v.5a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5V17z'/%3E%3C/svg%3E") center / 34% no-repeat;
}
.offre--liste-services .offre__carte h3 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 18px;
  color: var(--color-text);
  margin: 0 0 6px 0;
}
.offre--liste-services .offre__carte p { font-size: 14px; color: var(--color-text-muted); margin: 0; line-height: 1.5; }

/* --- parcours : étapes numérotées ---
   4 étapes par ligne maximum — même mécanisme que galerie/offre--catalogue,
   voir docs/composants.md#listes-à-nombre-variable. */
.offre--parcours .offre__etapes {
  display: grid;
  gap: var(--space-md);
  justify-content: center;
  position: relative;
  grid-template-columns: repeat(1, minmax(180px, 260px));
}
@media (min-width: 500px) {
  .offre--parcours .offre__etapes--n2 { grid-template-columns: repeat(2, minmax(180px, 260px)); }
  .offre--parcours .offre__etapes--n3 { grid-template-columns: repeat(2, minmax(180px, 260px)); }
  .offre--parcours .offre__etapes--n4 { grid-template-columns: repeat(2, minmax(180px, 260px)); }
}
/* Paliers calculés (Règle 10) — MIN=180px, gap=--space-md (24px) :
   3 col → 3×180+2×24+80 = 668px (700px passe) ; 4 col → 4×180+3×24+80 =
   872px (700px ne passe PAS — débordait à 768px, tablette portrait, voir
   docs/CHANGELOG.md, 2026-08-08). */
@media (min-width: 700px) {
  .offre--parcours .offre__etapes--n3 { grid-template-columns: repeat(3, minmax(180px, 260px)); }
}
@media (min-width: 880px) {
  .offre--parcours .offre__etapes--n4 { grid-template-columns: repeat(4, minmax(180px, 260px)); }
}
.offre--parcours .offre__etape { position: relative; padding-top: var(--space-md); }
.offre--parcours .offre__num {
  display: flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--color-primary);
  color: var(--color-primary-contrast);
  font-weight: 700;
  font-size: 15px;
  margin-bottom: var(--space-sm);
}
.offre--parcours .offre__etape h3 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 16px;
  color: var(--color-text);
  margin: 0 0 4px 0;
}
.offre--parcours .offre__etape p { font-size: 13.5px; color: var(--color-text-muted); margin: 0; line-height: 1.5; }

/* --- catalogue : grille dense, plus d'items, étiquette de catégorie ---
   4 articles par ligne maximum, quel que soit le nombre total d'articles —
   au-delà de 4, la grille redescend simplement sur une nouvelle ligne.
   Colonnes à largeur fixe (pas 1fr) + justify-content:center : avec un
   nombre d'articles variable (1 à 6, voir docs/composants.md#listes-à-nombre-variable),
   `repeat(N, 1fr)` collerait toujours le contenu à gauche avec du vide à
   droite dès qu'il y a moins de N articles — le modificateur
   `.offre__grid--nX` (X = nombre réel d'articles, calculé par le code,
   plafonné à 4) donne le bon nombre de colonnes à chaque fois, centrées. */
.offre--catalogue .offre__grid {
  display: grid;
  gap: var(--space-sm);
  justify-content: center;
  grid-template-columns: repeat(1, minmax(160px, 240px));
}
@media (min-width: 480px) {
  .offre--catalogue .offre__grid--n2 { grid-template-columns: repeat(2, minmax(160px, 240px)); }
  .offre--catalogue .offre__grid--n3 { grid-template-columns: repeat(2, minmax(160px, 240px)); }
  .offre--catalogue .offre__grid--n4 { grid-template-columns: repeat(2, minmax(160px, 240px)); }
}
/* Paliers calculés (Règle 10) — MIN=160px, gap=--space-sm (16px) : 3 col →
   3×160+2×16+80 = 592px (700px passe) ; 4 col → 4×160+3×16+80 = 768px
   (700px ne passe pas — voir docs/CHANGELOG.md, 2026-08-08). */
@media (min-width: 700px) {
  .offre--catalogue .offre__grid--n3 { grid-template-columns: repeat(3, minmax(160px, 240px)); }
}
@media (min-width: 780px) {
  .offre--catalogue .offre__grid--n4 { grid-template-columns: repeat(4, minmax(160px, 240px)); }
}
.offre--catalogue .offre__carte {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-sm);
}
.offre--catalogue .offre__categorie {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-primary);
  margin-bottom: 6px;
}
.offre--catalogue .offre__carte h3 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 15px;
  color: var(--color-text);
  margin: 0 0 4px 0;
}
.offre--catalogue .offre__carte p { font-size: 12.5px; color: var(--color-text-muted); margin: 0; line-height: 1.4; }

/* --- forfaits : nombre de forfaits ajustable (1 à 4) ---
   4 forfaits par ligne maximum — même mécanisme que catalogue/parcours,
   voir docs/composants.md#listes-à-nombre-variable. */
.offre--forfaits .offre__grid {
  display: grid;
  gap: var(--space-md);
  justify-content: center;
  align-items: start;
  grid-template-columns: repeat(1, minmax(240px, 320px));
}
@media (min-width: 560px) {
  .offre--forfaits .offre__grid--n2 { grid-template-columns: repeat(2, minmax(240px, 320px)); }
  .offre--forfaits .offre__grid--n3 { grid-template-columns: repeat(2, minmax(240px, 320px)); }
  .offre--forfaits .offre__grid--n4 { grid-template-columns: repeat(2, minmax(240px, 320px)); }
}
@media (min-width: 900px) {
  .offre--forfaits .offre__grid--n3 { grid-template-columns: repeat(3, minmax(240px, 320px)); }
  .offre--forfaits .offre__grid--n4 { grid-template-columns: repeat(4, minmax(240px, 320px)); }
}
.offre--forfaits .offre__carte {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-md);
}
.offre--forfaits .offre__carte--recommande {
  background: var(--color-bg);
  border: 2px solid var(--color-primary);
  position: relative;
}
.offre--forfaits .offre__badge {
  position: absolute;
  top: -12px; left: var(--space-md);
  background: var(--color-primary);
  color: var(--color-primary-contrast);
  font-size: 11px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
}
.offre--forfaits .offre__carte h3 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 19px;
  color: var(--color-text);
  margin: 0 0 6px 0;
}
.offre--forfaits .offre__carte > p { font-size: 13.5px; color: var(--color-text-muted); margin: 0 0 var(--space-sm) 0; }
.offre--forfaits .offre__liste { list-style: none; padding: 0; margin: 0 0 var(--space-md) 0; }
.offre--forfaits .offre__liste li {
  font-size: 13.5px;
  color: var(--color-text);
  padding: 6px 0;
  border-top: 1px solid var(--color-border);
}
.offre--forfaits .offre__liste li:first-child { border-top: none; }
.offre--forfaits .offre__cta { display: block; text-align: center; }

/* --- unique : un seul bloc centré, description + liste de points inline --- */
.offre--unique { text-align: center; }
.offre--unique .offre__unique-inner { max-width: 680px; margin: 0 auto; }
.offre--unique .offre__accroche { margin-left: auto; margin-right: auto; }
.offre--unique .offre__points {
  list-style: none;
  padding: 0;
  margin: var(--space-md) 0 var(--space-lg) 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-sm) var(--space-md);
}
.offre--unique .offre__points li {
  font-size: 14px;
  color: var(--color-text);
  padding-left: 20px;
  position: relative;
}
.offre--unique .offre__points li::before {
  content: "";
  position: absolute; left: 0; top: 6px;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--color-accent);
}


/* assets/02-composants/reassurance/reassurance.css */
/* Bloc optionnel /reassurance — badges de conversion (garantie, sans engagement...).
   N'utilise que les tokens de la Couche 1. */

.reassurance-badges {
  font-family: var(--font-body);
  padding: var(--space-md) var(--space-lg);
  background: var(--color-bg);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  justify-content: center;
}
.reassurance-badges__item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  padding: 8px 16px;
}
.reassurance-badges__icone {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-primary);
  flex-shrink: 0;
}


/* assets/02-composants/faq/faq.css */
/* Bloc optionnel /faq — objections fréquentes. Accordéon natif (details/summary),
   fonctionne sans JS. N'utilise que les tokens de la Couche 1. */

.faq { font-family: var(--font-body); padding: var(--space-xl) var(--space-lg); background: var(--color-surface); }
.faq__titre {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  color: var(--color-text);
  font-size: clamp(24px, 3.5vw, 32px);
  margin: 0 0 var(--space-md) 0;
}
.faq__liste { max-width: 640px; margin: 0 auto; display: flex; flex-direction: column; gap: var(--space-xs); }
.faq__item {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-sm) var(--space-md);
}
.faq__item summary {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 15.5px;
  color: var(--color-text);
  cursor: pointer;
  list-style: none;
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__reponse { font-size: 14px; color: var(--color-text-muted); margin: var(--space-xs) 0 0 0; line-height: 1.6; }


/* assets/02-composants/galerie/galerie.css */
/* Bloc optionnel /galerie — résultat visuel. Activé si le métier a un rendu visuel
   à montrer. N'utilise que les tokens de la Couche 1. */

.galerie { font-family: var(--font-body); padding: var(--space-xl) var(--space-lg); background: var(--color-bg); }
.galerie__titre {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  color: var(--color-text);
  font-size: clamp(24px, 3.5vw, 32px);
  margin: 0 0 var(--space-md) 0;
}
/* 4 photos par ligne maximum, quel que soit le nombre total (1 à 6) — au-delà
   de 4, la grille redescend sur une nouvelle ligne. Colonnes à largeur fixe
   (pas 1fr) + justify-content:center : avec un nombre de photos variable,
   `1fr` étirerait une photo unique sur toute la largeur (résultat démesuré) —
   le modificateur `.galerie__grid--nX` (X = nombre réel de photos, calculé
   par le code, plafonné à 4) donne le bon nombre de colonnes à chaque fois,
   centrées, avec une taille de photo qui ne dépasse jamais celle qu'aurait
   une grille à 3 colonnes. Même mécanisme que `offre--catalogue`, voir
   docs/composants.md#listes-à-nombre-variable. */
.galerie__grid {
  display: grid;
  gap: var(--space-sm);
  justify-content: center;
  grid-template-columns: repeat(1, minmax(160px, 280px));
}
@media (min-width: 480px) {
  .galerie__grid--n2 { grid-template-columns: repeat(2, minmax(160px, 280px)); }
  .galerie__grid--n3 { grid-template-columns: repeat(2, minmax(160px, 280px)); }
  .galerie__grid--n4 { grid-template-columns: repeat(2, minmax(160px, 280px)); }
}
/* Paliers calculés (Règle 10) — MIN=160px, gap=--space-sm (16px) : 3 col →
   3×160+2×16+80 = 592px (700px passe) ; 4 col → 4×160+3×16+80 = 768px
   (700px ne passe pas — c'est le bloc qui a déclenché cette règle en
   2026-08-03, mais son propre palier n4 n'avait jamais été recalculé
   après coup). Voir docs/CHANGELOG.md, 2026-08-08. */
@media (min-width: 700px) {
  .galerie__grid--n3 { grid-template-columns: repeat(3, minmax(160px, 280px)); }
}
@media (min-width: 780px) {
  .galerie__grid--n4 { grid-template-columns: repeat(4, minmax(160px, 280px)); }
}
.galerie__item {
  position: relative;
  aspect-ratio: 1;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  background-size: cover;
  background-position: center;
  border: 1px solid var(--color-border);
}
.galerie__item[style="background-image:url('');"]::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--color-text-muted);
  opacity: .35;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5zm2 0v14h14V5H5z'/%3E%3Ccircle cx='8.5' cy='8.5' r='1.6'/%3E%3Cpath d='M6 17l4.2-4.6a1 1 0 0 1 1.4-.08l.1.1L15 16l1.7-1.9a1 1 0 0 1 1.4-.06l.1.1L20 17v.5a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5V17z'/%3E%3C/svg%3E") center / 38% no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5zm2 0v14h14V5H5z'/%3E%3Ccircle cx='8.5' cy='8.5' r='1.6'/%3E%3Cpath d='M6 17l4.2-4.6a1 1 0 0 1 1.4-.08l.1.1L15 16l1.7-1.9a1 1 0 0 1 1.4-.06l.1.1L20 17v.5a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5V17z'/%3E%3C/svg%3E") center / 38% no-repeat;
}


/* assets/02-composants/localisation/localisation.css */
/* Bloc optionnel /localisation — activité mobile ou physique. N'utilise que les
   tokens de la Couche 1. */

.localisation { font-family: var(--font-body); padding: var(--space-xl) var(--space-lg); background: var(--color-bg); display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-lg); align-items: center; }
@media (max-width: 640px) {
  .localisation { grid-template-columns: 1fr; }
}
/* La carte n'est PAS une iframe tant que le visiteur ne l'a pas demandée
   (voir localisation.js) : ce bloc est d'abord un cadre d'invitation, puis
   devient le conteneur de l'iframe une fois chargée. Les deux états gardent
   exactement la même boîte (même aspect-ratio, même bordure) pour qu'aucun
   décalage de mise en page ne se produise au clic. */
.localisation__carte {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  width: 100%;
  aspect-ratio: 4/3;
  padding: var(--space-md);
  text-align: center;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  overflow: hidden;
}
/* Après le clic — déclaré APRÈS la règle de base : même spécificité (une
   seule classe), c'est l'ordre source qui tranche. */
.localisation__carte--chargee { display: block; padding: 0; }
.localisation__carte-invite {
  font-family: var(--font-body);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--color-text-muted);
  max-width: 34ch;
  margin: 0;
}
.localisation__carte-btn {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 14px;
  /* 44px : cible tactile confortable sur mobile, pas seulement le minimum
     réglementaire — c'est le seul geste à faire pour voir la carte. */
  min-height: 44px;
  padding: 12px 24px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-primary);
  background: transparent;
  color: var(--color-primary);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.localisation__carte-btn:hover { background: var(--color-primary); color: var(--color-primary-contrast); }
.localisation__iframe { display: block; width: 100%; height: 100%; border: 0; }
.localisation__titre {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  color: var(--color-text);
  font-size: clamp(22px, 3.5vw, 30px);
  margin: 0 0 var(--space-xs) 0;
}
.localisation__adresse { font-size: 14.5px; color: var(--color-text-muted); margin: 0 0 var(--space-sm) 0; line-height: 1.5; }
.localisation__cta {
  display: inline-block;
  font-family: var(--font-body);
  font-weight: 600;
  border-radius: var(--radius-pill);
  padding: 12px 24px;
  font-size: 14px;
  text-decoration: none;
  background: var(--color-primary);
  color: var(--color-primary-contrast);

  transition: filter 0.15s ease, transform 0.1s ease;
}
.localisation__cta:hover { filter: brightness(0.93); }
.localisation__cta:active { transform: scale(0.97); }
