/* ==========================================================================
   Dévams, accueil, variante A « CLAIR & NET », structure A2
   Mobile-first. Unités relatives uniquement (rem / em / clamp / %).
   Organisation : variables > reset > utilitaires > composants > sections
   ========================================================================== */


/* ==========================================================================
   1. VARIABLES : palette dérivée du logo
   ========================================================================== */

:root {

  /* --- Couleurs de marque --- */
  --marine-profond: #0A1F3D;
  --bleu-principal: #002D50;
  --bleu-moyen:     #3C6783;
  --bleu-clair:     #5DA8D3;   /* décoratif uniquement : 2,6:1 sur blanc, jamais pour du texte */
  --bleu-fond:      #EAF3F8;
  --blanc-casse:    #FCFDFE;

  /* --- Texte --- */
  --texte:      #1A2332;
  --texte-2:    #5A6472;       /* 6:1 sur blanc cassé, 5,3:1 sur bleu très clair : AA OK */
  --texte-clair:#EAF3F8;

  /* --- Traits et surfaces --- */
  --bordure:      #D5E3ED;
  --bordure-forte:#B9D2E2;
  --surface:      #FFFFFF;

  /* --- Dégradé du logo, calibré pour l'accessibilité ---
     Le logo va de #002D50 à #5DA8D3. Du blanc sur #5DA8D3 ne donne que 2,6:1.
     On arrête donc le dégradé des boutons à #3C6783 (6,07:1 avec du blanc) :
     l'esprit du dégradé est conservé, le contraste AA aussi. */
  --degrade: linear-gradient(135deg, #002D50 0%, #14456B 48%, #3C6783 100%);
  --degrade-hover: linear-gradient(135deg, #001E36 0%, #0E3452 48%, #2E5670 100%);

  /* --- Typographie --- */
  --font-titres: "Outfit", "Segoe UI", system-ui, sans-serif;
  --font-corps:  "Inter", "Segoe UI", system-ui, sans-serif;

  /* --- Rythme vertical (variante « beaucoup d'air ») --- */
  --section-y: clamp(4rem, 9vw, 7.5rem);

  /* Hauteur des vagues de raccord, et hauteur de bande sombre qu'elles
     mangent. Les vagues sont peintes DANS le bas de la section, remplies de la
     couleur de la section SUIVANTE : la bande sombre perçue s'arrête donc plus
     haut que la boîte. Mesuré au pixel sur quatre largeurs, la part opaque en
     mange 55 % (45 px sur 80 en grand écran). Les deux valeurs vivent ici pour
     que le rembourrage corrigé ne puisse pas diverger de la hauteur réelle des
     vagues. Voir .section--sombre:has(.vagues). */
  --vagues-hauteur: clamp(3rem, 7vw, 5rem);
  --vagues-mangee: calc(var(--vagues-hauteur) * 0.55);
  --gouttiere: clamp(1.25rem, 4vw, 2.5rem);
  --largeur-max: 75rem;

  /* --- Divers --- */
  --rayon:      0.75rem;
  --rayon-lg:   1.25rem;
  --focus:      var(--bleu-principal);
  --transition: 180ms ease;

  /* Hauteur du header collant. Valeur de repli ici, valeur réelle mesurée et
     réécrite par js/main.js. Sert au scroll-padding des ancres, au sticky de
     l'en-tête du tableau tarifaire et au masquage du header au scroll. */
  --header-hauteur: 4.5rem;

  /* --- Animations (sobres : durées courtes, aucune emphase) --- */
  --anim-hover:  200ms ease;
  --anim-entree: 480ms cubic-bezier(0.22, 0.61, 0.36, 1);
  --ombre-carte: 0 0.5rem 1.5rem -0.75rem rgba(10, 31, 61, 0.22);
  --survol-ligne:       #F2F8FC;   /* survol d'une ligne du tableau */
  --survol-ligne-phare: #DCEAF3;   /* idem, colonne mise en avant */

  /* --- Erreurs de formulaire ---
     #B3261E donne 6,1:1 sur blanc : lisible en AA pour du texte normal.
     La couleur n'est jamais le seul porteur de l'information (message en
     texte + aria-invalid), conformément à WCAG 1.4.1. */
  --erreur:       #B3261E;
  --erreur-fond:  #FDF3F2;
}


/* ==========================================================================
   2. RESET / BASES
   ========================================================================== */

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

html {
  /* Pas de font-size en px : on reste sur la taille choisie par l'utilisateur */
  scroll-behavior: smooth;
  /* Compense le header collant lors des ancres. Même source de vérité que le
     sticky du tableau : une seule variable pour les deux. */
  scroll-padding-top: calc(var(--header-hauteur) + 1rem);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--font-corps);
  font-size: 1rem;
  line-height: 1.65;
  color: var(--texte);
  background-color: var(--blanc-casse);
}

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

h1, h2, h3, h4 {
  font-family: var(--font-titres);
  color: var(--bleu-principal);
  line-height: 1.18;
  letter-spacing: -0.015em;
  margin: 0 0 0.6em;
  text-wrap: balance;
}

h1 { font-size: clamp(1.875rem, 4.4vw, 3rem); font-weight: 700; }
h2 { font-size: clamp(1.6rem, 3.6vw, 2.4rem);  font-weight: 700; }
h3 { font-size: clamp(1.125rem, 1.9vw, 1.3rem); font-weight: 600; }
h4 { font-size: 1rem; font-weight: 600; letter-spacing: -0.01em; }

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--bleu-principal); text-decoration-thickness: 0.08em; text-underline-offset: 0.2em; }
a:hover { color: var(--bleu-moyen); }

ul { margin: 0; padding: 0; list-style: none; }
ol { margin: 0; padding: 0; }

/* --- Focus visible : jamais supprimé, toujours 3px + décalage --- */
:focus-visible {
  outline: 0.1875rem solid var(--focus);
  outline-offset: 0.1875rem;
  border-radius: 0.25rem;
}

/* Lien d'évitement */
.skip-link {
  position: absolute;
  left: 0.75rem;
  top: -6rem;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--bleu-principal);
  color: #fff;
  font-weight: 600;
  text-decoration: none;
  border-radius: 0 0 var(--rayon) var(--rayon);
  transition: top var(--transition);
}
.skip-link:focus-visible { top: 0; color: #fff; outline-color: var(--bleu-clair); }

/* Contenu réservé aux technologies d'assistance */
.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;
}


/* ==========================================================================
   3. UTILITAIRES DE MISE EN PAGE
   ========================================================================== */

.container {
  width: min(100% - 2.5rem, var(--largeur-max));
  margin-inline: auto;
}
.container--etroit { width: min(100% - 2.5rem, 48rem); }

.section { padding-block: var(--section-y); }

/* Alternance des fonds */
.section--clair { background-color: var(--blanc-casse); }
.section--bleu  { background-color: var(--bleu-fond); }

/* --- Section sombre : la respiration du site ------------------------------
   Bande en dégradé marine, à réserver au MOMENT LE PLUS FORT d'une page.
   Règle d'usage : UNE SEULE par page, jamais deux. C'est un accent, et un
   accent qu'on répète n'accentue plus rien.
   Toutes les couleurs de texte sont réécrites ici pour que n'importe quel
   composant posé dedans reste lisible sans réglage supplémentaire.
   -------------------------------------------------------------------------- */
