@charset "UTF-8";
/* ==========================================================================
   MP Nettoyage de Vitres : feuille de style unique
   Organisée par sections, dans l'ordre du HTML.

   Si vous modifiez ce fichier, pensez à augmenter le « ?v=7 » dans les trois
   pages HTML, sinon les visiteurs déjà venus verront l'ancienne version.

   RÈGLE DE COULEUR À NE JAMAIS ENFREINDRE
   Le cyan #36B4EC sur le crème #F1ECD7 donne un contraste de 1.99 : illisible.
   Sur tout fond clair, le cyan est remplacé par le bleu #134F77.
   Le cyan ne sert que sur les fonds sombres.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. VARIABLES : valeurs issues des fichiers d'impression, voir docs/DESIGN.md
   -------------------------------------------------------------------------- */
:root {
  /* Palette */
  --bleu-profond:  #0F3954;
  --bleu:          #134F77;
  --cyan:          #36B4EC;
  --creme:         #F1ECD7;
  --blanc:         #FFFFFF;

  /* Dérivés. Le gris bleuté sert aux sous-titres, il tient le AA sur crème. */
  --gris-bleute:   #4A6478;
  --filet-clair:   rgba(15, 57, 84, .12);
  --filet-appuye:  rgba(15, 57, 84, .55);
  --filet-sombre:  rgba(241, 236, 215, .18);

  /* Typographie */
  --font-display: "Archivo", system-ui, -apple-system, sans-serif;
  --font-body:    "Inter", system-ui, -apple-system, sans-serif;

  /* Échelle fluide */
  --step--1: clamp(0.83rem, 0.8rem + 0.15vw, 0.9rem);
  --step-0:  clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
  --step-1:  clamp(1.25rem, 1.15rem + 0.5vw, 1.5rem);
  --step-2:  clamp(1.6rem, 1.4rem + 1vw, 2.25rem);
  --step-3:  clamp(2rem, 1.6rem + 2vw, 3.25rem);
  /* Paliers éditoriaux, pour les manchettes et le hero.
     Le plafond du palier 5 est contraint par le mot le plus long du titre,
     « impeccables, » : au-delà de 4.5rem il déborde de sa colonne et vient
     mordre sur la photo. */
  --step-4:  clamp(2.4rem, 1.5rem + 4vw, 4.75rem);
  --step-5:  clamp(2.6rem, 1.3rem + 4vw, 4.5rem);

  /* Trois densités verticales, pour que le rythme ne soit pas uniforme */
  --section-serre: clamp(2.25rem, 1.5rem + 3.5vw, 4rem);
  --section:       clamp(3rem, 2rem + 5vw, 6rem);
  --section-ample: clamp(4rem, 2.5rem + 7vw, 8.5rem);

  --largeur:  68rem;
  --gouttiere: clamp(1.25rem, 4vw, 2.5rem);

  /* Hauteur de la barre de contact fixe, mobile uniquement.
     Mesurée à 69px : on compense au-dessus pour que le pied de page ne soit
     jamais recouvert, même d'un pixel. */
  --barre-h: 4.75rem;
}

/* --------------------------------------------------------------------------
   2. POLICES : auto-hébergées, aucune requête externe
   -------------------------------------------------------------------------- */

/* Archivo remplace Montserrat depuis le 6 août 2026 : grotesque plus serrée
   et plus dense, qui tient mieux les très grands corps. Police variable, un
   seul fichier pour les graisses 400 à 900. */
