/* ==========================================================================
   Red Zone — feuille de style
   Palette d'origine conservée : bleu #233162, rouge #A02D29, bordeaux #611C1B

   DEUX THÈMES
   Le thème « marine » est celui par défaut, défini sur :root ci-dessous.
   Le thème « rouge », inspiré de la carte d'affaires, ne redéfinit que les
   variables : aucune règle de mise en page n'est dupliquée. Il s'active par
   la classe theme-rouge sur <html>, posée par includes/header.php.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Variables
   -------------------------------------------------------------------------- */

:root {
  /* Couleurs composées, exprimées en composantes pour pouvoir moduler
     leur transparence. Chaque thème les redéfinit. */
  --voile-rvb:   14, 21, 48;    /* voile du héros et du bandeau */
  --voile-sec-rvb: 16, 24, 54;  /* voile des sections sombres, très légèrement plus clair */
  --panneau-rvb: 17, 25, 56;    /* fond des cartes sur surface sombre */
  --lueur-rvb:   160, 45, 41;   /* halo rouge des dégradés */
  --ombre-rvb:   19, 28, 61;    /* teinte des ombres portées */

  --motif-image: url("../img/circuit.svg");

  /* Couleurs de marque */
  --bleu-900: #131c3d;
  --bleu-800: #1a2450;
  --bleu-700: #233162;
  --bleu-600: #2e4080;
  --bleu-500: #3d539e;
  --bleu-100: #e8ecf7;
  --bleu-50:  #f4f6fc;

  --rouge-800: #611c1b;
  --rouge-700: #832523;
  --rouge-600: #a02d29;
  --rouge-500: #c13a34;
  /* Rouge éclairci, réservé au TEXTE posé sur les fonds marine.
     Le #c13a34 n'y atteignait que 2,86 de contraste, sous le minimum de 4,5. */
  --rouge-400: #e86a62;
  --rouge-100: #fbeceb;

  /* Neutres */
  --blanc:     #ffffff;
  --gris-50:   #f7f8fb;
  --gris-100:  #eef0f6;
  --gris-200:  #dfe3ed;
  --gris-400:  #9aa2b8;
  --gris-600:  #5c6480;
  --gris-800:  #2b3145;

  /* Rôles */
  --fond:            var(--blanc);
  --fond-alt:        var(--gris-50);
  --texte:           var(--gris-800);
  --texte-doux:      var(--gris-600);
  --titre:           var(--bleu-700);
  --accent:          var(--rouge-600);
  --bordure:         var(--gris-200);

  /* Typographie */
  --police-titre: "Jura", "Trebuchet MS", sans-serif;
  --police-texte: "Montserrat", "Segoe UI", system-ui, sans-serif;

  /* Rythme */
  --largeur-max: 1200px;
  --gouttiere:   clamp(1.25rem, 4vw, 2.5rem);
  --section-y:   clamp(3.5rem, 8vw, 6.5rem);
  --rayon:       14px;
  --rayon-sm:    8px;

  /* Ombres */
  --ombre-sm: 0 1px 2px rgba(var(--ombre-rvb), .06), 0 2px 6px rgba(var(--ombre-rvb), .05);
  --ombre-md: 0 4px 12px rgba(var(--ombre-rvb), .07), 0 12px 28px rgba(var(--ombre-rvb), .07);
  --ombre-lg: 0 10px 24px rgba(var(--ombre-rvb), .10), 0 28px 60px rgba(var(--ombre-rvb), .12);

  --transition: 180ms cubic-bezier(.4, 0, .2, 1);

  /* Motif de circuit imprimé : intensité par défaut, ajustée section par section */
  --motif-opacite: .30;
  /* La tuile est dessinée en 1200 px. L'afficher un peu plus petit resserre
     le maillage et affine les pistes, sans perdre en netteté (c'est du SVG). */
  --motif-taille:  820px;
}

/* --------------------------------------------------------------------------
   1 bis. Thème rouge et noir
   Reprend les couleurs de la carte d'affaires : noir profond, pistes rouges,
   accents écarlates. Seules les variables changent.

   Les noms de variables gardent leur préfixe « bleu » : ils désignent un rôle
   dans la mise en page (fond sombre, couleur de titre, teinte claire), pas une
   teinte. Les renommer aurait obligé à retoucher 1500 lignes sans rien changer
   au résultat.
   -------------------------------------------------------------------------- */

html.theme-rouge {
  /* Rôle « fond sombre » : noirs très légèrement chauds */
  --bleu-900: #0a0607;
  --bleu-800: #17090b;
  /* Rôle « couleur des titres sur fond clair » */
  --bleu-700: #2b1114;
  /* Rôle « liens » */
  --bleu-600: #a8231d;
  /* Rôle « bordure de champ au focus » */
  --bleu-500: #d0342c;
  /* Rôles « teintes claires » : blancs légèrement rosés */
  --bleu-100: #f7e3e2;
  --bleu-50:  #fdf4f3;

  /* Rouges de marque, plus vifs que dans le thème marine */
  --rouge-800: #5c1512;
  --rouge-700: #8f1f1a;
  --rouge-600: #c62828;
  --rouge-500: #e33b31;
  /* Rouge éclairci pour le TEXTE sur fond noir. Vérifié à 6,9 de contraste. */
  --rouge-400: #ff8079;
  --rouge-100: #fdecea;

  /* Neutres réchauffés : un gris franchement neutre jurerait avec le rouge */
  --gris-50:   #faf7f7;
  --gris-100:  #f2eded;
  --gris-200:  #e4dbdb;
  --gris-400:  #a89b9b;
  --gris-600:  #6b5c5c;
  --gris-800:  #2f2223;

  /* Couleurs composées */
  --voile-rvb:     10, 6, 7;
  --voile-sec-rvb: 13, 8, 9;
  --panneau-rvb: 26, 13, 15;
  --lueur-rvb:   198, 40, 40;
  --ombre-rvb:   30, 10, 12;

  /* Le motif reprend les mêmes tracés, en rouge */
  --motif-image: url("../img/circuit-rouge.svg");
}

/* Les fonds sombres du thème rouge sont presque noirs : le motif y ressort
   davantage, on le retient donc un peu. */
html.theme-rouge .section--fonce::before { opacity: .26; }
html.theme-rouge .heros::before          { opacity: .34; }

/* --------------------------------------------------------------------------
   1 ter. Déclaration de la variable de parallaxe
   ...
   Point de performance important : sans « inherits: false », modifier cette
   variable sur une section obligerait le navigateur à recalculer le style de
   TOUS ses descendants, à chaque image du défilement. Sur une section de
   plusieurs centaines d'éléments, c'est la principale cause de saccade.
   Déclarée ainsi, la modification n'affecte que l'élément lui-même.
   -------------------------------------------------------------------------- */

@property --parallaxe-y {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}

/* --------------------------------------------------------------------------
   2. Réinitialisation
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 100px;
}

body {
  background: var(--fond);
  color: var(--texte);
  font-family: var(--police-texte);
  font-size: 1rem;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg, video { display: block; max-width: 100%; }
img { height: auto; }

a { color: var(--bleu-600); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--rouge-600); }

button, input, select, textarea { font: inherit; color: inherit; }

h1, h2, h3, h4 {
  font-family: var(--police-titre);
  color: var(--titre);
  font-weight: 600;
  line-height: 1.2;
  text-wrap: balance;
}

h1 { font-size: clamp(2.25rem, 5.5vw, 3.75rem); font-weight: 500; letter-spacing: -.01em; }
h2 { font-size: clamp(1.75rem, 3.6vw, 2.6rem); font-weight: 500; }
h3 { font-size: clamp(1.15rem, 2vw, 1.4rem); }
h4 { font-size: 1.05rem; }

p { text-wrap: pretty; }

:focus-visible {
  outline: 3px solid var(--rouge-500);
  outline-offset: 3px;
  border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* --------------------------------------------------------------------------
   3. Utilitaires
   -------------------------------------------------------------------------- */

.conteneur {
  width: 100%;
  max-width: var(--largeur-max);
  margin-inline: auto;
  padding-inline: var(--gouttiere);
}

.conteneur--etroit { max-width: 760px; }

.visuellement-cache {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.lien-evitement {
  position: absolute;
  top: -100px; left: 1rem;
  z-index: 999;
  padding: .75rem 1.25rem;
  background: var(--bleu-700);
  color: var(--blanc);
  border-radius: 0 0 var(--rayon-sm) var(--rayon-sm);
  text-decoration: none;
  transition: top var(--transition);
}
.lien-evitement:focus { top: 0; color: var(--blanc); }

.icone { width: 24px; height: 24px; flex: none; }
.icone--sm { width: 17px; height: 17px; stroke-width: 1.8; }
.icone--lg { width: 30px; height: 30px; }

.section {
  position: relative;
  isolation: isolate;
  padding-block: var(--section-y);
}

/* Toutes les sections claires portent le motif en filigrane : plus aucune
   grande surface de blanc plat.
   Cette couche-ci est FIXE. À 7 % d'opacité, un déplacement de parallaxe est
   invisible, alors qu'il coûte une couche composée de plus à chaque image. */
.section::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: var(--motif-image);
  background-size: var(--motif-taille) var(--motif-taille);
  background-repeat: repeat;
  opacity: .05;
  pointer-events: none;
}
.section > * { position: relative; z-index: 1; }

.section--alt { background: var(--fond-alt); }
.section--alt::before { opacity: .085; }

.section--fonce {
  background:
    radial-gradient(1000px 500px at 12% -10%, rgba(var(--lueur-rvb), .28), transparent 62%),
    linear-gradient(160deg, var(--bleu-800) 0%, var(--bleu-900) 100%);
  color: rgba(255, 255, 255, .82);
  /* Indispensable : la couche du motif déborde volontairement de 14 % en haut
     et en bas pour pouvoir glisser sans découvrir de vide. Sans ce découpage,
     ce débord se prolongeait dans le pied de page et s'y arrêtait net. */
  overflow: hidden;
}
/* Seules les sections sombres gardent la parallaxe : le motif y est assez
   visible pour que le mouvement se remarque. Pas de masque ici — un masque
   sort la couche du chemin rapide du compositeur et la fait repeindre à
   chaque image. Le voile ci-dessous se charge d'adoucir les bords. */
.section--fonce::before {
  inset: -14% 0;
  opacity: .30;
  transform: translate3d(0, var(--parallaxe-y, 0px), 0);
}

/* Voile posé sur le motif, sous le contenu : le circuit reste visible sur les
   bords et s'efface au centre, là où se trouve le texte. */
.section--fonce::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    radial-gradient(ellipse 78% 70% at 50% 50%,
      rgba(var(--voile-sec-rvb), .80) 0%, rgba(var(--voile-sec-rvb), .45) 55%, transparent 85%),
    linear-gradient(180deg, rgba(var(--voile-sec-rvb), .5), transparent 18%, transparent 82%, rgba(var(--voile-sec-rvb), .5));
  pointer-events: none;
}

.section--fonce h2, .section--fonce h3 { color: var(--blanc); }

.surtitre {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  margin-bottom: 1rem;
  font-family: var(--police-titre);
  font-size: .8rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--rouge-600);
}
.surtitre::before {
  content: "";
  width: 28px; height: 2px;
  background: var(--rouge-600);
}
/* Le surtitre est du petit texte en capitales : sur les fonds marine il lui
   faut le rouge éclairci, sans quoi il tombe à 2,3 de contraste. */
.section--fonce .surtitre,
.heros .surtitre {
  color: var(--rouge-400);
}
.section--fonce .surtitre::before,
.heros .surtitre::before {
  background: var(--rouge-400);
}

.entete-section { max-width: 720px; margin-bottom: clamp(2.5rem, 5vw, 3.5rem); }
.entete-section--centre { margin-inline: auto; text-align: center; }
.entete-section--centre .surtitre { justify-content: center; }
.entete-section p {
  margin-top: 1rem;
  font-size: 1.075rem;
  color: var(--texte-doux);
}
.section--fonce .entete-section p { color: rgba(255, 255, 255, .78); }