.section--sombre {
  position: relative;
  background-image: linear-gradient(135deg, #002D50 0%, #0A1F3D 100%);
  color: var(--texte-clair);
  overflow: hidden;
}
/* La classe est volontairement DOUBLÉE sur les règles de couleur.
   Sans ça, une règle de composant comme « .bandeau-passerelle p { color:
   var(--texte-2) } » a la même spécificité (0,1,1) et l'emporte simplement
   parce qu'elle est déclarée plus bas dans la feuille : on se retrouve avec
   du gris foncé sur du marine, mesuré à 2,35:1. Le doublement porte la
   spécificité à (0,2,1) et garantit la lisibilité quel que soit le composant
   posé dans la section, y compris ceux qui seront écrits plus tard. */
.section--sombre.section--sombre h1,
.section--sombre.section--sombre h2,
.section--sombre.section--sombre h3,
.section--sombre.section--sombre h4 { color: #fff; }
.section--sombre.section--sombre p,
.section--sombre.section--sombre li,
.section--sombre.section--sombre dd,
.section--sombre.section--sombre strong { color: var(--texte-clair); }
.section--sombre.section--sombre .eyebrow { color: var(--bleu-clair); }
.section--sombre .eyebrow::before {
  border-top-color: var(--bleu-clair);
  border-right-color: var(--bleu-clair);
}
.section--sombre.section--sombre a { color: #fff; }
.section--sombre :focus-visible { outline-color: var(--bleu-clair); }

/* Le contenu passe au-dessus des vagues décoratives */
.section--sombre > .container { position: relative; z-index: 1; }

/* Le lien à chevron reste lisible sur fond sombre */
.section--sombre .lien-fleche {
  color: #fff;
  border-bottom-color: rgba(234, 243, 248, 0.45);
}
.section--sombre .lien-fleche:hover { border-bottom-color: #fff; }

/* Un bouton fantôme sur fond sombre doit s'éclaircir, pas disparaître */
.section--sombre .btn--fantome {
  border-color: rgba(234, 243, 248, 0.55);
  color: #fff;
}
.section--sombre .btn--fantome:hover {
  border-color: #fff;
  background-color: rgba(255, 255, 255, 0.08);
}

/* Les blocs encadrés posés dans une section sombre perdent leur fond blanc :
   sur un fond marine, une carte claire ferait un pavé lourd. Le filet
   d'accent, lui, est conservé, c'est ce qui les identifie. */
.section--sombre .bandeau-or,
.section--sombre .bandeau-agence,
.section--sombre .bandeau-passerelle {
  background-color: transparent;
  border-color: rgba(234, 243, 248, 0.28);
  color: #fff;
}
.section--sombre .bandeau-or { border-left-color: var(--bleu-clair); }
.section--sombre .bandeau-agence { border-left-color: var(--bleu-clair); }
.section--sombre .bandeau-or::before {
  border-top-color: var(--bleu-clair);
  border-right-color: var(--bleu-clair);
}
.section--sombre .bandeau-passerelle strong { color: #fff; }

/* --- Vagues de raccord ----------------------------------------------------
   Elles portent la couleur de la section SUIVANTE : elles découpent le bas
   du bloc sombre au lieu de s'y ajouter. D'où le modificateur, à accorder
   avec le fond de la section qui suit.
   -------------------------------------------------------------------------- */
.vagues {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -0.0625rem;   /* évite un liseré d'un pixel au raccord */
  width: 100%;
  height: var(--vagues-hauteur);
  pointer-events: none;
}

/* Rattrapage du centre optique.

   Les vagues mangent le bas de la bande sombre (voir --vagues-mangee). Avec un
   rembourrage symétrique, le contenu tombe donc SOUS le centre de la zone
   sombre réellement visible : 20 px trop bas en grand écran, 13 px en mobile,
   mesurés au pixel.

   La correction vaut DEUX fois le décalage, et c'est contre-intuitif : en
   retirant du rembourrage haut, le contenu remonte, mais la section raccourcit
   d'autant, donc le centre optique remonte lui aussi, de la moitié. Retirer
   une fois le décalage n'en corrigerait que la moitié.

   Le :has() énonce la vraie condition plutôt que de supposer que toute section
   sombre porte des vagues. Là où il n'est pas reconnu, la règle entière est
   ignorée et on retombe sur le rembourrage symétrique : dégradation sans
   casse.

   --sombre-bas existe parce que le calcul se fait sur le rembourrage BAS, et
   que celui-ci n'est pas toujours --section-y. La section « Ce que je ne vous
   promets pas » de la page À propos a un bas volontairement plus généreux
   (80 px au lieu de 64 en mobile) : en prenant --section-y comme référence, la
   correction se calculait sur la mauvaise valeur et remontait le contenu 9 px
   TROP haut. Une section au rembourrage particulier pose donc la variable, et
   son haut s'en déduit. */
.section--sombre:has(.vagues) {
  padding-top: calc(var(--sombre-bas, var(--section-y)) - var(--vagues-mangee));
  padding-bottom: var(--sombre-bas, var(--section-y));
}
.vagues__forme { fill: var(--blanc-casse); }
.vagues__forme--arriere { fill: var(--blanc-casse); opacity: 0.35; }

.vagues--vers-bleu .vagues__forme,
.vagues--vers-bleu .vagues__forme--arriere { fill: var(--bleu-fond); }

/* Intro de section : surtitre + H2 + chapô */
.section__intro {
  max-width: 44rem;
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
.section__intro--large { max-width: 54rem; }

.section__chapo {
  font-size: 1.0625rem;
  color: var(--texte-2);
  max-width: 38rem;
}
.section__chapo--large { max-width: 46rem; }

/* Variante centrée (avis, périmètre sans comparaison...) */
.section__intro--centre { margin-inline: auto; text-align: center; }
.section__intro--centre .eyebrow { justify-content: center; }
.section__intro--centre .section__chapo { margin-inline: auto; }

/* Surtitre : reprise discrète du chevron du logo.
   Alignement : le chevron est un carré pivoté de 45deg, donc son centre visuel
   est exactement le centre de sa boîte. On le cale sur le centre de la PREMIÈRE
   ligne de texte (et non sur le bloc entier, pour rester juste quand le
   surtitre passe sur deux lignes en petit écran) :
   marge haute = (hauteur de ligne - hauteur du chevron) / 2. */
.eyebrow {
  display: flex;
  align-items: flex-start;
  gap: 0.6em;
  margin: 0 0 0.9em;
  font-family: var(--font-titres);
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--bleu-moyen);
}
.eyebrow::before {
  content: "";
  flex: none;
  width: 0.5em;
  height: 0.5em;
  margin-top: calc((1.5em - 0.5em) / 2);
  border-top: 0.15em solid var(--bleu-clair);
  border-right: 0.15em solid var(--bleu-clair);
  transform: rotate(45deg);
}

/* Empêche la coupure d'un mot en fin de ligne. Les mots à trait d'union
   comme « e-commerce » se cassent sur le tiret dans une colonne étroite :
   on lit « e- » puis « commerce » à la ligne suivante. */
.insecable { white-space: nowrap; }


/* ==========================================================================
   4. BOUTONS ET LIENS D'ACTION
   ========================================================================== */

.btn {
  display: inline-block;
  padding: 0.85em 1.6em;
  font-family: var(--font-titres);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
  border: 0.125rem solid transparent;
  border-radius: var(--rayon);
  cursor: pointer;
  transition: background var(--anim-hover), transform var(--anim-hover),
              border-color var(--anim-hover), box-shadow var(--anim-hover);
}
/* Retour au clic commun à tous les boutons : léger enfoncement, jamais plus */
.btn:active { transform: translateY(0) scale(0.98); }

/* CTA principal : seul usage du dégradé du logo */
.btn--primary {
  background-image: var(--degrade);
  color: #fff;
}
.btn--primary:hover {
  background-image: var(--degrade-hover);
  color: #fff;
  transform: translateY(-0.125rem);
  box-shadow: var(--ombre-carte);
}
.btn--primary:active { box-shadow: none; }
.btn--primary:focus-visible { outline-color: var(--bleu-principal); }

/* CTA secondaire : bordure fine, pas d'ombre */
.btn--fantome {
  background-color: transparent;
  border-color: var(--bordure-forte);
  color: var(--bleu-principal);
}
.btn--fantome:hover { border-color: var(--bleu-moyen); background-color: #fff; }

.btn--lg { padding: 1.05em 2.1em; font-size: 1.0625rem; }
.btn--sm { padding: 0.65em 1.15em; font-size: 0.9375rem; }

/* Lien de section avec chevron (géométrie du logo) */
.lien-fleche {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-titres);
  font-weight: 600;
  color: var(--bleu-principal);
  text-decoration: none;
  border-bottom: 0.125rem solid var(--bordure-forte);
  padding-bottom: 0.15em;
}
.lien-fleche::after {
  content: "";
  width: 0.45em;
  height: 0.45em;
  border-top: 0.15em solid currentColor;
  border-right: 0.15em solid currentColor;
  transform: rotate(45deg);
  transition: transform var(--transition);
}
.lien-fleche:hover { border-bottom-color: var(--bleu-moyen); }
.lien-fleche:hover::after { transform: rotate(45deg) translate(0.15em, -0.15em); }

.lien-section { margin-top: 2.5rem; text-align: center; }
.lien-section--gauche { margin-top: 2rem; text-align: left; }


/* ==========================================================================
   5. HEADER + NAVIGATION
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background-color: rgba(252, 253, 254, 0.94);
  backdrop-filter: blur(0.5rem);
  border-bottom: 0.0625rem solid var(--bordure);
  transition: transform 260ms ease, box-shadow var(--anim-hover);
}

/* Masquage au défilement vers le bas, piloté par js/main.js.
   La classe n'est jamais posée en haut de page, ni menu mobile ouvert, ni en
   mouvement réduit : sans JS, le header reste simplement collant. */
.site-header.est-masque { transform: translateY(-100%); }

/* Légère ombre dès qu'on a quitté le haut de page : détache le header du contenu */
.site-header.est-detache { box-shadow: 0 0.25rem 1rem -0.5rem rgba(10, 31, 61, 0.25); }

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 4.5rem;
  padding-block: 0.75rem;
}

.site-header__logo { display: inline-flex; }
.site-header__logo img { width: clamp(8.75rem, 18vw, 12.5rem); height: auto; }

/* --- Bouton menu mobile --- */
.nav-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.55em 0.9em;
  font-family: var(--font-titres);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--bleu-principal);
  background: transparent;
  border: 0.0625rem solid var(--bordure-forte);
  border-radius: var(--rayon);
  cursor: pointer;
  transition: background-color var(--anim-hover), border-color var(--anim-hover), transform var(--anim-hover);
}
.nav-toggle:hover { border-color: var(--bleu-moyen); background-color: var(--surface); }
.nav-toggle:active { transform: scale(0.97); }
.nav-toggle__bars {
  position: relative;
  display: block;
  width: 1.125em;
  height: 0.125em;
  background: currentColor;
}
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  height: 0.125em;
  background: currentColor;
  transition: transform var(--transition), opacity var(--transition);
}
.nav-toggle__bars::before { top: -0.375em; }
.nav-toggle__bars::after  { top:  0.375em; }

/* État ouvert : la barre centrale disparaît, les deux autres forment une croix */
.nav-toggle[aria-expanded="true"] .nav-toggle__bars { background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before { transform: translateY(0.375em) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after  { transform: translateY(-0.375em) rotate(-45deg); }

/* --- Navigation : repliée en mobile, dépliée dès 62em --- */
.nav {
  display: none;
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  padding: 1.25rem;
  background-color: var(--blanc-casse);
  border-bottom: 0.0625rem solid var(--bordure);
}
.nav.est-ouvert { display: block; }

.nav__list { display: flex; flex-direction: column; gap: 0.25rem; }
.nav__list a {
  display: block;
  padding: 0.7em 0.4em;
  font-family: var(--font-titres);
  font-weight: 500;
  color: var(--texte);
  text-decoration: none;
  border-bottom: 0.0625rem solid var(--bordure);
  transition: color var(--anim-hover), border-color var(--anim-hover), background-color var(--anim-hover);
}
.nav__list a:hover { color: var(--bleu-principal); }
.nav__list a:active { color: var(--bleu-moyen); }

.nav__cta { display: block; margin-top: 1.1rem; }

@media (min-width: 62em) {
  .nav-toggle { display: none; }

  .nav,
  .nav.est-ouvert {
    display: flex;
    align-items: center;
    gap: 1.75rem;
    position: static;
    padding: 0;
    background: none;
    border: 0;
  }
  .nav__list { flex-direction: row; gap: 1.5rem; }
  .nav__list a {
    padding: 0.25em 0;
    border-bottom: 0.125rem solid transparent;
    font-size: 0.9375rem;
  }
  .nav__list a:hover { border-bottom-color: var(--bleu-clair); }
  .nav__cta { margin-top: 0; }
}


/* ==========================================================================
   6. HERO : split asymétrique (~55/45), texte à gauche, portrait à droite
   ========================================================================== */

.hero { padding-block: clamp(3rem, 7vw, 5.5rem) var(--section-y); }

.hero__grid {
  display: grid;
  gap: clamp(2.5rem, 6vw, 4.5rem);
  align-items: center;
}

@media (min-width: 60em) {
  .hero__grid { grid-template-columns: 1.2fr 1fr; }
}

.hero__sous-titre {
  font-size: clamp(1.0625rem, 1.6vw, 1.1875rem);
  color: var(--texte-2);
  max-width: 34rem;
}

.hero__action { margin: 2rem 0 0; }

/* Bande de preuves : chiffres en dur, séparés par des chevrons décoratifs */
.preuves {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* Mobile : bande centrée sous le CTA (demande client). L'alignement à gauche
     reprend dès que les trois preuves tiennent sur une seule ligne. */
  justify-content: center;
  text-align: center;
  gap: 0.75rem 1.5rem;
  margin-top: 2.75rem;
  padding-top: 1.75rem;
  border-top: 0.0625rem solid var(--bordure);
  font-size: 0.9375rem;
  color: var(--texte-2);
}
.preuves strong {
  display: block;
  font-family: var(--font-titres);
  font-size: 1.375rem;
  font-weight: 700;
  color: var(--bleu-principal);
  line-height: 1.2;
}
.preuves li { position: relative; }

/* Séparateurs en chevrons seulement quand les trois preuves tiennent sur une ligne */
@media (min-width: 34em) {
  .preuves {
    justify-content: flex-start;
    text-align: left;
  }
  .preuves li + li { padding-left: 1.5rem; }
  .preuves li + li::before {
    content: "";
    position: absolute;
    left: 0;
    /* Centrage vertical réel sur la preuve (chiffre + libellé), au lieu d'un
       décalage fixe en em qui le faisait remonter au-dessus du texte. */
    top: 50%;
    width: 0.35em;
    height: 0.35em;
    border-top: 0.12em solid var(--bleu-clair);
    border-right: 0.12em solid var(--bleu-clair);
    transform: translateY(-50%) rotate(45deg);
  }
}

/* Portrait : médaillon à angles doux, encoche géométrique en angle */
.hero__photo-cadre {
  position: relative;
  margin: 0;
  max-width: 26rem;
  margin-inline: auto;
}
.hero__photo-cadre::before {
  /* Petite décoration d'angle, esprit chevron du logo */
  content: "";
  position: absolute;
  right: -0.75rem;
  top: -0.75rem;
  width: 3.75rem;
  height: 3.75rem;
  border-top: 0.1875rem solid var(--bleu-clair);
  border-right: 0.1875rem solid var(--bleu-clair);
  border-radius: 0 var(--rayon-lg) 0 0;
}
.hero__photo {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--rayon-lg);
  border: 0.0625rem solid var(--bordure);
  background-color: var(--bleu-fond);
}
.hero__legende {
  margin-top: 0.9rem;
  font-size: 0.875rem;
  color: var(--texte-2);
  text-align: center;
}


/* ==========================================================================
   7. SÉLECTEUR DE SITUATION : accordéon natif, transformé en onglets par le
   JS (desktop uniquement). Aucun contenu n'existe uniquement via le JS.
   ========================================================================== */

.selecteur {
  counter-reset: chemin;
}

.chemin {
  counter-increment: chemin;
  background-color: var(--surface);
  border: 0.0625rem solid var(--bordure);
  border-radius: var(--rayon);
  margin-bottom: 1rem;
  transition: border-color var(--anim-hover), box-shadow var(--anim-hover);
}
.chemin:last-child { margin-bottom: 0; }
.chemin:hover { border-color: var(--bordure-forte); box-shadow: var(--ombre-carte); }
/* En mode onglets les cartes n'ont plus de bordure propre : pas d'ombre non plus */
.selecteur--onglets .chemin:hover { box-shadow: none; }

.chemin__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
  padding: 1.25rem clamp(1.25rem, 3vw, 1.75rem);
  cursor: pointer;
  list-style: none;
}
.chemin__summary::-webkit-details-marker { display: none; }
/* Une fois remplacé par l'onglet généré en JS, le résumé natif est masqué :
   la règle [hidden] doit l'emporter sur le display:flex ci-dessus. */
.chemin__summary[hidden] { display: none; }

/* Numérotation décorative (01, 02, 03), non lue comme contenu essentiel */
.chemin__summary::before {
  content: counter(chemin, decimal-leading-zero);
  flex: none;
  font-family: var(--font-titres);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--bleu-clair);
  margin-right: -0.5rem;
}

.chemin__question {
  flex: 1 1 auto;
  margin: 0;
  font-family: var(--font-titres);
  font-size: clamp(1.0625rem, 2vw, 1.25rem);
  font-weight: 600;
  color: var(--bleu-principal);
}

.chemin__chevron {
  flex: none;
  width: 0.6em;
  height: 0.6em;
  border-bottom: 0.15em solid var(--bleu-moyen);
  border-right: 0.15em solid var(--bleu-moyen);
  transform: rotate(45deg);
  transition: transform var(--transition);
}
.chemin[open] .chemin__chevron { transform: rotate(-135deg); }

.chemin__contenu {
  padding: 0 clamp(1.25rem, 3vw, 1.75rem) clamp(1.5rem, 3vw, 2rem);
  border-top: 0.0625rem solid var(--bordure);
  padding-top: clamp(1.25rem, 3vw, 1.75rem);
}

.chemin__temps { margin-bottom: 1.25rem; }
.chemin__temps h4 { color: var(--bleu-moyen); margin-bottom: 0.3em; }
.chemin__temps p { color: var(--texte-2); margin: 0; }

.chemin__avis {
  margin: 1.5rem 0;
  padding: 1.1rem 1.25rem;
  background-color: var(--bleu-fond);
  border-left: 0.25rem solid var(--bleu-clair);
  border-radius: 0 var(--rayon) var(--rayon) 0;
}
.chemin__avis p {
  margin: 0 0 0.5em;
  font-size: 0.9375rem;
  font-style: italic;
  color: var(--texte);
}
.chemin__avis footer {
  font-size: 0.8125rem;
  color: var(--texte-2);
}
.chemin__avis cite { font-style: normal; font-weight: 600; color: var(--bleu-principal); }
.chemin__avis-source {
  margin-left: 0.4em;
  padding: 0.1em 0.5em;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--bleu-moyen);
  background-color: var(--surface);
  border-radius: 0.25rem;
}

.chemin__action { margin: 1.5rem 0 0; }

/* --- Amélioration JS (desktop uniquement) : accordéon → onglets --- */
.selecteur--onglets {
  border: 0.0625rem solid var(--bordure);
  border-radius: var(--rayon-lg);
  overflow: hidden;
  background-color: var(--surface);
}
.selecteur--onglets .chemin {
  margin-bottom: 0;
  border: 0;
  border-radius: 0;
  border-top: 0.0625rem solid var(--bordure);
}
.selecteur--onglets .chemin:first-of-type { border-top: 0; }

.selecteur__tablist {
  display: flex;
}
.selecteur__tab {
  flex: 1 1 0;
  padding: 1.1rem 1.25rem;
  font-family: var(--font-titres);
  font-size: 1rem;
  font-weight: 600;
  text-align: left;
  color: var(--texte-2);
  background-color: var(--bleu-fond);
  border: 0;
  border-bottom: 0.1875rem solid transparent;
  cursor: pointer;
  transition: background-color var(--transition), color var(--transition), border-color var(--transition);
}
.selecteur__tab:hover { color: var(--bleu-principal); background-color: var(--surface); }
/* Retour au clic sur l'onglet : fond plus soutenu, pas de déplacement */
.selecteur__tab:active { background-color: var(--bordure); }
.selecteur__tab[aria-selected="true"] {
  color: var(--bleu-principal);
  background-color: var(--surface);
  border-bottom-color: var(--bleu-principal);
}