@font-face {
  font-family: "Archivo";
  src: url("/assets/fonts/archivo-latin-var.woff2") format("woff2-variations");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  src: url("/assets/fonts/inter-latin-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* --------------------------------------------------------------------------
   3. BASES
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* L'en-tête est collant : sans cette marge, une ancre amènerait le titre
     de section juste dessous, à moitié caché. */
  scroll-padding-top: 5.5rem;
}

body {
  margin: 0;
  background: var(--creme);
  color: var(--bleu-profond);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  /* Compense la barre de contact fixe pour qu'elle ne masque pas le pied. */
  padding-bottom: calc(var(--barre-h) + env(safe-area-inset-bottom, 0px));
}

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

h1, h2, h3 {
  font-family: var(--font-display);
  line-height: 1.06;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0; text-wrap: pretty; }

a { color: inherit; }

strong { font-weight: 600; }

/* Focus visible partout. Le bleu est la valeur par défaut car la majorité des
   fonds sont clairs ; le cyan n'apparaît que sur les fonds sombres, où il est
   le seul des deux à être lisible. */
:focus-visible {
  outline: 3px solid var(--bleu);
  outline-offset: 3px;
  border-radius: 2px;
}
.bloc--fonce :focus-visible,
.pied :focus-visible {
  outline-color: var(--cyan);
}

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

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

.saut-contenu {
  position: absolute;
  left: 50%;
  transform: translate(-50%, -150%);
  z-index: 100;
  background: var(--bleu-profond);
  color: var(--creme);
  padding: .75rem 1.25rem;
  font-family: var(--font-display);
  font-weight: 600;
  text-decoration: none;
  transition: transform .18s ease;
}
.saut-contenu:focus { transform: translate(-50%, 0); }

.svg-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* --------------------------------------------------------------------------
   4. ÉLÉMENTS RÉCURRENTS
   -------------------------------------------------------------------------- */

/* Filet horizontal, écho du trait sous le wordmark MP.
   Sur fond clair il est bleu, jamais cyan. */
.filet {
  border: 0;
  height: 4px;
  width: 4.5rem;
  background: var(--bleu);
  margin: 1.75rem 0;
}
.bloc--fonce .filet { background: var(--cyan); }
.filet--sobre { width: 3rem; height: 3px; margin-bottom: 0; }

/* TROIS TRAITEMENTS DE TITRE, pour que les sections ne se ressemblent pas.

   1. .manchette      : titre très grand, pleine largeur, qui ouvre la section
   2. .section--marge : titre placé dans la marge, à gauche du contenu
   3. .titre-courant  : discret, pour les sections qui n'ont pas besoin d'un
                        effet d'annonce
   La section des tarifs se distingue autrement : par son aplat sombre grainé
   pleine largeur, sans autre artifice. */

/* Coupe de ligne des titres. Un <br> ne garantit pas une frontière de mot pour
   les moteurs de recherche, qui peuvent lire « indicatifspar intervention ».
   Chaque ligne est donc un bloc, séparé par une vraie espace dans le balisage. */
.ligne { display: block; }

.manchette {
  font-weight: 900;
  font-size: var(--step-4);
  letter-spacing: -.035em;
  line-height: .98;
  margin-bottom: clamp(2rem, 5vw, 3.5rem);
  text-wrap: initial;
}
.manchette--claire { color: var(--creme); }

.titre-section {
  font-weight: 900;
  font-size: var(--step-3);
  letter-spacing: -.03em;
}

/* Aligné sur .titre-section : à --step-2 il faisait 36px contre 52px partout
   ailleurs, et les sections concernées avaient l'air secondaires. */
.titre-courant {
  font-weight: 800;
  font-size: var(--step-3);
  letter-spacing: -.03em;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--filet-clair);
  margin-bottom: clamp(1.75rem, 4vw, 2.75rem);
}

.texte-large {
  font-size: var(--step-1);
  line-height: 1.5;
  max-width: 42ch;
}

/* --------------------------------------------------------------------------
   5. BOUTONS
   -------------------------------------------------------------------------- */
.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .625rem;
  min-height: 48px;               /* cible tactile */
  padding: .75rem 1.5rem;
  border-radius: 999px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-0);
  line-height: 1.2;
  text-decoration: none;
  border: 2px solid transparent;
  transition: transform .16s ease, background-color .16s ease, border-color .16s ease;
}
.bouton:hover { transform: translateY(-2px); }
.bouton:active { transform: translateY(0); }

.bouton .ico { width: 1.25em; height: 1.25em; flex: none; }

/* Bouton principal : cyan, texte bleu profond. Ratio 5.13, conforme AA. */
.bouton--principal { background: var(--cyan); color: var(--bleu-profond); }
.bouton--principal:hover { background: #52c1f0; }

/* Bordures à 3:1 minimum, exigence WCAG 1.4.11 sur les éléments d'interface. */
.bouton--fantome {
  background: transparent;
  color: var(--bleu);
  border-color: var(--filet-appuye);
}
.bouton--fantome:hover { border-color: var(--bleu-profond); background: rgba(15, 57, 84, .05); }

.bouton--sombre { background: var(--bleu-profond); color: var(--creme); }
.bouton--sombre:hover { background: #0a2b40; }

.bouton--contour {
  background: transparent;
  color: var(--bleu-profond);
  border-color: var(--bleu-profond);
}
.bouton--contour:hover { background: rgba(15, 57, 84, .08); }

/* --------------------------------------------------------------------------
   6. EN-TÊTE
   -------------------------------------------------------------------------- */
.entete {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--creme);
  border-bottom: 1px solid var(--filet-clair);
}

.entete__grille {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 4.5rem;
}

.marque {
  display: flex;
  align-items: center;
  gap: .875rem;
  text-decoration: none;
  flex: none;
}

/* Wordmark MP : Archivo en graisse maximale + filet, proportions du support
   imprimé */
.marque__signe { width: 3rem; height: 1.875rem; overflow: visible; }
.marque__signe rect { fill: var(--bleu); }
.marque__lettres {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 30px;
  letter-spacing: -.02em;
  fill: var(--bleu-profond);
}

.marque__texte { display: flex; flex-direction: column; line-height: 1.15; }
.marque__nom {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: .8125rem;
  letter-spacing: .04em;
  color: var(--bleu-profond);
}
.marque__lieu {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: .6875rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--bleu);
}