/* --------------------------------------------------------------------------
   4. Boutons
   -------------------------------------------------------------------------- */

.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  padding: .85rem 1.6rem;
  border: 2px solid transparent;
  border-radius: 999px;
  font-family: var(--police-titre);
  font-size: .95rem;
  font-weight: 700;
  letter-spacing: .03em;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--transition), box-shadow var(--transition),
              background-color var(--transition), color var(--transition),
              border-color var(--transition);
}
.bouton:hover { transform: translateY(-2px); }
.bouton:active { transform: translateY(0); }

.bouton--primaire {
  background: var(--rouge-600);
  border-color: var(--rouge-600);
  color: var(--blanc);
  box-shadow: 0 6px 18px rgba(var(--lueur-rvb), .32);
}
.bouton--primaire:hover {
  background: var(--rouge-700);
  border-color: var(--rouge-700);
  color: var(--blanc);
  box-shadow: 0 10px 26px rgba(var(--lueur-rvb), .38);
}

.bouton--secondaire {
  background: transparent;
  border-color: var(--bleu-700);
  color: var(--bleu-700);
}
.bouton--secondaire:hover {
  background: var(--bleu-700);
  color: var(--blanc);
}

.bouton--clair {
  background: transparent;
  border-color: rgba(255, 255, 255, .55);
  color: var(--blanc);
}
.bouton--clair:hover {
  background: var(--blanc);
  border-color: var(--blanc);
  color: var(--bleu-700);
}



.bouton--bloc { width: 100%; }

.groupe-boutons {
  display: flex;
  flex-wrap: wrap;
  gap: .9rem;
  margin-top: 2rem;
}

/* Ligne « autres façons de nous joindre », sous un groupe de boutons.
   Le courriel et les messageries passent devant ; le telephone reste
   accessible, mais annonce comme la voie des urgences. */
.note-joindre {
  margin-top: 1.1rem;
  font-size: .92rem;
  color: var(--texte-doux);
}
.note-joindre a {
  color: var(--rouge-600);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid rgba(var(--lueur-rvb), .4);
}
.note-joindre a:hover {
  color: var(--rouge-700);
  border-bottom-color: currentColor;
}

.note-joindre--clair { color: rgba(255, 255, 255, .74); }
.note-joindre--clair a {
  color: var(--blanc);
  border-bottom-color: rgba(255, 255, 255, .45);
}
.note-joindre--clair a:hover { border-bottom-color: var(--blanc); }

.lien-fleche {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .92rem;
  color: var(--rouge-600);
  text-decoration: none;
}
.lien-fleche .icone { width: 18px; height: 18px; transition: transform var(--transition); }
.lien-fleche:hover { color: var(--rouge-700); }
.lien-fleche:hover .icone { transform: translateX(4px); }

/* --------------------------------------------------------------------------
   5. Barre d'information + en-tête
   -------------------------------------------------------------------------- */

.barre-info {
  background: var(--bleu-900);
  color: rgba(255, 255, 255, .78);
  font-size: .82rem;
}
.barre-info__interieur {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .4rem 1.75rem;
  padding-block: .55rem;
}
.barre-info__item {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  color: inherit;
  text-decoration: none;
}
a.barre-info__item:hover { color: var(--blanc); }
.barre-info__item .icone { color: var(--rouge-400); }
/* Bloc « ecrivez-nous » : le libelle donne son sens aux deux icones. */
.barre-info__ecrire {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
}
.barre-info__ecrire-libelle { white-space: nowrap; }

/* Les heures prennent le bord droit, la place qu'occupait le badge
   « Urgence : (514) 795-4902 » jusqu'au 25 septembre 2026. Sans elles, la
   barre aurait tout empile a gauche et laisse un vide a droite. */
.barre-info__item--heures { margin-left: auto; }

/* --------------------------------------------------------------------------
   5 bis. Réseaux sociaux
   -------------------------------------------------------------------------- */

.reseaux {
  display: flex;
  align-items: center;
  gap: .4rem;
  margin: 0 0 0 .35rem;
  padding: 0;
  list-style: none;
}
.barre-info__ecrire .reseaux { margin-left: 0; }

.reseaux__lien {
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  border-radius: 50%;
  color: rgba(255, 255, 255, .9);
  background: rgba(255, 255, 255, .12);
  text-decoration: none;
  transition: background-color var(--transition), color var(--transition),
              transform var(--transition), box-shadow var(--transition);
}
.reseaux__lien .icone { width: 20px; height: 20px; }

.reseaux__lien:hover {
  color: var(--blanc);
  transform: translateY(-2px) scale(1.06);
}
.reseaux__lien--facebook  { background: rgba(24, 119, 242, .38); }
.reseaux__lien--facebook:hover {
  background: #1877f2;
  box-shadow: 0 4px 14px rgba(24, 119, 242, .55);
}
.reseaux__lien--instagram { background: rgba(220, 39, 67, .34); }
.reseaux__lien--instagram:hover {
  background: linear-gradient(45deg, #f09433, #dc2743 45%, #bc1888);
  box-shadow: 0 4px 14px rgba(188, 24, 136, .5);
}

/* Version plus grande dans le pied de page */
.reseaux--pied { margin: 1.25rem 0 0; gap: .7rem; }
.reseaux--pied .reseaux__lien { width: 48px; height: 48px; }
.reseaux--pied .reseaux__lien .icone { width: 26px; height: 26px; }

/* --------------------------------------------------------------------------
   5 ter. Blocs « écrivez-nous » des réseaux sociaux
   -------------------------------------------------------------------------- */

.messageries {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1rem;
  margin-top: 1.75rem;
}

.messagerie {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  padding: 1.25rem;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  background: var(--blanc);
  box-shadow: var(--ombre-sm);
  text-decoration: none;
  transition: transform var(--transition), box-shadow var(--transition),
              border-color var(--transition);
}
.messagerie:hover {
  transform: translateY(-3px);
  box-shadow: var(--ombre-md);
}

.messagerie__icone {
  display: grid;
  place-items: center;
  flex: none;
  width: 52px; height: 52px;
  border-radius: 14px;
  color: var(--blanc);
}
.messagerie__icone .icone { width: 30px; height: 30px; }

.messagerie--facebook .messagerie__icone { background: #1877f2; }
.messagerie--facebook:hover { border-color: #1877f2; }
.messagerie--instagram .messagerie__icone {
  background: linear-gradient(45deg, #f09433, #dc2743 45%, #bc1888);
}
.messagerie--instagram:hover { border-color: #dc2743; }

/* Les deux lignes sont des <span> dans un lien : il faut les empiler. */
.messagerie__titre {
  display: block;
  font-family: var(--police-titre);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--titre);
  margin-bottom: .25rem;
}
.messagerie__texte {
  display: block;
  font-size: .88rem;
  color: var(--texte-doux);
  line-height: 1.6;
}

/* En-tête collant, donc redessiné en permanence pendant le défilement.
   Aucun backdrop-filter ici : un flou d'arrière-plan sur un élément collant
   oblige le navigateur à reflouter toute la page derrière lui à chaque image.
   C'était la cause principale des saccades et du texte qui « bavait ».
   Un fond opaque donne le même effet visuel pour un coût nul. */
.entete {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--blanc);
  border-bottom: 1px solid var(--bordure);
  transition: box-shadow var(--transition);
}
.entete.est-defile { box-shadow: var(--ombre-md); }

.entete__interieur {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding-block: .8rem;
}

.entete__logo { flex: none; line-height: 0; }
.entete__logo img { width: auto; height: 46px; }

.entete__bascule {
  display: none;
  margin-left: auto;
  padding: .5rem;
  background: none;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-sm);
  color: var(--bleu-700);
  cursor: pointer;
}
.entete__bascule-fermer { display: none; }
.entete__bascule[aria-expanded="true"] .entete__bascule-ouvrir { display: none; }
.entete__bascule[aria-expanded="true"] .entete__bascule-fermer { display: block; }

.nav {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex: 1;
  min-width: 0;
}

/* LE MENU AU CENTRE DE LA BARRE, pas au centre de l'espace restant.
   Jusqu'au 25 septembre 2026, il commencait juste apres le logo et le bouton
   rouge « Appel d'urgence » etait pousse au bord droit. Le bouton retire,
   Dominic a demande de recentrer. Un simple justify-content: center l'aurait
   centre dans l'espace A DROITE du logo, donc decale vers la droite d'une
   demi-largeur de logo. Trois colonnes 1fr / auto / 1fr : la troisieme, vide,
   fait contrepoids au logo, et le menu tombe au vrai centre.
   Seulement au-dessus de 1120 px : en dessous, c'est le panneau mobile. */
@media (min-width: 1121px) {
  .entete__interieur {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
  }
  .entete__logo { justify-self: start; }
  .nav { flex: none; justify-self: center; }
}
.nav__liste {
  display: flex;
  align-items: center;
  gap: .35rem;
  list-style: none;
  padding: 0;
}
.nav__lien {
  position: relative;
  display: block;
  padding: .55rem .7rem;
  border-radius: var(--rayon-sm);
  font-family: var(--police-titre);
  font-size: 1.12rem;
  font-weight: 600;
  color: var(--bleu-700);
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--transition), background-color var(--transition);
}

@media (min-width: 1121px) {
  /* PLACEE APRES LA REGLE DE BASE .nav__lien, ET C'EST VOULU : a priorite
     egale, la derniere regle gagne. Une premiere version se trouvait plus haut,
     dans le groupe de centrage : l'interligne s'appliquait, la taille non,
     reprise par le 1,12 rem de la regle de base. Un essai injecte avec
     !important l'avait masque — d'ou la verification sur le vrai fichier. */
  /* PLUS GROS, MAIS SEULEMENT LA OU IL Y A LA PLACE. Le bouton rouge parti,
     Dominic a trouve le menu « un peu vide » et demande un texte plus gros
     (25 septembre 2026). La taille suit la largeur de l'ecran :
       1121 px et moins -> 1,12 rem, comme avant : a cette largeur le menu n'a
                           que 59 px de marge autour du logo, rien a gagner ;
       vers 1380 px et + -> 1,3 rem, soit 16 % de plus.
     Pourquoi s'arreter a 1,3 : la barre est plafonnee a 1200 px quelle que soit
     la taille de l'ecran. Essaye a 1,4 rem, le menu arrivait a 31 px du logo
     des 1600 px — centre, mais a l'etroit. A 1,3 rem il reste 58 px, le meme
     degagement qu'a la plus petite largeur.
     LE line-height EST INDISPENSABLE. Avec l'interligne general du site, un
     lien plus gros depassait la hauteur du logo et l'en-tete grandissait de
     5 px — pile la marge prevue pour que l'accueil tienne sur un ecran
     (calc(100svh - 8.25rem) du heros). A 1,3 l'en-tete ne depend plus que du
     logo : 124 px, barre du haut comprise, a toutes les largeurs. */
  .nav__lien {
    font-size: clamp(1.12rem, 0.35rem + 1.1vw, 1.3rem);
    line-height: 1.3;
  }
}
.nav__lien:hover { background: var(--bleu-50); color: var(--rouge-600); }
.nav__lien.est-actif { color: var(--rouge-600); }
.nav__lien.est-actif::after {
  content: "";
  position: absolute;
  left: .7rem; right: .7rem; bottom: .25rem;
  height: 2px;
  border-radius: 2px;
  background: var(--rouge-600);
}

@media (max-width: 760px) {
  /* Les heures cedent la place : le courriel et les messageries sont ce qui
     doit rester visible sur un petit ecran. Elles disparaissaient des 1120 px
     tant que le badge du numero d'urgence occupait la barre; depuis son
     retrait, le 25 septembre 2026, elles tiennent jusqu'aux tablettes. */
  .barre-info__item--heures { display: none; }
}

@media (max-width: 600px) {
  .barre-info__ecrire-libelle { display: none; }
  .barre-info__interieur { justify-content: space-between; }
}

@media (max-width: 1120px) {
  /* Le bouton doit passer AU-DESSUS du panneau. Celui-ci est en position fixe,
     couvre tout l'écran et porte un fond blanc opaque; comme il vient après le
     bouton dans le HTML et qu'aucun des deux n'a de z-index, il le recouvrait.
     La croix de fermeture existait donc, mais invisible : il ne restait que la
     touche Échap pour sortir du menu, ce qu'un visiteur ne devine pas.
     Signalé par Dominic le 15 septembre 2026. */
  .entete__bascule { display: block; position: relative; z-index: 1; }
  .nav {
    position: fixed;
    inset: auto 0 0 0;
    top: 0;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: .5rem;
    margin: 0;
    /* 8rem et non 6 : à 6rem, le premier lien passait sous le bouton de
       fermeture. Cette marge doit rester supérieure à la hauteur de l'en-tête
       plus un espace de respiration. */
    padding: 8rem var(--gouttiere) 2rem;
    background: var(--blanc);
    overflow-y: auto;
    /* LE PANNEAU JAILLIT DU BOUTON, il ne glisse plus depuis la droite.
       Avant : transform: translateX(100%), donc une nappe blanche qui balayait
       toute la page. Dominic a demandé le 15 septembre 2026 que le mouvement
       parte du hamburger, « pour dire que tout est rendu là ».

       Le centre et le rayon du cercle sont posés par le script, qui MESURE la
       position réelle du bouton. Les valeurs de repli ici ne servent que si le
       JavaScript ne s'exécute pas. */
    clip-path: circle(0px at var(--origine-x, 92%) var(--origine-y, 3rem));
    visibility: hidden;
    transition: clip-path .42s cubic-bezier(.4, 0, .2, 1),
                visibility .42s;
  }
  .nav.est-ouvert {
    clip-path: circle(var(--rayon-menu, 150vmax) at var(--origine-x, 92%) var(--origine-y, 3rem));
    visibility: visible;
  }
  .nav__liste { flex-direction: column; align-items: stretch; gap: .25rem; }
  .nav__lien {
    padding: .9rem 1rem;
    font-size: 1.1rem;
    border-bottom: 1px solid var(--bordure);
    border-radius: 0;
  }
  .nav__lien.est-actif::after { display: none; }

  body.menu-ouvert { overflow: hidden; }
}

/* --------------------------------------------------------------------------
   6. Héros
   -------------------------------------------------------------------------- */

/* MARGES LIEES A LA HAUTEUR, ET NON A LA LARGEUR.
   Elles valaient clamp(4rem, 9vw, 7.5rem) : sur un ecran ultra-large, 9vw
   depassait le plafond et donnait 120 px en haut comme en bas, alors que c'est
   la HAUTEUR qui manquait. Resultat, la derniere ligne du heros etait coupee.
   Dominic l'a signale le 15 septembre 2026 sur un 3440 x 1440.
   Avec vh, la marge se resserre sur un ecran bas et respire sur un grand. */
.heros {
  position: relative;
  padding-block: clamp(2.5rem, 5vh, 7.5rem);
  /* PLUS AUCUNE LUEUR DE COIN, LE FOND EST UNI.
     Il y en avait deux : une bleue en bas à gauche, reste du thème marine,
     et une rouge en haut à droite. Tant que le voile sombre couvrait une
     large ellipse, elles passaient inaperçues. En allégeant ce voile pour
     rendre le circuit visible partout — ce que Dominic demandait le
     16 septembre 2026 — elles sont devenues deux taches franches, la bleue
     puis la rouge. Un fond uni est la seule façon d'avoir un motif d'égale
     intensité d'un bord à l'autre. */
  background: linear-gradient(155deg, var(--bleu-800) 0%, var(--bleu-900) 100%);
  color: rgba(255, 255, 255, .84);
  overflow: hidden;
}
/* Deux couches distinctes derrière le contenu du héros :
   ::before porte le circuit imprimé, ::after pose un voile sombre par-dessus.
   Séparer les deux permet de garder un motif bien présent tout en gardant
   le texte parfaitement lisible. */

.heros::before {
  content: "";
  position: absolute;
  inset: -25% 0;
  z-index: 0;
  background-image: var(--motif-image);
  background-size: var(--motif-taille) var(--motif-taille);
  background-repeat: repeat;
  opacity: .38;
  transform: translate3d(0, var(--parallaxe-y, 0px), 0);
  pointer-events: none;
}

.heros::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    radial-gradient(ellipse 70% 80% at 28% 50%,
      rgba(var(--voile-rvb), .93) 0%, rgba(var(--voile-rvb), .78) 42%,
      rgba(var(--voile-rvb), .32) 70%, transparent 88%),
    linear-gradient(180deg, rgba(var(--voile-rvb), .55), transparent 22%, transparent 78%, rgba(var(--voile-rvb), .55));
  pointer-events: none;
}