.selecteur--onglets .chemin__contenu {
  border-top: 0;
  padding-top: clamp(1.5rem, 3vw, 2rem);
}


/* ==========================================================================
   8. FRISE « UN MOIS AVEC MOI » : chronologie, pas une grille de cartes
   ========================================================================== */

/* La piste de la frise est portée par le CONTENEUR, pas par chaque élément.
   Avec une bordure par élément, la ligne se découpait en segments séparés par
   les gouttières de la grille : ça ne lisait pas comme une frise.
   Deux pseudo-éléments : ::before = la piste grise, ::after = le remplissage
   bleu, dont la longueur suit --frise-progression (0 à 1), publiée par le JS
   pendant le défilement. */
.frise {
  position: relative;
  list-style: none;
  display: grid;
  gap: 0;
  /* Sans JS : la frise est entièrement remplie. L'état « vide » n'existe que
     sous .js-anim, comme pour les animations d'entrée de section. */
  --frise-progression: 1;
}
.js-anim .frise { --frise-progression: 0; }

.frise::before,
.frise::after {
  content: "";
  position: absolute;
  border-radius: 999px;
  pointer-events: none;
}
.frise::before {
  left: 0;
  top: 0;
  bottom: 0;
  width: 0.1875rem;
  background-color: var(--bordure-forte);
}
.frise::after {
  left: 0;
  top: 0;
  width: 0.1875rem;
  height: calc(var(--frise-progression) * 100%);
  background-color: var(--bleu-principal);
  transition: height 120ms linear;
}

.frise__item {
  position: relative;
  padding: 0 0 clamp(1.75rem, 4vw, 2.25rem) clamp(1.75rem, 4vw, 2.25rem);
}
.frise__item:last-child { padding-bottom: 0; }

.frise__item::before {
  content: "";
  position: absolute;
  left: -0.5625rem;
  /* Centré sur la ligne du libellé (1.0625rem x 1.35 de hauteur de ligne),
     et non calé sur son sommet : le repère ne remonte plus au-dessus du texte. */
  top: 0.4rem;
  width: 0.875rem;
  height: 0.875rem;
  /* Sans JS, tous les repères sont allumés (cohérent avec la piste pleine). */
  background-color: var(--bleu-principal);
  border: 0.1875rem solid var(--bleu-principal);
  border-radius: 50%;
  transition: background-color 180ms ease, transform 180ms ease;
}
/* Avec JS, les repères s'allument au passage du remplissage. */
.js-anim .frise__item::before { background-color: var(--surface); }
.js-anim .frise__item.est-atteint::before {
  background-color: var(--bleu-principal);
  transform: scale(1.15);
}

.frise__moment {
  margin: 0 0 0.3em;
  font-family: var(--font-titres);
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.35;
  color: var(--bleu-principal);
}
.frise__texte { margin: 0; color: var(--texte-2); max-width: 34rem; }

/* Desktop : bascule en frise horizontale */
@media (min-width: 64em) {
  .frise {
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: clamp(1rem, 2.5vw, 1.75rem);
  }
  /* La piste bascule à l'horizontale : elle se remplit de la gauche vers la
     droite à mesure qu'on descend dans la page. */
  .frise::before,
  .frise::after {
    top: 0;
    bottom: auto;
    left: 0;
    height: 0.1875rem;
  }
  .frise::before { width: 100%; }
  .frise::after {
    width: calc(var(--frise-progression) * 100%);
    height: 0.1875rem;
    transition: width 120ms linear;
  }
  .frise__item {
    padding: clamp(1.75rem, 3vw, 2.25rem) clamp(0.75rem, 1.5vw, 1.25rem) 0 0;
  }
  .frise__item::before {
    left: -0.1rem;
    top: -0.5625rem;
  }
  .frise__texte { max-width: none; }

  /* Variante verticale forcée : utilisée quand le contenu de chaque repère
     est trop long pour tenir en colonne étroite (page Maintenance, où le
     process est détaillé outil par outil). On annule tout le bloc horizontal
     ci-dessus en réaffirmant les valeurs du mobile.
     Le JS s'adapte tout seul : il déduit l'orientation de la position des
     éléments entre eux, pas d'un point de rupture. */
  .frise--verticale {
    grid-auto-flow: row;
    grid-auto-columns: auto;
    gap: 0;
  }
  .frise--verticale::before,
  .frise--verticale::after {
    top: 0;
    left: 0;
    width: 0.1875rem;
    height: auto;
  }
  .frise--verticale::before { bottom: 0; }
  .frise--verticale::after {
    bottom: auto;
    width: 0.1875rem;
    height: calc(var(--frise-progression) * 100%);
    transition: height 120ms linear;
  }
  .frise--verticale .frise__item {
    padding: 0 0 clamp(1.75rem, 4vw, 2.25rem) clamp(1.75rem, 4vw, 2.25rem);
  }
  .frise--verticale .frise__item:last-child { padding-bottom: 0; }
  .frise--verticale .frise__item::before {
    left: -0.5625rem;
    top: 0.4rem;
  }
  .frise--verticale .frise__texte { max-width: 42rem; }
}


/* ==========================================================================
   9. TABLEAU TARIFAIRE COMPLET
   ========================================================================== */

.table-scroll {
  /* Défilement sur les DEUX axes à l'intérieur du conteneur.
     C'est la condition pour que l'en-tête (position: sticky; top: 0) ait un
     scrollport auquel s'accrocher : un conteneur en overflow-x seul voit son
     overflow-y forcé à auto par la spec, mais sans hauteur contrainte rien ne
     défile jamais dedans et le sticky vertical reste inerte.
     La hauteur maxi se cale sur la hauteur réelle du header (variable publiée
     par js/main.js), pour que le tableau ne passe jamais dessous. */
  overflow: auto;
  /* Hauteur contrainte UNIQUEMENT en petit écran. C'est là que le scroll
     horizontal a lieu et que l'en-tête figé sert vraiment. Sur desktop, le
     tableau tient dans la page et une zone de défilement imbriquée serait
     contre-nature : il s'y déroule donc normalement (arbitrage de Rémy). */
  max-height: calc(100vh - var(--header-hauteur) - 4rem);
  -webkit-overflow-scrolling: touch;
  /* Le balayage horizontal ne déclenche pas le retour arrière du navigateur.
     Le débordement vertical, lui, reprend le défilement de la page. */
  overscroll-behavior-x: contain;
  /* Empêche tout débordement du tableau de remonter dans la largeur de la
     page (le conteneur doit rester seul responsable de son propre scroll).
     contain: layout ne fait pas de containment de peinture : les cellules
     sticky restent parfaitement fonctionnelles. */
  contain: layout;
  border: 0.0625rem solid var(--bordure);
  border-radius: var(--rayon-lg);
  background-color: var(--surface);
}
.table-scroll:focus-visible { outline-offset: -0.1875rem; }

.table-tarifs {
  width: 100%;
  /* Largeur mini réduite en petit écran : une fois la colonne des libellés
     figée, il reste assez de place pour lire une colonne de prix entière. */
  min-width: 40rem;
  /* separate (et non collapse) : avec border-collapse, les bordures sont
     peintes par le tableau et non par les cellules, elles disparaissent donc
     sous les cellules sticky. C'est le piège classique de ce composant. */
  border-collapse: separate;
  border-spacing: 0;
}
@media (min-width: 48em) {
  .table-tarifs { min-width: 46rem; }
}

/* Sur grand écran, le tableau reprend son déroulement normal dans la page :
   plus de zone de défilement imbriquée, donc plus d'en-tête figé vertical.
   La colonne des libellés reste figée si un défilement horizontal survient. */
@media (min-width: 64em) {
  .table-scroll {
    max-height: none;
    overflow-y: visible;
  }
}

.table-tarifs caption {
  padding: 1.25rem clamp(1.25rem, 3vw, 1.75rem) 0.5rem;
  text-align: left;
  font-size: 0.875rem;
  color: var(--texte-2);
}

.table-tarifs th,
.table-tarifs td {
  padding: 0.9rem clamp(1rem, 2vw, 1.5rem);
  text-align: left;
  font-size: 0.9375rem;
  border-top: 0.0625rem solid var(--bordure);
  vertical-align: top;
}

.table-tarifs thead th {
  border-top: 0;
  border-bottom: 0.125rem solid var(--bordure-forte);
  vertical-align: bottom;
  padding-top: 1.5rem;
}

.table-tarifs tbody th {
  font-family: var(--font-titres);
  font-weight: 600;
  color: var(--bleu-principal);
  white-space: normal;
}

/* --- En-têtes figés -------------------------------------------------------
   Colonne des libellés figée à gauche pendant le défilement horizontal,
   ligne d'en-tête figée en haut pendant le défilement vertical.
   Points de vigilance traités ici :
   1. fond opaque obligatoire, sinon le contenu défile visiblement dessous ;
   2. empilement croissant : corps < colonne figée < en-tête < cellule d'angle ;
   3. aucun parent en overflow: hidden entre la cellule et .table-scroll ;
   4. border-collapse: separate (voir plus haut) pour garder les filets.
   -------------------------------------------------------------------------- */

/* Première colonne : les libellés de ligne restent lisibles en permanence */
.table-tarifs tbody th[scope="row"],
.table-tarifs thead th:first-child {
  position: sticky;
  left: 0;
  z-index: 2;
  width: 10rem;
  background-color: var(--surface);
  /* Filet net + ombre courte : la colonne figée se détache des colonnes
     qui défilent dessous, sans se transformer en bloc lourd. */
  box-shadow: 0.0625rem 0 0 var(--bordure),
              0.5rem 0 0.625rem -0.5rem rgba(10, 31, 61, 0.3);
}
@media (min-width: 48em) {
  .table-tarifs tbody th[scope="row"],
  .table-tarifs thead th:first-child { width: 15rem; }
}

/* Ligne d'en-tête : reste visible pendant le défilement vertical du tableau */
.table-tarifs thead th {
  position: sticky;
  top: 0;
  z-index: 3;
  background-color: var(--surface);
}

/* Cellule d'angle : au croisement des deux axes, donc au-dessus de tout */
.table-tarifs thead th:first-child {
  z-index: 4;
  box-shadow: 0.0625rem 0 0 var(--bordure),
              0.5rem 0 0.625rem -0.5rem rgba(10, 31, 61, 0.3);
}

/* Survol de ligne : le fond doit aussi couvrir la cellule figée, sinon la
   première colonne reste seule à ne pas réagir. */
.table-tarifs tbody th[scope="row"],
.table-tarifs tbody td { transition: background-color var(--anim-hover); }
.table-tarifs tbody tr:hover th[scope="row"],
.table-tarifs tbody tr:hover td { background-color: var(--survol-ligne); }
.table-tarifs tbody tr:hover td.col-phare { background-color: var(--survol-ligne-phare); }

.table-tarifs__nom {
  display: block;
  font-family: var(--font-titres);
  font-size: 1.0625rem;
  font-weight: 700;
  color: var(--bleu-principal);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.table-tarifs__prix {
  display: block;
  margin-top: 0.2em;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--texte-2);
}
.table-tarifs__badge {
  display: inline-block;
  margin-bottom: 0.4em;
  padding: 0.2em 0.7em;
  font-family: var(--font-titres);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #fff;
  background-image: var(--degrade);
  border-radius: 0.375rem;
}

/* Colonne Vitrine mise en avant : fond teinté, pas de couleur seule pour porter l'info (badge + libellé).
   Sélecteur volontairement plus spécifique que la règle de fond des cellules
   figées ci-dessus, pour que l'en-tête « Vitrine » garde sa teinte une fois
   collé en haut du conteneur. */
.table-tarifs th.col-phare,
.table-tarifs td.col-phare {
  background-color: var(--bleu-fond);
}
.table-tarifs thead .col-phare {
  border-top-left-radius: var(--rayon);
  border-top-right-radius: var(--rayon);
}

.tarifs__note {
  margin-top: 1.25rem;
  font-size: 0.875rem;
  color: var(--texte-2);
}

/* Bandeau « ligne en or » sous le tableau */
.bandeau-or {
  display: flex;
  align-items: flex-start;
  gap: 0.85em;
  margin: clamp(2.5rem, 5vw, 3.5rem) 0 0;
  padding: clamp(1.25rem, 3vw, 1.75rem) clamp(1.25rem, 3vw, 2rem);
  background-color: var(--surface);
  border: 0.0625rem solid var(--bordure-forte);
  border-left: 0.3125rem solid var(--bleu-principal);
  border-radius: var(--rayon);
  font-family: var(--font-titres);
  font-size: clamp(1.0625rem, 2vw, 1.25rem);
  font-weight: 500;
  line-height: 1.5;
  color: var(--bleu-principal);
}
.bandeau-or::before {
  content: "";
  flex: none;
  /* Calé sur le centre de la première ligne : (hauteur de ligne - chevron) / 2 */
  margin-top: calc((1.5em - 0.55em) / 2);
  width: 0.55em;
  height: 0.55em;
  border-top: 0.16em solid var(--bleu-clair);
  border-right: 0.16em solid var(--bleu-clair);
  transform: rotate(45deg);
}

/* La même « ligne en or », mais en DÉCLARATION et non en encadré.

   Sur la page maintenance, cette phrase est le seul contenu de sa section
   sombre. Encadrée, elle se lisait comme un encadré qui accompagne un texte
   absent : d'où l'impression franche qu'un titre manquait. Le cadre est le
   vocabulaire d'un complément, il réclame ce qu'il complète. Sans cadre et en
   plus grand, la phrase ne réclame plus rien et devient le point d'arrêt du
   regard que le gabarit voulait depuis le début.

   CENTRÉE, et sans filet latéral. Première tentative faite avec le filet de
   .phrase-canonique, bornée à 34rem et alignée à gauche : la phrase formait un
   petit îlot décalé au milieu d'une bande pleine largeur, hachée sur trois
   lignes. Un filet latéral ancre à gauche, ce qui n'a de sens que dans une
   colonne de texte ; dans une bande pleine largeur, c'est la bande qui est
   l'ornement et la phrase n'a besoin de rien d'autre.

   Bornée à 44rem pour tomber sur DEUX lignes. Une seule traverserait la bande
   et se lirait comme une légende ; trois hachent une phrase qui doit s'énoncer
   d'un trait.

   AUCUN « color » ici, volontairement. .section--sombre applique déjà
   --texte-clair aux paragraphes avec une spécificité doublée (0,2,1) : une
   couleur posée ici en (0,1,0) perdrait de toute façon, et c'est le
   comportement voulu. La teinte du texte sur fond sombre reste décidée en un
   seul endroit, voir le commentaire de la section 2. */