/* La navigation textuelle n'apparaît qu'en grand écran : sur mobile, la barre
   fixe du bas porte l'action, et le reste se parcourt en défilant. Il n'y a
   donc aucun menu à déplier. */
.nav { display: none; }
.nav__liste {
  display: flex;
  gap: 1.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step--1);
  letter-spacing: .02em;
}
.nav__liste a {
  text-decoration: none;
  color: var(--bleu);
  padding-block: .5rem;
  border-bottom: 2px solid transparent;
  transition: border-color .16s ease;
}
.nav__liste a:hover { border-bottom-color: var(--bleu); }
/* Section courante, posée par assets/js/main.js. Sans JavaScript, le lien
   reste simplement non souligné : aucune perte de fonction. */
.nav__liste a.est-actif { color: var(--bleu-profond); border-bottom-color: var(--bleu); }

.entete__action { display: none; }
.entete__retour { padding-inline: 1.125rem; }

/* --------------------------------------------------------------------------
   7. HERO
   -------------------------------------------------------------------------- */
.hero {
  padding-block: clamp(2.5rem, 7vw, 5rem) var(--section);
  background: var(--creme);
}

.hero__grille { display: grid; gap: clamp(2.5rem, 6vw, 4rem); }

.hero__titre { font-weight: 900; }

/* L'accroche domine visuellement ; la ligne métier, plus discrète, porte le
   mot-clé pour les moteurs de recherche sans casser la composition. */
.hero__accroche {
  display: block;
  font-size: var(--step-5);
  letter-spacing: -.045em;
  line-height: .95;
}
.hero__accroche em { font-style: normal; color: var(--bleu); }

.hero__metier {
  display: block;
  margin-top: 1.25rem;
  font-weight: 600;
  font-size: var(--step--1);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--bleu);
}

.hero__intro {
  font-size: var(--step-1);
  line-height: 1.5;
  max-width: 44ch;
  color: var(--gris-bleute);
}

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

/* Le visuel est posé sur un aplat bleu décalé : de la profondeur sans ombre
   portée, conformément aux interdits visuels de docs/DESIGN.md. */
.hero__visuel { margin: 0; position: relative; }
.hero__visuel::before {
  content: "";
  position: absolute;
  inset: auto -0.75rem -0.75rem 1.5rem;
  height: 70%;
  background: var(--bleu);
  z-index: 0;
}
.hero__visuel img {
  position: relative;
  z-index: 1;
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
}

/* --------------------------------------------------------------------------
   8. BLOCS DE SECTION
   -------------------------------------------------------------------------- */
.bloc { padding-block: var(--section); }
.bloc--serre { padding-block: var(--section-serre); }
.bloc--ample { padding-block: var(--section-ample); }

.bloc--creme { background: var(--blanc); }

.bloc--fonce {
  background: var(--bleu-profond);
  color: var(--creme);
}
.bloc--fonce .titre-section,
.bloc--fonce .titre-courant { color: var(--creme); }
.bloc--fonce .titre-courant { border-bottom-color: var(--filet-sombre); }

.bloc--accent { background: var(--cyan); color: var(--bleu-profond); }

/* Grain sur les aplats sombres. Le fichier SVG ne contient aucun pixel : il
   décrit un filtre de bruit que le navigateur calcule lui-même, d'où ses
   quelques centaines d'octets. Servi depuis le domaine, donc compatible avec
   la directive img-src 'self' du .htaccess.
   L'opacité est volontairement très basse : le grain doit se sentir, pas se
   voir. Ce n'est pas un dégradé, les aplats restent des aplats. */