.heros > * { position: relative; z-index: 1; }

.heros__grille {
  display: grid;
  grid-template-columns: 1.15fr .85fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}

.heros h1 { color: var(--blanc); }

/* CHAQUE LETTRE PORTE SON PROPRE FOND.
   Le motif du héros comporte des faisceaux de sept ou huit traits serrés.
   Quand l'un d'eux passe derrière le texte, la lecture devient pénible —
   Dominic l'a signalé le 16 septembre 2026.

   ON NE PEUT PAS LES DÉPLACER. La tuile fait 820 px et la colonne de texte
   environ 795 : leur position relative change avec la largeur de la fenêtre.
   Et la couche se déplace en parallaxe pendant le défilement, donc même à
   largeur fixe un faisceau finit par traverser le texte. Aucun décalage
   statique ne peut l'éviter.

   D'où cette ombre portée, la même technique que les étiquettes du noyau,
   qui sont posées directement sur le circuit sans aucun voile et restent
   lisibles. Elle assombrit juste autour des caractères, ce qui laisse le
   voile aussi pâle que Dominic l'a validé. */
.heros__texte {
  text-shadow: 0 1px 9px rgba(0, 0, 0, .9), 0 0 20px rgba(0, 0, 0, .55);
}
/* Les pastilles ont déjà leur propre panneau : l'ombre y serait inutile et
   viendrait salir leur bord. */
.heros__texte .heros__puces li { text-shadow: none; }

/* Grand logo de la page d'accueil. Il respire légèrement, et un halo rouge
   diffus le décolle du fond sombre. */
.heros__logo {
  width: clamp(170px, 22vw, 260px);
  height: auto;
  margin-bottom: 1.25rem;
  filter: drop-shadow(0 12px 30px rgba(0, 0, 0, .55))
          drop-shadow(0 0 42px rgba(var(--lueur-rvb), .45));
}

@keyframes logo-flottant {
  0%, 100% { transform: translateY(0) scale(1); }
  50%      { transform: translateY(-10px) scale(1.015); }
}

.heros__slogan {
  display: block;
  font-size: clamp(1.6rem, 3.6vw, 2.5rem);
  font-weight: 300;
  color: var(--rouge-400);
  letter-spacing: .04em;
}
.heros__intro {
  max-width: 46ch;
  margin-top: 1.5rem;
  font-size: 1.075rem;
  color: rgba(255, 255, 255, .8);
}

.heros__puces {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-top: 1.75rem;
  padding: 0;
  list-style: none;
}
.heros__puces li {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .4rem .95rem;
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 999px;
  background: rgba(var(--panneau-rvb), .68);
  font-family: var(--police-titre);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .88);
}
.heros__puces .icone { width: 15px; height: 15px; color: var(--rouge-400); }

/* La carte flottante du héros (.heros__carte, .heros__stats) a été retirée le
   15 septembre 2026 : son contenu est devenu la bande « Pourquoi nous écrire »
   sous le héros, pour laisser toute la largeur au noyau. Les règles qui la
   décrivaient sont parties avec elle — plus aucune page ne s'en sert. */

/* Héros compact des pages intérieures */
.heros--compact { padding-block: clamp(3rem, 6vw, 4.5rem); }
.heros--compact .heros__grille { grid-template-columns: 1fr; }
.heros--compact h1 { max-width: 18ch; }

.fil-ariane {
  margin-bottom: 1rem;
  font-size: .84rem;
  color: rgba(255, 255, 255, .62);
}
.fil-ariane ol { display: flex; flex-wrap: wrap; gap: .4rem; list-style: none; padding: 0; }
.fil-ariane li:not(:last-child)::after { content: "›"; margin-left: .4rem; opacity: .6; }
.fil-ariane a { color: rgba(255, 255, 255, .8); }
.fil-ariane a:hover { color: var(--blanc); }

@media (max-width: 900px) {
  .heros__grille { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   7. Cartes
   -------------------------------------------------------------------------- */

.grille { display: grid; gap: 1.5rem; }
/* Exactement deux colonnes : quatre cartes se rangent en 2 + 2, et non en
   3 + 1 comme le faisait auto-fit sur les grands écrans.
   minmax(0, 1fr) plutôt que 1fr : sans cela, un contenu long empêche la
   colonne de rétrécir et déborde. */
.grille--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 760px) {
  .grille--2 { grid-template-columns: 1fr; }
}
.grille--3 { grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); }
.grille--4 { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }

.carte {
  display: flex;
  flex-direction: column;
  padding: 1.9rem;
  background: var(--blanc);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-sm);
  transition: transform var(--transition), box-shadow var(--transition),
              border-color var(--transition);
}
.carte:hover {
  transform: translateY(-4px);
  border-color: var(--bleu-100);
  box-shadow: var(--ombre-md);
}
/* La couleur est posée explicitement : une carte blanche placée dans une
   section sombre hériterait sinon du blanc, donc d'un titre invisible. */
.carte h2, .carte h3 { margin-bottom: .75rem; color: var(--titre); }
.carte p { color: var(--texte-doux); font-size: .95rem; }
.carte__pied { margin-top: auto; padding-top: 1.25rem; }

.carte__icone {
  display: grid;
  place-items: center;
  width: 56px; height: 56px;
  margin-bottom: 1.35rem;
  border-radius: var(--rayon-sm);
  background: var(--bleu-50);
  color: var(--bleu-700);
  transition: background-color var(--transition), color var(--transition);
}
.carte:hover .carte__icone { background: var(--rouge-100); color: var(--rouge-600); }
.carte__icone .icone { width: 28px; height: 28px; }

/* Carte de service avec numérotation */
.carte--service { position: relative; }
.carte--service .carte__numero {
  position: absolute;
  top: 1.4rem; right: 1.6rem;
  font-family: var(--police-titre);
  font-size: 2.4rem;
  font-weight: 700;
  line-height: 1;
  color: var(--gris-100);
}
.carte--service:hover .carte__numero { color: var(--rouge-100); }

/* Carte de valeur sur fond foncé.
   Fond noir semi-transparent : le circuit imprimé reste visible au travers,
   tout en assombrissant assez pour que le texte reste net. Vérifié à 12,9 de
   contraste dans le pire cas, c'est-à-dire une carte posée sur la piste la
   plus claire du motif. */
.carte--valeur {
  background: rgba(0, 0, 0, .55);
  border-color: rgba(255, 255, 255, .14);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .35);
}

/* Au survol, la carte se teinte de rouge. L'opacité reste modérée pour que
   le motif transparaisse encore et que le texte demeure lisible (7,3). */
.carte--valeur:hover {
  background: rgba(var(--lueur-rvb), .34);
  border-color: rgba(var(--lueur-rvb), .85);
  box-shadow: 0 10px 30px rgba(var(--lueur-rvb), .32);
}
.carte--valeur h2, .carte--valeur h3 { color: var(--blanc); }
.carte--valeur p { color: rgba(255, 255, 255, .84); }
.carte--valeur .carte__icone {
  background: rgba(var(--lueur-rvb), .32);
  color: var(--rouge-400);
}
/* La carte devenant rouge au survol, une pastille rouge s'y fondrait :
   on l'assombrit au contraire pour qu'elle continue de se détacher. */
.carte--valeur:hover .carte__icone {
  background: rgba(0, 0, 0, .40);
  color: var(--blanc);
}