.declaration-or {
  max-width: 44rem;
  margin-inline: auto;
  font-family: var(--font-titres);
  font-size: clamp(1.375rem, 3vw, 1.75rem);
  font-weight: 500;
  line-height: 1.4;
  text-align: center;
}


/* ==========================================================================
   10. CHAQUE SITE EST UN CAS DIFFÉRENT : carte en grand format
   ========================================================================== */

.carte-secteur {
  margin-top: clamp(1rem, 3vw, 1.5rem);
}
.carte-secteur svg {
  width: 100%;
  height: auto;
  border: 0.0625rem solid var(--bordure);
  border-radius: var(--rayon-lg);
}

.carte-secteur__phrase {
  margin: clamp(1.75rem, 4vw, 2.5rem) 0 0.75rem;
  padding-left: 1.25rem;
  border-left: 0.25rem solid var(--bleu-clair);
  font-family: var(--font-titres);
  font-size: clamp(1.125rem, 2.2vw, 1.375rem);
  font-weight: 500;
  line-height: 1.45;
  color: var(--bleu-principal);
  max-width: 42rem;
}
/* ==========================================================================
   CARTE INTERACTIVE : repères et fiche associée

   Le mécanisme est un groupe de boutons radio masqués, dont les libellés
   sont posés en absolu sur la carte. Aucun JavaScript, et par conséquent :
   navigation aux flèches acquise, tactile acquis, pas de saut de page,
   pas de fragment ajouté à l'URL.

   Les quatre fiches existent toujours dans le HTML, une seule est
   affichée. Sans feuille de style, elles se lisent toutes à la suite : la
   page reste complète.
   ========================================================================== */

.carte-zone {
  /* Un fieldset porte une bordure et des marges par défaut. */
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

.carte-zone__carte { position: relative; }

/* --- Les repères --- */

/* --- Géométrie du repère ---

   C'EST LE POINT QUI DOIT TOMBER SUR LA COORDONNÉE, pas le libellé.

   Un translate(-50%, -50%) centrait l'ensemble point plus nom sur la
   coordonnée : le point rendait donc décalé de la moitié de la largeur du
   libellé, soit une quarantaine de pixels vers la gauche. L'erreur était
   invisible dans le code et se voyait seulement à l'écran, ce qui a fait
   chercher le problème du mauvais côté (dans les coordonnées).

   On décale donc de la distance exacte entre le bord du libellé et le
   centre du point : la marge intérieure plus la moitié du point. Les deux
   sont des variables, elles ne peuvent pas se désynchroniser. */

.carte-zone__repere {
  --marge: 0.7rem;
  --point: 0.6rem;
  --decalage: calc(var(--marge) + var(--point) / 2);

  position: absolute;
  transform: translate(calc(var(--decalage) * -1), -50%);
  display: flex;
  align-items: center;
  gap: 0.4rem;
  /* Zone tactile confortable, quelle que soit la taille du point. */
  padding: var(--marge);
  cursor: pointer;
}

/* Nom à gauche : le point passe au bout droit du libellé, il faut donc
   remonter de toute la largeur, moins le même décalage. */
.carte-zone__repere--gauche {
  flex-direction: row-reverse;
  transform: translate(calc(-100% + var(--decalage)), -50%);
}

.carte-zone__point {
  flex: none;
  width: var(--point);
  height: var(--point);
  border-radius: 50%;
  background-color: var(--surface);
  border: 0.125rem solid var(--bleu-moyen);
  transition: transform var(--anim-hover), background-color var(--anim-hover);
}

.carte-zone__nom {
  font-size: 0.875rem;
  font-weight: 500;
  /* Mesuré à 4,35:1 avec l'ancienne teinte, juste sous les 4,5 exigés.
     Celle-ci passe à 5,3:1 sans changer la discrétion voulue. */
  color: #52738A;
  white-space: nowrap;
  transition: color var(--anim-hover);
}

/* L'état sélectionné est posé par les règles générées dans le gabarit,
   qui ciblent l'identifiant du bouton coché. Rien à déclarer ici. */

.carte-zone__repere:hover .carte-zone__nom { color: var(--bleu-principal); }
.carte-zone__repere:hover .carte-zone__point { transform: scale(1.35); }

/* --- La fiche --- */

.carte-zone__panneau {
  /* Hauteur réservée : sans elle, passer d'une fiche courte à une fiche
     longue ferait sauter tout ce qui suit. */
  min-height: 8.5rem;
  max-width: 42rem;
  margin: clamp(1.5rem, 3vw, 2rem) auto 0;
  padding: 1.25rem 1.5rem;
  text-align: center;
  background-color: var(--bleu-fond);
  border-radius: var(--rayon);
}

.carte-zone__fiche { display: none; }

.carte-zone__lieu {
  margin: 0 0 0.35rem;
  font-family: var(--font-titres);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--bleu-moyen);
}

.carte-zone__titre {
  margin: 0 0 0.5rem;
  font-family: var(--font-titres);
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--bleu-principal);
}

.carte-zone__texte {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--texte-2);
}

/* Pas de repli « première fiche visible » ici : il resterait actif quand
   une AUTRE commune est choisie, et deux fiches s'afficheraient. Le
   premier bouton est coché côté PHP, donc la règle générée fait le
   travail dès le chargement. Et sans CSS du tout, les quatre fiches se
   lisent à la suite, ce qui est le bon repli. */

@media (max-width: 40em) {
  /* Les noms encombreraient une carte réduite au tiers. Les points
     restent, agrandis, et le nom de la commune est de toute façon repris
     en tête de la fiche. */
  .carte-zone__nom { display: none; }

  /* Le nom masqué, le libellé se réduit au point : la cible tombait à
     34 px, sous le minimum de 44. La marge intérieure compense.
     12 px de point + 2 x 16 px = 44. Le décalage suit tout seul, il est
     calculé depuis ces deux variables. */
  .carte-zone__repere { --marge: 1rem; --point: 0.75rem; }

  .carte-zone__panneau { min-height: 10.5rem; }
}

@media (prefers-reduced-motion: reduce) {
  .carte-zone__point { transition: none; }
}


/* --- Libellés de la carte du littoral ---
   Le SVG est inséré dans la page, donc stylable. À 350 px de large pour un
   viewBox de 1200, tout est réduit au tiers : un libellé de 17 unités
   tombe à 5 pixels, illisible. On masque alors les communes secondaires et
   on grossit Concarneau.

   Rien n'est perdu : la légende sous la carte nomme les quatre communes,
   et les points restent visibles. */

@media (max-width: 40em) {
  .carte__nom--secondaire { display: none; }
  .carte__nom--principal { font-size: 46px; }
  .carte__point { stroke-width: 4; }
}

.carte-secteur__note {
  max-width: 42rem;
  color: var(--texte-2);
  font-size: 0.9375rem;
}

/* Deux témoignages côte à côte en grand écran, empilés en petit écran */
.avis-duo {
  display: grid;
  gap: clamp(1rem, 2.5vw, 1.75rem);
  margin-top: clamp(2rem, 4vw, 2.75rem);
}
@media (min-width: 50em) {
  .avis-duo { grid-template-columns: repeat(2, 1fr); align-items: stretch; }
}

/* Avis isolé (hors grille) : version compacte du composant avis */
.avis--isole {
  margin: 0;
  padding: clamp(1.5rem, 3vw, 2rem);
  max-width: 34rem;
  background-color: var(--surface);
  border: 0.0625rem solid var(--bordure);
  border-radius: var(--rayon);
  transition: border-color var(--anim-hover), box-shadow var(--anim-hover), transform var(--anim-hover);
}
.avis--isole:hover {
  border-color: var(--bordure-forte);
  box-shadow: var(--ombre-carte);
  transform: translateY(-0.125rem);
}
/* Posée SEULE dans le flux d'une section, la carte a besoin de respirer : le
   « margin: 0 » ci-dessus n'a de sens que dans .avis-duo, où c'est le gap de la
   grille qui espace. Sans cette règle, elle se colle au paragraphe précédent.

   Le sélecteur exige un parent .container, ce qui exclut le cas de la paire :
   dans .avis-duo les cartes sont enfants de la grille et non du conteneur, donc
   la seconde ne récupère pas cette marge par le sélecteur de voisinage. */
.container > * + .avis--isole { margin-top: clamp(2rem, 4vw, 3rem); }

/* Dans la paire, les deux cartes occupent toute leur colonne et la même hauteur */
.avis-duo .avis--isole {
  max-width: none;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.avis--isole p {
  margin: 0 0 0.75em;
  font-size: 1rem;
  line-height: 1.7;
  color: var(--texte);
}
.avis--isole footer {
  font-size: 0.875rem;
  color: var(--texte-2);
}
.avis--isole cite { font-style: normal; font-weight: 600; color: var(--bleu-principal); }
/* La pastille de plateforme est blanche : sur une carte blanche, on la teinte */
.avis--isole .chemin__avis-source { background-color: var(--bleu-fond); }


/* ==========================================================================
   11. BLOC ÉDITORIAL « QUI S'OCCUPE DE VOTRE SITE »
   ========================================================================== */

/* La grille à deux colonnes, le médaillon rond et son cadre ont été retirés
   avec la photo de cette section : c'était la seule instance du composant dans
   tout le thème, ces règles ne servaient plus rien. Voir front-page.php pour
   la raison du retrait. */

.editorial__texte p { color: var(--texte-2); }


/* ==========================================================================
   12. FAQ : <details>/<summary> natifs, aucun JS
   ========================================================================== */

.faq {
  border-top: 0.0625rem solid var(--bordure-forte);
}
.faq__item {
  border-bottom: 0.0625rem solid var(--bordure-forte);
  background-color: transparent;
}

.faq__item summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.35rem 0.25rem;
  font-family: var(--font-titres);
  font-size: clamp(1rem, 1.8vw, 1.125rem);
  font-weight: 600;
  line-height: 1.45;
  color: var(--bleu-principal);
  cursor: pointer;
  list-style: none;
  transition: color var(--anim-hover);
}
.faq__item summary:hover { color: var(--bleu-moyen); }
.faq__item summary::-webkit-details-marker { display: none; }

/* Chevron indicateur, pivoté à l'ouverture.
   Calé sur le centre de la première ligne de la question, pas sur son sommet :
   (hauteur de ligne - hauteur du chevron) / 2. */
.faq__item summary::after {
  content: "";
  flex: none;
  margin-top: calc((1.45em - 0.55em) / 2);
  width: 0.55em;
  height: 0.55em;
  border-bottom: 0.15em solid var(--bleu-moyen);
  border-right: 0.15em solid var(--bleu-moyen);
  transform: rotate(45deg);
  transition: transform var(--transition);
}
.faq__item[open] summary::after { transform: rotate(-135deg); }

.faq__reponse {
  padding: 0 0.25rem 1.5rem;
  max-width: 44rem;
  color: var(--texte-2);
}


/* ==========================================================================
   13. CTA FINAL
   ========================================================================== */

.cta-final {
  max-width: 42rem;
  margin-inline: auto;
  padding: clamp(2.25rem, 5vw, 3.5rem) clamp(1.5rem, 4vw, 3rem);
  text-align: center;
  background-color: var(--bleu-fond);
  border: 0.0625rem solid var(--bordure-forte);
  border-radius: var(--rayon-lg);
}
.cta-final p { color: var(--texte-2); }
.cta-final__action { margin: 2rem 0 1rem; }
.cta-final__mail { font-size: 0.9375rem; margin: 0; }


/* ==========================================================================
   14. FOOTER : seule zone sombre de la page
   ========================================================================== */