.bloc--grain { position: relative; isolation: isolate; }
.bloc--grain > * { position: relative; z-index: 1; }
.bloc--grain::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: url("/assets/img/grain.svg");
  background-size: 200px 200px;
  opacity: .16;
  pointer-events: none;
}

/* Titre en marge : sur grand écran il se cale à gauche et reste au regard
   pendant que le contenu défile. */
.section--marge__grille { display: grid; gap: 2rem; }
.section--marge__titre { display: flex; flex-direction: column; gap: 1.25rem; }

/* --------------------------------------------------------------------------
   9. CONTRAT D'ENTRETIEN
   -------------------------------------------------------------------------- */
.contrat__grille { display: grid; gap: 2rem; align-items: center; }
.contrat__corps .texte-large { margin-block: 1.5rem 2rem; color: rgba(241, 236, 215, .82); }

/* Le « 15 % » en très grand, traité comme un élément graphique.
   Le filet est exprimé en em pour garder la même graisse optique à toutes les
   tailles, et le signe pour cent revient sur la ligne de base : en exposant il
   chevauchait l'épaule du 5. */
.contrat__chiffre {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(5.5rem, 22vw, 13rem);
  line-height: .85;
  letter-spacing: -.05em;
  color: transparent;
  -webkit-text-stroke: .018em var(--cyan);
  user-select: none;
  justify-self: start;
}
.contrat__chiffre span { font-size: .38em; vertical-align: baseline; margin-left: .04em; }

/* --------------------------------------------------------------------------
   10. PRESTATIONS
   -------------------------------------------------------------------------- */
.prestations {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--filet-clair);
}

.prestation {
  display: grid;
  gap: .25rem;
  padding-block: 1.5rem;
  border-bottom: 1px solid var(--filet-clair);
}
.prestation__titre {
  font-weight: 700;
  font-size: var(--step-2);
  letter-spacing: -.02em;
  line-height: 1.12;
}
.prestation__detail { color: var(--gris-bleute); font-size: var(--step-0); }

/* --------------------------------------------------------------------------
   11. CE QUI EST INCLUS
   -------------------------------------------------------------------------- */
.inclus {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2rem;
}
.inclus__item {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: 1rem;
}
.inclus__ico {
  width: 2.25rem;
  height: 2.25rem;
  color: var(--bleu);
  flex: none;
}
.inclus__item p { font-size: var(--step-0); }

/* --------------------------------------------------------------------------
   12. TARIFS
   -------------------------------------------------------------------------- */

/* Vrai <table>, remis en page en lignes lisibles sur mobile.
   La grille est portée par le <tbody> et non par chaque <tr> : sans cela, les
   colonnes de chaque ligne se calaient indépendamment et ne s'alignaient pas
   entre elles. */
.tarifs {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
}

.tarifs tbody { display: grid; }

.tarifs tbody tr {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: .25rem 1rem;
  padding-block: 1.25rem;
  border-bottom: 1px solid var(--filet-sombre);
}

.tarifs__nom {
  display: flex;
  align-items: center;
  gap: .75rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-0);
  color: var(--creme);
}
.tarifs__ico { width: 1.75rem; height: 1.75rem; color: var(--cyan); flex: none; }

.tarifs__detail {
  grid-column: 1;
  font-size: var(--step--1);
  color: rgba(241, 236, 215, .72);
  padding-left: 2.5rem;
}

.tarifs__prix {
  grid-column: 2;
  grid-row: 1 / 3;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--step-2);
  letter-spacing: -.03em;
  color: var(--cyan);
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.tarifs__des {
  display: block;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: .5em;
  letter-spacing: 0;
  color: rgba(241, 236, 215, .72);
}
.tarifs__unite {
  display: block;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: .4em;
  letter-spacing: .04em;
  color: rgba(241, 236, 215, .72);
}
.tarifs__prix--texte { font-size: var(--step-1); }

.mentions {
  margin-top: 2.5rem;
  display: grid;
  gap: .75rem;
  max-width: 46ch;
  font-size: var(--step--1);
  color: rgba(241, 236, 215, .78);
}

/* --------------------------------------------------------------------------
   13. LE TRAVAIL
   Galerie en pleine largeur, hors du conteneur : c'est la seule section qui
   touche les deux bords de l'écran.
   -------------------------------------------------------------------------- */
.galerie {
  display: grid;
  gap: 2px;
  margin-top: clamp(1.5rem, 4vw, 2.5rem);
}
.galerie__item { margin: 0; position: relative; }
.galerie__item img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
}
.galerie__item figcaption {
  padding: .75rem var(--gouttiere);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step--1);
  letter-spacing: .04em;
  color: var(--gris-bleute);
}