/* Le lien « En savoir plus » est en --rouge-600, un rouge sombre pensé pour
   les cartes blanches : sur ce fond noir il tombait à 2,4 de contraste,
   sous le minimum lisible. On prend le rouge clair, celui déjà utilisé pour
   tout le texte d'accent sur fond foncé. Au survol la carte vire au rouge,
   le lien passe donc au blanc pour continuer de s'en détacher. */
.carte--valeur .lien-fleche        { color: var(--rouge-400); }
.carte--valeur:hover .lien-fleche  { color: var(--blanc); }

/* --------------------------------------------------------------------------
   8. Bandeau d'appel à l'action
   -------------------------------------------------------------------------- */

.bandeau {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.75rem;
  padding: clamp(2rem, 4vw, 3rem);
  border-radius: var(--rayon);
  background:
    radial-gradient(700px 300px at 88% 10%, rgba(var(--lueur-rvb), .35), transparent 62%),
    linear-gradient(140deg, var(--bleu-700), var(--bleu-900));
  color: rgba(255, 255, 255, .84);
  box-shadow: var(--ombre-lg);
}
.bandeau::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: var(--motif-image);
  /* Tuile affichée plus grande ici : le bandeau est une petite surface, un
     motif trop resserré y devenait illisible derrière le texte. */
  background-size: 660px 660px;
  opacity: .22;
  pointer-events: none;
}

/* Voile du bandeau.
   C'était la seule surface sombre du site sans voile : le motif s'y trouvait
   à pleine intensité juste derrière le texte, ce qui donnait l'impression
   qu'il passait devant. Le contenu occupant presque toute la boîte, le voile
   est ici plus couvrant que sur les grandes sections. */
.bandeau::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    linear-gradient(100deg,
      rgba(var(--voile-rvb), .92) 0%,
      rgba(var(--voile-rvb), .82) 45%,
      rgba(var(--voile-rvb), .55) 72%,
      rgba(var(--voile-rvb), .30) 100%);
  pointer-events: none;
}

.bandeau > * { position: relative; z-index: 1; }
.bandeau h2 { color: var(--blanc); }
.bandeau p { margin-top: .6rem; max-width: 52ch; color: rgba(255, 255, 255, .78); }
.bandeau__actions { display: flex; flex-wrap: wrap; gap: .8rem; }

/* --------------------------------------------------------------------------
   9. Tarifs
   -------------------------------------------------------------------------- */

.tarifs-groupe + .tarifs-groupe { margin-top: clamp(2.5rem, 5vw, 3.5rem); }
.tarifs-groupe__titre {
  margin-bottom: 1.5rem;
  font-family: var(--police-titre);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--bleu-700);
}
/* Sur fond sombre, le titre de groupe doit rester lisible. */
.section--fonce .tarifs-groupe__titre { color: var(--blanc); }

.tarif {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 2rem;
  background: var(--blanc);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-sm);
  transition: transform var(--transition), box-shadow var(--transition);
}
.tarif:hover { transform: translateY(-4px); box-shadow: var(--ombre-md); }

.tarif--vedette {
  border-color: var(--rouge-600);
  box-shadow: 0 0 0 1px var(--rouge-600), var(--ombre-md);
}
.tarif__etiquette {
  position: absolute;
  top: -.75rem; left: 2rem;
  padding: .2rem .8rem;
  border-radius: 999px;
  background: var(--rouge-600);
  color: var(--blanc);
  font-family: var(--police-titre);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.tarif__titre { font-size: 1.2rem; margin-bottom: .2rem; }
.tarif__soustitre {
  font-size: .88rem;
  color: var(--texte-doux);
  min-height: 2.6em;
}
.tarif__prix {
  display: flex;
  align-items: baseline;
  gap: .25rem;
  margin: 1.25rem 0 .25rem;
  font-family: var(--police-titre);
  color: var(--bleu-700);
}
.tarif__devise { font-size: 1.35rem; font-weight: 600; align-self: flex-start; margin-top: .5rem; }
.tarif__montant { font-size: 3.25rem; font-weight: 700; line-height: 1; }
.tarif__unite { font-size: .95rem; font-weight: 600; color: var(--texte-doux); }
.tarif__note {
  margin-top: auto;
  padding-top: 1.25rem;
  font-size: .82rem;
  color: var(--texte-doux);
  font-style: italic;
}

/* L'estimation gratuite : l'atout que Dominic veut en avant (28 sept. 2026).
   Bordure rouge comme la carte vedette des tarifs, pour qu'on la voie aussi
   sur fond sombre. */
.estimation {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 1.25rem 1.5rem;
  align-items: center;
  padding: 1.75rem 2rem;
  background: var(--blanc);
  border: 1px solid var(--rouge-600);
  border-radius: var(--rayon);
  box-shadow: 0 0 0 1px var(--rouge-600), var(--ombre-md);
  color: var(--texte);
  text-shadow: none;
}
.estimation__marque {
  display: grid;
  place-items: center;
  width: 3.25rem; height: 3.25rem;
  border-radius: 50%;
  background: var(--rouge-600);
  color: var(--blanc);
}
.estimation__marque .icone { width: 1.6rem; height: 1.6rem; }
.estimation__titre {
  font-family: var(--police-titre);
  font-size: 1.45rem;
  font-weight: 700;
  color: var(--rouge-600);
  margin-bottom: .4rem;
}
.estimation__titre span {
  font-size: .95rem;
  font-weight: 600;
  color: var(--texte-doux);
  margin-left: .35rem;
}
.estimation p { margin: 0 0 .5rem; }
.estimation .estimation__precision { font-size: .85rem; color: var(--texte-doux); margin: 0; }
@media (max-width: 760px) {
  .estimation { grid-template-columns: 1fr; padding: 1.5rem; }
  .estimation__marque { display: none; }
}

/* Les trois repères de prix de l'accueil. */
.reperes-prix {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: 1.25rem;
  margin-top: 1.5rem;
}
.repere-prix {
  padding: 1.35rem 1.5rem;
  background: var(--blanc);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-sm);
}
.repere-prix__montant {
  font-family: var(--police-titre);
  font-size: 2rem;
  font-weight: 700;
  line-height: 1.1;
  color: var(--bleu-700);
}
.repere-prix__montant small { font-size: .9rem; font-weight: 600; color: var(--texte-doux); }
.repere-prix__titre { font-weight: 700; margin: .35rem 0 .2rem; }
.repere-prix p { font-size: .88rem; color: var(--texte-doux); margin: 0; }

/* La pastille « Estimation gratuite » du héros de l'accueil. */
.heros__offre {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  margin-top: 1.5rem;
  padding: .55rem 1.1rem;
  border-radius: 999px;
  background: var(--rouge-600);
  color: var(--blanc);
  font-family: var(--police-titre);
  font-weight: 700;
  letter-spacing: .04em;
  text-decoration: none;
  text-shadow: none;
}
.heros__offre:hover { color: var(--blanc); filter: brightness(1.1); }
.heros__offre span { font-weight: 500; opacity: .9; }
.heros__offre .icone { width: 16px; height: 16px; }

/* --------------------------------------------------------------------------
   10. Témoignages
   -------------------------------------------------------------------------- */

.temoignage {
  position: relative;
  max-width: 720px;
  margin-inline: auto;
  padding: 0 2.5rem;
  text-align: center;
}
.temoignage__icone {
  width: 40px; height: 40px;
  margin: 0 auto 1.5rem;
  color: var(--rouge-400);
  opacity: .85;
}

/* --------------------------------------------------------------------------
   10 bis. Carrousel de témoignages

   Les diapositives sont empilées dans une seule cellule de grille. Le bloc
   prend ainsi la hauteur du plus long témoignage et reste stable : sans cela,
   la page sauterait à chaque changement.
   -------------------------------------------------------------------------- */

.carrousel { padding-top: 2.5rem; }

.carrousel__scene {
  display: grid;
  max-width: 720px;
  margin-inline: auto;
}

.carrousel__diapo {
  grid-area: 1 / 1;
  opacity: 0;
  transform: translateY(14px) scale(.985);
  transition: opacity .6s cubic-bezier(.22, .8, .3, 1),
              transform .6s cubic-bezier(.22, .8, .3, 1);
  /* Une diapositive masquée ne doit pas capter le clavier. */
  visibility: hidden;
}
.carrousel__diapo.est-actif {
  opacity: 1;
  transform: none;
  visibility: visible;
}
/* La diapositive qui sort part vers le haut, celle qui entre vient du bas :
   le mouvement se lit alors comme un défilement, pas comme un clignotement. */
.carrousel__diapo.est-sortante {
  opacity: 0;
  transform: translateY(-14px) scale(.985);
  visibility: visible;
}

.carrousel__pastilles {
  display: flex;
  justify-content: center;
  gap: .6rem;
  margin-top: 2.25rem;
}

.carrousel__pastille {
  width: 30px; height: 4px;
  padding: 0;
  border: 0;
  border-radius: 99px;
  background: rgba(255, 255, 255, .26);
  cursor: pointer;
  transition: background-color var(--transition), width var(--transition);
}
.carrousel__pastille:hover { background: rgba(255, 255, 255, .5); }
.carrousel__pastille.est-actif {
  width: 46px;
  background: var(--rouge-400);
}
.carrousel__pastille:focus-visible { outline: 3px solid var(--rouge-400); outline-offset: 5px; }

/* --------------------------------------------------------------------------
   Fiche d'un service
   Texte à gauche, encadré récapitulatif à droite qui suit le défilement.
   -------------------------------------------------------------------------- */

.fiche-service {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 320px);
  gap: clamp(2rem, 5vw, 3.5rem);
  align-items: start;
}
@media (max-width: 900px) {
  .fiche-service { grid-template-columns: 1fr; }
}

.fiche-service__intro {
  font-size: 1.1rem;
  line-height: 1.75;
  color: var(--texte);
}
.fiche-service__texte h2 {
  margin-top: 2.5rem;
  margin-bottom: 1rem;
  font-size: clamp(1.3rem, 2.4vw, 1.65rem);
}

/* Liste « ce qui est compris » */
.liste-marquee {
  display: grid;
  gap: .7rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.liste-marquee li {
  display: flex;
  align-items: flex-start;
  gap: .65rem;
  color: var(--texte-doux);
}
.liste-marquee .icone {
  flex: none;
  margin-top: .32rem;
  color: var(--rouge-600);
}

/* Étapes numérotées */
.etapes {
  display: grid;
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: etape;
}
.etapes li {
  display: flex;
  align-items: flex-start;
  gap: .9rem;
  color: var(--texte-doux);
}
.etapes__numero {
  display: grid;
  place-items: center;
  flex: none;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--rouge-600);
  color: var(--blanc);
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .92rem;
  font-variant-numeric: tabular-nums;
}

/* Encadré récapitulatif */
.fiche-resume {
  position: sticky;
  top: 110px;
  padding: 1.6rem;
  background: var(--blanc);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-md);
}
@media (max-width: 900px) {
  .fiche-resume { position: static; }
}

.fiche-resume__titre {
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--rouge-600);
  margin-bottom: 1.25rem;
}
.fiche-resume__ligne {
  display: flex;
  align-items: flex-start;
  gap: .8rem;
  padding-block: .8rem;
  border-top: 1px solid var(--bordure);
}
.fiche-resume__ligne:first-of-type { border-top: 0; padding-top: 0; }
.fiche-resume__ligne .icone { flex: none; margin-top: .15rem; color: var(--titre); }
.fiche-resume__ligne > div { display: grid; gap: .1rem; font-size: .92rem; }
.fiche-resume__etiquette {
  font-family: var(--police-titre);
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--texte-doux);
}

/* --------------------------------------------------------------------------
   Liste des villes, sur la page des secteurs desservis
   -------------------------------------------------------------------------- */

.liste-villes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: .3rem .8rem;
  margin: 1.1rem 0 0;
  padding: 0;
  list-style: none;
}
.liste-villes li {
  display: flex;
  align-items: center;
  gap: .35rem;
  font-size: .9rem;
  color: rgba(255, 255, 255, .86);
}
.liste-villes .icone { flex: none; color: var(--rouge-400); width: 14px; height: 14px; }