.site-footer {
  padding-block: clamp(3rem, 6vw, 4.5rem) 2rem;
  background-color: var(--marine-profond);
  color: var(--texte-clair);
}
.site-footer a { color: var(--texte-clair); text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
.site-footer :focus-visible { outline-color: var(--bleu-clair); }

.site-footer__haut {
  display: grid;
  gap: 2.5rem;
  padding-bottom: 2.5rem;
  border-bottom: 0.0625rem solid rgba(234, 243, 248, 0.18);
}
@media (min-width: 40em) { .site-footer__haut { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64em) { .site-footer__haut { grid-template-columns: 1.6fr repeat(3, 1fr); } }

.site-footer__marque img {
  /* Version blanche du logo : plus besoin de pastille claire derrière lui,
     il se pose directement sur le fond marine. */
  width: 11.25rem;
  height: auto;
}
.site-footer__baseline { margin: 1.1rem 0 0.6rem; font-size: 0.9375rem; }
/* La ligne géographique est le point d'entrée vers la page zone : elle doit
   se lire comme un lien, discrètement. Jamais de liste de villes ici. */
.site-footer__baseline a {
  border-bottom: 0.0625rem solid rgba(234, 243, 248, 0.35);
  transition: border-color var(--anim-hover);
}
.site-footer__baseline a:hover { text-decoration: none; border-bottom-color: #fff; }

/* Réseaux : sous le bloc marque plutôt qu'en colonne dédiée, faute de place
   une fois les cinq prestations listées. Liens externes, donc rel="noopener"
   et mention « nouvelle fenêtre » en sr-only côté HTML. */
.site-footer__reseaux {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  margin-top: 1.1rem;
  font-size: 0.9375rem;
}
.site-footer__reseaux a {
  border-bottom: 0.0625rem solid rgba(234, 243, 248, 0.35);
  transition: border-color var(--anim-hover);
}
.site-footer__reseaux a:hover { text-decoration: none; border-bottom-color: #fff; }

.site-footer__titre {
  margin: 0 0 1rem;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--bleu-clair);
}
.site-footer__col li { margin-bottom: 0.6rem; font-size: 0.9375rem; }

.site-footer__bas {
  margin: 1.75rem 0 0;
  font-size: 0.875rem;
  color: rgba(234, 243, 248, 0.75);
}


/* ==========================================================================
   15. ANIMATIONS D'ENTRÉE DE SECTION

   RÈGLE NON NÉGOCIABLE : aucun contenu n'est masqué par défaut.
   L'état initial n'existe que sous le double préfixe .js-anim (classe posée sur
   <html> par un script en tête de page) ET .anim (classe posée sur chaque bloc
   par js/main.js, juste avant de l'observer). Sans JS, ni l'une ni l'autre
   n'existe : aucune de ces règles ne s'applique, tout est visible, y compris
   pour les robots d'indexation et les lecteurs d'écran.
   ========================================================================== */

.js-anim .anim {
  opacity: 0;
  transform: translateY(1.25rem);
  transition: opacity var(--anim-entree), transform var(--anim-entree);
  /* transform vertical uniquement : aucun risque de débordement horizontal */
  will-change: opacity, transform;
}
.js-anim .anim.est-visible {
  opacity: 1;
  transform: none;
  will-change: auto;
}


/* ==========================================================================
   16. PRÉFÉRENCE DE MOUVEMENT RÉDUIT
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .btn--primary:hover { transform: none; }
  .btn:active { transform: none; }
  .nav-toggle:active { transform: none; }
  .avis--isole:hover { transform: none; }

  /* Le raccourcissement des transitions ne suffit pas pour l'animation
     d'entrée : il faut annuler explicitement l'état initial, sinon le contenu
     resterait à opacity 0. js/main.js applique la même règle de son côté et
     n'ajoute alors même pas la classe .anim. */
  .js-anim .anim,
  .js-anim .anim.est-visible {
    opacity: 1;
    transform: none;
    transition: none;
  }

  /* Même logique pour la frise : piste pleine et repères allumés d'emblée,
     plutôt qu'un remplissage piloté par le défilement. */
  .js-anim .frise { --frise-progression: 1; }
  .js-anim .frise__item::before,
  .js-anim .frise__item.est-atteint::before {
    background-color: var(--bleu-principal);
    transform: none;
    transition: none;
  }

  /* Header : plus de masquage au défilement, il reste collant en permanence */
  .site-header,
  .site-header.est-masque {
    transform: none;
    transition: none;
  }

  /* Carrousel d'avis : le JS ne l'active déjà pas sous ce réglage, mais ce
     filet CSS garantit que tous les avis restent visibles et empilés même
     si le script tourne quand même (mêmes garde-fous que la frise). */
  .avis-carrousel--actif .avis-carrousel__slide {
    grid-area: auto;
    opacity: 1;
    visibility: visible;
    transition: none;
    pointer-events: auto;
  }
}


/* ==========================================================================
   17. PAGES INTERNES : composants communs (fil d'ariane, page courante)
   ========================================================================== */

.fil-ariane { padding-block: 1rem 0; }
.fil-ariane__liste {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.8125rem;
  color: var(--texte-2);
}
.fil-ariane__liste li { display: flex; align-items: center; gap: 0.4rem; }
.fil-ariane__liste a { color: var(--texte-2); text-decoration: none; }
.fil-ariane__liste a:hover { color: var(--bleu-principal); text-decoration: underline; }
.fil-ariane__separateur { color: var(--bordure-forte); }
.fil-ariane [aria-current="page"] { color: var(--bleu-principal); font-weight: 600; }

/* Page courante dans le header et le footer */
.nav__list a[aria-current="page"] { color: var(--bleu-principal); font-weight: 600; }
.site-footer__col a[aria-current="page"] { color: #fff; font-weight: 600; }


/* ==========================================================================
   18. HERO COMPACT : pages internes (pas le split de l'accueil)
   ========================================================================== */

.hero-compact { padding-block: clamp(2.25rem, 6vw, 3.75rem) clamp(2.75rem, 6vw, 4rem); }
.hero-compact__interieur { max-width: 42rem; }
.hero-compact__chapo {
  font-size: clamp(1.0625rem, 1.6vw, 1.1875rem);
  color: var(--texte-2);
}
.hero-compact__reassurance {
  margin-top: 1rem;
  font-size: 0.9375rem;
  color: var(--texte-2);
}


/* ==========================================================================
   19. PÉRIMÈTRE : deux colonnes de poids inégal (je prends en charge / non)
   ========================================================================== */

.perimetre {
  display: grid;
  gap: clamp(1.5rem, 4vw, 2.5rem);
}
@media (min-width: 55em) {
  .perimetre { grid-template-columns: 1.6fr 1fr; align-items: start; }
}

.perimetre__bloc {
  padding: clamp(1.5rem, 3vw, 2rem);
  background-color: var(--surface);
  border: 0.0625rem solid var(--bordure);
  border-radius: var(--rayon-lg);
}

.perimetre__titre {
  margin: 0 0 1rem;
  font-family: var(--font-titres);
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--bleu-principal);
}

.perimetre__liste { display: grid; gap: 0.85rem; }
.perimetre__liste li {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  color: var(--texte-2);
}
.perimetre__liste li::before {
  content: "";
  flex: none;
  margin-top: 0.5em;
  width: 0.55em;
  height: 0.55em;
  border-radius: 50%;
  background-color: var(--bleu-clair);
}

.perimetre__note {
  margin-top: 1.25rem;
  font-size: 0.875rem;
  color: var(--texte-2);
}

/* Variante à un seul bloc (pas de comparaison "ce que je ne fais pas") :
   le bloc occupe toute la largeur, sa liste passe en 2 colonnes sur grand
   écran pour ne pas s'étirer en une longue colonne unique. */
.perimetre--simple { display: block; }
.perimetre--simple .perimetre__bloc { max-width: 46rem; }
@media (min-width: 40em) {
  .perimetre--simple .perimetre__liste {
    grid-template-columns: repeat(2, 1fr);
    column-gap: clamp(1.5rem, 4vw, 2.5rem);
  }
}
/* Centre le bloc dans le conteneur (le texte des puces reste aligné à
   gauche à l'intérieur : centrer chaque ligne d'une checklist nuirait à
   la lecture). */
.perimetre--centre .perimetre__bloc { margin-inline: auto; }


/* ==========================================================================
   20. PARCOURS NUMÉROTÉ : étapes franches, PAS la frise (pas de remplissage
   au scroll). Piste statique portée par le conteneur, badges numérotés pleins.
   ========================================================================== */

.parcours {
  position: relative;
  list-style: none;
  counter-reset: etape;
  display: grid;
  gap: clamp(1.75rem, 4vw, 2.25rem);
}
.parcours::before {
  content: "";
  position: absolute;
  left: 1.1875rem;
  top: 0.25rem;
  bottom: 0.25rem;
  width: 0.125rem;
  background-color: var(--bordure-forte);
  border-radius: 999px;
}

.parcours__etape {
  counter-increment: etape;
  position: relative;
  padding-left: 3.25rem;
}
.parcours__etape::before {
  content: counter(etape);
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  font-family: var(--font-titres);
  font-size: 1.0625rem;
  font-weight: 700;
  color: #fff;
  background-image: var(--degrade);
  border-radius: 50%;
}

.parcours__titre {
  margin: 0 0 0.4em;
  font-family: var(--font-titres);
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--bleu-principal);
}
.parcours__texte { margin: 0; color: var(--texte-2); max-width: 32rem; }

@media (min-width: 60em) {
  .parcours {
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: clamp(1.25rem, 2.5vw, 2rem);
  }
  .parcours::before {
    left: 0.25rem;
    right: 0.25rem;
    top: 1.1875rem;
    bottom: auto;
    height: 0.125rem;
    width: auto;
  }
  .parcours__etape { padding-left: 0; padding-top: 3.5rem; }
  .parcours__etape::before { left: 0; top: 0; }
  .parcours__texte { max-width: none; }
}


/* ==========================================================================
   21. BLOC DEUX VOIES : forfait / pack d'heures, poids égal
   ========================================================================== */

.voies {
  display: grid;
  gap: clamp(1.25rem, 3vw, 1.75rem);
}
@media (min-width: 50em) {
  .voies { grid-template-columns: repeat(2, 1fr); align-items: stretch; }
}

.voie {
  display: flex;
  flex-direction: column;
  padding: clamp(1.5rem, 3vw, 2rem);
  background-color: var(--surface);
  border: 0.0625rem solid var(--bordure);
  border-radius: var(--rayon-lg);
}
.voie__titre {
  margin: 0 0 0.6em;
  font-family: var(--font-titres);
  font-size: 1.1875rem;
  font-weight: 700;
  color: var(--bleu-principal);
}
.voie p { color: var(--texte-2); }

/* Réutilisation du bandeau or, en version compacte et calée en bas de carte */
.voie .bandeau-or {
  margin-top: auto;
  padding: 1rem 1.25rem;
  font-size: 1rem;
}

.voies__note {
  margin-top: clamp(1.5rem, 3vw, 2rem);
  text-align: center;
  color: var(--texte-2);
  font-size: 0.9375rem;
}


/* ==========================================================================
   22. BANDEAU PASSERELLE : renvoi vers une autre offre (l'étage au-dessus)
   ========================================================================== */

.bandeau-passerelle {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: clamp(1.5rem, 3vw, 2rem) clamp(1.5rem, 4vw, 2.5rem);
  background-color: var(--surface);
  border: 0.0625rem solid var(--bordure);
  border-radius: var(--rayon-lg);
}
.bandeau-passerelle p { margin: 0; max-width: 34rem; color: var(--texte-2); }
.bandeau-passerelle strong { color: var(--texte); }
.bandeau-passerelle .btn { flex: none; }


/* ==========================================================================
   23. OPTIONS IA : bloc secondaire sous le tableau des formules.
   Traitement volontairement plus léger que le tableau (pas de second
   tableau : ce serait la même forme deux fois de suite), et libellés
   honnêtes qui disent ce que l'option fait vraiment.
   ========================================================================== */

.options-ia {
  margin-top: clamp(1.5rem, 3vw, 2rem);
  padding: clamp(1.5rem, 3vw, 2rem);
  background-color: transparent;
  border: 0.0625rem dashed var(--bordure-forte);
  border-radius: var(--rayon-lg);
}

.options-ia__titre {
  margin: 0 0 1.25rem;
  font-family: var(--font-titres);
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--texte-2);
}

.options-ia__liste { display: grid; gap: 1.5rem; }

.option-ia__nom {
  margin: 0 0 0.6rem;
  font-weight: 600;
  color: var(--bleu-principal);
}

.option-ia__repartition {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  font-size: 0.9375rem;
  color: var(--texte-2);
}
.option-ia__formule {
  display: inline-block;
  margin-right: 0.4em;
  padding: 0.1em 0.5em;
  font-family: var(--font-titres);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--bleu-moyen);
  background-color: var(--bleu-fond);
  border-radius: 0.25rem;
}

.options-ia__note {
  margin: 1.5rem 0 0;
  font-size: 0.875rem;
  color: var(--texte-2);
}
/* Deux notes se suivent désormais : le cadrage de l'offre, puis les modalités.
   L'écart de 1,5rem sépare le bloc d'options de la première ; entre les deux
   notes, un simple interligne de paragraphe suffit. */
.options-ia__note + .options-ia__note { margin-top: 0.75rem; }


/* ==========================================================================
   24. GUIDE DE CHOIX : trois lignes descriptives, pas trois cartes.
   Le tableau juste au-dessus a déjà fait la comparaison ; ici on aide
   seulement le visiteur à se reconnaître dans une des trois situations.
   ========================================================================== */

.guide-choix {
  display: grid;
  gap: 0;
  border-top: 0.0625rem solid var(--bordure-forte);
}

.guide-choix__ligne {
  display: grid;
  gap: 0.5rem 2rem;
  padding: clamp(1.25rem, 3vw, 1.75rem) 0;
  border-bottom: 0.0625rem solid var(--bordure-forte);
}
@media (min-width: 45em) {
  .guide-choix__ligne { grid-template-columns: 11rem 1fr; align-items: baseline; }
}

/* Le marquage du phare (filet + badge) est mutualisé avec le catalogue des
   services, en fin de section 24 : le filet y devient aussi l'état de survol
   de toutes les lignes. */

.guide-choix__etiquette {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  /* Le nom et le prix passent à la ligne l'un sous l'autre quand la colonne
     de 11 rem ne les tient pas côte à côte. C'est le cas de « E-COMMERCE »,
     dont la mise en majuscules gonfle la largeur : sans ce wrap, le nom se
     coupait en deux au milieu du mot. */
  flex-wrap: wrap;
}
.guide-choix__nom {
  font-family: var(--font-titres);
  font-size: 1.0625rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--bleu-principal);
  /* Un nom de formule ne se coupe jamais : c'est un libellé, pas de la prose.
     « E-COMMERCE » cassait sur son trait d'union. */
  white-space: nowrap;
}
.guide-choix__prix {
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--texte-2);
}

.guide-choix__texte { margin: 0; color: var(--texte-2); }

.guide-choix__chute {
  margin: clamp(1.5rem, 3vw, 2rem) 0 0;
  font-family: var(--font-titres);
  font-size: 1.0625rem;
  font-weight: 500;
  color: var(--bleu-principal);
}


/* ==========================================================================
   25. LOGOS CLIENTS : bande statique, jamais un carrousel auto-play
   ========================================================================== */

.logos-clients {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(1rem, 3vw, 2.5rem);
  margin-bottom: clamp(2.5rem, 5vw, 3.5rem);
}
.logos-clients__item {
  flex: 0 1 9rem;
  max-width: 11rem;
}
.logos-clients__item svg,
.logos-clients__item img {
  display: block;
  width: 100%;
  height: auto;
  /* Les logos réels sont de couleurs variées : on les apaise au repos et on
     leur rend leur couleur au survol, pour que la bande reste homogène. */
  filter: grayscale(1);
  opacity: 0.75;
  transition: filter var(--anim-hover), opacity var(--anim-hover);
}
.logos-clients__item:hover svg,
.logos-clients__item:hover img { filter: grayscale(0); opacity: 1; }