/* --------------------------------------------------------------------------
   13 bis. BANDE DÉFILANTE
   La baseline, en boucle continue. Le déplacement porte sur un tiers de la
   piste, et la piste contient trois copies du texte : au bout d'un tiers, la
   deuxième copie occupe exactement la position de départ de la première, donc
   la boucle est invisible.
   Aucun JavaScript. À l'arrêt si l'utilisateur a demandé moins d'animation.
   -------------------------------------------------------------------------- */
.bande {
  overflow: hidden;
  background: var(--bleu-profond);
  border-block: 1px solid var(--filet-sombre);
  padding-block: clamp(.75rem, 2vw, 1.25rem);
  /* Empêche la piste, plus large que l'écran, de créer une barre horizontale */
  max-width: 100vw;
}

.bande__piste {
  display: flex;
  width: max-content;
  animation: defiler 28s linear infinite;
}

.bande__texte {
  flex: none;
  padding-inline: clamp(1rem, 3vw, 2.5rem);
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(1.75rem, 5vw, 3.5rem);
  letter-spacing: -.03em;
  line-height: 1.1;
  white-space: nowrap;
  color: transparent;
  -webkit-text-stroke: 1px var(--cyan);
}
/* Une copie sur deux est pleine : le rythme évite l'effet de frise uniforme. */
.bande__texte:nth-child(2) {
  color: var(--creme);
  -webkit-text-stroke: 0;
}

@keyframes defiler {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-100% / 3)); }
}

@media (prefers-reduced-motion: reduce) {
  .bande__piste { animation: none; }
}

/* --------------------------------------------------------------------------
   14. RÉFÉRENCES
   Logos de clients ayant donné leur accord écrit. Fond clair impératif : le
   logo Audacia est bleu marine et disparaîtrait sur le bleu profond du site.
   -------------------------------------------------------------------------- */
.references {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(2rem, 7vw, 4.5rem);
}
/* Le titre est centré lui aussi : un titre à gauche au-dessus de logos
   centrés donnait une composition bancale. */
#references .titre-courant { text-align: center; }

.references__item { display: flex; align-items: center; }
.references__item img { width: auto; }
/* Les deux logos n'ont pas le même format : l'un est une signature large,
   l'autre un carré. On les cale sur une hauteur optique comparable plutôt que
   sur une hauteur identique, sinon le carré écrase la signature. */
.references__item:nth-child(1) img { height: clamp(2.5rem, 6vw, 3.75rem); }
.references__item:nth-child(2) img { height: clamp(6rem, 15vw, 9rem); }

/* --------------------------------------------------------------------------
   15. QUESTIONS FRÉQUENTES
   Blocs <details> natifs : fonctionnent sans JavaScript.
   -------------------------------------------------------------------------- */
.faq { border-top: 1px solid var(--filet-clair); }

.faq__item { border-bottom: 1px solid var(--filet-clair); }

.faq__q {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1.375rem;
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-1);
  line-height: 1.25;
  letter-spacing: -.01em;
}
.faq__q::-webkit-details-marker { display: none; }

/* Marqueur + / moins dessiné en CSS, pas d'image. En bleu : c'est un
   indicateur d'état, il doit tenir le 3:1 de WCAG 1.4.11. */
.faq__q::after {
  content: "+";
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.5em;
  line-height: 1;
  color: var(--bleu);
  flex: none;
  transition: transform .2s ease;
}
.faq__item[open] .faq__q::after {
  content: "\2212";
  transform: rotate(180deg);
}

.faq__r { padding-bottom: 1.5rem; max-width: 60ch; color: var(--gris-bleute); }

/* --------------------------------------------------------------------------
   16. CONTACT
   -------------------------------------------------------------------------- */
.contact { display: grid; gap: 2.5rem; }
.contact__titre { color: var(--bleu-profond); }
.contact__intro { margin-top: 1.5rem; max-width: 40ch; }
.contact__dispo {
  margin-top: 1rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step--1);
  letter-spacing: .04em;
  color: var(--bleu-profond);
}
.contact__actions { display: flex; flex-wrap: wrap; gap: .75rem; align-content: start; }

/* --------------------------------------------------------------------------
   17. PIED DE PAGE
   -------------------------------------------------------------------------- */
.pied {
  background: var(--bleu-profond);
  color: var(--creme);
  padding-top: var(--section);
}