/* Dans le pied de page, une simple énumération suffit. */
.pied__villes {
  font-size: .84rem;
  line-height: 1.8;
  color: rgba(255, 255, 255, .62);
}

/* Invitation à déposer un avis, sous le carrousel. */
.invite-avis {
  margin: 2.5rem auto 0;
  max-width: 52ch;
  text-align: center;
  font-size: .95rem;
  color: rgba(255, 255, 255, .72);
}
.invite-avis a {
  color: var(--rouge-400);
  font-weight: 600;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.invite-avis a:hover { color: var(--blanc); }

@media (prefers-reduced-motion: reduce) {
  .carrousel__diapo { transition-duration: 1ms; }
}
.temoignage__citation {
  font-family: var(--police-titre);
  font-size: clamp(1.25rem, 2.6vw, 1.7rem);
  font-weight: 300;
  line-height: 1.5;
  color: var(--blanc);
}
.temoignage__auteur {
  margin-top: 1.5rem;
  font-family: var(--police-titre);
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  font-size: .9rem;
  color: var(--blanc);
}
.temoignage__lieu { font-size: .84rem; color: rgba(255, 255, 255, .62); }

/* --------------------------------------------------------------------------
   11. FAQ (accordéon)
   -------------------------------------------------------------------------- */

.faq-categorie + .faq-categorie { margin-top: 2.75rem; }
.faq-categorie__titre {
  margin-bottom: 1.1rem;
  font-family: var(--police-titre);
  font-size: .85rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--rouge-600);
}

.accordeon { display: grid; gap: .75rem; }

.accordeon__item {
  background: var(--blanc);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-sm);
  overflow: hidden;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.accordeon__item:hover { border-color: var(--bleu-100); }
.accordeon__item.est-ouvert {
  border-color: var(--bleu-100);
  box-shadow: var(--ombre-sm);
}

.accordeon__bouton {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  padding: 1.15rem 1.35rem;
  background: none;
  border: 0;
  text-align: left;
  cursor: pointer;
  font-family: var(--police-titre);
  font-size: 1.02rem;
  font-weight: 600;
  color: var(--bleu-700);
}
.accordeon__bouton:hover { color: var(--rouge-600); }
.accordeon__bouton .icone {
  flex: none;
  color: var(--rouge-600);
  transition: transform var(--transition);
}
.accordeon__item.est-ouvert .accordeon__bouton .icone { transform: rotate(45deg); }

.accordeon__panneau {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--transition);
}
.accordeon__item.est-ouvert .accordeon__panneau { grid-template-rows: 1fr; }

/* visibility: hidden retire aussi la réponse repliée des lecteurs d'écran
   et du parcours au clavier, ce que « height: 0 » seul ne fait pas. */
.accordeon__contenu {
  overflow: hidden;
  visibility: hidden;
  transition: visibility var(--transition);
}
.accordeon__item.est-ouvert .accordeon__contenu { visibility: visible; }
.accordeon__contenu > div {
  padding: 0 1.35rem 1.35rem;
  color: var(--texte-doux);
  font-size: .95rem;
}

/* --------------------------------------------------------------------------
   12. Formulaire
   -------------------------------------------------------------------------- */

.contact-grille {
  display: grid;
  grid-template-columns: .8fr 1.2fr;
  gap: clamp(2rem, 5vw, 3.5rem);
  align-items: start;
}
@media (max-width: 900px) { .contact-grille { grid-template-columns: 1fr; } }

.coordonnees { display: grid; gap: 1.5rem; }
.coordonnees__item { display: flex; gap: 1rem; }
.coordonnees__item .icone {
  flex: none;
  width: 40px; height: 40px;
  padding: 9px;
  border-radius: var(--rayon-sm);
  background: var(--bleu-50);
  color: var(--bleu-700);
}
.coordonnees__etiquette {
  font-family: var(--police-titre);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--texte-doux);
}
.coordonnees__valeur {
  font-family: var(--police-titre);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--bleu-700);
  text-decoration: none;
}
a.coordonnees__valeur:hover { color: var(--rouge-600); }

.formulaire {
  padding: clamp(1.75rem, 3.5vw, 2.5rem);
  background: var(--blanc);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-md);
}
.formulaire__grille {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.1rem;
}
.champ--pleine-largeur { grid-column: 1 / -1; }
@media (max-width: 620px) {
  .formulaire__grille { grid-template-columns: 1fr; }
  .champ--pleine-largeur { grid-column: auto; }
}

.champ { display: flex; flex-direction: column; gap: .4rem; }
.champ label {
  font-family: var(--police-titre);
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--bleu-700);
}
.champ__requis { color: var(--rouge-600); }

.champ input,
.champ select,
.champ textarea {
  width: 100%;
  padding: .8rem 1rem;
  background: var(--gris-50);
  border: 1.5px solid var(--bordure);
  border-radius: var(--rayon-sm);
  font-size: .95rem;
  transition: border-color var(--transition), background-color var(--transition),
              box-shadow var(--transition);
}
.champ textarea { min-height: 140px; resize: vertical; }
.champ select { cursor: pointer; }

.champ input:focus,
.champ select:focus,
.champ textarea:focus {
  outline: none;
  background: var(--blanc);
  border-color: var(--bleu-500);
  box-shadow: 0 0 0 3px rgba(61, 83, 158, .14);
}

.champ input[aria-invalid="true"],
.champ select[aria-invalid="true"],
.champ textarea[aria-invalid="true"] {
  border-color: var(--rouge-600);
  background: var(--rouge-100);
}

.champ__erreur {
  font-family: var(--police-texte);
  font-size: .82rem;
  font-weight: 600;
  color: var(--rouge-700);
  text-transform: none;
  letter-spacing: 0;
}

/* Piège à robots : invisible pour les humains, rempli par les robots. */
.pot-de-miel {
  position: absolute !important;
  left: -9999px !important;
  opacity: 0;
  height: 0;
  overflow: hidden;
}

.alerte {
  display: flex;
  gap: .85rem;
  padding: 1.1rem 1.35rem;
  margin-bottom: 1.75rem;
  border-radius: var(--rayon-sm);
  border-left: 4px solid;
  font-size: .95rem;
}
.alerte .icone { flex: none; margin-top: .15rem; }
.alerte--succes {
  background: #ecf8f0;
  border-color: #2e7d4f;
  color: #1c5233;
}
.alerte--erreur {
  background: var(--rouge-100);
  border-color: var(--rouge-600);
  color: var(--rouge-800);
}
.alerte strong { display: block; font-family: var(--police-titre); }

.formulaire__note {
  margin-top: 1rem;
  font-size: .82rem;
  color: var(--texte-doux);
}

/* --------------------------------------------------------------------------
   13. Article / blogue
   -------------------------------------------------------------------------- */

.liste-articles { display: grid; gap: 1.75rem; }

.carte-article {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 1.75rem;
  align-items: center;
  padding: 1.5rem;
  background: var(--blanc);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-sm);
  transition: transform var(--transition), box-shadow var(--transition);
}
.carte-article:hover { transform: translateY(-4px); box-shadow: var(--ombre-md); }
.carte-article__image {
  border-radius: var(--rayon-sm);
  aspect-ratio: 1 / 1;
  object-fit: cover;
  width: 100%;
}
.carte-article__date {
  font-family: var(--police-titre);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--rouge-600);
}
.carte-article h3 { margin: .5rem 0 .6rem; }
.carte-article p { color: var(--texte-doux); font-size: .95rem; margin-bottom: 1rem; }
@media (max-width: 720px) {
  .carte-article { grid-template-columns: 1fr; }
}

/* Capsules : les publications des réseaux, reprises sur le blogue. */
.liste-capsules {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  gap: 1.75rem;
  align-items: start;
}
.carte-capsule {
  background: var(--blanc);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-sm);
  overflow: hidden;
  transition: transform var(--transition), box-shadow var(--transition);
}
.carte-capsule:hover { transform: translateY(-4px); box-shadow: var(--ombre-md); }
.carte-capsule__image { display: block; width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover; }
.carte-capsule__corps { padding: 1.35rem 1.5rem 1.5rem; }
.carte-capsule__titre { font-size: 1.2rem; margin: .5rem 0 .7rem; }
.carte-capsule p { color: var(--texte-doux); font-size: .95rem; margin-bottom: .8rem; }

.article { padding-block: var(--section-y); }
.article__contenu { max-width: 760px; margin-inline: auto; }
.article__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-bottom: 2rem;
  font-size: .86rem;
  color: var(--texte-doux);
}
/* L'illustration de l'article est carrée : on la borne pour qu'elle
   n'occupe pas toute la hauteur de l'écran. */
.article__vedette {
  width: 100%;
  max-width: 460px;
  margin: 0 auto 2.5rem;
  border-radius: var(--rayon);
  box-shadow: var(--ombre-md);
}

.article__contenu h2 {
  margin-top: 2.75rem;
  margin-bottom: .9rem;
  font-size: clamp(1.4rem, 2.6vw, 1.85rem);
}
.article__contenu h3 { margin-top: 2rem; margin-bottom: .7rem; }
.article__contenu p { margin-bottom: 1.15rem; }
.article__contenu ul, .article__contenu ol { margin: 0 0 1.15rem 1.35rem; }
.article__contenu li { margin-bottom: .5rem; }
.article__contenu strong { color: var(--bleu-700); }

.encadre {
  margin: 2rem 0;
  padding: 1.5rem 1.75rem;
  border-left: 4px solid var(--rouge-600);
  border-radius: 0 var(--rayon-sm) var(--rayon-sm) 0;
  background: var(--bleu-50);
}
.encadre p:last-child { margin-bottom: 0; }
.encadre__titre {
  font-family: var(--police-titre);
  font-weight: 700;
  color: var(--bleu-700);
  margin-bottom: .5rem;
}

.comparaison {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1.25rem;
  margin: 2rem 0;
}
.comparaison figure {
  margin: 0;
  padding: 1.5rem;
  text-align: center;
  background: var(--gris-50);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-sm);
}
.comparaison img { width: 84px; margin: 0 auto .9rem; }
.comparaison figcaption {
  font-family: var(--police-titre);
  font-weight: 600;
  color: var(--bleu-700);
  font-size: .95rem;
}

/* --------------------------------------------------------------------------
   14. Pied de page
   -------------------------------------------------------------------------- */

.pied {
  padding-top: clamp(3rem, 6vw, 4.5rem);
  background: var(--bleu-900);
  color: rgba(255, 255, 255, .68);
  font-size: .92rem;
}
.pied__grille {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1.2fr;
  gap: 2.5rem;
  padding-bottom: 3rem;
}
@media (max-width: 900px) { .pied__grille { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .pied__grille { grid-template-columns: 1fr; } }

.pied__logo { height: 48px; width: auto; margin-bottom: 1rem; }
.pied__slogan {
  font-family: var(--police-titre);
  font-size: 1rem;
  color: var(--rouge-400);
  letter-spacing: .05em;
  margin-bottom: .75rem;
}
.pied__texte { font-size: .88rem; line-height: 1.7; }

.pied__titre {
  margin-bottom: 1.1rem;
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--blanc);
}
.pied__liste { list-style: none; padding: 0; display: grid; gap: .6rem; }
.pied__liste a { color: rgba(255, 255, 255, .68); text-decoration: none; }
.pied__liste a:hover { color: var(--blanc); text-decoration: underline; }
.pied__liste--contact li { display: flex; align-items: flex-start; gap: .65rem; }
.pied__liste--contact .icone { color: var(--rouge-400); margin-top: .2rem; }
.pied__urgence {
  margin-top: 1rem;
  font-size: .82rem;
  font-style: italic;
  color: rgba(255, 255, 255, .5);
}

.pied__bas {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: .75rem;
  padding-block: 1.5rem;
  border-top: 1px solid rgba(255, 255, 255, .1);
  font-size: .82rem;
  color: rgba(255, 255, 255, .5);
}
.pied__bas a { color: rgba(255, 255, 255, .6); }
.pied__bas a:hover { color: var(--blanc); }