/* ==========================================================================
   26. TROIS PAS : forme brève, une ligne, chevrons de liaison.
   Sert quand un enchaînement se résume en trois jalons et qu'un parcours
   numéroté complet (page Dépannage) serait disproportionné.
   ========================================================================== */

.trois-pas__titre { text-align: center; margin-bottom: clamp(1.75rem, 4vw, 2.5rem); }

/* Précision posée sous les trois jalons. Volontairement PAS le traitement de
   .guide-choix__chute, qui passe en police de titrage et en bleu principal :
   celle-ci est une explication de trois lignes, pas une chute. Lui donner du
   poids typographique la ferait concurrencer les jalons qu'elle commente. */
.trois-pas__chute {
  max-width: 40rem;
  margin: clamp(1.5rem, 3vw, 2rem) auto 0;
  text-align: center;
  color: var(--texte-2);
}

.trois-pas {
  counter-reset: pas;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.75rem;
  list-style: none;
}
.trois-pas__pas {
  position: relative;
  padding: 1rem 1.25rem;
  font-family: var(--font-titres);
  font-weight: 500;
  color: var(--bleu-principal);
  background-color: var(--surface);
  border: 0.0625rem solid var(--bordure);
  border-radius: var(--rayon);
  text-align: center;
}

@media (min-width: 48em) {
  .trois-pas {
    flex-direction: row;
    /* « stretch » et non « center » : avec center, chaque jalon ne fait que
       la hauteur de son propre texte, et celui qui tient sur une seule ligne
       est visiblement plus bas que ses voisins. Le défaut touchait les trois
       pages qui utilisent ce composant (maintenance, refonte, sur mesure). */
    align-items: stretch;
    gap: 0;
  }
  /* Les jalons faisant désormais tous la même hauteur, le texte des plus
     courts doit être recentré verticalement dans son bloc. */
  .trois-pas__pas {
    flex: 1 1 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 0;
  }
  .trois-pas__pas:first-child {
    border-radius: var(--rayon) 0 0 var(--rayon);
  }
  .trois-pas__pas:last-child {
    border-radius: 0 var(--rayon) var(--rayon) 0;
  }
  /* Les jalons se touchent : on évite le doublon de filet entre deux blocs */
  .trois-pas__pas + .trois-pas__pas { border-left: 0; }
  /* Chevron de liaison, posé sur la jonction */
  .trois-pas__pas + .trois-pas__pas::before {
    content: "";
    position: absolute;
    left: -0.375rem;
    top: 50%;
    width: 0.55rem;
    height: 0.55rem;
    border-top: 0.125rem solid var(--bleu-clair);
    border-right: 0.125rem solid var(--bleu-clair);
    background-color: var(--surface);
    transform: translateY(-50%) rotate(45deg);
  }
}


/* ==========================================================================
   27. CONTENU ÉDITORIAL (.contenu)

   Pages rédigées depuis l'éditeur WordPress : mentions légales, CGV,
   confidentialité, cookies. Le balisage y est produit par l'éditeur, pas
   par nous : il faut donc redonner un style à des éléments que le reset a
   neutralisés.

   ⚠ Le point critique : le reset global pose « ul { list-style: none } ».
   Sans les règles ci-dessous, une énumération de conditions générales
   s'afficherait sans aucune puce ni numéro, ce qui rend un texte juridique
   illisible et fait perdre la numérotation des articles.
   ========================================================================== */

/* 42rem convient à un texte de lecture. Les pages légales, elles, sont des
   documents de référence qu'on parcourt : trop étroites, elles s'étirent sur
   une longueur décourageante. D'où la largeur portée à 56rem sur ces pages
   via .page-legale (voir plus bas). */
.contenu { max-width: 42rem; }

.contenu > * + * { margin-top: 1.1em; }

.contenu h2 {
  margin-top: 2.2em;
  font-size: clamp(1.25rem, 2.6vw, 1.625rem);
}
.contenu h3 {
  margin-top: 1.8em;
  font-size: clamp(1.0625rem, 2.1vw, 1.25rem);
}
.contenu h2:first-child,
.contenu h3:first-child { margin-top: 0; }

.contenu p,
.contenu li { color: var(--texte-2); }

/* Restauration des listes, neutralisées par le reset global. */
.contenu ul,
.contenu ol {
  padding-left: 1.5em;
  display: grid;
  gap: 0.5em;
}
.contenu ul { list-style: disc; }
.contenu ol { list-style: decimal; }
.contenu ul ul { list-style: circle; margin-top: 0.5em; }
.contenu ol ol { list-style: lower-alpha; margin-top: 0.5em; }
.contenu li::marker { color: var(--bleu-moyen); }

.contenu a {
  color: var(--bleu-principal);
  text-decoration: underline;
}
.contenu a:hover { color: var(--bleu-moyen); }

.contenu strong { color: var(--texte); font-weight: 600; }

.contenu blockquote {
  margin: 1.5em 0;
  padding-left: 1.25rem;
  border-left: 0.25rem solid var(--bleu-clair);
  font-style: italic;
}

/* Un tableau dans du texte juridique ne doit jamais déborder de la page */
.contenu table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}
.contenu th,
.contenu td {
  padding: 0.7em 0.9em;
  text-align: left;
  border: 0.0625rem solid var(--bordure);
  vertical-align: top;
}
.contenu th { background-color: var(--bleu-fond); color: var(--bleu-principal); }

.contenu hr {
  margin: 2.5em 0;
  border: 0;
  border-top: 0.0625rem solid var(--bordure);
}

/* --- Pages légales -------------------------------------------------------
   Mentions, confidentialité, cookies, CGV. Ce sont des documents de
   référence, pas des pages de vente : le titre doit être suivi du texte
   presque immédiatement, et la colonne doit être assez large pour qu'un
   contrat de 57 000 caractères ne s'étire pas sur une longueur absurde.

   Trois réglages, tous liés :
   1. le hero se resserre et perd sa marge basse ;
   2. la section de contenu perd sa marge haute : les deux blocs se
      touchent, au lieu de laisser 11rem de vide entre le titre et la
      première ligne ;
   3. la colonne de lecture passe de 42rem à 56rem.
   -------------------------------------------------------------------------- */

.page-legale .hero-compact {
  padding-block: clamp(1.75rem, 4vw, 2.5rem) 0;
}

.page-legale .section--contenu {
  padding-top: clamp(1.25rem, 3vw, 1.75rem);
}

.page-legale .container--etroit { width: min(100% - 2.5rem, 58rem); }
.page-legale .contenu { max-width: 56rem; }

/* Le titre d'un document juridique n'a pas besoin du poids d'un titre de
   page de vente : on le ramène à une échelle de document. */
.page-legale .hero-compact h1 {
  font-size: clamp(1.5rem, 3.2vw, 2.125rem);
}


/* ==========================================================================
   28. HUB SERVICES : le catalogue

   Lignes riches et non des cartes : la page distribue vers les 5 services,
   elle ne les vend pas. Le titre de chaque ligne EST le lien (zone de clic
   large, libellé explicite pour la navigation à la voix et au lecteur
   d'écran), et le repère de prix vit à droite du titre.
   ========================================================================== */

.catalogue { border-top: 0.0625rem solid var(--bordure-forte); }

.catalogue__ligne {
  padding: clamp(1.5rem, 3.5vw, 2rem) 0;
  border-bottom: 0.0625rem solid var(--bordure-forte);
}

/* Le produit phare est signalé par un filet, pas par un fond : le fond
   teinté est déjà le langage de la colonne mise en avant du tableau. */
/* Le marquage du phare est mutualisé plus bas, avec celui des guides de
   choix : voir « Marquage phare et filet de survol ». */

.catalogue__entete {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.4rem 1.5rem;
  margin-bottom: 0.6rem;
}

.catalogue__titre {
  margin: 0;
  font-size: clamp(1.125rem, 2.3vw, 1.375rem);
}
.catalogue__titre a {
  text-decoration: none;
  border-bottom: 0.125rem solid transparent;
  transition: color var(--anim-hover), border-color var(--anim-hover);
}
.catalogue__titre a:hover {
  color: var(--bleu-moyen);
  border-bottom-color: var(--bleu-clair);
}
/* La flèche accompagne le titre sans être un second lien à tabuler */
.catalogue__titre a::after {
  content: "";
  display: inline-block;
  width: 0.4em;
  height: 0.4em;
  margin-left: 0.5em;
  border-top: 0.14em solid currentColor;
  border-right: 0.14em solid currentColor;
  transform: rotate(45deg) translate(-0.05em, 0.05em);
  transition: transform var(--transition);
}
.catalogue__titre a:hover::after {
  transform: rotate(45deg) translate(0.1em, -0.1em);
}

.catalogue__repere {
  margin: 0;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--bleu-moyen);
  white-space: nowrap;
}

.catalogue__texte { margin: 0; color: var(--texte-2); max-width: 44rem; }


/* --------------------------------------------------------------------------
   MARQUAGE PHARE ET FILET DE SURVOL
   Sert au catalogue des services et aux deux guides de choix (maintenance,
   création).

   Le filet bleu ne servait qu'à désigner le phare. Il devient l'état de
   SURVOL de toutes les lignes : allumé en permanence sur le phare, il
   s'anime à l'approche du pointeur ou du clavier sur les autres.

   Conséquence directe : le filet ne peut plus IDENTIFIER le phare, puisque
   n'importe quelle ligne l'affiche au survol. C'est un badge en texte qui
   prend le relais. Au passage c'est mieux qu'avant : le phare n'était
   signalé que par une couleur, sans équivalent textuel (WCAG 1.4.1).
   -------------------------------------------------------------------------- */

.catalogue__ligne,
.guide-choix__ligne {
  position: relative;
  /* Rembourrage permanent, même sans filet visible : le survol ne doit
     JAMAIS déplacer le texte. C'était le défaut de l'écriture précédente,
     où seule la ligne phare était décalée vers la droite. */
  padding-left: 1.25rem;
}

.catalogue__ligne::before,
.guide-choix__ligne::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.4rem;
  bottom: 0.4rem;
  width: 0.25rem;
  border-radius: 0.125rem;
  background-color: var(--bleu-clair);
  transform: scaleY(0);
  transition: transform var(--anim-hover);
}

/* Le phare garde son filet allumé en continu. */
.catalogue__ligne--phare::before,
.guide-choix__ligne--phare::before { transform: scaleY(1); }

/* focus-within autant que hover : les lignes du catalogue contiennent un
   lien, le filet doit donc répondre au clavier et pas qu'au pointeur. */
.catalogue__ligne:hover::before,
.catalogue__ligne:focus-within::before,
.guide-choix__ligne:hover::before,
.guide-choix__ligne:focus-within::before { transform: scaleY(1); }

/* Le guide de choix est une GRILLE à deux colonnes (étiquette | description).
   Sans « grid-column », le badge s'y insère comme un troisième élément de
   grille : il prend la case 1, l'étiquette est poussée dans la colonne de
   droite et la description tombe à la ligne suivante dans la colonne étroite
   de 11 rem. En occupant toute la largeur, il forme sa propre rangée et laisse
   le couple étiquette / description intact en dessous.

   Cette règle ne traite que le PLACEMENT. La largeur est réglée sur
   .badge-phare directement, voir le commentaire là-bas. */
.guide-choix__ligne .badge-phare { grid-column: 1 / -1; }

/* Badge du phare. Mêmes valeurs que .table-tarifs__badge : le tableau
   tarifaire a déjà posé ce langage, on ne va pas en inventer un troisième. */
.badge-phare {
  display: inline-block;
  /* L'inline-block ne suffit pas : le display d'un élément de grille est
     BLOCKIFIÉ par le navigateur, donc il devient block et s'étire sur toute
     la largeur de sa case. fit-content règle la question dans tous les
     contextes à la fois (grille, flex, bloc), là où un justify-self n'aurait
     tenu que dans la grille. */
  width: fit-content;
  margin: 0 0 0.6rem;
  padding: 0.2em 0.7em;
  font-family: var(--font-titres);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #fff;
  background-image: var(--degrade);
  border-radius: 0.375rem;
}

/* Mention légale accompagnant tout prix affiché (non-assujettissement à la
   TVA). Discrète mais jamais masquée : c'est une obligation d'affichage. */
.mention-tva {
  margin: clamp(1.25rem, 3vw, 1.75rem) 0 0;
  font-size: 0.8125rem;
  color: var(--texte-2);
}


/* ==========================================================================
   29. PAGE RÉALISATIONS : liste éditoriale alternée + gabarit de fiche

   La preuve se raconte, elle ne se met pas en vignettes : chaque entrée est
   une rangée pleine largeur, alternée, avec un vrai poids éditorial.
   Volontairement PAS une grille de cartes.
   ========================================================================== */

.etudes {
  list-style: none;
  display: grid;
  gap: clamp(3rem, 7vw, 5rem);
}

.etude {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
}
@media (min-width: 56em) {
  .etude { grid-template-columns: 1fr 1fr; }
  /* Alternance : une entrée sur deux inverse visuellement les colonnes.
     L'ordre du DOM reste visuel puis texte, donc la lecture linéaire
     (lecteur d'écran, navigation clavier) garde un ordre cohérent. */
  .etude:nth-child(even) .etude__media { order: 2; }
}

.etude__visuel {
  width: 100%;
  height: auto;
  border-radius: var(--rayon-lg);
  border: 0.0625rem solid var(--bordure);
  background-color: var(--bleu-fond);
}

/* ==========================================================================
   JOURNAL D'INTERVENTIONS (page dépannage)

   Une liste de définitions : le type de client est le terme, l'intervention
   sa description. C'est exactement la sémantique d'un <dl>, et un lecteur
   d'écran annonce alors les paires correctement.

   Volontairement austère : ni carte, ni ombre, ni icône. La forme doit
   évoquer un carnet d'interventions, pas une vitrine. C'est cette sobriété
   qui la rend crédible.
   ========================================================================== */