.pied__grille { display: grid; gap: 2.5rem; }

/* Verrou complet du pied de page : MP, filet et sous-titre en un seul bloc, aux
   proportions du logo d'origine. Tout est peint en une seule couleur via
   « currentColor » : pour changer la teinte, il suffit de changer « color ».
   La largeur pilote tout le reste, le SVG se met à l'échelle seul. */
.verrou {
  display: block;
  width: 13.5rem;
  max-width: 100%;
  height: auto;
  color: var(--creme);
  fill: currentColor;
  margin-bottom: 1.5rem;
}
/* En SVG, « px » vaut une unité du viewBox, pas un pixel d'écran. 115 n'est pas
   un chiffre rond par hasard : la hauteur de capitale d'Archivo vaut 0,6909 em,
   et 115 × 0,6909 donne les 79,4 unités mesurées sur le logo d'origine. */
.verrou__sous { font-family: var(--font-display); font-weight: 400; font-size: 115px; }

.pied__detail { color: rgba(241, 236, 215, .75); font-size: var(--step--1); }

.pied__intitule {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step--1);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--cyan);
  margin-bottom: 1rem;
}
.pied ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .625rem; }
.pied__horaires { color: rgba(241, 236, 215, .68); font-size: var(--step--1); }

.pied a {
  text-decoration: none;
  border-bottom: 1px solid var(--filet-sombre);
  padding-bottom: 2px;
  transition: border-color .16s ease;
}
.pied a:hover { border-bottom-color: var(--cyan); }

.pied__bas {
  margin-top: var(--section);
  padding-block: 1.75rem;
  border-top: 1px solid var(--filet-sombre);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step--1);
  letter-spacing: .18em;
  text-transform: uppercase;
  /* .68 et non .55 : en dessous, le rapport tombe sous 4.5:1 à cette taille. */
  color: rgba(241, 236, 215, .68);
}

/* --------------------------------------------------------------------------
   18. PAGES LÉGALES
   Colonne de lecture étroite, pas de barre fixe : ce ne sont pas des pages
   de conversion.
   -------------------------------------------------------------------------- */
.page-legale { padding-bottom: 0; }
.page-legale .pied { padding-top: 0; }
.pied__bas--seul { margin-top: 0; border-top: 0; }

.legal { max-width: 42rem; }
.legal h2 {
  font-weight: 700;
  font-size: var(--step-1);
  letter-spacing: -.01em;
  margin-top: 2.75rem;
  margin-bottom: .75rem;
}
.legal p { margin-bottom: 1rem; }
.legal a { color: var(--bleu); }

.legal__chapo {
  font-size: var(--step-1);
  line-height: 1.5;
  color: var(--gris-bleute);
}

.legal__maj {
  margin-top: 3rem;
  font-size: var(--step--1);
  color: var(--gris-bleute);
}

.legal__retour {
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--filet-clair);
  font-family: var(--font-display);
  font-weight: 600;
}

/* --------------------------------------------------------------------------
   19. BARRE DE CONTACT FIXE : mobile uniquement
   Fond sombre, pour que le contenu de la page ne semble pas défiler dedans.
   -------------------------------------------------------------------------- */
.barre-fixe {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 60;
  display: flex;
  gap: .5rem;
  padding: .625rem var(--gouttiere);
  padding-bottom: calc(.625rem + env(safe-area-inset-bottom, 0px));
  background: var(--bleu-profond);
}
.barre-fixe :focus-visible { outline-color: var(--cyan); }

.barre-fixe__bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  min-height: 48px;
  border-radius: 999px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-0);
  text-decoration: none;
}
.barre-fixe__bouton .ico { width: 1.375em; height: 1.375em; flex: none; }

.barre-fixe__bouton--wa { flex: 1; background: var(--cyan); color: var(--bleu-profond); }
.barre-fixe__bouton--tel {
  flex: none;
  width: 3.25rem;
  background: transparent;
  color: var(--creme);
  border: 2px solid rgba(241, 236, 215, .45);
}

/* --------------------------------------------------------------------------
   20. GRAND ÉCRAN : point de bascule unique, 48rem
   -------------------------------------------------------------------------- */