/* --------------------------------------------------------------------------
   15. Bouton « Écrivez-nous » flottant

   Il n'apparaissait que sous 1120 px. Dominic l'a demandé sur tous les formats
   le 15 septembre 2026 : c'est le seul rappel permanent de la façon de le
   joindre, et rien ne justifiait de le retirer aux visiteurs sur grand écran.

   La marge basse du corps reste réservée aux petits écrans : là, le bouton
   occupe une part notable de la largeur et masquerait la fin du pied de page.
   Sur grand écran il flotte dans un coin largement libre.
   -------------------------------------------------------------------------- */

.bouton-flottant {
  position: fixed;
  right: 1rem; bottom: 1rem;
  z-index: 90;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .85rem 1.35rem;
  border-radius: 999px;
  background: var(--rouge-600);
  color: var(--blanc);
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .9rem;
  text-decoration: none;
  box-shadow: 0 8px 24px rgba(var(--lueur-rvb), .45);
}
.bouton-flottant:hover { background: var(--rouge-700); color: var(--blanc); }

/* Sur la page Contact il pointerait vers la page où le visiteur se trouve
   déjà. Signalé par Dominic le 15 septembre 2026. */
.page-contact .bouton-flottant { display: none; }

@media (max-width: 1120px) {
  body { padding-bottom: 4.5rem; }
}

/* --------------------------------------------------------------------------
   16. Apparition au défilement
   -------------------------------------------------------------------------- */

.apparait {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .65s cubic-bezier(.22, .8, .3, 1),
              transform .65s cubic-bezier(.22, .8, .3, 1);
}
.apparait.est-visible { opacity: 1; transform: none; }

/* Variantes de direction, pour éviter que tout entre de la même façon. */
.apparait--gauche { transform: translateX(-32px); }
.apparait--droite { transform: translateX(32px); }
.apparait--zoom   { transform: scale(.94); }

/* Entrée du héros, jouée au chargement plutôt qu'au défilement. */
.heros__logo,
.heros h1,
.heros__intro,
.heros__puces,
.heros .groupe-boutons,
.heros .note-joindre,
.heros__sante {
  animation: entree-heros .8s cubic-bezier(.22, .8, .3, 1) backwards;
}
.heros h1              { animation-delay: .10s; }
.heros__intro          { animation-delay: .18s; }
.heros__puces          { animation-delay: .26s; }
.heros .groupe-boutons { animation-delay: .34s; }
.heros .note-joindre   { animation-delay: .42s; }
.heros__sante          { animation-delay: .50s; }

@keyframes entree-heros {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: none; }
}

/* Le logo enchaîne sur sa respiration une fois l'entrée terminée. */
/* Le logo NE BOUGE PAS. Il flottait de 10 px en grossissant de 1,5 %;
   Dominic a demandé le 15 septembre 2026 que ce soit la lumière derrière lui
   qui respire, et non la marque elle-même. */
.heros__logo {
  animation: entree-heros .8s cubic-bezier(.22, .8, .3, 1) backwards;
}

/* --------------------------------------------------------------------------
   16 bis. Parallaxe
   La position est calculée en JavaScript et déposée dans --parallaxe-y.
   Sans JavaScript, la variable vaut 0 et le motif reste simplement fixe.
   -------------------------------------------------------------------------- */

/* will-change n'est posé que sur les deux couches réellement déplacées.
   L'appliquer largement crée autant de textures GPU inutiles. */
.heros::before,
.section--fonce::before {
  will-change: transform;
}

/* Respect des préférences système : aucune animation ni parallaxe. */
@media (prefers-reduced-motion: reduce) {
  .apparait { opacity: 1; transform: none; }
  .heros__logo,
  .heros h1, .heros__intro, .heros__puces,
  .heros .groupe-boutons, .heros .note-joindre, .heros__sante { animation: none; }
  .heros::before, .section--fonce::before {
    transform: none !important;
    will-change: auto;
  }
}

/* --------------------------------------------------------------------------
   17. Page 404
   -------------------------------------------------------------------------- */

.erreur-404 { text-align: center; padding-block: clamp(4rem, 10vw, 8rem); }
.erreur-404__code {
  font-family: var(--police-titre);
  font-size: clamp(5rem, 18vw, 10rem);
  font-weight: 700;
  line-height: 1;
  color: var(--bleu-100);
}
.erreur-404 h1 { margin-top: -1rem; }
.erreur-404 p { max-width: 46ch; margin: 1rem auto 0; color: var(--texte-doux); }
.erreur-404 .groupe-boutons { justify-content: center; }

/* --------------------------------------------------------------------------
   18. Impression
   -------------------------------------------------------------------------- */