.journal { margin: 0; }

.journal__ligne {
  display: grid;
  gap: 0.3rem;
  padding: 1.15rem 0;
  border-top: 0.0625rem solid var(--bordure);
}
.journal__ligne:last-child { border-bottom: 0.0625rem solid var(--bordure); }

@media (min-width: 44em) {
  .journal__ligne {
    grid-template-columns: 15rem 1fr;
    gap: 2rem;
    align-items: baseline;
  }
}

.journal__client {
  margin: 0;
  font-family: var(--font-titres);
  font-weight: 600;
  color: var(--bleu-principal);
}


/* Le reset met déjà les dd à zéro, on le réaffirme : ce composant ne doit
   pas dépendre de l'ordre de déclaration pour ne pas se décaler. */
.journal__acte {
  margin: 0;
  color: var(--texte-2);
  line-height: 1.65;
}


/* --- Étude de cas sans visuel ---
   Certains projets ne peuvent pas être montrés : le site a été refait
   depuis et ce qui est en ligne n'est plus notre travail. Plutôt qu'une
   capture qui s'attribuerait le travail d'un autre, la colonne porte une
   déclaration.

   Même rapport 8:5 que les captures, pour que la rangée reste équilibrée.
   La hauteur n'est pas figée : si le texte demande plus de place à
   l'étroit, la carte grandit au lieu de rogner. */

.etude__declaration {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  aspect-ratio: 8 / 5;
  padding: clamp(1.75rem, 4vw, 2.75rem);
  overflow: hidden;
  border-radius: var(--rayon-lg);
  background-image: linear-gradient(135deg, #002D50 0%, #0A1F3D 100%);
}

/* Halo décoratif, écho de l'image de partage et de la section « mer ». */
.etude__declaration::after {
  content: "";
  position: absolute;
  right: -18%;
  top: -38%;
  width: 70%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(93, 168, 211, 0.28) 0%, rgba(93, 168, 211, 0) 70%);
  pointer-events: none;
}

/* Encoche d'angle, comme sur les deux portraits. */
.etude__declaration::before {
  content: "";
  position: absolute;
  left: 1.15rem;
  top: 1.15rem;
  width: 2.75rem;
  height: 2.75rem;
  border-top: 0.1875rem solid var(--bleu-clair);
  border-left: 0.1875rem solid var(--bleu-clair);
  border-radius: var(--rayon) 0 0 0;
  opacity: 0.75;
}

.etude__declaration-label,
.etude__declaration-texte { position: relative; z-index: 1; }

.etude__declaration-label {
  margin: 0 0 0.75rem;
  font-family: var(--font-titres);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  /* 6,3:1 sur le marine : lisible en AA malgré la petite taille. */
  color: #93C5E2;
}

.etude__declaration-texte {
  margin: 0;
  font-family: var(--font-titres);
  font-size: clamp(1.25rem, 2.4vw, 1.75rem);
  font-weight: 600;
  line-height: 1.3;
  color: #FFFFFF;
}

.etude__angle {
  margin: 0 0 0.5rem;
  font-family: var(--font-titres);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--bleu-moyen);
}

.etude__titre {
  margin: 0 0 0.7em;
  font-size: clamp(1.25rem, 2.6vw, 1.625rem);
}

.etude__contexte { color: var(--texte-2); }

.etude__lien { margin: 1.5rem 0 0; }


/* --- Gabarit de fiche réalisation --- */

.fiche__entete { padding-block: clamp(2.25rem, 6vw, 3.5rem) clamp(1.5rem, 4vw, 2.5rem); }

.fiche__resume {
  max-width: 38rem;
  font-size: clamp(1.0625rem, 1.7vw, 1.1875rem);
  color: var(--texte-2);
}

/* Repères factuels : uniquement du vérifiable, jamais d'estimation. */
.fiche__reperes {
  display: grid;
  gap: 1.25rem;
  margin: clamp(1.75rem, 4vw, 2.25rem) 0 0;
  padding-top: 1.5rem;
  border-top: 0.0625rem solid var(--bordure);
}
@media (min-width: 45em) {
  .fiche__reperes { grid-template-columns: repeat(3, 1fr); }
}
.fiche__repere dt {
  font-family: var(--font-titres);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--bleu-moyen);
  margin-bottom: 0.3rem;
}
.fiche__repere dd {
  margin: 0;
  font-size: 0.9375rem;
  color: var(--texte);
}

.fiche__visuel {
  margin: 0 0 calc(var(--section-y) * -0.5);
  position: relative;
  z-index: 1;
}
.fiche__visuel svg {
  width: 100%;
  height: auto;
  border-radius: var(--rayon-lg);
  border: 0.0625rem solid var(--bordure);
}
.fiche__visuel figcaption {
  margin-top: 0.75rem;
  font-size: 0.875rem;
  color: var(--texte-2);
  text-align: center;
}

.fiche__corps { display: grid; gap: clamp(2.25rem, 5vw, 3rem); }

.fiche__bloc { max-width: 40rem; }
.fiche__bloc-titre {
  margin: 0 0 0.7em;
  font-size: clamp(1.1875rem, 2.4vw, 1.4375rem);
}
.fiche__bloc p { color: var(--texte-2); }

.fiche__note {
  padding-left: 1.25rem;
  border-left: 0.25rem solid var(--bordure-forte);
  font-size: 0.9375rem;
}

.fiche__renvoi { margin-top: 1.75rem; }

/* Zone à compléter : volontairement très visible en maquette. Ces blocs ne
   doivent JAMAIS subsister en production. Ils marquent ce que seul Rémy
   peut écrire, plutôt que de le laisser inventer par défaut. */
.a-completer {
  margin: 1.5rem 0;
  padding: 1.25rem 1.5rem;
  background-color: var(--erreur-fond);
  border: 0.0625rem dashed var(--erreur);
  border-radius: var(--rayon);
}
.a-completer__titre {
  margin: 0 0 0.5rem;
  font-family: var(--font-titres);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--erreur);
}
.a-completer p:not(.a-completer__titre) {
  margin: 0;
  font-size: 0.9375rem;
  color: var(--texte);
}


/* ==========================================================================
   30. PAGE À PROPOS : portrait, récit chapitré, la mer, méthode, CTA doux

   C'est la page la plus calme du site : aucune frise, aucun tableau, aucune
   carte, aucun carrousel. Le rythme vient de la largeur de lecture et d'une
   seule rupture visuelle (la section « mer »).
   ========================================================================== */

/* --- Portrait : photo à GAUCHE, à l'inverse du hero de l'accueil --- */
.portrait-section { padding-block: clamp(2.25rem, 6vw, 4rem) var(--section-y); }

.portrait {
  display: grid;
  gap: clamp(2rem, 5vw, 3.5rem);
  align-items: center;
}
@media (min-width: 56em) {
  .portrait { grid-template-columns: 0.85fr 1.15fr; }
}

.portrait__media { max-width: 22rem; margin-inline: auto; }
@media (min-width: 56em) { .portrait__media { margin-inline: 0; } }

.portrait__cadre { position: relative; margin: 0; }
/* Encoche d'angle en HAUT À GAUCHE : miroir de celle du hero de l'accueil,
   pour que les deux portraits ne soient pas le même objet. */
.portrait__cadre::before {
  content: "";
  position: absolute;
  left: -0.75rem;
  top: -0.75rem;
  width: 3.75rem;
  height: 3.75rem;
  border-top: 0.1875rem solid var(--bleu-clair);
  border-left: 0.1875rem solid var(--bleu-clair);
  border-radius: var(--rayon-lg) 0 0 0;
}
.portrait__photo {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--rayon-lg);
  border: 0.0625rem solid var(--bordure);
  background-color: var(--bleu-fond);
}
.portrait__legende {
  margin-top: 0.9rem;
  font-size: 0.875rem;
  color: var(--texte-2);
  text-align: center;
}

.portrait__accroche {
  font-size: clamp(1.0625rem, 1.6vw, 1.125rem);
  color: var(--texte-2);
  max-width: 34rem;
}

/* --- Récit chapitré : numéro discret, jamais un badge ---
   Volontairement différent du parcours numéroté du dépannage (badges pleins
   sur une piste) : ici le numéro est un simple repère de lecture. */
.recit { display: grid; gap: clamp(2.25rem, 5vw, 3rem); }

.recit__chapitre { max-width: 40rem; }

.recit__numero {
  margin: 0 0 0.35rem;
  font-family: var(--font-titres);
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  /* --bleu-clair est marqué « décoratif uniquement, jamais pour du texte »
     à sa déclaration : il donne 2,33:1 ici, contre 4,5 exigé. La règle
     était écrite, elle avait quand même été enfreinte. --bleu-moyen donne
     6:1 et garde le même registre. */
  color: var(--bleu-moyen);
}

.recit__titre {
  margin: 0 0 0.6em;
  font-size: clamp(1.1875rem, 2.4vw, 1.4375rem);
}

.recit__chapitre p:not(.recit__numero) { color: var(--texte-2); }

/* --- La mer : la rupture visuelle de l'à propos ---
   S'appuie sur le composant générique .section--sombre (voir utilitaires) ;
   ne restent ici que les réglages propres à cette section. */
/* Cette section ne porte PAS la classe .section : son rembourrage bas est
   volontairement plus généreux que --section-y (80 px au lieu de 64 en mobile).

   --sombre-bas le déclare au rattrapage de centre optique, qui calcule le haut
   à partir du bas : sans cette variable il prendrait --section-y comme
   référence et remonterait le contenu 9 px trop haut en mobile.

   Le padding-block reste, et n'est pas mort pour autant : .section--sombre
   :has(.vagues) est plus spécifique (0,2,0 contre 0,1,0) et l'écrase là où
   :has() est reconnu, mais ailleurs c'est le seul rembourrage de la section.
   Sans lui, elle n'en aurait aucun. Ne pas le retirer. */
.sans-promesse {
  --sombre-bas: clamp(5rem, 10vw, 8rem);
  padding-block: clamp(3.5rem, 8vw, 6rem) var(--sombre-bas);
}

.sans-promesse__interieur { max-width: 44rem; position: relative; z-index: 1; }

.sans-promesse__titre {
  font-size: clamp(1.5rem, 3.4vw, 2.125rem);
  margin-bottom: 0.8em;
}
.sans-promesse__texte {
  font-size: clamp(1.0625rem, 1.7vw, 1.1875rem);
  max-width: 40rem;
}

/* --- Méthode : intitulé au-dessus du détail, chevron discret ---
   Ni les filets en deux colonnes du guide de choix (maintenance), ni les
   lignes de liens des renvois (zone) : ici, de l'air et rien d'autre. */
.methode { display: grid; gap: clamp(1.75rem, 4vw, 2.25rem); }

.methode__point { max-width: 38rem; }

.methode__intitule {
  display: flex;
  align-items: flex-start;
  gap: 0.7em;
  margin: 0 0 0.4rem;
  font-family: var(--font-titres);
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.45;
  color: var(--bleu-principal);
}
.methode__intitule::before {
  content: "";
  flex: none;
  margin-top: calc((1.45em - 0.5em) / 2);
  width: 0.5em;
  height: 0.5em;
  border-top: 0.15em solid var(--bleu-clair);
  border-right: 0.15em solid var(--bleu-clair);
  transform: rotate(45deg);
}
.methode__detail {
  margin: 0;
  padding-left: 1.2em;   /* aligné sur le texte de l'intitulé, pas sur le chevron */
  color: var(--texte-2);
}

/* --- Ancrage --- */
.ancrage__texte {
  max-width: 40rem;
  color: var(--texte-2);
  margin-bottom: clamp(1.75rem, 4vw, 2.25rem);
}

/* --- CTA doux : une invitation, pas un encadré commercial ---
   Après un récit personnel, le bandeau encadré des autres pages sonnerait
   comme une relance. Ici, juste une phrase et un bouton. */
.cta-doux { text-align: center; }
.cta-doux__titre {
  max-width: 34rem;
  margin-inline: auto;
  font-size: clamp(1.3125rem, 2.8vw, 1.75rem);
  font-weight: 500;
}
.cta-doux__action { margin: 2rem 0 1rem; }
.cta-doux__mail { font-size: 0.9375rem; margin: 0; color: var(--texte-2); }


/* ==========================================================================
   31. PAGE ZONE : phrase canonique, double volet, bandeau anti-agence, renvois
   ========================================================================== */

/* La phrase canonique est répétée mot pour mot sur plusieurs pages. Ici, dans
   le hero de la page zone, c'est son emplacement le plus visible du site :
   elle tient le rôle du chapô, avec le poids qui va avec. */
.phrase-canonique {
  margin: 0;
  padding-left: 1.25rem;
  border-left: 0.25rem solid var(--bleu-clair);
  font-family: var(--font-titres);
  font-size: clamp(1.125rem, 2.2vw, 1.375rem);
  font-weight: 500;
  line-height: 1.45;
  color: var(--bleu-principal);
  max-width: 38rem;
}

/* --- Double volet ---
   UN bloc à deux faces, séparé par un filet, et non deux cartes distinctes
   comme .voies : « sur place » et « à distance » ne sont pas deux options
   entre lesquelles choisir, mais deux faces du même travail. */
.double-volet {
  display: grid;
  gap: 0;
  background-color: var(--surface);
  border: 0.0625rem solid var(--bordure);
  border-radius: var(--rayon-lg);
  overflow: hidden;
}
@media (min-width: 52em) {
  .double-volet { grid-template-columns: 1fr 1fr; }
}

.double-volet__face { padding: clamp(1.5rem, 3.5vw, 2.25rem); }

/* Le filet de séparation : horizontal en pile, vertical côte à côte. */
.double-volet__face + .double-volet__face {
  border-top: 0.0625rem solid var(--bordure);
}
@media (min-width: 52em) {
  .double-volet__face + .double-volet__face {
    border-top: 0;
    border-left: 0.0625rem solid var(--bordure);
  }
}

.double-volet__etiquette {
  margin: 0 0 0.9rem;
  font-family: var(--font-titres);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--bleu-moyen);
}
.double-volet__face p:not(.double-volet__etiquette) { color: var(--texte-2); }