@media (min-width: 48rem) {

  body { padding-bottom: 0; }
  .barre-fixe { display: none; }

  .nav { display: block; }
  .entete__action { display: inline-flex; }

  /* À 48rem pile, six entrées plus le wordmark plus le bouton ne tiennent pas
     sur une ligne : le bouton sortait de l'écran. Références et Questions
     n'apparaissent donc qu'une fois la place disponible. Elles restent
     atteignables en défilant, et par les liens du pied de page. */
  .nav__liste li:nth-child(3),
  .nav__liste li:nth-child(5) { display: none; }

  /* Hero asymétrique. minmax(0, …) est indispensable : sans lui, la largeur
     minimale du mot « impeccables » impose sa loi et la colonne image perd
     une soixantaine de pixels. */
  .hero__grille {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    align-items: center;
  }

  .contrat__grille { grid-template-columns: minmax(0, 1fr) auto; gap: 4rem; }
  .contrat__chiffre { justify-self: end; }

  .prestation {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: baseline;
    gap: 2rem;
    padding-block: 1.75rem;
  }
  .prestation__detail { text-align: right; }

  /* Le titre en marge reste empilé jusqu'à 62rem : voir la règle plus bas.
     À 48rem, une colonne assez large pour « fréquentes » ne laisserait pas
     de place utilisable au contenu. */

  .inclus { gap: 2.5rem; }

  .tarifs tbody tr {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr) 11rem;
    gap: 1.5rem;
    padding-block: 1.75rem;
  }
  .tarifs__nom { font-size: var(--step-1); }
  .tarifs__detail { grid-column: 2; padding-left: 0; text-align: left; }
  .tarifs__prix { grid-column: 3; grid-row: 1; }
  .tarifs__des { display: inline; font-size: .45em; }
  .tarifs__unite { font-size: .32em; }

  .galerie { grid-template-columns: 1fr 1fr; }

  .contact { grid-template-columns: minmax(0, 1fr) auto; gap: 4rem; align-items: center; }
  .contact__actions { flex-direction: column; align-items: stretch; }

  .pied__grille { grid-template-columns: 2fr 1fr 1fr; gap: 3rem; }

}

/* Seconde bascule. Elle rétablit les deux entrées de navigation masquées, et
   fait passer les titres en marge sur deux colonnes.
   La colonne fait 20rem, soit 320px : le titre le plus large, « fréquentes »,
   mesure 290px à 52px de corps. En dessous il était coupé sur la droite. */
@media (min-width: 62rem) {
  .nav__liste li:nth-child(3),
  .nav__liste li:nth-child(5) { display: list-item; }

  .section--marge__grille { grid-template-columns: 20rem minmax(0, 1fr); gap: 4rem; }
  .section--marge__titre { position: sticky; top: 7rem; align-self: start; }
}

/* --------------------------------------------------------------------------
   21. ANIMATIONS AU DÉFILEMENT
   Pilotées par la timeline native du CSS : aucun JavaScript, aucun
   observateur, rien à charger. Sur un navigateur qui ne les gère pas, le
   contenu s'affiche simplement sans animation, ce qui est le comportement
   voulu.
   -------------------------------------------------------------------------- */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {

    @keyframes apparition {
      from { opacity: 0; transform: translateY(1.5rem); }
      to   { opacity: 1; transform: none; }
    }

    @keyframes trace {
      from { transform: scaleX(0); }
      to   { transform: scaleX(1); }
    }

    .manchette,
    .titre-courant,
    .prestation,
    .inclus__item,
    .tarifs tbody tr,
    .galerie__item,
    .references__item,
    .contact__actions,
    .hero__visuel {
      animation: apparition linear both;
      animation-timeline: view();
      animation-range: entry 5% cover 22%;
    }

    /* Les grands titres se dévoilent par le bas, comme une raclette qui
       découvre la vitre. Le masque est un clip-path : le texte reste
       sélectionnable et lisible par un lecteur d'écran pendant toute
       l'animation, contrairement à un découpage par opacité sur des blocs. */
    @keyframes reveler {
      from { clip-path: inset(0 0 105% 0); }
      to   { clip-path: inset(0 0 -15% 0); }
    }

    /* La révélation s'achève dès que le titre a fini d'entrer dans l'écran,
       et non après avoir défilé au-delà. Avec « cover 30% », un titre situé
       bas dans la page restait partiellement masqué faute de défilement
       restant, et se lisait comme un titre coupé. */
    .reveler {
      animation: reveler linear both;
      animation-timeline: view();
      animation-range: entry 10% entry 90%;
    }

    /* Le filet se trace au lieu d'apparaître */
    .filet {
      transform-origin: left center;
      animation: trace linear both;
      animation-timeline: view();
      animation-range: entry 20% cover 25%;
    }

    /* Le « 15 % » monte un peu plus lentement que le reste : la page gagne en
       profondeur sans qu'aucun élément ne parte en vrille. */
    .contrat__chiffre {
      animation: apparition linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 35%;
    }

  }
}