@media print {
  .barre-info, .entete, .pied, .bouton-flottant, .lien-evitement,
  .bandeau, .groupe-boutons { display: none !important; }
  body { color: #000; background: #fff; }
  .heros { background: none; color: #000; padding-block: 1rem; }
  .heros h1, .heros__marque { color: #000; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .8em; }
}

/* --------------------------------------------------------------------------
   Impulsions lumineuses sur les pistes du circuit

   Une toile par surface sombre portant le motif : le héros, les sections
   foncées, les bandeaux. Les sections claires en sont exclues volontairement —
   leur motif est à 5 % d'opacité sur du presque blanc, un point lumineux y
   serait invisible ou prendrait l'air d'un défaut d'affichage.

   Chaque toile reproduit EXACTEMENT la boîte du ::before de sa surface : même
   décalage vertical, même parallaxe. C'est ce qui garantit que les points
   glissent sur les pistes réellement visibles. **Si l'un de ces insets change
   plus haut dans ce fichier, il faut le changer ici aussi**, sinon les points
   se décollent des tracés.

   Placée comme premier enfant, la toile se peint après le motif et avant le
   voile — les impulsions passent donc sous le voile, qui les adoucit là où se
   trouve le texte. C'est voulu : la lisibilité passe avant l'effet.
   -------------------------------------------------------------------------- */
.circuit-impulsions {
  position: absolute;
  left: 0;
  /* <canvas> est un élément remplacé : un inset le positionne mais ne l'étire
     pas, il garderait sa taille intrinsèque de 300 × 150. D'où une largeur et
     une hauteur explicites. */
  width: 100%;
  z-index: 0;
  pointer-events: none;
}

/* .heros::before — inset: -25% 0 */
.heros .circuit-impulsions {
  top: -25%;
  height: 150%;
  transform: translate3d(0, var(--parallaxe-y, 0px), 0);
}

/* .section--fonce::before — inset: -14% 0 */
.section--fonce .circuit-impulsions {
  top: -14%;
  height: 128%;
  transform: translate3d(0, var(--parallaxe-y, 0px), 0);
}

/* .bandeau::before — inset: 0, sans parallaxe */
.bandeau .circuit-impulsions {
  top: 0;
  height: 100%;
}

/* .section::before (claire) — inset: 0, couche fixe, donc pas de parallaxe.
   Le :not() est indispensable : une section foncée porte elle aussi la classe
   .section, et cette règle écraserait son décalage de -14 %. */
.section:not(.section--fonce) .circuit-impulsions {
  top: 0;
  height: 100%;
}

@media (prefers-reduced-motion: reduce) {
  .circuit-impulsions { display: none; }
}

/* --------------------------------------------------------------------------
   Deux animations d'interface

   Inspirées de animationconcept.com, que Dominic a montré le 15 septembre 2026.
   Ce site tourne sur Elementor avec GSAP, ScrollTrigger, anime.js et Swiper —
   quatre bibliothèques. Les deux effets qu'il en retenait se font ici en CSS,
   sans une ligne de bibliothèque.
   -------------------------------------------------------------------------- */

/* 1. LE TRAIT QUI GLISSE SOUS LE MENU
   Le lien actif portait déjà un trait fixe. Il glisse maintenant d'un lien à
   l'autre au survol, puis revient se poser sur la page courante.

   Le trait fixe n'est masqué que si le script a pris la main (.nav--curseur) :
   sans JavaScript, rien ne disparaît. */
.nav__liste { position: relative; }

.nav__curseur {
  position: absolute;
  left: 0;
  bottom: .25rem;
  width: 0;
  height: 2px;
  border-radius: 2px;
  background: var(--rouge-600);
  opacity: 0;
  pointer-events: none;
  will-change: transform, width;
  transition: transform .3s cubic-bezier(.4, 0, .2, 1),
              width     .3s cubic-bezier(.4, 0, .2, 1),
              opacity   .2s ease;
}
.nav--curseur .nav__lien.est-actif::after { opacity: 0; }

/* Sous 1120 px le menu devient un panneau vertical : le trait n'a plus de sens. */
@media (max-width: 1120px) {
  .nav__curseur { display: none; }
  .nav--curseur .nav__lien.est-actif::after { opacity: 1; }
}

/* 2. LE TITRE QUI S'ÉCRIT, CARACTÈRE PAR CARACTÈRE
   Dominic aimait « la personne qui tape à l'ordi » vue sur codeur.com — une
   boucle vidéo. Voici la même idée sans un octet d'image.

   POURQUOI CARACTÈRE PAR CARACTÈRE ET NON PAR MASQUE
   La première version dévoilait le texte avec un clip-path qui balayait de la
   gauche vers la droite. Élégant sur une ligne, inutilisable sur deux : les
   deux lignes se dévoilaient en même temps. Sur téléphone, le slogan se casse
   justement en deux lignes. Chaque caractère porte donc sa propre apparition,
   ce qui marche quel que soit le nombre de lignes.

   Le script découpe le texte en <span> inline. Le texte reste donc entier dans
   le HTML — Google et les lecteurs d'écran le lisent d'un bloc, des <span>
   inline ne créant aucune coupure de mot.

   Le curseur reste après la frappe et clignote. Il n'a pas d'animation de
   départ : son opacité nulle et le délai de l'animation suffisent à le tenir
   invisible jusqu'à ce que la phrase soit écrite. */
.heros__slogan--frappe {
  --frappe-pas: 45ms;      /* durée d'un caractère */
  --frappe-debut: 200ms;   /* petit temps mort avant de commencer */
}
/* Sur téléphone la phrase est plus courte à l'écran mais tient sur deux
   lignes : on accélère pour que l'attente reste la même. */
@media (max-width: 699px) {
  .heros__slogan--frappe { --frappe-pas: 30ms; }
}

@keyframes rz-frappe-lettre { from { opacity: 0; } to { opacity: 1; } }
@keyframes rz-frappe-curseur {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0; }
}

.heros__slogan--frappe .frappe__c {
  opacity: 0;
  /* PAS de durée de 1 ms ici. La première version en utilisait une, avec
     steps(1, end) : toute lettre dont le délai dépassait une seconde restait
     invisible. Une fenêtre active de 1 ms est plus courte qu'une image à
     l'écran, et le moteur d'animation finit par ne jamais l'échantillonner.
     90 ms, c'est assez court pour lire comme une frappe et assez long pour
     qu'aucune image ne soit sautée. */
  animation: rz-frappe-lettre 90ms ease-out both;
  animation-delay: calc(var(--i) * var(--frappe-pas) + var(--frappe-debut));
}

.heros__slogan--frappe .frappe__curseur {
  display: inline-block;
  width: .07em;
  height: .95em;
  margin-left: .08em;
  vertical-align: -.12em;
  background: currentColor;
  opacity: 0;
  /* --frappe-n est le nombre de caractères, posé par le script. */
  animation: rz-frappe-curseur 1s steps(1, end) infinite;
  animation-delay: calc(var(--frappe-n) * var(--frappe-pas) + var(--frappe-debut));
}

@media (prefers-reduced-motion: reduce) {
  .nav__curseur { transition: none; }
  /* Le menu s'ouvre d'un coup plutôt que de se déployer depuis le bouton. */
  @media (max-width: 1120px) {
    .nav { transition: visibility 0s; }
  }
  .heros__slogan--frappe .frappe__c { opacity: 1; animation: none; }
  .heros__slogan--frappe .frappe__curseur { display: none; }
}

/* --------------------------------------------------------------------------
   Le noyau : le logo, son aura, et les services autour

   Demandé par Dominic le 15 septembre 2026, à partir d'une vidéo où un logo
   trônait au centre, entouré des domaines d'une entreprise.

   TROIS RÈGLES QU'IL A POSÉES
   1. Le logo NE BOUGE PAS. C'est la lumière derrière lui qui respire.
   2. L'aura rouge est conservée — elle existait déjà en ombre portée.
   3. Les libellés sont visibles d'emblée : « pour que le client les voie au
      premier coup d'œil ». Pas de survol obligatoire.

   Tout le placement vient de --k, l'index du service, et de --n, leur nombre.
   Aucun JavaScript : sans lui, les huit liens restent une liste utilisable.
   C'est aussi ce qui permet d'ajouter ou de retirer un service dans index.php
   sans toucher à ce fichier.
   -------------------------------------------------------------------------- */

.noyau {
  /* Plafonne aussi par la hauteur : sur un ecran bas, le noyau retrecit pour
     que toute la premiere section reste visible sans defiler. */
  --taille:        min(clamp(300px, 38vw, 470px), 42vh);
  --rayon-noeud:   calc(var(--taille) * .405);
  --rayon-anneau:  calc(var(--taille) * .245);
  --rayon-pastille: calc(var(--taille) * .052);

  position: relative;
  width: var(--taille);
  aspect-ratio: 1;
  /* Aligné à GAUCHE, comme le titre et le texte qui suivent. Centré sur la
     colonne, il paraissait décalé vers la droite : le titre est aligné à
     gauche dans sa boîte, alors que la boîte, elle, occupe toute la colonne.
     Signalé par Dominic le 15 septembre 2026. */
  margin: 0 0 1.5rem;
  max-width: 100%;
}

/* L'aura. Elle respire : c'est le seul mouvement du centre. */
/* 85 %, ET NON 78 % : L'AURA EST DESSINÉE À SA TAILLE MAXIMALE.
   Le navigateur met cette couche en cache une fois, à la taille naturelle de
   l'élément. Tant qu'on ne fait que la RÉDUIRE, il réutilise cette image
   telle quelle. Dès qu'on l'agrandit — c'était scale(1.09) — il doit la
   redessiner pour la garder nette, et ce redessin se fait par à-coups.
   Dominic a signalé une saccade le 16 septembre 2026, après l'élargissement
   de l'amplitude. En posant la taille naturelle au sommet de la respiration,
   l'échelle ne dépasse plus jamais 1 : plus rien à redessiner.
   78 % x 1,09 = 85 % : le sommet est donc rigoureusement le même qu'avant. */
.noyau__aura {
  position: absolute;
  left: 50%; top: 50%;
  width: 85%; height: 85%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(var(--lueur-rvb), .55) 0%,
    rgba(var(--lueur-rvb), .28) 42%,
    rgba(var(--lueur-rvb), 0) 72%);
  /* 10 s et non 6 s. L'amplitude a été multipliée par cinq le 16 septembre;
     à durée égale, la lueur se déplaçait donc cinq fois plus vite, ce qui se
     lit comme un à-coup et non comme un souffle. Allonger le cycle rend son
     mouvement plus lent qu'avant l'élargissement, pas seulement égal. */
  animation: noyau-respire 10s ease-in-out infinite;
  pointer-events: none;
}
/* LE CREUX DESCEND JUSQU'AU CERCLE, LE SOMMET NE BOUGE PAS.
   Demandé par Dominic le 16 septembre 2026 : une respiration plus ample, qui
   se retire jusqu'à la taille de l'anneau et s'éteint davantage, mais dont le
   maximum reste celui d'avant, qu'il trouvait déjà juste.

   D'OÙ VIENT LE 0,576. L'aura mesure 85 % du noyau (voir plus haut : c'est
   sa taille au SOMMET, pour que l'échelle ne dépasse jamais 1); l'anneau,
   lui, fait 2 x --rayon-anneau, soit 49 %. Pour que la lueur se retire
   exactement sur le cercle : 49 / 85 = 0,576. Si l'une de ces deux
   proportions change un jour, ce rapport doit être recalculé, sinon le creux
   déborde du cercle ou s'arrête avant lui. */
@keyframes noyau-respire {
  0%, 100% { opacity: .40; transform: translate(-50%, -50%) scale(.576); }
  50%      { opacity: 1;   transform: translate(-50%, -50%) scale(1); }
}

/* L'anneau se dessine au chargement. pathLength="100" rend le calcul du
   pointillé indépendant du rayon réel. */
.noyau__anneau {
  position: absolute;
  left: 50%; top: 50%;
  width: calc(var(--rayon-anneau) * 2);
  height: calc(var(--rayon-anneau) * 2);
  transform: translate(-50%, -50%);
  overflow: visible;
  pointer-events: none;
}
.noyau__anneau circle {
  fill: none;
  stroke: var(--rouge-400);
  stroke-width: 1.1;
  opacity: .5;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  animation: noyau-tracer 1.2s ease-out .35s forwards;
}
@keyframes noyau-tracer { to { stroke-dashoffset: 0; } }

/* Le logo, centré et immobile. */
/* L'ENTRÉE EST PORTÉE PAR LE CONTENEUR, JAMAIS PAR LE LOGO.
   Le logo est centré par translate(-50%, -50%). L'animation entree-heros
   anime elle aussi transform : elle écrasait donc le centrage pendant ses
   0,8 s, le logo apparaissait décalé vers la droite et le bas, puis sautait en
   place. Dominic l'a vu au rechargement le 15 septembre 2026.
   Régle générale : ne jamais animer transform sur un élément qui s'appuie sur
   transform pour son placement. */
.noyau {
  animation: entree-heros .8s cubic-bezier(.22, .8, .3, 1) backwards;
}
.noyau .heros__logo {
  position: absolute;
  left: 50%; top: 50%;
  width: 38%;
  margin: 0;
  transform: translate(-50%, -50%);
  /* OMBRE CENTRÉE, et non décalée vers le bas.
     L'ombre d'origine était « 0 12px 30px » : pensée pour un logo flottant
     librement, elle débordait sous l'anneau et tirait l'oeil vers le bas — le
     logo paraissait décentré alors qu'il ne l'était pas. Dominic l'a vu sur
     téléphone le 15 septembre 2026, là où l'espace entre le logo et l'anneau
     est le plus mince. */
  filter: drop-shadow(0 0 20px rgba(0, 0, 0, .5))
          drop-shadow(0 0 34px rgba(var(--lueur-rvb), .38));
}
.noyau .heros__logo { animation: none; }

.noyau__services { list-style: none; margin: 0; padding: 0; }

/* Chaque service est posé sur le cercle par son index. Le li porte la
   rotation, le lien la contre-rotation : le contenu reste donc droit, et la
   piste dessinée sur le li reste orientée vers le centre. */
.noyau__services li {
  position: absolute;
  left: 50%; top: 50%;
  width: 0; height: 0;
  transform: rotate(calc(var(--k) * (360deg / var(--n))))
             translateY(calc(var(--rayon-noeud) * -1));
}

/* La piste, du bord de l'anneau jusqu'à la pastille. */
.noyau__services li::before {
  content: "";
  position: absolute;
  left: 50%;
  top: var(--rayon-pastille);
  width: 1.5px;
  height: calc(var(--rayon-noeud) - var(--rayon-anneau) - var(--rayon-pastille));
  transform: translateX(-50%);
  background: linear-gradient(to bottom, rgba(var(--lueur-rvb), .1), rgba(232, 106, 98, .55));
}

/* L'impulsion qui remonte du centre vers le service, en boucle décalée. */
.noyau__services li::after {
  content: "";
  position: absolute;
  left: 50%;
  top: var(--rayon-pastille);
  width: 5px; height: 5px;
  margin-left: -2.5px;
  border-radius: 50%;
  background: #ffe2da;
  box-shadow: 0 0 8px rgba(255, 226, 218, .9);
  opacity: 0;
  /* Rythme propre à chaque impulsion, posé dans le HTML par index.php.
     Un pas régulier dessinait un balayage circulaire; des durées toutes
     différentes font dériver les phases, donc le motif ne se reforme jamais. */
  animation: noyau-flux var(--flux-duree, 3.4s) linear infinite;
  animation-delay: var(--flux-retard, 0s);
}
@keyframes noyau-flux {
  0%   { transform: translateY(calc(var(--rayon-noeud) - var(--rayon-anneau) - var(--rayon-pastille))); opacity: 0; }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { transform: translateY(0); opacity: 0; }
}

.noyau__services a {
  position: absolute;
  left: 50%; top: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .35rem;
  width: max-content;
  max-width: calc(var(--taille) * .30);
  transform: translate(-50%, -50%)
             rotate(calc(var(--k) * (-360deg / var(--n))));
  text-decoration: none;
  color: rgba(255, 255, 255, .82);
}

.noyau__pastille {
  display: grid;
  place-items: center;
  width: calc(var(--rayon-pastille) * 2);
  height: calc(var(--rayon-pastille) * 2);
  border-radius: 50%;
  border: 1px solid rgba(232, 106, 98, .55);
  background: rgba(24, 10, 12, .85);
  color: var(--rouge-400);
  transition: border-color var(--transition), background-color var(--transition), color var(--transition);
}
.noyau__pastille .icone { width: 52%; height: 52%; }

.noyau__libelle {
  font-size: clamp(.68rem, 1.35vw, .78rem);
  font-weight: 600;
  line-height: 1.25;
  text-align: center;
  letter-spacing: .01em;
  /* Le libellé se pose sur le motif de circuit : sans cette ombre, les
     caractères fins s'y perdent. */
  text-shadow: 0 1px 6px rgba(0, 0, 0, .85);
  transition: color var(--transition);
}

.noyau__services a:hover .noyau__pastille,
.noyau__services a:focus-visible .noyau__pastille {
  border-color: var(--rouge-400);
  background: rgba(70, 20, 20, .92);
  color: var(--blanc);
}
.noyau__services a:hover .noyau__libelle,
.noyau__services a:focus-visible .noyau__libelle { color: var(--blanc); }

/* Apparition en cascade, dans le sens de la lecture du cercle. */
.noyau__services li {
  opacity: 0;
  animation: noyau-entree .45s ease-out forwards;
  animation-delay: calc(.95s + var(--k) * .11s);
}
@keyframes noyau-entree { to { opacity: 1; } }

@media (max-width: 760px) {
  .noyau { --taille: clamp(290px, 86vw, 380px); }
}

@media (prefers-reduced-motion: reduce) {
  .noyau__aura { animation: none; opacity: .8; }
  .noyau__anneau circle { animation: none; stroke-dashoffset: 0; }
  .noyau__services li { animation: none; opacity: 1; }
  .noyau__services li::after { display: none; }
}

/* --------------------------------------------------------------------------
   Le menu se replie DANS le hamburger

   Quand la fenêtre passe sous 1120 px, le menu horizontal disparaissait d'un
   coup et le bouton apparaissait : rien ne disait où le menu était parti.
   Dominic l'a demandé le 15 septembre 2026 — « un effet de fermeture vers le
   hamburger, pour dire que tout est rendu là ».

   Des copies fantômes des liens partent de leur dernière position connue et
   convergent vers le bouton, qui pulse à leur arrivée. Ce sont des copies :
   le vrai menu est déjà replié par la media query, rien n'est déplacé.
   -------------------------------------------------------------------------- */
.fantome-menu {
  position: fixed;
  z-index: 200;
  margin: 0;
  padding: 0;
  pointer-events: none;
  white-space: nowrap;
  font-family: var(--police-titre);
  font-size: 1.12rem;
  font-weight: 600;
  color: var(--rouge-600);
  transition: transform .44s cubic-bezier(.55, 0, .35, 1),
              opacity   .44s cubic-bezier(.55, 0, .35, 1);
  will-change: transform, opacity;
}
.fantome-menu--parti { opacity: 0; }

/* Le bouton accuse réception. */
@keyframes bascule-recoit {
  0%   { transform: scale(1);    box-shadow: 0 0 0 0 rgba(var(--lueur-rvb), .55); }
  45%  { transform: scale(1.14); box-shadow: 0 0 0 10px rgba(var(--lueur-rvb), 0); }
  100% { transform: scale(1);    box-shadow: 0 0 0 0 rgba(var(--lueur-rvb), 0); }
}
.entete__bascule--recoit { animation: bascule-recoit .5s ease-out; }

@media (prefers-reduced-motion: reduce) {
  .fantome-menu { display: none; }
  .entete__bascule--recoit { animation: none; }
}

/* --------------------------------------------------------------------------
   Le noyau ne s'anime que s'il est à l'écran

   L'aura et les huit impulsions tournaient en permanence, y compris quand le
   héros était sorti de l'écran depuis longtemps. Sur une page longue — et elle
   l'est en fenêtre étroite — ça coûtait sans rien donner.

   Seules les animations SANS FIN sont mises en pause. Celles d'entrée, qui ne
   jouent qu'une fois, ne sont pas touchées : elles doivent se dérouler même si
   l'observateur met un instant à réagir.
   -------------------------------------------------------------------------- */
.noyau__aura,
.noyau__services li::after {
  animation-play-state: paused;
}
.noyau--visible .noyau__aura,
.noyau--visible .noyau__services li::after {
  animation-play-state: running;
}

/* L'aura change d'échelle et d'opacité en boucle : la promouvoir en couche
   évite de repeindre son dégradé radial à chaque image. */
.noyau__aura { will-change: transform, opacity; }

/* --------------------------------------------------------------------------
   Page d'accueil : le noyau à gauche, le texte à droite, une hauteur d'écran

   Demandé par Dominic le 15 septembre 2026. En retirant la carte « Pourquoi
   nous écrire » de la colonne de droite, le héros récupère toute sa largeur :
   le noyau passe de 470 px au plus à 673 px, et il n'est plus empilé au-dessus
   du titre mais à côté.

   CE QUI A ÉTÉ APPRIS EN CHEMIN, et qu'il ne faut pas défaire :

   1. --taille doit rester une LONGUEUR ABSOLUE. En pourcentage, le calc() des
      rayons — translateY(calc(var(--taille) * .405)) — se résout sur la
      hauteur de l'élément, qui vaut zéro : tout le noyau s'effondre au
      centre. D'où la largeur de colonne reconstituée à la main ci-dessous.
   2. Le noyau doit se mesurer sur SA COLONNE, pas sur la fenêtre. Dimensionné
      en vw, il débordait sur le texte dès que la fenêtre dépassait la largeur
      maximale du conteneur : les étiquettes de droite passaient par-dessus
      l'intro.
   3. Sans min-height, il restait 595 px de vide sous le héros sur un
      3440 x 1440 : la section ressemblait à une bande, pas à une page
      d'accueil. Les 8,25 rem retranchés sont la hauteur des deux barres du
      haut (52 + 75 px), arrondie vers le haut pour que ça tienne plutôt que
      ça déborde.

   Ce bloc remplace les deux paliers en max-height qui resserraient les marges
   du héros : avec une hauteur imposée et un contenu centré, ils n'avaient
   plus d'effet.

   RIEN NE CHANGE SOUS 1200 px. En dessous, la grille reste sur une colonne,
   le noyau garde sa taille et son alignement à gauche : l'affichage mobile
   est celui que Dominic a validé, consigne du 15 septembre 2026.

   POURQUOI 1200 px ET NON 1121 px, le seuil du menu. Entre les deux, le
   bouton « Appel d'urgence » passe sur deux lignes et l'en-tête grandit de
   22 px. La hauteur retranchée ci-dessous ne le prévoit pas : le héros
   débordait alors de 16 px, mesuré à 1130 x 800. Au-delà de 1200 px,
   l'en-tête tient sur une ligne et fait 126 px, partout.
   -------------------------------------------------------------------------- */
@media (max-width: 1199px) {
  .heros__grille--noyau { grid-template-columns: 1fr; }
}

@media (min-width: 1200px) {
  /* Le héros occupe exactement le reste de l'écran, contenu centré.
     Les marges haut et bas sont resserrées : la hauteur imposée les rend
     inutiles sur un grand écran, et sur un écran bas elles étaient les
     80 px qui faisaient déborder la section (mesuré à 1280 x 720 et
     1400 x 650). Les pages intérieures gardent les leurs. */
  .page-accueil .heros {
    min-height: calc(100svh - 8.25rem);
    padding-block: clamp(1.5rem, 3.5vh, 4rem);
    display: flex;
    align-items: center;
  }

  .heros__grille--noyau {
    /* Plus large que les 1200 px du reste du site : c'est là que le logo
       gagne réellement en taille, maintenant que la carte ne prend plus la
       place. Le texte reçoit la plus grande part, sinon « Solutions
       informatiques » débordait dans la gouttière. */
    max-width: 1600px;
    width: 100%;
    grid-template-columns: minmax(0, 46fr) minmax(0, 54fr);
    gap: clamp(1.5rem, 3vw, 3.5rem);
    align-items: center;
  }

  .heros__grille--noyau .noyau {
    --taille: min(calc((min(1600px, 100vw) - 5rem) * .46), 72vh);
    margin: 0 auto;
  }

  .heros__grille--noyau .heros__slogan { font-size: clamp(1.9rem, 2.9vw, 3.1rem); }
  .heros__grille--noyau .heros__intro {
    max-width: 50ch;
    margin-top: .9rem;
    font-size: clamp(1.05rem, 1.2vw, 1.28rem);
  }
  .heros__grille--noyau .heros__puces    { margin-top: 1.1rem; }
  .heros__grille--noyau .groupe-boutons  { margin-top: 1.4rem; }

  /* --- LE VOILE SOMBRE SUIT LE TEXTE, PLUS LA FENÊTRE -------------------
     Le voile du héros est une ellipse posée à 28 % de la largeur : elle a
     été dessinée quand le texte occupait la colonne de gauche. Depuis que
     le noyau a pris cette place, elle assombrissait le logo et laissait le
     texte sur le motif à pleine intensité — exactement l'inverse de ce
     qu'elle doit faire. Dominic l'a vu le 16 septembre 2026 : le circuit
     était net à droite, éteint et bleuté à gauche.

     POURQUOI SUR LE TEXTE ET NON SUR LE HÉROS. Le conteneur est plafonné à
     1600 px et centré : le centre de la colonne de texte se trouve à 73 %
     de la fenêtre sur un écran de 1600 px, mais à 59 % sur un 3440. Aucun
     pourcentage fixe ne peut suivre les deux. Accroché au bloc de texte
     lui-même, le voile est juste partout, sans média-requête de plus.

     Le héros ne garde donc que ses bandes de haut et de bas, et le motif
     reste à pleine intensité sur toute la largeur. */
  .page-accueil .heros::after {
    background: linear-gradient(180deg,
      rgba(var(--voile-rvb), .55), transparent 22%,
      transparent 78%, rgba(var(--voile-rvb), .55));
  }

  /* LE LIT SOMBRE DU TEXTE.
     Première version trop timide : le dégradé tombait à 0,28 d'opacité dès
     72 % du rayon, donc les bords du texte — le titre, la ligne des
     messageries — se retrouvaient presque à nu sur le circuit. Dominic l'a
     signalé le 16 septembre 2026.
     Le noir reste maintenant dense jusqu'aux deux tiers, puis se retire
     longuement : le texte est assis sur du plein, et la transition vers le
     motif ne dessine pas de bord visible. */
  /* ATTENTION AU SENS DES POURCENTAGES.
     Dans radial-gradient(ellipse 70% ...), 70 % est un RAYON, pas une
     largeur : le voile couvrait donc 140 % de sa boîte, elle-même déjà
     élargie de 22 % de chaque côté. Il débordait largement du texte et
     assombrissait toute la moitié droite. Dominic l'a signalé le
     16 septembre 2026, après une première version à l'inverse trop pâle.
     Ici le rayon est calé pour que le noir tienne jusqu'au bout des lignes
     les plus longues, puis s'éteigne peu après — pas à l'autre bout de
     l'écran. */
  .heros__grille--noyau .heros__texte { position: relative; }
  .heros__grille--noyau .heros__texte::before {
    content: "";
    position: absolute;
    inset: -12% -7%;
    z-index: -1;
    background: radial-gradient(ellipse 52% 54% at 50% 50%,
      rgba(var(--voile-rvb), .76) 0%,
      rgba(var(--voile-rvb), .70) 52%,
      rgba(var(--voile-rvb), .42) 74%,
      rgba(var(--voile-rvb), .13) 90%,
      transparent 100%);
    pointer-events: none;
  }
}


/* --------------------------------------------------------------------------
   Évaluation de santé — bouton du héros de l'accueil et page
   /sante-ordinateur/ (2 octobre 2026). Tout passe par les variables : le
   thème rouge les redéfinit sur <html>, rien à dupliquer ici.
   -------------------------------------------------------------------------- */

/* Sous la ligne Messenger du héros (fond sombre). Bordure rouge pour qu'il se
   distingue de « Voir nos services » sans concurrencer le bouton principal. */
.heros__sante { margin-top: 1.4rem; }
.heros__sante .bouton { border-color: var(--rouge-500); }
.heros__sante .bouton .icone { margin-right: .5rem; margin-left: 0; }
.heros__sante-note {
  margin-top: .55rem;
  font-size: .88rem;
  color: rgba(255, 255, 255, .7);
}
.heros__sante-note a { color: var(--blanc); text-decoration: underline; text-underline-offset: 3px; }

/* L'image du rapport, posée comme une capture d'écran. Elle est haute : on la
   limite en largeur et on fond le bas, le rapport continuant au-delà. */
.sante-apercu {
  position: relative;
  max-width: 760px;
  margin: 0 auto clamp(2.5rem, 5vw, 4rem);
  border-radius: var(--rayon);
  border: 1px solid var(--bordure);
  box-shadow: var(--ombre-md);
  overflow: hidden;
  background: var(--blanc);
}
.sante-apercu img { display: block; width: 100%; height: auto; }
.sante-apercu figcaption {
  padding: .8rem 1.1rem;
  font-size: .9rem;
  color: var(--texte-doux);
  border-top: 1px solid var(--bordure);
}

/* Sous le bouton de téléchargement, dans le héros de la page */
.sante-fiche {
  margin-top: 1rem;
  font-size: .9rem;
  color: rgba(255, 255, 255, .7);
}

/* Téléphone ou tablette : main.js affiche ce bloc et masque le téléchargement */
.sante-mobile {
  margin-top: 1.6rem;
  padding: 1.25rem 1.4rem;
  max-width: 34rem;
  border-radius: var(--rayon);
  border: 1px solid rgba(255, 255, 255, .18);
  border-left: 4px solid var(--rouge-500);
  background: rgba(var(--panneau-rvb), .72);
  color: rgba(255, 255, 255, .85);
}
.sante-mobile[hidden],
[data-sante-telecharger][hidden],
[data-sante-mobile-lien][hidden] { display: none; }
.sante-mobile__titre {
  display: flex;
  align-items: center;
  gap: .55rem;
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: 1.1rem;
  color: var(--blanc);
  margin-bottom: .35rem;
}
.sante-mobile .groupe-boutons { margin-top: 1rem; }
.sante-mobile__confirmation { margin-top: .75rem; font-weight: 600; color: var(--rouge-400); }

/* « Votre navigateur demande une confirmation? » : affiché au clic sur un
   téléchargement, dans un héros (fond sombre). */
.sante-aide {
  margin-top: .8rem;
  max-width: 34rem;
  padding: .7rem 1rem;
  border-left: 3px solid var(--rouge-500);
  border-radius: 0 var(--rayon-sm) var(--rayon-sm) 0;
  background: rgba(var(--panneau-rvb), .72);
  font-size: .92rem;
  color: rgba(255, 255, 255, .85);
}
.sante-aide[hidden] { display: none; }
.sante-aide a { color: var(--blanc); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