/* --- Bandeau anti-agence ---
   Bloc éditorial, seul endroit du site où le mot « agence » sert à se
   positionner. Traitement affirmé : c'est une prise de parole. */
.bandeau-agence {
  max-width: 46rem;
  margin-inline: auto;
  padding: clamp(1.75rem, 4vw, 2.75rem) clamp(1.5rem, 4vw, 3rem);
  background-color: var(--surface);
  border: 0.0625rem solid var(--bordure-forte);
  border-left: 0.3125rem solid var(--bleu-principal);
  border-radius: var(--rayon-lg);
}
.bandeau-agence__titre {
  margin: 0 0 1rem;
  font-size: clamp(1.25rem, 2.6vw, 1.625rem);
}
.bandeau-agence p { color: var(--texte-2); }

/* --- Renvois services ---
   Sommaire de circulation, pas une vitrine : des lignes, jamais des cartes. */
.renvois {
  margin-top: clamp(1.75rem, 4vw, 2.5rem);
  border-top: 0.0625rem solid var(--bordure-forte);
}
.renvois__ligne {
  display: grid;
  gap: 0.25rem;
  padding: 1.1rem 0;
  border-bottom: 0.0625rem solid var(--bordure-forte);
}
@media (min-width: 45em) {
  .renvois__ligne {
    grid-template-columns: 16rem 1fr;
    gap: 1.5rem;
    align-items: baseline;
  }
}
.renvois__lien {
  font-family: var(--font-titres);
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--bleu-principal);
  text-decoration: none;
  border-bottom: 0.125rem solid transparent;
  justify-self: start;
  transition: border-color var(--anim-hover), color var(--anim-hover);
}
.renvois__lien:hover { color: var(--bleu-moyen); border-bottom-color: var(--bleu-clair); }
.renvois__note { font-size: 0.9375rem; color: var(--texte-2); }

/* Note de carte centrée (page zone) */
.carte-secteur__note--centre {
  max-width: 42rem;
  margin-inline: auto;
  margin-top: clamp(1.25rem, 3vw, 1.75rem);
  text-align: center;
}


/* ==========================================================================
   32. PAGE CONTACT : formulaire et colonne latérale

   La page est le CTA du site : aucune distraction, aucun bandeau d'appel à
   l'action, aucune vitrine. Le formulaire occupe la colonne principale, la
   latérale ne sert qu'à rassurer (email direct, suite du parcours, un avis).
   ========================================================================== */

.contact__grid {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4rem);
  align-items: start;
}
@media (min-width: 58em) {
  /* Le formulaire garde la part large : c'est lui qui travaille. */
  .contact__grid { grid-template-columns: 1.5fr 1fr; }
}

/* --- Le formulaire --- */

.formulaire {
  padding: clamp(1.5rem, 4vw, 2.5rem);
  background-color: var(--surface);
  border: 0.0625rem solid var(--bordure);
  border-radius: var(--rayon-lg);
}

.champ { margin-bottom: 1.5rem; }

.champ__label {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.4rem;
  font-family: var(--font-titres);
  font-weight: 600;
  color: var(--bleu-principal);
}
.champ__facultatif {
  font-family: var(--font-corps);
  font-size: 0.8125rem;
  font-weight: 400;
  color: var(--texte-2);
}

/* Astérisque des champs obligatoires. Elle est aria-hidden : le champ porte
   déjà « required », les lecteurs d'écran l'annoncent seuls, et lire
   « étoile » à chaque libellé n'apporte rien. Pour les voyants, en revanche,
   c'est le seul repère visuel : la couleur doit donc rester lisible.
   #B3261E donne 6,5:1 sur blanc, largement au-dessus des 4,5 exigés. */
.champ__requis {
  color: var(--erreur);
  font-weight: 600;
}

/* La légende explique l'astérisque. Sans elle, le symbole ne veut rien dire
   pour qui ne connaît pas la convention (WCAG 3.3.2). */
.formulaire__legende {
  margin: 0 0 1.25rem;
  font-size: 0.875rem;
  color: var(--texte-2);
}

.champ__saisie {
  display: block;
  width: 100%;
  padding: 0.75em 0.9em;
  font-family: var(--font-corps);
  font-size: 1rem;
  line-height: 1.5;
  color: var(--texte);
  background-color: var(--surface);
  border: 0.0625rem solid var(--bordure-forte);
  border-radius: var(--rayon);
  transition: border-color var(--anim-hover), box-shadow var(--anim-hover);
}
.champ__saisie:hover { border-color: var(--bleu-moyen); }
.champ__saisie:focus-visible {
  outline: 0.1875rem solid var(--focus);
  outline-offset: 0.125rem;
  border-color: var(--bleu-principal);
}
.champ__saisie::placeholder { color: var(--texte-2); opacity: 0.85; }

.champ__zone { resize: vertical; min-height: 8rem; }

/* Le chevron du select est dessiné en fond : on retire l'apparence système
   pour rester cohérent avec le reste des champs. */
.champ__select {
  appearance: none;
  padding-right: 2.5em;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--bleu-moyen) 50%),
    linear-gradient(135deg, var(--bleu-moyen) 50%, transparent 50%);
  background-position:
    calc(100% - 1.15em) calc(50% - 0.1em),
    calc(100% - 0.8em) calc(50% - 0.1em);
  background-size: 0.35em 0.35em, 0.35em 0.35em;
  background-repeat: no-repeat;
}

.champ__aide {
  margin: 0.4rem 0 0;
  font-size: 0.875rem;
  color: var(--texte-2);
}

/* --- Compteur de caractères ---
   Posé par le script, jamais visible sans lui (l'attribut hidden est dans
   le HTML). Sans JavaScript, minlength assure la même contrainte et le
   navigateur affiche son propre message. */

.champ__compteur {
  margin: 0.4rem 0 0;
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
  color: var(--texte-2);
}
.champ__compteur[hidden] { display: none; }

/* Le passage au vert n'est qu'un renfort : le texte du compteur dit déjà
   où l'on en est, la couleur ne porte donc jamais l'information seule. */
.champ__compteur--ok { color: #1E7A46; }

/* --- États d'erreur ---
   La couleur ne porte jamais seule l'information : il y a toujours le
   message en texte, et aria-invalid posé par le JS. */
.champ__erreur {
  margin: 0.45rem 0 0;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--erreur);
}
.champ__erreur[hidden] { display: none; }

.champ__saisie[aria-invalid="true"] {
  border-color: var(--erreur);
  background-color: var(--erreur-fond);
}
.champ__saisie[aria-invalid="true"]:focus-visible { outline-color: var(--erreur); }

/* --- Résumé des erreurs, en tête de formulaire ---
   Affiché uniquement au retour du serveur. Il porte le focus, d'où le
   contour au focus : sinon on déplace le curseur clavier sans que rien ne
   le montre à l'écran. */

.formulaire__resume {
  margin: 0 0 1.75rem;
  padding: 1.15rem 1.35rem;
  color: var(--erreur);
  background-color: var(--erreur-fond);
  border-left: 0.25rem solid var(--erreur);
  border-radius: 0 var(--rayon) var(--rayon) 0;
}
.formulaire__resume:focus-visible {
  outline: 0.1875rem solid var(--erreur);
  outline-offset: 0.25rem;
}

.formulaire__resume-titre {
  margin: 0;
  font-family: var(--font-titres);
  font-size: 1rem;
  font-weight: 600;
}

.formulaire__resume-liste {
  margin: 0.6rem 0 0;
  padding-left: 1.15rem;
  list-style: disc;
  font-size: 0.9375rem;
  line-height: 1.65;
}
.formulaire__resume-liste a { color: inherit; }

/* --- Champ piège ---
   Déporté hors du cadre plutôt que masqué par display:none : certains
   robots ignorent les champs explicitement cachés, mais remplissent
   celui-ci. Il reste hors tabulation et hors arbre d'accessibilité (voir
   tabindex et aria-hidden dans le gabarit), donc invisible aux humains,
   au clavier comme au lecteur d'écran. */

.piege {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --- Vérification anti-robot Cloudflare ---
   Ne s'affiche que si les clés sont posées dans wp-config.php. */

.cf-turnstile { margin-bottom: 1.5rem; }

/* --- Confirmation d'envoi, à la place du formulaire --- */

.formulaire__succes {
  padding: clamp(1.75rem, 4vw, 2.5rem);
  background-color: var(--bleu-fond);
  border-left: 0.25rem solid var(--bleu-moyen);
  border-radius: 0 var(--rayon-lg) var(--rayon-lg) 0;
}
.formulaire__succes:focus-visible {
  outline: 0.1875rem solid var(--focus);
  outline-offset: 0.25rem;
}

.formulaire__succes-titre {
  margin: 0 0 0.75rem;
  font-size: clamp(1.375rem, 3vw, 1.75rem);
  color: var(--bleu-principal);
}

.formulaire__succes p { margin: 0 0 1rem; }
.formulaire__succes-suite { margin: 1.5rem 0 0; }

/* --- Pied de formulaire --- */

.formulaire__action { margin: 0 0 1.25rem; }

.formulaire__rgpd {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--texte-2);
}

.formulaire__retour {
  margin: 1.5rem 0 0;
  padding: 1rem 1.25rem;
  font-weight: 500;
  color: var(--bleu-principal);
  background-color: var(--bleu-fond);
  border-left: 0.25rem solid var(--bleu-clair);
  border-radius: 0 var(--rayon) var(--rayon) 0;
}
.formulaire__retour[hidden] { display: none; }

/* --- Colonne latérale --- */

.contact__lateral { display: grid; gap: clamp(1.75rem, 4vw, 2.25rem); }

.contact__email {
  padding: clamp(1.25rem, 3vw, 1.5rem);
  background-color: var(--surface);
  border: 0.0625rem solid var(--bordure);
  border-radius: var(--rayon);
}
.contact__email-intro {
  margin: 0 0 0.4rem;
  font-size: 0.9375rem;
  color: var(--texte-2);
}
.contact__email-adresse {
  margin: 0;
  font-family: var(--font-titres);
  font-size: clamp(1.0625rem, 2vw, 1.1875rem);
  font-weight: 600;
  word-break: break-word;
}

/* « Ce qui se passe ensuite » : trois jalons compacts.
   Forme volontairement plus légère que le parcours numéroté de la page
   dépannage et que les trois pas de la page maintenance : ici c'est une
   colonne latérale, elle rassure sans concurrencer le formulaire. */
.ensuite__titre {
  margin: 0;
  font-family: var(--font-titres);
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--bleu-principal);
}

.ensuite {
  counter-reset: ensuite;
  display: grid;
  gap: 1.1rem;
  list-style: none;
  margin-top: -0.75rem;
}
.ensuite__pas {
  counter-increment: ensuite;
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  font-size: 0.9375rem;
  color: var(--texte-2);
}
.ensuite__pas::before {
  content: counter(ensuite);
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.625rem;
  height: 1.625rem;
  font-family: var(--font-titres);
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--bleu-principal);
  background-color: var(--bleu-fond);
  border: 0.0625rem solid var(--bordure-forte);
  border-radius: 50%;
}

.avis-lateral {
  margin: 0;
  padding-left: 1.25rem;
  border-left: 0.25rem solid var(--bleu-clair);
}
.avis-lateral p {
  margin: 0 0 0.5rem;
  font-size: 0.9375rem;
  font-style: italic;
  color: var(--texte);
}
.avis-lateral footer { font-size: 0.8125rem; color: var(--texte-2); }
.avis-lateral cite { font-style: normal; font-weight: 600; color: var(--bleu-principal); }


/* ==========================================================================
   33. AVIS CARROUSEL : un avis visible à la fois, défilement automatique.
   Utilisé quand une paire de cartes (.avis-duo) répéterait la forme d'une
   section deux-colonnes juste au-dessus (ex. le bloc "deux voies").

   Base (sans JS) : tous les avis restent empilés et visibles, aucune
   pagination, aucun contenu masqué (règle du robot). Amélioration JS
   (.avis-carrousel--actif) : un seul avis affiché à la fois, en fondu,
   avec défilement automatique.

   Aucun bouton, aucune pagination : le défilement s'interrompt au survol et
   au focus clavier, et s'arrête définitivement dès que le visiteur clique ou
   navigue aux flèches. C'est ce qui satisfait WCAG 2.2.2 sans commande
   visible : le mécanisme d'arrêt existe pour la souris, le tactile ET le
   clavier (le conteneur reçoit tabindex + aria par le JS).
   Neutralisé entièrement en prefers-reduced-motion (comme la frise).
   ========================================================================== */

.avis-carrousel {
  max-width: 42rem;
  margin: 0 auto;
  text-align: center;
}

.avis-carrousel__piste { display: grid; gap: clamp(1.5rem, 4vw, 2.5rem); }

.avis-carrousel__slide { margin: 0; }
.avis-carrousel__slide p {
  margin: 0 0 1rem;
  font-family: var(--font-titres);
  font-size: clamp(1.25rem, 2.6vw, 1.625rem);
  font-weight: 500;
  line-height: 1.5;
  color: var(--bleu-principal);
}
.avis-carrousel__slide footer { font-size: 0.9375rem; color: var(--texte-2); }
.avis-carrousel__slide cite { font-style: normal; font-weight: 600; color: var(--bleu-principal); }
/* La pastille de plateforme est blanche : sur un fond clair, on la teinte */
.avis-carrousel__slide .chemin__avis-source { background-color: var(--bleu-fond); }

/* Amélioration JS : les avis se superposent dans la même cellule de grille
   (grid-area partagée), un seul reste visible, en fondu. */
.avis-carrousel--actif .avis-carrousel__slide {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  transition: opacity 500ms ease;
  pointer-events: none;
}
.avis-carrousel--actif .avis-carrousel__slide.est-actif {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

/* Le conteneur devient focusable (tabindex posé par le JS) : le contour de
   focus doit respirer autour de la citation, pas la serrer. */
.avis-carrousel--actif:focus-visible { outline-offset: 0.75rem; }