/* --------------------------------------------------------------------------
   21 bis. ENTRÉE DU HERO
   Les animations de la section 21 sont pilotées par le défilement. Or le hero
   est déjà à l'écran au chargement : sa plage de défilement est franchie
   d'emblée, donc rien n'y bouge jamais. Le premier écran — celui sur lequel
   arrive le visiteur qui scanne le QR code du flyer — était le seul de la page
   à être parfaitement immobile.

   Ces règles lui donnent une entrée unique, jouée une fois, au chargement. Le
   vocabulaire est celui du reste du site, rien n'est inventé : le même geste de
   raclette pour l'accroche, le même filet qui se trace, la même montée pour le
   reste. Seul l'ordre est nouveau, décalé de quelques centièmes de seconde d'un
   élément au suivant.

   Trois garde-fous, dans l'ordre d'importance :

   1. LA PHOTO N'EST JAMAIS ANIMÉE. C'est elle qui porte le LCP : la faire
      apparaître en fondu retarderait d'autant la mesure de performance exigée
      par docs/ACCEPTANCE.md. Seul l'aplat bleu posé derrière elle se cale, et
      il est purement décoratif.

   2. animation-fill-mode vaut « backwards » et non « both ». Avec « both »,
      l'état final resterait appliqué après coup et écraserait définitivement le
      « transform: translateY(-2px) » du survol des boutons, qui ne lèveraient
      donc plus jamais. Avec « backwards », l'élément retrouve son état normal
      dès l'animation terminée. Les images finales étant identiques à l'état
      naturel, rien ne saute à l'écran.

   3. Le bouton WhatsApp est entièrement visible à 0,95 s. Au-delà, on ferait
      patienter quelqu'un qui vient précisément pour appeler.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {

  @keyframes hero-monter {
    from { opacity: 0; transform: translateY(1.25rem); }
    to   { opacity: 1; transform: none; }
  }

  @keyframes hero-raclette {
    from { clip-path: inset(0 0 105% 0); }
    to   { clip-path: inset(0 0 -15% 0); }
  }

  @keyframes hero-tracer {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
  }

  @keyframes hero-caler {
    from { transform: scaleY(0); }
    to   { transform: scaleY(1); }
  }

  /* « animation-timeline: auto » neutralise la timeline de défilement héritée
     de la section 21 : dans le hero, ces deux éléments se jouent sur une durée,
     pas sur une position de défilement. */
  .hero .reveler {
    animation: hero-raclette .7s cubic-bezier(.2, .7, .3, 1) backwards;
    animation-timeline: auto;
    animation-range: normal;
  }

  .hero .filet {
    transform-origin: left center;
    animation: hero-tracer .5s cubic-bezier(.2, .7, .3, 1) .28s backwards;
    animation-timeline: auto;
    animation-range: normal;
  }

  .hero__metier {
    animation: hero-monter .5s cubic-bezier(.2, .7, .3, 1) .18s backwards;
  }

  .hero__intro {
    animation: hero-monter .5s cubic-bezier(.2, .7, .3, 1) .34s backwards;
  }

  .hero__actions .bouton:nth-child(1) {
    animation: hero-monter .45s cubic-bezier(.2, .7, .3, 1) .48s backwards;
  }

  .hero__actions .bouton:nth-child(2) {
    animation: hero-monter .45s cubic-bezier(.2, .7, .3, 1) .56s backwards;
  }

  /* L'aplat bleu se cale derrière la photo, du bas vers le haut, pendant que
     l'accroche se dévoile. La photo, elle, est déjà là. */
  .hero__visuel::before {
    transform-origin: bottom;
    animation: hero-caler .7s cubic-bezier(.2, .7, .3, 1) .15s backwards;
  }

}

/* Respect systématique de la préférence système */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* --------------------------------------------------------------------------
   22. IMPRESSION
   -------------------------------------------------------------------------- */
@media print {
  .barre-fixe, .entete__action, .nav, .saut-contenu { display: none !important; }
  body { padding-bottom: 0; background: #fff; color: #000; }
  .bloc--fonce, .bloc--accent { background: #fff !important; color: #000 !important; }
  .bloc--grain::before { display: none !important; }
  .bloc--fonce .titre-section, .bloc--fonce .titre-courant,
  .manchette--claire, .tarifs__nom, .tarifs__prix { color: #000 !important; }
}
