/* ==========================================================================
   AU DOMAINE — feuille de style globale
   Salon de massage, Lévis (Québec)

   THÈME : clair par défaut (crème chaud, texte brun). La seule zone
   clair-sur-sombre est le hero de chaque page, qui porte la classe
   « .sur-photo » : elle rebascule localement les variables de rôle.
   Partout ailleurs les photos sont CONTENUES dans un cadre et le texte
   repose sur du crème uni — donc aucun halo ni ombre portée nulle part.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Variables
   -------------------------------------------------------------------------- */
:root {
  /* --- Teintes brutes --- */
  --creme:          #FDF8EC;   /* fond de page */
  --creme-carte:    #FFFCF3;   /* cartes, un cran plus clair */
  --creme-appui:    #F6EEDC;   /* sections d'appui, un cran plus soutenu */
  --brun:           #3A2A1C;   /* texte courant */
  --brun-profond:   #1A110B;   /* fonds sombres (pied de page) */
  --brun-nuit:      #150D07;

  --or:             #C9A05C;   /* or « pur » — SUR FOND SOMBRE uniquement
                                  (2,3:1 sur crème : illisible) */
  --or-clair:       #D4B476;   /* survols sur fond sombre */
  --or-texte:       #856228;   /* or lisible sur crème — 5,3:1 sur --creme,
                                  4,8:1 sur --creme-appui (le fond le plus
                                  soutenu). #8C6A2F tombait à 4,31:1 sur
                                  --creme-appui, sous le seuil AA. */
  --or-texte-vif:   #5C4319;   /* survols sur crème : on FONCE, on n'éclaircit
                                  pas — 8:1. Un or plus clair au survol
                                  passait sous le seuil. */
  --ivoire:         #F4ECDC;

  /* --- Rôles : thème clair (défaut) --- */
  --fond-page:      var(--creme);
  --texte:          var(--brun);
  --texte-doux:     rgba(58, 42, 28, 0.72);
  --titre:          var(--or-texte);
  --accent:         var(--or-texte);
  --accent-vif:     var(--or-texte-vif);
  --carte-fond:     var(--creme-carte);
  --carte-bordure:  rgba(201, 160, 92, 0.55);
  --filet:          rgba(201, 160, 92, 0.3);
  --trait:          var(--or-texte);

  /* --- Typographie --- */
  --serif:          'Cormorant Garamond', 'Times New Roman', Times, serif;
  --sans:           'Jost', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  /* --- Rythme --- */
  --pad-section:    clamp(4.5rem, 9vw, 8.5rem);
  --largeur-max:    1280px;
  /* 58ch : voir « .prose » pour le calcul. Un « ch » vaut l'avance du 0, soit
     1,24 caractère réel en Cormorant — 62ch en rendaient ~77, au-dessus des
     75 admis. */
  --largeur-texte:  58ch;
  --hauteur-nav:    68px;

  /* --- Transitions --- */
  --t-douce:        0.3s cubic-bezier(0.4, 0, 0.2, 1);
  --t-lente:        0.9s cubic-bezier(0.22, 0.61, 0.36, 1);
  /* Apparition au défilement : durée propre, pour ne pas dépendre de
     --t-lente qui pilote aussi les zooms d'image au survol. */
  --t-apparition:   0.7s;
  /* Fondu de la galerie des fiches personnel. Valeur reprise TELLE QUELLE
     dans js/personnel-galerie.js (constante DUREE) : la source de la grande
     photo est échangée à opacité nulle, les deux doivent rester alignées. */
  --t-galerie:      0.22s;
  --courbe-douce:   cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* Zones posées sur une photo : on inverse les rôles, sans toucher aux
   teintes brutes. Tout composant enfant suit automatiquement. */
.sur-photo {
  --texte:          var(--ivoire);
  --texte-doux:     rgba(244, 236, 220, 0.82);
  --titre:          var(--or);
  --accent:         var(--or);
  --accent-vif:     var(--or-clair);
  --carte-fond:     rgba(26, 17, 11, 0.42);
  --carte-bordure:  rgba(201, 160, 92, 0.42);
  --filet:          rgba(201, 160, 92, 0.3);
  --trait:          var(--or);
}

/* --------------------------------------------------------------------------
   2. Réinitialisation
   -------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  background-color: var(--creme);
}

body {
  margin: 0;
  background-color: var(--fond-page);
  color: var(--texte);
  font-family: var(--sans);
  font-weight: 300;
  font-size: 1rem;
  line-height: 1.75;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img { max-width: 100%; display: block; }

a {
  color: var(--accent);
  text-decoration: none;
  transition: color var(--t-douce);
}
a:hover { color: var(--accent-vif); }

h1, h2, h3, h4 {
  font-family: var(--serif);
  font-weight: 600;
  line-height: 1.15;
  margin: 0;
  color: var(--titre);
  letter-spacing: 0.01em;
}

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

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.saut-contenu {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: 0.75rem 1.25rem;
  background: var(--or-texte);
  color: var(--creme);
  font-family: var(--sans);
  font-size: 0.8rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.saut-contenu:focus { left: 0.5rem; top: 0.5rem; }

/* Texte réservé aux lecteurs d'écran. Ni « display: none » ni
   « visibility: hidden » : l'un comme l'autre le retireraient AUSSI de la
   restitution vocale, soit l'inverse exact du but. On le sort du cadre visible
   en gardant un élément rendu.
   Employé par les fiches personnel, pour dire « Non renseigné » là où l'œil ne
   voit qu'un tiret cadratin. */
.hors-ecran {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   3. Éléments typographiques récurrents
   -------------------------------------------------------------------------- */
.surtitre {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.75rem;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 1.4rem;
  line-height: 1.6;
}

.surtitre--serre { letter-spacing: 0.25em; }

/* Sur-titre du hero uniquement : agrandi pour mieux tenir face au titre
   géant. Ciblé sur .hero — la classe .surtitre sert aussi dans la vitrine
   et sur la carte Signature, qui ne doivent pas bouger. */
.hero .surtitre {
  font-size: clamp(0.85rem, 1.9vw, 1.05rem);
  margin-bottom: 1.6rem;
}

.titre-geant {
  font-size: clamp(3.4rem, 12vw, 8rem);
  font-weight: 600;
  line-height: 0.95;
  letter-spacing: 0.02em;
}

.titre-hero {
  font-size: clamp(2rem, 6vw, 4rem);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.titre-section {
  font-size: clamp(1.7rem, 4.2vw, 2.9rem);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.italique {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
}

.texte {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.05rem, 2vw, 1.3rem);
  line-height: 1.85;
  color: var(--texte-doux);
}

/* Variante ample : corps de texte agrandi pour les deux blocs éditoriaux
   de l'accueil (intro et Services). Modificateur plutôt que modification
   de .texte, qui sert aussi sur Candidature, Nous contacter et Horaire.
   La mesure est resserrée à 52ch : à cette taille, 62ch donnait des lignes
   trop longues pour rester confortables. */
.texte--ample {
  --largeur-texte: 52ch;
  font-size: clamp(1.25rem, 2.5vw, 1.6rem);
  line-height: 1.75;
}

/* Mention du nom de la maison à l'intérieur d'un paragraphe.
   --or-texte et non --or : sur crème, l'or pur tombe à 2,3:1, illisible
   même au seuil du texte d'affichage. Ici 5,25:1. */
.mention {
  color: var(--or-texte);
  font-weight: 600;
}

/* Titre de section dont UN mot est mis en or par « .mention ».
   Les titres du site sont déjà entièrement en --or-texte : sans cette
   bascule vers le brun, l'accent serait invisible faute d'écart. Le brun
   #3A2A1C donne 12,97:1 sur --creme et le mot en or 5,25:1 — les deux
   au-dessus du seuil, y compris en petit corps. */
.titre-section--accent {
  color: var(--brun);
  /* Corps abaissé — ce modificateur ne sert que sur candidature.html, la règle
     est donc de fait propre à cette page.

     MOTIF : le H1 de son hero est géométriquement plafonné (colonne de 22 %,
     « CANDIDATURE » coûte 7,29 × le corps, d'où 2,95vw maximum — c'est
     documenté au § hero « lumière » et INTOUCHABLE). Ce H2, lui, était borné à
     46,4 px en dur. Le titre de section dépassait donc le titre de page à
     TOUTE largeur desktop, et l'écart se creusait en rétrécissant la fenêtre :
     43,0 contre 46,4 px à 1456, mais 33,0 contre 46,4 à 1120.

     On abaisse le H2, le H1 ne pouvant pas bouger. Et l'on abaisse sa PENTE,
     pas seulement son plafond : le H1 suit la largeur en 2,95vw, donc un
     plafond fixe le laissait repasser devant dès 1120 px. À 2,6vw le H2 reste
     sous le H1 à toute largeur. */
  font-size: clamp(1.6rem, 2.6vw, 2.3rem);
}

.mesure {
  max-width: var(--largeur-texte);
  margin-left: auto;
  margin-right: auto;
}

.telephone {
  display: inline-block;
  font-family: var(--serif);
  font-size: clamp(1.15rem, 2.6vw, 1.6rem);
  font-weight: 600;
  letter-spacing: 0.16em;
  color: var(--accent);
}
.telephone:hover { color: var(--accent-vif); }

/* Un numéro de téléphone ne doit jamais se couper en fin de ligne.

   html-validate réclame ici des traits d'union insécables (U+2011), et le
   glyphe EST disponible dans le sous-ensemble Cormorant livré — vérifié : même
   avance que le trait normal, là où un glyphe absent bascule sur une fonte de
   secours. On le refuse quand même : le numéro est fait pour être COPIÉ, et un
   U+2011 collé dans un composeur ou un carnet d'adresses ne s'interprète pas
   toujours comme un trait d'union. « nowrap » obtient le même résultat visuel
   en gardant des traits ASCII qui se collent proprement.
   Les avertissements « tel-non-breaking » du validateur restent donc attendus. */
a[href^='tel:'] { white-space: nowrap; }

.separateur {
  width: 80px;
  height: 1px;
  margin: 2.2rem auto;
  border: 0;
  background: linear-gradient(90deg,
    transparent, var(--trait) 22%, var(--trait) 78%, transparent);
  opacity: 0.8;
  --opacite-repos: 0.8;   /* voir § apparition : évite l'écrasement à 1 */
}
.separateur--gauche { margin-left: 0; margin-right: auto; }

/* --------------------------------------------------------------------------
   4. Mise en page
   -------------------------------------------------------------------------- */
.contenant {
  width: 100%;
  max-width: var(--largeur-max);
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 5vw, 3rem);
}

.section {
  position: relative;
  padding: var(--pad-section) 0;
}

/* Vignettage chaud très léger — donne du relief au crème sans l'assombrir */
.section--vignette::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(130% 90% at 50% 50%,
      transparent 45%, rgba(58, 42, 28, 0.055) 100%);
}
.section--vignette > * { position: relative; z-index: 1; }

/* Section d'appui : crème un cran plus soutenu, pour alterner les blocs */
.section--appui { background-color: var(--creme-appui); }

/* Section des univers : rembourrage HAUT réduit.

   Il valait 132px, et s'ajoutait aux 132px de rembourrage bas de la section
   des rituels juste au-dessus — 264px de blanc avant la première ligne. Le
   cartouche y paraissait échoué. Ramené à ~80px, l'ouverture reste aérée mais
   le regard trouve le texte. Le rembourrage BAS n'est pas touché : c'est lui
   qui sépare la dernière salle de la clôture. */
.section--univers { padding-top: clamp(3rem, 5.5vw, 5rem); }

/* Section aérée : respiration verticale renforcée, pour les blocs de texte
   seul posés entre deux sections photo */
.section--aere { padding: clamp(6.5rem, 13vw, 12rem) 0; }

.centre { text-align: center; }

/* --------------------------------------------------------------------------
   5. Boutons
   -------------------------------------------------------------------------- */
.bouton {
  display: inline-block;
  padding: 1.05rem 2.6rem;
  border: 1px solid var(--accent);
  background: transparent;
  color: var(--accent);
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.75rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--t-douce),
              color var(--t-douce),
              border-color var(--t-douce);
}

.bouton:hover,
.bouton:focus-visible {
  background-color: var(--accent);
  border-color: var(--accent);
  color: var(--creme);
}

/* Sur fond sombre, le texte du survol repasse en brun profond */
.sur-photo .bouton:hover,
.sur-photo .bouton:focus-visible { color: var(--brun-profond); }

.bouton--large { padding: 1.2rem 3.4rem; }

/* --------------------------------------------------------------------------
   6. Cartes
   -------------------------------------------------------------------------- */
.carte {
  background-color: var(--carte-fond);
  border: 1px solid var(--carte-bordure);
  border-radius: 6px;
  padding: clamp(1.75rem, 3.5vw, 2.75rem);
  transition: border-color var(--t-douce),
              box-shadow var(--t-douce),
              transform var(--t-douce);
}

.carte:hover {
  border-color: var(--accent);
  box-shadow: 0 10px 30px rgba(58, 42, 28, 0.08);
}

/* --------------------------------------------------------------------------
   7. Navigation
   -------------------------------------------------------------------------- */
.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  min-height: var(--hauteur-nav);
  display: flex;
  align-items: center;
  border-bottom: 1px solid rgba(201, 160, 92, 0.28);
}

/* Le fond translucide et le flou vivent sur un pseudo-élément, PAS sur
   .nav elle-même : « backdrop-filter » fait de l'élément porteur le bloc
   conteneur de ses descendants « position: fixed ». Posé sur .nav, il
   enfermerait le panneau mobile (inset: 0) dans les 68 px de la barre
   au lieu du viewport. */
.nav::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-color: rgba(253, 248, 236, 0.88);
  -webkit-backdrop-filter: blur(10px) saturate(1.05);
  backdrop-filter: blur(10px) saturate(1.05);
}

.nav__interieur {
  width: 100%;
  max-width: var(--largeur-max);
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 5vw, 3rem);
  display: flex;
  align-items: center;
  justify-content: center;
}

.nav__liste {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: clamp(0.9rem, 2.2vw, 2rem);
  list-style: none;
  margin: 0;
  padding: 0.9rem 0;
}

.nav__lien {
  position: relative;
  display: inline-block;
  padding: 0.35rem 0;
  color: var(--or-texte);
  font-family: var(--sans);
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  white-space: nowrap;
}

.nav__lien::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--or-texte);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform var(--t-douce);
}

.nav__lien:hover { color: var(--brun); }
.nav__lien:hover::after { transform: scaleX(0.6); background: var(--brun); }

.nav__lien[aria-current='page'] { color: var(--brun); }
.nav__lien[aria-current='page']::after {
  transform: scaleX(1);
  background: var(--or-texte);
}

.nav__burger {
  display: none;
  position: absolute;
  right: clamp(1.25rem, 5vw, 3rem);
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid rgba(201, 160, 92, 0.55);
  border-radius: 4px;
  background: transparent;
  cursor: pointer;
  transition: border-color var(--t-douce);
}
.nav__burger:hover { border-color: var(--or-texte); }

.nav__burger span {
  position: absolute;
  left: 50%;
  width: 20px;
  height: 1px;
  background: var(--or-texte);
  transform: translateX(-50%);
  transition: transform var(--t-douce), opacity var(--t-douce);
}
.nav__burger span:nth-child(1) { top: 15px; }
.nav__burger span:nth-child(2) { top: 21.5px; }
.nav__burger span:nth-child(3) { top: 28px; }

.nav__burger[aria-expanded='true'] span:nth-child(1) {
  transform: translateX(-50%) translateY(6.5px) rotate(45deg);
}
.nav__burger[aria-expanded='true'] span:nth-child(2) { opacity: 0; }
.nav__burger[aria-expanded='true'] span:nth-child(3) {
  transform: translateX(-50%) translateY(-6.5px) rotate(-45deg);
}

/* --------------------------------------------------------------------------
   8. Hero
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: calc(var(--hauteur-nav) + 4.5rem) 0 4.5rem;
  overflow: hidden;
  background-color: var(--brun-profond);
}

.hero__fond {
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}

/* Deux couches : un dégradé vertical pour l'ambiance, plus un halo
   sombre centré qui garantit le contraste du texte même lorsque la
   photo est claire à cet endroit.

   Les deux ont été allégés pour laisser respirer les tons chauds de la
   photo, mais PAS dans la même proportion, et ce n'est pas arbitraire :
   le texte du hero est en or clair sur fond sombre. En éclaircissant, le
   fond se rapproche de la luminance de l'or et le contraste s'effondre.
   Un abattement uniforme de 30 % faisait tomber le sur-titre à 2,86:1.
   Le dégradé vertical — celui qui alourdit vraiment l'image — est donc
   réduit de 32 %, le halo central de 10 % seulement : c'est lui seul qui
   tient l'or au-dessus du plancher. Résultat : luminance moyenne de la
   section multipliée par 2,3, sur-titre à 3,20:1 et titre à 3,32:1. */
.hero__fond::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(64% 62% at 50% 54%,
      rgba(15, 8, 4, 0.558) 0%,
      rgba(15, 8, 4, 0.306) 58%,
      transparent 100%),
    linear-gradient(180deg,
      rgba(15, 8, 4, 0.530) 0%,
      rgba(15, 8, 4, 0.374) 38%,
      rgba(15, 8, 4, 0.374) 62%,
      rgba(15, 8, 4, 0.578) 100%);
}

.hero__contenu {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--largeur-max);
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 5vw, 3rem);
}

.hero--plein {
  min-height: 100vh;
  min-height: 100svh;
}

.hero--bandeau { min-height: min(56vh, 460px); }

/* --- Hero de la page Services : la soie en plein écran ---------------------

   Le visage est le point focal et il occupe le centre-gauche de la source
   (x 28–58 %, y 25–67 % de 1548 × 1016). Deux conséquences :

   1. Le texte descend dans le tiers inférieur — sur les draps et les bras,
      jamais sur le visage. D'où « align-items: flex-end ».
   2. L'assombrissement est ANCRÉ EN BAS et ne monte pas : les 38 % supérieurs
      ne reçoivent strictement rien, la lumière dorée et le visage restent
      tels quels. C'est pourquoi on remplace intégralement la double couche
      de « .hero__fond::after » — halo central + dégradé pleine hauteur —
      calibrée, elle, pour un texte centré au milieu de l'image. */
.hero--soie {
  align-items: flex-end;
  padding-bottom: clamp(3rem, 9vh, 6.5rem);
  /* Titre en ivoire et non en or : sur la soie claire du bas, l'or --or
     tombe à 1,8:1 sur les hautes lumières. L'ivoire y tient au-dessus de 3.
     L'or clair est réservé au numéro, plus bas, où le voile est plus dense. */
  --titre:      var(--ivoire);
  --accent:     var(--or-clair);
  --accent-vif: var(--ivoire);
  --trait:      var(--or-clair);
}

.hero__fond--soie {
  /* 42 % en X maintient le visage entier dans la fenêtre visible. C'est
     déterminant en mobile : « cover » y ajuste sur la hauteur et ne laisse
     voir qu'environ 30 % de la largeur — un cadrage centré couperait le
     regard.

     82 % en Y remonte le sujet en desktop, où « cover » ajuste cette fois sur
     la largeur et laisse un débord vertical. À 40 %, le menton tombait à
     y ≈ 593 sur un écran de 831 px et le titre lui passait dessus. Sans effet
     en mobile, où le débord vertical est nul. */
  background-position: 42% 82%;
}

/* Filet resserré ici : il faut ~26 px de plus entre le bas du visage et le
   haut du titre, et les prendre sur le filet plutôt que sur le titre ou sur
   la marge basse préserve l'échelle typographique voulue. */
.hero--soie .separateur { margin: 1.5rem auto; }

/* La rampe est raide entre 60 et 75 % — là où commence le titre — et douce
   avant : les 40 % supérieurs sont intacts, et le bas du visage (jusqu'à
   ~63 % de la hauteur) ne reçoit qu'un voile de 0,10 à 0,31 qui se lit comme
   une vignette, pas comme un filtre. Calibré sur mesure : les hautes lumières
   de la soie sont à 0,86 de luminance et faisaient tomber l'ivoire à 2,94:1
   avec une rampe linéaire. */
.hero--soie .hero__fond::after {
  background: linear-gradient(180deg,
    transparent 0%,
    transparent 40%,
    rgba(12, 6, 3, 0.10) 55%,
    rgba(12, 6, 3, 0.34) 64%,
    rgba(12, 6, 3, 0.52) 74%,
    rgba(12, 6, 3, 0.68) 86%,
    rgba(12, 6, 3, 0.76) 100%);
}

/* --- Hero de la page Le personnel : le mur solaire en plein écran ---------

   Seul hero CLAIR du site : le mur crème et la lumière dorée occupent presque
   tout le cadre. Le texte y est donc FONCÉ, et la classe « .sur-photo » —
   qui bascule les rôles en clair-sur-sombre — n'est volontairement PAS posée
   sur ce header. On repart des rôles du thème clair, avec deux ajustements.

   Relevé de la photo en grille (1537 × 1023) : la silhouette occupe x 23–64 %,
   et mord jusqu'à x 68 % à mi-hauteur (coude et hanche). Le mur franc est
   entre x 68 et 92 % ; au-delà de 92 %, une ombre de palmier fait chuter la
   luminance à 0,11. La colonne de texte vise donc x 66–94 %. */
.hero--solaire {
  justify-content: flex-end;
  background-color: var(--creme);   /* et non --brun-profond : hero clair */

  --titre:      var(--brun);
  --texte-doux: var(--brun);        /* la hiérarchie passe par le corps et
                                       l'italique, pas par une opacité qui
                                       coûterait du contraste sur la photo */
  --accent:     var(--or-texte-vif); /* or FONCÉ : --or-texte ne donne que
                                        3,5:1 sur ce mur, --or-texte-vif 5,8 */
  --accent-vif: var(--brun);
  --trait:      var(--or-texte);
}

/* Aucun voile en desktop. La zone de texte relevée sur la photo est à 0,609
   de luminance moyenne et 0,431 au minimum : le brun y tient 8,6:1 en moyenne
   et 6,3:1 au pire. Rien à corriger — l'éclat de la photo reste intact. */
.hero--solaire .hero__fond::after { background: none; }

/* ANCRAGE À DROITE, et c'est le correctif central de ce hero.

   « cover » rogne sur la largeur dès que la fenêtre est plus étroite que le
   rapport de l'image (1537/1023 = 1,50). Avec un ancrage centré, ce rognage
   mordait des DEUX côtés : le mur dégagé de droite rétrécissait en même temps
   que la silhouette occupait une fraction croissante de la largeur. La colonne
   de texte, elle, restait à 63 % du VIEWPORT — d'où une collision mesurée dès
   1280 × 900 (−3 px) et de −23 px à 1200 × 950 : le « P » de
   « PROFESSIONNELLES » se posait sur le bras.

   Ancrée à droite, l'image garde tout son mur : le rognage ne mange plus que
   la gauche, c'est-à-dire la silhouette, qui se recadre serré — ce qui est une
   image de mode parfaitement lisible. Le bord droit du coude passe alors de
   63,1 % à 56 % de la largeur en 1200 × 950, et la marge de sécurité GRANDIT
   au lieu de disparaître.

   En 16/9 et au-delà il n'y a aucun rognage horizontal : la règle n'a
   simplement aucun effet, et le cadrage reste celui d'origine. */
.hero__fond--solaire { background-position: 100% 50%; }

/* Colonne de droite. Largeur et marge en POURCENTAGE et non en pixels : la
   photo est cadrée sur la largeur du viewport, donc la silhouette occupe
   toujours la même fraction. Un bloc en pixels passerait dessus dès que la
   fenêtre se rétrécit. Ici le bord gauche reste à 66 % à toute largeur. */
.hero--solaire .hero__contenu {
  max-width: none;
  padding: 0;
}

/* Colonne entre 63,7 % et 93,7 %. Les deux bornes sortent d'un balayage de la
   luminance minimale colonne par colonne sur le composite rendu, au seuil de
   0,40 (le brun y tient 5,9:1) : à gauche la silhouette, à droite l'ombre de
   palmier qui longe le bord de l'image.

   La largeur utile dépend de la HAUTEUR à laquelle on se place, et fortement :

     y 10–58 %  →  199 px  (le bras levé barre la zone)
     y 18–66 %  →  443 px
     y 26–74 %  →  413 px
     y 34–82 %  →  383 px  (l'ombre du bas resserre)

   D'où le décalage du bloc vers le haut : c'est lui qui autorise le titre
   agrandi. Le facteur qui plafonne tout est la largeur du mot insécable
   « PROFESSIONNELLES » : **10,08 × le corps**, tracking de 0,05em compris. */
/* Le bord DROIT commun est dicté par l'élément le plus BAS. L'ombre étant
   diagonale, elle mord d'autant plus à gauche qu'on descend :

     bande du titre     dégagée jusqu'à 98,1 %
     bande de citation  dégagée jusqu'à 94,9 %
     bande du numéro    dégagée jusqu'à 92,4 %   ← contrainte

   Le bloc étant aligné à droite, tout partage ce bord : 91,5 % laisse ~1 % de
   marge. À 93,7 %, le numéro tombait à 1,63:1. */
.hero__bloc {
  /* 27 % et non 28,5 % : le bord gauche passe de 63,0 % à 65,0 %, soit ~1,9 %
     de marge devant le coude relevé à 63,1 %. L'ancien réglage laissait 0,1 %,
     c'est-à-dire 2 px à 1470 — la collision était garantie au premier écran un
     peu moins large. Coût réel : 0,15vw de corps sur le titre, soit 2 px. */
  width: 27%;
  /* « margin-left: auto » et non « justify-content » sur le parent :
     .hero__contenu est un bloc en largeur 100 %, l'alignement du conteneur
     flex ne le déplace pas. */
  margin-left: auto;
  /* 8,5 % conservé du réglage d'origine : le bord droit reste à 91,5 %, alors
     que la bande du numéro — la plus basse, donc la plus mordue par l'ombre de
     palmier diagonale — n'est dégagée que jusqu'à 92,4 %. Le ramener à 8 %
     aurait grignoté cette marge pour rien. */
  margin-right: 8.5%;
  text-align: right;
  /* Plus de « translateY » : la citation partie, le bloc ne fait plus que
     trois lignes de titre, un filet et le numéro. Il tient dans la bande la
     plus dégagée sans qu'on ait à le remonter, et le centrage vertical naturel
     du hero comble le tiers bas qui restait vide auparavant. */
}

.hero--solaire .titre-hero {
  /* Approche resserrée de 0,05em à 0,02em. Ce n'est pas un détail : sur un mot
     de 16 signes, le tracking pèse 0,8 em, soit 8 % de la largeur totale. Le
     facteur passe de 10,09 à 9,61 et le corps maximal de 43,7 à 45,9 px — sans
     ce resserrement, la taille demandée ne rentrait pas dans le mur dégagé.
     Un grand corps demande de toute façon moins d'approche qu'un petit. */
  letter-spacing: 0.02em;
  /* Colonne de 27 % / facteur 9,61 = 2,81vw de corps maximal ; on reste 2 % en
     deçà. C'est le plafond géométrique, pas un choix esthétique. */
  font-size: clamp(1.9rem, 2.75vw, 3.3rem);
  line-height: 1.16;
}

.hero--solaire .telephone { font-size: clamp(1.3rem, 2vw, 1.8rem); }

/* Le filet et le numéro respirent davantage : trois éléments seulement dans le
   bloc, ils peuvent s'espacer sans le faire déborder de la bande dégagée. */
.hero--solaire .separateur { margin-top: 2rem; margin-bottom: 2rem; }
.hero--solaire .hero__action { margin: 0; }

.hero--solaire .separateur { margin-left: auto; margin-right: 0; }

.hero--solaire .hero__sous-titre { margin-left: auto; margin-right: 0; }

/* --- Hero de la page Horaire : les pampas en plein écran -------------------

   Relevé de la photo (1409 × 1117) : le visage occupe x 40–64 %, y 8–55 % ;
   les pampas et le vase tiennent la gauche. La bande la plus propre pour du
   texte est **x 2–33 %, y 48–72 %** : luminance 0,140 de moyenne pour un
   maximum de 0,464 — aucune haute lumière. Les pampas du HAUT, elles, montent
   à 0,948 : y poser du texte aurait demandé un voile bien plus lourd.

   Le bloc va donc en bas à gauche, et le voile est ancré à GAUCHE : la moitié
   droite — visage, regard, lumière ambrée — ne reçoit rien. */
.hero--pampas {
  justify-content: flex-start;
  align-items: center;

  /* Titre en IVOIRE et non en or. Sous le bloc se trouve la lueur chaude
     derrière le vase, relevée à 0,768 de luminance sur le composite rendu.
     Pour y tenir 3:1, l'or --or exigerait un voile de 0,58 — assez pour
     éteindre la texture des pampas ; l'ivoire s'en tire avec 0,38. L'or clair
     est réservé au numéro, plus bas, où le voile est le plus dense. */
  --titre:      var(--ivoire);
  --accent:     var(--or-clair);
  --accent-vif: var(--ivoire);
  --trait:      var(--or-clair);
}

.hero__fond--pampas { background-position: 50% 25%; }

/* Voile ancré à GAUCHE, et à décroissance rapide : il tient sa densité sur la
   colonne de texte (0 à 30 %) puis s'éteint avant le visage. La moitié droite
   — regard, chevelure, lumière ambrée — ne reçoit rien. */
.hero--pampas .hero__fond::after {
  background: linear-gradient(90deg,
    rgba(12, 6, 3, 0.64) 0%,
    rgba(12, 6, 3, 0.60) 30%,
    rgba(12, 6, 3, 0.26) 40%,
    transparent 50%);
}

.hero--pampas .hero__contenu {
  max-width: none;
  padding: 0;
}

/* Bloc DENSE et posé bas. Quatre placements ont été comparés à l'écran :

     centré à 50 %, pleine largeur  →  le titre traverse les yeux, écarté
     colonne gauche, centre 57,5 %  →  200 px de vide sous le numéro
     colonne gauche, centre 66 %    →  bien ancré, mais le numéro descend
                                        sur la lueur du vase (3,50:1)
     colonne gauche, centre 63 %    →  retenu

   Le raisonnement qui départage : au-DESSUS du bloc, l'espace est rempli par
   la texture des pampas ; en DESSOUS, c'est un aplat sombre. Descendre le bloc
   réduit donc le vide perçu et laisse la matière occuper le haut du cadre. */
.hero__bloc--gauche {
  width: 28%;
  margin-left: 5%;
  text-align: left;
  /* Le conteneur est centré, mais la réserve haute du hero (barre de nav
     + 4,5rem) est plus épaisse que la basse : le centre optique tombe à
     57,5 % et non à 50 %. +5,5vh l'amène à 63 %. */
  transform: translateY(5.5vh);
}

/* Titre agrandi : un bloc de trois lignes seulement paraît flotter s'il n'a
   pas de masse. « HORAIRE » ne fait que sept signes, la colonne l'absorbe. */
.hero--pampas .titre-hero { font-size: clamp(2.4rem, 5.2vw, 4.8rem); }

/* Interlignes resserrés, filet raccourci : c'est la densité du bloc, autant
   que sa position, qui l'empêche de flotter. */
.hero--pampas .separateur {
  width: 64px;
  margin: 1rem auto 1rem 0;
}

.hero--pampas .hero__sous-titre {
  font-size: clamp(1.4rem, 2.8vw, 2rem);
  margin-top: 0.75rem;
}

/* Filet et sous-titre calés à gauche : ils sont centrés par défaut. */
/* Le filet cale ses marges latérales dans son raccourci plus haut. */
.hero--pampas .hero__sous-titre { margin-left: 0; margin-right: auto; }

/* --- Hero de la page Prendre rendez-vous : le portrait en plein écran -------

   Seule source VERTICALE du site (1055 × 1491, format 0,708). En paysage,
   « cover » ajuste sur la LARGEUR : toute la largeur est montrée, mais on ne
   voit que 37 % de la hauteur. Deux conséquences qui commandent tout :

   1. Le cadrage horizontal est FIXE. « background-position-x » n'a aucun effet
      en desktop, le visage reste donc centré quoi qu'on fasse. Le texte ne
      peut aller que sur la chevelure, à gauche ou à droite.
   2. Le cadrage vertical est le seul réglage disponible. 28 % place le regard
      au tiers supérieur et garde la bouche dans le cadre.

   Valeurs de la colonne de texte et du voile : voir plus bas, calibrées sur le
   composite rendu. */
.hero--portrait {
  justify-content: flex-end;
  align-items: flex-end;
  padding-bottom: clamp(1.75rem, 4.5vh, 3rem);
}

.hero__fond--portrait { background-position: 50% 28%; }

/* Voile LOCALISÉ, en ellipse ancrée au coin bas-droit — pas un dégradé de
   flanc. La raison tient à la géométrie : les deux obstacles ne sont pas sur
   le même axe. La boucle d'oreille est à MI-HAUTEUR (x 70-77 %, y 40-70 %,
   pointe spéculaire à 1,00) et le bord de fond crème est VERTICAL
   (x 92-100 %). Un dégradé horizontal seul laissait la boucle à 1,79:1 ; un
   dégradé vertical seul ne l'atteignait pas davantage.

   L'ellipse couvre exactement l'empreinte du bloc et retombe à zéro avant le
   visage : mesuré, le bord droit du visage (x 68 %) ne reçoit que ~0,16, et
   rien au-delà de x 60 %. La lumière chaude et le fond crème du haut sont
   intacts. */
.hero--portrait .hero__fond::after {
  background:
    /* Couche HORIZONTALE : l'ellipse seule, ancrée au coin, s'épuise avant
       d'atteindre la boucle d'oreille une fois le titre agrandi — celui-ci
       remonte à y 48 % et y retombait à 1,54:1. Cette couche couvre le flanc
       droit à TOUTES les hauteurs. Elle ne démarre qu'à 58 %, le bord du
       visage étant plus à gauche. */
    linear-gradient(90deg,
      transparent 0%,
      transparent 58%,
      rgba(12, 6, 3, 0.44) 70%,
      rgba(12, 6, 3, 0.56) 100%),
    /* Couche ELLIPTIQUE : densité supplémentaire sous le bloc, là où se
       trouvent le bord de fond crème et le bas de la chevelure. */
    radial-gradient(ellipse 70% 108% at 100% 100%,
      rgba(12, 6, 3, 0.58) 0%,
      rgba(12, 6, 3, 0.54) 60%,
      rgba(12, 6, 3, 0.20) 85%,
      transparent 100%);
}

.hero--portrait .hero__contenu {
  max-width: none;
  padding: 0;
}

/* Colonne calée sur la seule zone vraiment calme du cadre. Relevé du flanc
   droit sur le composite, par cellules :

     x 70-77 %, y 40-70 %  →  la boucle d'oreille, pointe spéculaire à 1,00
     x 92-100 %            →  le fond crème, 0,68 en haut, 0,15 en bas
     x 62-92 %, y > 70 %   →  0,00 à 0,05, maximum 0,31

   D'où un bloc calé en bas à droite : son bord droit s'arrête à 92 % pour
   éviter le crème, et sa ligne longue (« RENDEZ-VOUS ») passe SOUS la boucle
   d'oreille. La ligne courte (« PRENDRE ») ne descend pas assez à gauche pour
   l'atteindre. */
.hero__bloc--droite {
  /* 34 % et non 30 : le balayage post-voile de la bande y 55-100 % donne, par
     colonne de 2 %, un ivoire au pire de 2,20:1 à x 52-54 %, 2,93 à 54-56,
     3,86 à 56-58 et 5,19 à 58-60. La colonne peut donc descendre à x 58 % — le
     visage est plus à gauche — ce qui porte sa largeur de 441 à 500 px. */
  width: 34%;
  margin-left: auto;
  margin-right: 8%;
  text-align: right;
}

/* Bornes calculées, pas choisies. « RENDEZ-VOUS » coûte 6,79 x le corps
   (approche resserrée à 0,02em ; à 0,05em c'était 7,12). La colonne vaut 34 %
   du viewport, d'où un plafond de 0,34 / 6,79 = 5,0vw. On reste à 4,85vw :
   sans ce bornage le titre débordait dès 1280 px de large, là où le terme vw
   reprend la main sur le plafond en rem. */
.hero--portrait .titre-hero {
  letter-spacing: 0.02em;
  font-size: clamp(2.4rem, 4.85vw, 4.5rem);
  line-height: 1.14;
}

.hero--portrait .telephone { font-size: clamp(1.35rem, 2.1vw, 1.95rem); }

.hero--portrait .separateur {
  width: 64px;
  margin: 0.75rem 0 0.75rem auto;
}

/* Bouton d'action : le visiteur doit pouvoir agir depuis le hero. Ancre vers
   la section des deux options, plus bas — à remplacer par l'URL de
   réservation en ligne le jour où elle existe. */
.hero__action { margin: 1.4rem 0 0; }

.hero--portrait .hero__sous-titre {
  /* Même logique : la plus longue des deux lignes coûte 18,4 x le corps, d'où
     un plafond de 0,34 / 18,4 = 1,85vw. Le 1,8rem demandé (28,8 px) réclamait
     530 px pour 500 px de colonne et repassait à la ligne. */
  font-size: clamp(1.15rem, 1.8vw, 1.6rem);
  margin-top: 0.7rem;
  margin-left: auto;
  margin-right: 0;
}

/* --- Hero de la page Candidature : la lumière chaude en plein écran --------

   GÉOMÉTRIE. Source 1537 × 1023 (format 1,502), donc PAYSAGE comme le
   viewport. En desktop « cover » ajuste sur la LARGEUR : à 1470 × 831 l'échelle
   vaut max(1470/1537 ; 831/1023) = 0,956, l'image rendue fait 1470 × 978 et
   déborde de 147 px en HAUTEUR seulement. Conséquence directe :
   « background-position-x » est INERTE en desktop — toute la largeur de la
   photo est montrée, 85 % de sa hauteur. Seul le Y est réglable.
   Et comme la largeur est montrée en entier, un pourcentage de viewport
   correspond au MÊME pourcentage de la photo, à toute largeur d'écran : les
   bornes en % ci-dessous sont donc stables.

   RELEVÉ DE LUMINANCE de la photo composée, par colonnes de 5 %, sur la bande
   y 35–70 % (celle où le bloc se pose) — moyenne / centile 99 / maximum :

     x  0– 5 %  0,244 / 0,271 / 0,286   ← mur sombre, très régulier
     x  5–10 %  0,271 / 0,301 / 0,317
     x 10–15 %  0,303 / 0,331 / 0,348
     x 15–20 %  0,339 / 0,389 / 0,401
     x 20–25 %  0,195 / 0,408 / 0,433   ← la chevelure commence
     x 25–65 %  0,043 à 0,212           ← visage et chevelure
     x 65–70 %  0,212 / 0,467 / 0,529   ← mèche éclairée, bord droit
     x 70–90 %  0,325 à 0,353           ← mur flou : l'autre zone dégagée
     x 90–95 %  0,387 / 0,631 / 0,726   ← l'applique
     x 95–100 % 0,500 / 0,882 / 0,914   ← l'applique, plein feu

   POURQUOI LE BLOC VA À GAUCHE ET NON À DROITE. Les deux flancs sont dégagés
   et font la même largeur utile (≈ 21 %). Sur le critère du contraste ils sont
   équivalents : x 1–21 % relève 0,295 de moyenne pour 0,423 au pire,
   x 70–90 % relève 0,338 pour 0,420. Trois choses les départagent :

   1. L'APPLIQUE. C'est l'élément qui porte à lui seul l'ambiance ambrée que
      l'on veut préserver, et elle est à x 90–100 %. Un voile de flanc droit —
      qui par construction se densifie vers le bord — l'éteindrait. À gauche,
      le voile ne tombe que sur un mur uni et déjà sombre : la lampe, le
      modelé du visage et le mur chaud de droite ne reçoivent RIEN.
   2. Le flanc gauche est déjà 13 % plus sombre (0,295 contre 0,338) : à
      résultat égal, il demande moins de voile.
   3. Le regard part vers la GAUCHE. Le bloc se pose dans l'axe du regard,
      qui conduit l'œil jusqu'au texte, au lieu d'être plaqué derrière la
      nuque.
   -------------------------------------------------------------------------- */
.hero--lumiere {
  justify-content: flex-start;

  /* Titre en IVOIRE et non en or, comme sur « soie » et « pampas ». Le mur de
     gauche culmine à 0,423 de luminance. Pour y tenir 3:1, l'or --or (L 0,383)
     exigerait de descendre le fond à 0,094 — soit un voile de 0,70, un aplat
     noir. L'ivoire (L 0,844) s'en sort avec 0,248, donc 0,23 de voile.
     L'or clair (L 0,480) est réservé au numéro, plus bas, là où l'ellipse est
     la plus dense. */
  --titre:      var(--ivoire);
  --accent:     var(--or-clair);
  --accent-vif: var(--ivoire);
  --trait:      var(--or-clair);
}

/* Y à 44 % et non 50 % : l'image déborde de 147 px, 44 % en rogne 65 en haut
   et 82 en bas. Cela descend le sujet de 9 px, dégage le sommet de la
   chevelure et remonte l'applique dans le cadre. */
.hero__fond--lumiere { background-position: 50% 44%; }

/* Deux couches, aucune uniforme, et calibrées AU PLUS JUSTE.

   Les deux seuils à tenir, tirés des luminances des encres :
     ivoire    L 0,844  →  3:1 exige un fond ≤ 0,248
     or clair  L 0,480  →  3:1 exige un fond ≤ 0,127
   Le pire pixel BRUT sous le titre relève 0,417, sous le numéro 0,347.

   A — VIGNETTE DE FLANC. Ancrée à gauche, éteinte à 45 % : elle n'atteint
       jamais le visage, dont le bord gauche est à x 50 %. Elle tient son
       plateau jusqu'à 25 % — la borne droite exacte du bloc — et c'est elle
       qui porte le contraste du titre.
   B — ELLIPSE, décentrée VERS LE BAS (60 % et non 50 %) et volontairement
       plate (18 % de la hauteur en rayon) pour ne culminer que sur la ligne
       du numéro, à y 57–63 %. Le numéro en or clair demande 0,127 de fond là
       où le titre en ivoire se contente de 0,248 : c'est lui seul qui commande
       cette densité, il était donc absurde de la répandre sur tout le bloc.

   Première version essayée : 0,50 sous le titre et 0,55 sous le numéro. Elle
   mesurait 5,81:1 et 4,23:1 — largement au-dessus du seuil, donc du voile
   payé pour rien. Ramenée aux valeurs ci-dessous, la mesure donne 4,03:1 et
   3,96:1 à 1470 px, et l'ambre de la photo est visiblement plus vif.

   Les 55 % de droite du cadre — visage, mur chaud, applique — reçoivent 0. */
.hero--lumiere .hero__fond::after {
  background:
    radial-gradient(ellipse 24% 18% at 11% 60%,
      rgba(12, 6, 3, 0.31) 0%,
      rgba(12, 6, 3, 0.25) 50%,
      transparent 100%),
    linear-gradient(90deg,
      rgba(12, 6, 3, 0.34) 0%,
      rgba(12, 6, 3, 0.32) 25%,
      rgba(12, 6, 3, 0.12) 35%,
      transparent 45%);
}

.hero--lumiere .hero__contenu {
  max-width: none;
  padding: 0;
}

/* Colonne x 3–25 %. Bornes tirées du relevé ci-dessus : à droite, 25 % mord de
   trois points sur le début de la chevelure, ce qui ne coûte rien puisque sa
   luminance moyenne y est PLUS BASSE que celle du mur (0,195 contre 0,339) et
   que son maximum ne bouge presque pas (0,433 contre 0,401). Ces trois points
   valent 44 px de colonne à 1470 px, donc 6 px de corps sur le titre.
   À gauche, 3 % (44 px à 1470) plutôt que 2 % : à 29 px le titre venait
   frôler le bord du cadre. */
.hero__bloc--lumiere {
  width: 22%;
  margin-right: auto;
  margin-left: 3%;
  text-align: left;
}

/* Plafond géométrique, pas un choix esthétique : « CANDIDATURE » coûte
   7,292 × le corps à 0,02em d'approche (7,622 à 0,05em — le tracking pèse
   4,5 % de la largeur sur un mot de onze signes). Colonne de 22 % →
   0,22 / 7,292 = 3,017vw de corps maximal. On reste à 2,95vw, 2 % en deçà.
   Le plancher est à 1,85rem : à 1025 px — la largeur la plus étroite où cette
   mise en colonne s'applique encore — 2rem aurait demandé 233 px pour
   225 px de colonne. */
.hero--lumiere .titre-hero {
  letter-spacing: 0.02em;
  font-size: clamp(1.85rem, 2.95vw, 4rem);
  line-height: 1.1;
}

/* Filet calé à gauche et resserré : la colonne est étroite, un filet de 80 px
   à 2,2rem de marge y ferait flotter les trois éléments. */
.hero--lumiere .separateur {
  width: 64px;
  margin: 1.2rem auto 1.2rem 0;
}

/* Plancher à 1,55rem (24,8 px) et non 1,15rem : au-dessous de 24 px le seuil
   WCAG applicable passe de 3:1 à 4,5:1, ce que l'or clair (L 0,480) ne peut
   atteindre qu'avec un fond à 0,068 — un aplat noir sous le numéro. Rester
   au-dessus de 24 px coûte moins cher à l'image que de descendre le fond.
   Plafond : 1,8rem × 7,693 = 221 px pour 225 px de colonne au pire cas. */
.hero--lumiere .telephone {
  font-size: clamp(1.55rem, 1.95vw, 1.8rem);
}

/* --- Hero de la page Nous contacter : le téléphone vintage en plein écran ---

   Même géométrie que « lumière chaude » : source 1537 × 1023 en paysage, donc
   « background-position-x » INERTE en desktop, 84,9 % de la hauteur visible, et
   des bornes en % stables à toute largeur d'écran.

   RELEVÉ DE LUMINANCE du composite (centile 3 par cellule, 1470 × 831, cadrage
   retenu). Colonnes de 4 %, lignes de 7 % :

     x %      0    4    8   12   16   20   24   28   32   36   40
     y 28  0,48 0,57 0,67 0,70 0,73 0,62 0,57 0,67 0,63 0,53 0,44
     y 35  0,53 0,60 0,70 0,73 0,72 0,71 0,70 0,67 0,65 0,64 0,62
     y 42  0,53 0,59 0,60 0,73 0,72 0,72 0,70 0,68 0,66 0,47 0,28
     y 49  0,62 0,21 0,59 0,74 0,73 0,73 0,70 0,68 0,67 0,47 0,31
     y 56  0,24 0,09 0,15 0,70 0,71 0,69 0,65 0,62 0,62 0,45 0,23
     y 63  0,07 0,12 0,62 0,71 0,72 0,70 0,67 0,66 0,62 0,34 0,14
     y 70  0,17 0,54 0,64 0,70 0,72 0,69 0,66 0,61 0,52 0,23 0,20
     y 77  0,16 0,55 0,52 0,68 0,71 0,72 0,68 0,65 0,33 0,09 0,15

   Trois zones s'en dégagent, et ce sont elles qui dictent la mise en page :

   A. LA BOISERIE DE GAUCHE, x 12–32 %, y 28–77 % : jamais sous 0,52, le plus
      souvent au-dessus de 0,65. Seule zone du cadre à la fois large, claire ET
      régulière. Le brun --brun (L 0,026) y tient 8,2:1 au pire.
   B. LES ROSES, x 0–12 %, y 50–71 % : 0,07 à 0,24. Le feuillage sombre y ferait
      chuter le brun à 2,0:1. Zone EXCLUE.
   C. LE FLANC DROIT, à partir de x 36 % : la pénombre qui borde la robe fait
      tomber le relevé de 0,64 à 0,09 selon la hauteur. Borne dure à 38 %.

   Le sujet occupe : visage x 54–66 %, combiné noir x 62–71 %, cordon en
   diagonale de x 62 %/y 45 % à x 71 %/y 78 %, et le TÉLÉPHONE À CADRAN
   x 70–89 %, y 77–100 %. Le bloc s'arrêtant à x 38 %, il reste 16 points de
   viewport entre le bord droit du titre et le bord gauche du visage, et 32
   avant le cadran — qui porte le récit de la page et devait rester intact.
   -------------------------------------------------------------------------- */
.hero--telephone {
  justify-content: flex-start;
  background-color: var(--creme);   /* et non --brun-profond : hero clair */

  /* Deuxième hero CLAIR du site après « solaire », et traité comme lui : la
     classe « .sur-photo » n'est PAS posée sur le header. Le texte est FONCÉ,
     on repart des rôles du thème clair avec deux ajustements.
     --or (L 0,383) sur une boiserie à 0,65 ne donnerait que 1,6:1 : sur ce
     fond, l'or pur est aussi illisible que sur le crème de la page. */
  --titre:      var(--brun);
  --texte-doux: var(--brun);        /* la hiérarchie passe par le corps et
                                       l'italique, pas par une opacité qui
                                       coûterait du contraste sur la photo */
  --accent:     var(--or-texte-vif); /* or FONCÉ (L 0,064) : 5,5:1 sur 0,57 et
                                        7,0:1 sur 0,74. --or-texte (L 0,127)
                                        n'y donnerait que 3,9:1. */
  --accent-vif: var(--brun);
  --trait:      var(--or-texte);
}

/* Y à 68 %, soit 100 px rognés en haut et 47 en bas des 147 px de débord.
   Ce n'est pas un centrage :

   — En HAUT, il n'y a rien à sauver. Le sommet du chignon est à y 4,7 % de la
     source ; même à « background-position-y: 0 » il retomberait à 46 px du
     haut du hero, donc SOUS la barre de navigation qui en occupe 68. Aucune
     valeur de Y ne le rend visible : la contrainte haute n'existe pas.
   — En BAS, il y a le téléphone à cadran. À 50 % son socle était coupé ; à
     68 % il est entier, posé sur le guéridon, ~20 px de marge sous lui.
   — Le plafond vient du visage : la ligne de cheveux est à y 21 %, et le front
     reste dégagé jusqu'à un viewport de rapport 2,18:1. Au-delà, voir la règle
     « min-aspect-ratio » ci-dessous. */
.hero__fond--telephone { background-position: 50% 68%; }

/* AUCUN VOILE EN DESKTOP, exactement comme « solaire ». Ce n'est pas un oubli,
   c'est le résultat de la mesure : sous les glyphes du bloc, le composite
   relève 0,60 de luminance en moyenne et 0,52 au minimum. Le titre y tient
   6,7:1 au PIRE pixel pour un seuil de 3, le sous-titre 9,0:1 et le numéro
   6,5:1. Il n'y a rien à corriger, et tout à perdre : la scène claire et
   chaleureuse est le premier critère esthétique de la page.

   Un ÉCLAIRCISSEMENT local sur les roses a été essayé puis écarté par le
   calcul : il aurait fallu 0,50 de crème pour hisser le feuillage (L 0,09) à
   4,8:1, un aplat qui aurait effacé les fleurs. Déplacer le bloc de 2 points
   vers la droite (11 % → 13 %) règle le même problème pour 0 % d'image
   altérée. C'est le seul hero du site sans aucune couche en desktop. */
.hero--telephone .hero__fond::after { background: none; }

/* Garde-fou pour les écrans très larges et bas. Au-delà de 2:1 le débord
   vertical explose — à 2560 × 950 il vaut 754 px — et 68 % ferait démarrer la
   fenêtre visible à y 30 % de la source, c'est-à-dire SOUS les yeux. On
   recentre. Le bloc, lui, reste dans la boiserie : mesuré 9,1:1 au pire. */
@media (min-aspect-ratio: 2 / 1) {
  .hero__fond--telephone { background-position: 50% 50%; }
}

.hero--telephone .hero__contenu {
  max-width: none;
  padding: 0;
}

/* Colonne x 13–38 %, bornes tirées du relevé et non choisies :

   — Bord GAUCHE à 13 % et non 11 %. Balayage du feuillage des roses (seuil
     L < 0,40) ligne par ligne : il ne dépasse jamais x 5,5 % au-dessus de
     y 50 %, mais POINTE à x 10,8 % à y 60 %. À 11 % le « N » de « Nous sommes
     là pour vous » tombait dessus et le sous-titre mesurait 2,72:1 — sous le
     seuil. 13 % laisse 32 px entre la pointe du feuillage et la première
     hampe. Les roses restent entières, à gauche du texte.
   — Bord DROIT à 38 %. Au-delà, la pénombre de la robe : le relevé passe de
     0,64 à x 36–40 %/y 35 % à 0,09 à la même colonne/y 77 %.

   Aucun décalage vertical : la réserve haute du hero suffit à poser le bloc
   entre y 35 et 74 %, soit la bande la plus régulière de la boiserie. */
.hero__bloc--telephone {
  width: 27%;
  margin-left: 13%;
  margin-right: auto;
  text-align: left;
}

/* Plafond géométrique, pas un choix esthétique. Le titre se casse au seul
   espace qu'il contient, en « NOUS » / « CONTACTER » : c'est la seconde ligne
   qui commande, et elle coûte 6,189 × le corps à 0,02em d'approche (6,459 à
   0,05em). Colonne de 27 % → 0,27 / 6,189 = 4,36vw de corps maximal. On reste
   à 4,1vw, 6 % en deçà, ce qui absorbe la variation de rendu des fontes. */
.hero--telephone .titre-hero {
  letter-spacing: 0.02em;
  font-size: clamp(2.4rem, 4.1vw, 4rem);
  line-height: 1.12;
}

/* Filet calé à gauche et raccourci : la colonne fait 397 px à l'écran de
   référence, un filet de 80 px centré y flotterait entre deux alignements. */
.hero--telephone .separateur {
  width: 64px;
  margin: 1.2rem auto 1.2rem 0;
}

.hero--telephone .hero__sous-titre {
  margin-left: 0;
  margin-right: auto;
}

/* Plancher à 1,55rem (24,8 px) : sous 24 px le seuil WCAG passerait de 3:1 à
   4,5:1. L'or foncé le tient quand même ici (5,4:1 au pire en mobile), mais
   rester au-dessus de 24 px garde une marge sur les écrans où le bloc glisse
   vers une zone moins contrastée. Même plancher que sur « lumière chaude ». */
.hero--telephone .telephone {
  font-size: clamp(1.55rem, 1.95vw, 1.8rem);
}

/* Grain argentique, même recette que la section tarifs : « overlay » à 5 %
   laisse les tons moyens en place et rend au grain de peau une
   micro-structure que l'agrandissement avait lissée. Sous le texte, qui est
   en z-index 1. */
.hero__grain {
  position: absolute;
  inset: 0;
  background-image: url('../images/grain.svg');
  background-size: 300px 300px;
  background-repeat: repeat;
  mix-blend-mode: overlay;
  opacity: 0.05;
  pointer-events: none;
}

.hero__sous-titre {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.05rem, 2.4vw, 1.5rem);
  color: var(--texte-doux);
  margin: 1.5rem auto 0;
  max-width: 48ch;
}

/* --- Disponibilités du jour, intégrées au hero de l'accueil --- */
.hero__dispo {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.25rem, 5vw, 3.5rem);
  max-width: 540px;
  margin: clamp(2rem, 4.5vw, 3rem) auto 0;
  padding-top: clamp(1.4rem, 3vw, 2rem);
  border-top: 1px solid var(--filet);
}

.hero__dispo-bloc { text-align: center; }

.hero__dispo-titre {
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(0.75rem, 1.5vw, 0.8rem);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--or);
  margin: 0 0 0.65rem;
}

.hero__dispo-noms {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1rem, 2.2vw, 1.25rem);
  letter-spacing: 0.05em;
  line-height: 1.5;
  color: var(--ivoire);
  margin: 0;
  min-height: 1.6em;
}

.hero__dispo-noms--vide::before {
  content: '—';
  color: rgba(201, 160, 92, 0.6);
}

/* --------------------------------------------------------------------------
   9. Grilles
   -------------------------------------------------------------------------- */
.grille {
  display: grid;
  gap: clamp(1.1rem, 2.4vw, 1.9rem);
}

.grille--2 { grid-template-columns: repeat(2, 1fr); }
.grille--3 { grid-template-columns: repeat(3, 1fr); }
.grille--4 { grid-template-columns: repeat(4, 1fr); }

/* --------------------------------------------------------------------------
   10. Section tarifs — photo plein cadre
   Reproduit reference-tarifs.png. Trois couches empilées sous le texte :
   la photo, la texture de peinture, puis le grain argentique.
   Aucune ombre portée sur le texte — il se pose à nu sur la photo.
   -------------------------------------------------------------------------- */
.tarifs-photo {
  position: relative;
  /* Hauteur bornée : elle contient le facteur d'agrandissement de la
     source (1023 px de large) et respecte le format de la référence
     (2940 × 1526, soit 1,93). */
  min-height: clamp(520px, 88vh, 840px);
  overflow: hidden;
  background-color: var(--brun-profond);
}

/* Cadrage de la référence : nez et lèvres entrouvertes en haut à droite,
   oreille et boucles à gauche, menton en bas. Valeur calée sur la
   référence : la boucle d'oreille doit tomber vers 69 % de la hauteur de
   section, sous la ligne des durées. À 59 % elle remontait à mi-hauteur et
   venait chevaucher « 15 minutes ». */
.tarifs-photo__fond {
  position: absolute;
  inset: 0;
  background-image: url('../images/beaute-chignon.webp');
  background-position: 50% 48%;
  background-size: cover;
  background-repeat: no-repeat;
}

/* Texture de peinture : dense sur les bords gauche, droit et bas,
   centre laissé propre. Voir images/texture-peinture.svg. */
.tarifs-photo__peinture {
  position: absolute;
  inset: 0;
  background-image: url('../images/texture-peinture.svg');
  background-size: 100% 100%;
  background-repeat: no-repeat;
  mix-blend-mode: multiply;
  opacity: 1;
  pointer-events: none;
}

/* Grain argentique uniforme, par-dessus la peinture, toujours sous le
   texte. « overlay » laisse les tons moyens en place et n'ajoute que la
   micro-texture qui compense la douceur d'agrandissement. */
.tarifs-photo__grain {
  position: absolute;
  inset: 0;
  background-image: url('../images/grain.svg');
  background-size: 300px 300px;
  background-repeat: repeat;
  mix-blend-mode: overlay;
  opacity: 0.05;
  pointer-events: none;
}

.tarifs-photo__titre {
  position: absolute;
  top: 25%;
  left: 0;
  right: 0;
  z-index: 1;
  margin: 0;
  padding: 0 clamp(1.25rem, 5vw, 3rem);
  text-align: center;
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(1.35rem, 2.6vw, 2.05rem);
  line-height: 1.1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  /* Même brun quasi noir que les durées : le titre était à 2,97:1, sous le
     seuil de 3 exigé pour du texte d'affichage. Aucune couche ajoutée. */
  color: #1C1006;
}

/* Les quatre prix. Largeur bridée à 82 % : les centres de colonnes tombent
   alors à 20 / 40 / 60 / 80 % de la largeur, ce qui reproduit l'écartement
   de la référence. */
.tarifs {
  position: absolute;
  /* 42 % place le CENTRE des chiffres à ~53 % de la hauteur, valeur
     relevée sur la référence. Le décalage entre « top » et le centre
     optique vient de la boîte de ligne du texte. */
  top: 42%;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1;
  width: min(1180px, 82%);
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}

.tarif {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
}

/* Décalage vertical d'une colonne à l'autre, comme sur la référence : la
   ligne des prix n'est pas rigoureusement alignée, elle suit le modelé du
   visage. Amplitude calée sur la référence : ~1,3 % de la hauteur entre la
   colonne la plus haute et la plus basse. Un décalage plus marqué a été
   essayé pour sortir « 60 minutes » de la lèvre sombre — il déséquilibrait
   la composition sans rien gagner, la lèvre s'étendant aussi plus bas. */
/* Décalage porté par « margin-top » et non par « transform » : l'animation
   d'apparition pose « transform: none » sur .est-visible, déclaré plus bas
   dans cette feuille, ce qui écrasait silencieusement un translateY. */
.tarif:nth-child(2) { margin-top: -0.2rem; }
.tarif:nth-child(3) { margin-top: 0.55rem; }
.tarif:nth-child(4) { margin-top: 0.75rem; }

/* Chiffres alinéaires : sur la référence les quatre prix ont exactement la
   même hauteur et reposent sur la même ligne de base. Sans « lnum »,
   Cormorant sort ses chiffres elzéviriens et le 4 comme le 7 descendent. */
.tarif__prix {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(3.2rem, 7.2vw, 6.6rem);
  line-height: 1;
  letter-spacing: 0.005em;
  font-variant-numeric: lining-nums;
  font-feature-settings: "lnum" 1;
  color: var(--ivoire);
}

/* Bas de casse, sans interlettrage : c'est le rendu de la référence.
   Couche 1 de lisibilité — brun quasi noir et graisse 600 : à couleur de
   fond égale, cela fait gagner 36 % de contraste par rapport à --brun. */
.tarif__duree {
  position: relative;
  /* Nécessaire pour que le ::before en z-index négatif reste DANS cette
     boîte : sans contexte d'empilement il passerait derrière la photo. */
  isolation: isolate;
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(1rem, 2.05vw, 1.6rem);
  line-height: 1.2;
  letter-spacing: 0.01em;
  color: #1C1006;
}

/* Couche 2 — éclaircissement local diffus. Ce n'est pas un contour de
   texte : une large ellipse crème très étalée qui relève la luminance de
   la photo à cet endroit, comme une zone naturellement plus claire.
   Dégradé étalé plutôt que « filter: blur » : même diffusion, pas de
   repeint coûteux, et surtout simulable exactement pour la mesure. */
.tarif__duree::before {
  content: '';
  position: absolute;
  left: 50%;
  /* Centrée bas et resserrée en hauteur : ainsi la lueur ne remonte pas
     sur les chiffres. Étalée vers le haut, elle éclaircissait le fond des
     prix ivoire et leur faisait perdre du contraste (2,77:1 au minimum). */
  top: 60%;
  width: 340%;
  height: 400%;
  transform: translate(-50%, -50%);
  z-index: -1;
  pointer-events: none;
  /* « closest-side » est essentiel : par défaut le dégradé est dimensionné
     sur le coin le plus éloigné, il conserve donc de l'alpha au bord de sa
     boîte et la lueur se découpe en rectangle. Ici l'ellipse épouse
     exactement la boîte et l'alpha atteint zéro sur ses bords. */
  background: radial-gradient(ellipse closest-side at center,
    rgba(248, 236, 219, 0.26) 0%,
    rgba(248, 236, 219, 0.19) 40%,
    rgba(248, 236, 219, 0.07) 70%,
    rgba(248, 236, 219, 0)    100%);
}

/* Couche 3 — « 60 minutes » seul. Il tombe sur la lèvre, la zone la plus
   sombre de la photo : après les couches 1 et 2 il plafonnait à 3,2:1
   quand les autres dépassaient 5:1. Lueur un peu plus large et plus dense,
   sur ce libellé uniquement — les trois autres restent inchangés. */
.tarif:nth-child(4) .tarif__duree::before {
  width: 380%;
  height: 440%;
  background: radial-gradient(ellipse closest-side at center,
    rgba(248, 236, 219, 0.44) 0%,
    rgba(248, 236, 219, 0.33) 40%,
    rgba(248, 236, 219, 0.13) 70%,
    rgba(248, 236, 219, 0)    100%);
}

/* --------------------------------------------------------------------------
   10 bis. Vitrine — « l'invitation finale ». Accueil uniquement.
   La photo occupe la moitié gauche, collée au bord, sans cadre, et son
   flanc droit se dissout dans le crème de la page par un masque en
   dégradé : on ne doit pas pouvoir dire où l'image finit.
   -------------------------------------------------------------------------- */
.vitrine {
  position: relative;
  display: flex;
  align-items: center;
  min-height: min(80vh, 800px);
  overflow: hidden;
  /* Crème d'appui plutôt que crème de base : la photo est très saturée
     (R−B ≈ 93) et le crème de base très peu (17). Cet écart de saturation
     est ce qui faisait lire le fondu comme « blanc », alors qu'il
     atterrissait déjà exactement sur la couleur de section. Un fond plus
     chaud et un cran plus dense réduit l'écart. */
  background-color: var(--creme-appui);
}

/* Largeur plafonnée à 1040 px — la résolution native de la photo — et
   hauteur plafonnée à 800 px : ces deux bornes garantissent que l'image
   n'est jamais affichée au-delà de sa taille native, quelle que soit la
   largeur de l'écran. Au-delà, c'est le crème qui gagne du terrain, pas
   la photo qui s'étire. */
.vitrine__media {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: min(68%, 1040px);
  /* Masque plutôt qu'un voile crème posé par-dessus : la photo se dissout
     réellement, sans risque d'écart de teinte avec le fond de section. */
  /* Décroissance étalée : la photo garde de la matière plus loin vers la
     droite, la perte de saturation s'étale au lieu de tomber d'un coup. */
  -webkit-mask-image: linear-gradient(90deg,
    #000 0%, #000 36%, rgba(0, 0, 0, 0.62) 56%,
    rgba(0, 0, 0, 0.18) 72%, transparent 88%);
  mask-image: linear-gradient(90deg,
    #000 0%, #000 36%, rgba(0, 0, 0, 0.62) 56%,
    rgba(0, 0, 0, 0.18) 72%, transparent 88%);
}

.vitrine__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 38%;
}

/* Bouffée chaude confinée à la zone de fondu. Sans elle, la transition
   passe par des tons désaturés qui se lisent comme du blanc. Elle
   s'éteint avant le crème plat : la couleur de destination reste donc
   rigoureusement celle de la section. */
.vitrine__media::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(90deg,
    rgba(214, 176, 132, 0) 24%,
    rgba(214, 176, 132, 0.24) 52%,
    rgba(214, 176, 132, 0.09) 70%,
    rgba(214, 176, 132, 0) 84%);
}

.vitrine__grille {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  width: 100%;
}

.vitrine__corps { grid-column: 2; }

.vitrine__titre {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 600;
  font-size: clamp(1.9rem, 4.4vw, 3.2rem);
  line-height: 1.18;
  letter-spacing: 0.01em;
  text-transform: none;
  color: var(--brun);
  margin: 0;
}

.vitrine__ligne {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.05rem, 2vw, 1.3rem);
  color: var(--texte-doux);
  margin: clamp(1.1rem, 2.5vw, 1.6rem) 0 0;
}

/* --------------------------------------------------------------------------
   11. Rituels (massages) — typographie nue

   Aucune carte, aucune bordure, aucun fond de bloc, aucune photo : le nom en
   or lisible et sa description en brun, posés sur le crème. Le vide entre les
   blocs porte la composition, d'où des gouttières bien plus larges que les
   grilles habituelles du site.
   -------------------------------------------------------------------------- */
.rituels-nus {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(3.5rem, 8vw, 6.5rem) clamp(2.5rem, 5.5vw, 4.5rem);
  margin-top: clamp(4rem, 9vw, 7rem);
}

/* Rangée de deux : on borne la largeur et on centre, sinon les deux colonnes
   s'étaleraient chacune sur une demi-page et perdraient le rythme donné par
   la rangée de trois au-dessus. */
.rituels-nus--paire {
  grid-template-columns: repeat(2, 1fr);
  max-width: 62rem;
  margin-left: auto;
  margin-right: auto;
}

.rituel-nu { text-align: center; }

.rituel-nu__nom {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(1.75rem, 3.1vw, 2.35rem);
  line-height: 1.15;
  letter-spacing: 0.015em;
  /* --or-texte et non --or : sur crème l'or pur tombe à 2,3:1. Ici 5,3:1.
     Casse de phrase voulue — pas de text-transform. */
  color: var(--or-texte);
  margin: 0 0 1.15rem;
}

.rituel-nu__texte {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.18rem, 1.9vw, 1.32rem);
  line-height: 1.8;
  color: var(--brun);
  max-width: 45ch;
  margin: 0 auto;
}

/* --------------------------------------------------------------------------
   11 bis. Phrase-signature (page Services, entre les rituels et les salles)

   Le constat était que l'italique pleine largeur d'origine sonnait comme une
   légende face aux rituels en romain juste au-dessus. Les deux phrases
   passent donc en Cormorant ROMAIN, et seule la question garde l'italique —
   une italique isolée sur une ligne se lit comme un accent maîtrisé, là où
   une italique sur tout le bloc introduisait une seconde voix.

   L'accent en ligne (question dans le flux, distinguée par la seule couleur)
   a été essayé et écarté : à 30ch, « Et la vôtre ? » se coupait en deux
   lignes et l'accent doré se retrouvait à cheval sur le retour, avec un
   moignon « vôtre ? » en dernière ligne.
   -------------------------------------------------------------------------- */
/* Le cartouche : fleuron + phrase + filet, resserrés en un seul bloc.

   L'ancien montage laissait 30px entre la seconde phrase et la question, 58
   entre la question et le filet, et posait le tout sous 132px de rembourrage
   de section — trois lignes perdues au milieu du beige. Ici les écarts sont
   réduits de moitié et l'ensemble est encadré par deux ornements, en haut le
   fleuron, en bas le filet. Le vide entoure le bloc au lieu de le diluer. */
.cartouche {
  position: relative;
  text-align: center;
}

/* FILIGRANE « AD » ESSAYÉ ET ÉCARTÉ. Un monogramme géant à 3,5 % d'opacité
   derrière le bloc : à l'écran il ne meuble pas, il salit. Le jambage du D
   passait juste sous « Et la vôtre ? » et posait une tache grise sous la seule
   ligne qui doit porter — l'italique or y perdait son éclat, et l'ensemble
   prenait un air d'artefact plutôt que d'ornement. Le fleuron et le
   resserrement suffisent à donner sa présence au cartouche. Ne pas
   réintroduire sans regarder le rendu à côté de la version sans. */

/* Fleuron : un losange évidé entre deux filets qui s'éteignent. Même
   vocabulaire que « .separateur », avec un point d'ancrage au centre — c'est
   lui qui donne au bloc un haut, et donc une forme. */
.cartouche__ornement {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.8rem;
  width: 132px;
  margin: 0 auto clamp(1.2rem, 2.4vw, 1.6rem);
}

.cartouche__ornement::before,
.cartouche__ornement::after {
  content: '';
  flex: 1;
  height: 1px;
}
.cartouche__ornement::before { background: linear-gradient(90deg, transparent, var(--or-texte)); }
.cartouche__ornement::after  { background: linear-gradient(90deg, var(--or-texte), transparent); }

.cartouche__losange {
  flex: none;
  width: 7px;
  height: 7px;
  border: 1px solid var(--or-texte);
  transform: rotate(45deg);
}

.signature {
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(1.6rem, 3.5vw, 2.4rem);
  line-height: 1.45;
  letter-spacing: 0.02em;
  color: var(--brun);
  /* 32ch et non 30 : la deuxième phrase mesure 550 px pour 550 px de bloc à
     30ch, elle butait pile sur la limite et repassait à la ligne. */
  max-width: 32ch;
  margin: 0 auto;
  text-align: center;
}

/* Une phrase par ligne, en blocs plutôt qu'avec des <br> : sur un écran
   étroit chaque phrase se replie normalement dans la largeur disponible,
   là où un <br> imposerait sa coupure à toutes les tailles.

   « text-wrap: balance » a été essayé et retiré : en égalisant la longueur
   des lignes, il rejetait le « Chaque » de la seconde phrase en fin de
   première ligne. Les deux phrases commencent par le même mot — les empiler
   fait entendre l'anaphore, qu'une coupe au milieu détruisait. */
.signature__ligne { display: block; }

/* La question, seule sur sa ligne. --or-texte et non --or : sur le crème
   d'appui, l'or pur tombe à 2,1:1 — illisible. Ici 4,8:1.

   Portée de 1,12em à 1,3em, et l'air au-dessus de 0,42 à 0,6em : c'est elle
   l'invitation, et c'est sur elle que s'ouvrent les trois univers qui suivent.
   À 1,12em elle passait pour une troisième ligne de l'énoncé. */
.signature__accent {
  display: block;
  /* 0,32em et non 0,6 : la question doit rester dans le souffle de la
     phrase, pas s’en détacher. L’écart passe de 30 à 16px. */
  margin-top: 0.32em;
  font-style: italic;
  font-size: 1.3em;
  color: var(--or-texte);
}

/* Le filet reprend le vocabulaire du site, simplement plus aéré : la phrase
   doit respirer entre les rituels au-dessus et les salles en dessous. */
/* Rapproché du texte : 26px au lieu de 58. Le filet ferme le cartouche, il
   ne le quitte pas. */
.separateur--signature { margin: clamp(1.3rem, 2.6vw, 1.7rem) auto 0; }

/* --------------------------------------------------------------------------
   12. Les salles — « Choisissez votre univers »

   DISPOSITION ALTERNÉE, en rangées pleine largeur : photo à gauche et texte à
   droite, puis l'inverse, et ainsi de suite sur les cinq salles. Chaque salle
   a sa rangée, donc son moment de lecture — des cartes identiques alignées ne
   racontaient rien et se ressemblaient toutes.

   L'ORDRE EST UNE PROGRESSION, pas un rangement : Sakura, Acajou, Rouge,
   Ivoire, Noire. L'alternance gauche/droite est portée par « nth-child(even) »
   seul, donc elle se prolonge d'elle-même à chaque salle ajoutée — il n'y a
   aucune règle à écrire par rangée.

   Le triptyque animé au survol (cartes qui s'élargissent en « flex-grow ») a
   été écarté, et pas par goût : son principe même n'existe pas sur écran
   tactile. Il aurait fallu lui inventer un rendu de repli pour la moitié des
   visiteurs, c'est-à-dire concevoir la section deux fois. Ici les cinq salles
   se lisent à l'identique partout et la souris ne fait qu'ajouter.

   L'IDENTITÉ DE CHAQUE SALLE tient en trois signes : le mot-signature en
   italique or, le nom en capitales serif, et le filet teinté qui les sépare.
   La couleur ne passe QUE par le filet, le lavis du placeholder et la bordure
   au survol — jamais par le texte, dont le contraste doit rester tenu.
   -------------------------------------------------------------------------- */
.univers {
  display: grid;
  /* Resserré de 88 à 74 px avec le passage à cinq salles — voir « max-width »
     juste dessous, même raisonnement. */
  gap: clamp(2.6rem, 6vw, 4.6rem);
  /* Élargi pendant que le cartouche se resserrait : c’est ce blanc-là qui
     marque le passage de l’ouverture aux salles. Le resserrer AUSSI aurait
     collé Sakura au filet et fait perdre la respiration. */
  margin-top: clamp(4rem, 8vw, 6rem);

  /* CINQ SALLES, ET UNE PAGE QUI DOIT RESTER TENABLE.
     Le cadre étant en 5/4, la hauteur d'une rangée découle directement de sa
     largeur : à pleine largeur de contenant (1184 px), chaque colonne fait
     556 px et chaque rangée 445 px. Cinq rangées faisaient 2 577 px de
     défilement pour la seule liste des salles.
     Ramener la grille à 1040 px ramène la rangée à 387 px (−13 %) et
     l'ensemble à 2 231 px : cinq salles ne coûtent plus que 48 % de défilement
     de plus que trois n'en coûtaient. On ne touche NI au ratio, NI à la
     typographie — seule la largeur bouge, et la réduction suit.
     Effet de bord voulu : la bande de salles se centre sous un cartouche lui
     aussi centré, ce qui resserre la section au lieu de l'étaler. */
  width: 100%;
  max-width: 1040px;
  margin-inline: auto;
}

.univers__salle {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}

/* Rangées paires : le texte passe à gauche. Colonnes explicites plutôt que
   « order » — l'ordre du DOM reste photo puis texte sur les cinq rangées,
   donc la lecture vocale et la tabulation ne zigzaguent pas, alors que
   l'alternance visuelle, elle, est bien là. */
.univers__salle:nth-child(even) .univers__media { grid-column: 2; grid-row: 1; }
.univers__salle:nth-child(even) .univers__texte { grid-column: 1; grid-row: 1; }

/* Cadre en 5/4 paysage : on photographie une pièce en largeur. Le 4/5 portrait
   des anciennes cartes aurait donné, sur une demi-largeur de page, un cadre de
   plus de 700 px de haut par rangée — un écran par salle. */
.univers__media {
  position: relative;
  overflow: hidden;
  aspect-ratio: 5 / 4;
  border: 1px solid var(--carte-bordure);
  border-radius: 6px;
  transition: border-color var(--t-douce), box-shadow var(--t-douce);
}

.univers__salle:hover .univers__media {
  border-color: var(--teinte-trait);
  box-shadow: 0 14px 38px rgba(58, 42, 28, 0.13);
}

/* Le zoom porte sur le CONTENU du cadre — placeholder comme photo — et non sur
   le cadre : sa bordure et son rayon doivent rester nets pendant le mouvement. */
.univers__media > * { transition: transform var(--t-lente); }
.univers__salle:hover .univers__media > * { transform: scale(1.045); }

/* Prête pour les vraies photos : l'image se pose par-dessus le placeholder,
   qui reste en fond. Rien d'autre à changer que le décommentage dans le HTML. */
.univers__photo {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.univers__mot {
  margin: 0 0 0.4rem;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.05rem, 2.2vw, 1.3rem);
  line-height: 1.3;
  color: var(--or-texte);
}

/* Brun au repos, or au survol : le nom doit avoir quelque part où aller. Il
   était déjà doré en permanence sur les anciennes cartes, ce qui ne laissait
   aucune marge au survol. */
.univers__nom {
  margin: 0;
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(1.6rem, 3.6vw, 2.3rem);
  letter-spacing: 0.26em;
  text-transform: uppercase;
  line-height: 1.15;
  color: var(--brun);
  transition: color var(--t-douce);
}

.univers__salle:hover .univers__nom { color: var(--or-texte); }

/* Le seul trait de couleur de la salle. Dégradé et non trait plein, construit
   comme « .separateur » : il s'éteint au lieu de s'arrêter net. */
.univers__filet {
  width: 62px;
  height: 1px;
  margin: 1.2rem 0;
  border: 0;
  background: linear-gradient(90deg, var(--teinte-trait), transparent);
}

.univers__ambiance {
  margin: 0;
  max-width: 34ch;
  font-size: clamp(1rem, 1.9vw, 1.05rem);
  line-height: 1.75;
  color: var(--texte-doux);
}

/* Clôture : l'invitation reprend l'italique or de « Et la vôtre ? », en plus
   petit — la question ouvrait la section, celle-ci la referme. */
.univers__cloture {
  margin: clamp(3rem, 6vw, 4.5rem) 0 1.7rem;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.25rem, 2.6vw, 1.6rem);
  color: var(--or-texte);
}

/* ---- ≤ 1024px : les rangées s'empilent ----
   La personnalité de chaque salle survit à la pile : lavis teinté, mot-signature
   et filet coloré restent en place, seule l'alternance gauche/droite disparaît
   puisqu'il n'y a plus qu'une colonne. */
@media (max-width: 1024px) {
  .univers__salle {
    grid-template-columns: 1fr;
    gap: clamp(1.4rem, 4vw, 2rem);
    text-align: center;
  }

  /* Les colonnes explicites ne valent qu'en deux colonnes : en pile, tout
     revient à l'ordre du DOM — photo puis texte, pour les cinq rangées. */
  .univers__salle:nth-child(even) .univers__media,
  .univers__salle:nth-child(even) .univers__texte {
    grid-column: 1;
    grid-row: auto;
  }

  .univers__media,
  .univers__texte {
    width: 100%;
    max-width: 520px;
    margin-inline: auto;
  }

  .univers__filet { margin-inline: auto; }
  .univers__ambiance { max-width: none; }

  /* L'interlettrage s'applique aussi après la dernière lettre : sans ce
     rattrapage, le nom centré paraît décalé d'un quart de cadratin à gauche. */
  .univers__nom { text-indent: 0.26em; }
}

/* Placeholder clair : dégradé crème + teinte propre à la salle */
.espace-reserve {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(90% 70% at 50% 25%,
      var(--teinte, rgba(201, 160, 92, 0.2)) 0%, transparent 70%),
    linear-gradient(165deg, #FFFDF6 0%, #F6EEDC 55%, #EFE3CB 100%);
}

.espace-reserve::after {
  content: '';
  position: absolute;
  inset: 0;
  opacity: 0.6;
  background-image:
    repeating-linear-gradient(135deg,
      rgba(140, 106, 47, 0.045) 0 1px, transparent 1px 9px);
}

/* Deux teintes par salle, et pas une seule :
     --teinte        le lavis du placeholder, très dilué, il doit rester un
                     souffle de couleur sur du crème ;
     --teinte-trait  le filet et la bordure au survol, presque opaques, sinon
                     un trait d'un pixel à 25 % d'alpha ne se voit pas.
   Le second est aussi un cran plus foncé que le premier : à saturation égale,
   un trait fin paraît toujours plus clair qu'un aplat. */
.univers__salle--sakura {
  --teinte:       rgba(206, 118, 128, 0.26);
  --teinte-trait: rgba(178,  84,  96, 0.88);
}
/* ACAJOU — la salle s'appelait « Mauve » tant qu'elle n'avait qu'un lavis. Sa
   photo est arrivée : murs crème, plancher d'acajou, lumière ambrée, et pas un
   gramme de mauve. Le nom, le filet et la phrase ont suivi la pièce plutôt que
   l'inverse. Brun-rouge profond (5,92:1), franchement distinct du rouge de la
   salle Rouge (#A2423F, plus clair et plus rouge) comme du bronze d'Ivoire. */
.univers__salle--acajou {
  --teinte:       rgba(140,  74,  46, 0.26);
  --teinte-trait: rgba(112,  56,  36, 0.88);
}
.univers__salle--rouge {
  --teinte:       rgba(170,  56,  56, 0.24);
  --teinte-trait: rgba(150,  42,  42, 0.88);
}

/* IVOIRE — le cas difficile de la série, et la raison pour laquelle son filet
   n'est pas le champagne clair qu'on attendrait : il s'agit de poser de
   l'ivoire SUR du crème. Mesuré sur --creme-appui, un champagne clair tombe à
   1,78:1 et un champagne moyen à 2,35:1 — invisibles l'un comme l'autre. Le
   ton retenu est descendu jusqu'au bronze doux, seul rang où le filet
   redevient franc : 3,50:1, soit exactement le rang de Sakura (3,48:1).
   Ne pas l'éclaircir « pour faire plus ivoire » — il disparaîtrait.
   Le lavis, lui, est monté à 0,32 (contre ~0,25 ailleurs) pour la même
   raison : à 0,26 le placeholder ne se distinguait pas du crème nu. */
.univers__salle--ivoire {
  --teinte:       rgba(182, 150,  92, 0.32);
  --teinte-trait: rgba(130, 108,  66, 0.88);
}

/* NOIRE — la seule salle dont l'identité est un fond, pas un accent. Le filet
   est un brun-noir presque opaque (11,24:1) ; l'or n'entre pas par le trait
   mais par la lueur du placeholder, ci-dessous. */
.univers__salle--noire {
  --teinte:       rgba(201, 160,  92, 0.30);   /* la lueur dorée, pas un lavis */
  --teinte-trait: rgba( 38,  26,  16, 0.90);
}

/* Le placeholder de la salle Noire part d'un fond SOMBRE — la seule des cinq.
   Même géométrie que « .espace-reserve » (lueur radiale au même point, base
   linéaire au même angle) : seule la base bascule du crème au brun-nuit.
   Un lavis noir à 25 % sur le dégradé crème aurait donné un beige gris, et
   une salle annoncée « ombres profondes » serait arrivée en beige.
   L'or de la lueur porte à 7,68:1 sur cette base — il brille vraiment. */
.univers__salle--noire .espace-reserve {
  background:
    radial-gradient(90% 70% at 50% 25%,
      var(--teinte) 0%, transparent 70%),
    linear-gradient(165deg, #2A1D12 0%, #1A110B 55%, #120B06 100%);
}

/* La trame du placeholder est réglée pour du crème : sur le fond sombre elle
   s'annule. On la reprend en or, à la même discrétion. */
.univers__salle--noire .espace-reserve::after {
  background-image:
    repeating-linear-gradient(135deg,
      rgba(201, 160, 92, 0.05) 0 1px, transparent 1px 9px);
}

/* Au survol, les quatre autres salles allument leur cadre de leur propre
   teinte. Ici --teinte-trait est un brun-noir : posé sur un placeholder déjà
   sombre, il ne se verrait pas. C'est l'or qui prend le relais — le même
   geste, avec la seule couleur qui se détache de ce fond-là. */
.univers__salle--noire:hover .univers__media { border-color: var(--or); }

/* --------------------------------------------------------------------------
   13. Personnel
   -------------------------------------------------------------------------- */
/* Citation d'ouverture de la grille. Descendue du hero : elle parle des
   femmes, sa place est au-dessus de leurs portraits, pas noyée dans un bloc
   qui portait déjà un titre de trois lignes et un numéro de téléphone. Elle y
   gagne aussi de tenir sur UNE ligne au lieu de trois. */
.equipe-citation {
  max-width: 30ch;
  margin: 0 auto clamp(2.8rem, 5.5vw, 4.2rem);
  text-align: center;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.35rem, 3vw, 2rem);
  line-height: 1.45;
  color: var(--brun);
}

/* La source en petites capitales espacées, non italiques : elle se détache de
   la citation sans lui disputer la voix. */
.equipe-citation__source {
  display: block;
  margin-top: 0.85rem;
  font-family: var(--sans);
  font-style: normal;
  font-weight: 400;
  font-size: clamp(0.75rem, 1.4vw, 0.78rem);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--or-texte);
}

.equipe {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1rem, 2.2vw, 1.8rem);
}

.pro { text-align: center; }

.pro__media {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--carte-bordure);
  border-radius: 6px;
  aspect-ratio: 3 / 4;
  transition: border-color var(--t-douce), box-shadow var(--t-douce);
}

.pro:hover .pro__media {
  border-color: var(--accent);
  box-shadow: 0 12px 34px rgba(58, 42, 28, 0.16);
}

.pro__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-lente);
}
.pro:hover .pro__media img { transform: scale(1.05); }

/* Monogramme filigrané dans le placeholder, quand aucune photo n'est
   disponible. Seule l'initiale : le prénom complet figure déjà sous la
   carte, l'afficher deux fois ferait doublon.
   Purement décoratif (aria-hidden) : le contraste volontairement faible
   ne pose pas de problème d'accessibilité, l'information est portée par
   .pro__nom juste en dessous. */
.pro__initiale {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(3.5rem, 8vw, 5.5rem);
  line-height: 1;
  text-transform: uppercase;
  color: rgba(133, 98, 40, 0.5);
  transition: opacity var(--t-douce);
}

/* Au survol, le monogramme S'EFFACE au lieu de se renforcer (il fonçait, avant
   que le voile n'existe). Le voile est translucide : une initiale de 5 rem
   posée dessous continuait de transparaître en clair, juste derrière
   « VOIR PLUS », et les deux se disputaient le centre du cadre. Sur les cartes
   qui portent une vraie photo, cette règle ne s'applique à rien. */
.pro:hover .pro__initiale { opacity: 0; }

/* --------------------------------------------------------------------------
   « PHOTO À VENIR » — le placeholder commun aux douze professionnelles

   UN SEUL FICHIER pour les douze : « images/placeholder-professionnelle.webp ».
   Il porte déjà son texte en dur, il n'y a donc rien à superposer.

   IL NE REMPLACE PAS LE MÉCANISME, il en est le dernier étage : dès qu'une
   vraie photo existe pour une fille, le générateur émet celle-ci à sa place
   dans la grille, et l'empile PAR-DESSUS dans la galerie. Déposer une photo
   suffit, aucune ligne à toucher.

   Posé en « absolute » et non en flux : dans la galerie, la vraie photo
   (« .galerie__image », z-index 1) doit pouvoir se superposer au placeholder
   sans le pousser. Sans z-index ici — donc en dessous de la photo (1) comme
   du voile « VOIR PLUS » (2).

   AUCUN « object-position » : le texte est centré verticalement dans le
   fichier (49,9 % de sa hauteur), et la source est plus étroite en ratio que
   tous les cadres où elle sert — 3:4 pour les cartes et les vignettes, 4:5
   pour la grande photo. « cover » n'y rogne donc que la hauteur, également en
   haut et en bas, et le texte reste au centre dans les trois. Vérifié par le
   calcul et à l'œil. */
.photo-attente {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity var(--t-douce);
}

/* AU SURVOL D'UNE CARTE, LE PLACEHOLDER RECULE — même problème que le
   monogramme avant lui, et même remède.

   « VOIR PLUS » est centré dans le cadre ; « PHOTO À VENIR » l'est aussi,
   puisqu'il est gravé au milieu de l'image. Les deux se retrouvaient donc
   l'un sur l'autre, en clair sur clair, et aucun des deux ne se lisait.

   Le monogramme, lui, pouvait passer à « opacity: 0 » puisqu'il était un
   élément à part. Ici le texte EST l'image : on ne peut pas l'effacer seul.
   On fait donc reculer l'image entière, assez pour que sa mention s'éteigne,
   pas assez pour vider le cadre — la silhouette reste lisible en fond.

   Ne s'applique qu'au placeholder : une vraie photo garde son voile et son
   zoom, sans rien perdre de sa lumière. */
.pro:hover .photo-attente,
.pro:focus-within .photo-attente { opacity: 0.1; }

.pro__nom {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(1.05rem, 2.1vw, 1.35rem);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--or-texte);
  margin: 1.1rem 0 0;
}

/* --------------------------------------------------------------------------
   13 bis. Carte du personnel — lien vers la fiche

   Toute la carte est cliquable, pas seulement la photo : le lien enveloppe le
   cadre photo ET le prénom. Les règles de survol existantes (§13) portent sur
   « .pro:hover » et continuent donc de jouer sans modification, puisque le
   lien remplit la carte.
   -------------------------------------------------------------------------- */
.pro__lien {
  display: block;
  color: inherit;
}
.pro__lien:hover { color: inherit; }

/* Au clavier, la carte doit rendre ce que rend le survol — sinon la
   tabulation ne donne que le contour par défaut, sans le zoom ni le voile.
   L'anneau est reposé à la main sur le cadre photo : le contour du lien
   lui-même épouserait le bloc entier et flotterait sous le prénom, à distance
   de l'image qu'il est censé désigner. */
.pro__lien:focus-visible { outline: none; }

.pro__lien:focus-visible .pro__media {
  border-color: var(--accent);
  box-shadow: 0 12px 34px rgba(58, 42, 28, 0.16);
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.pro__lien:focus-visible .pro__media img { transform: scale(1.05); }

/* Le monogramme s'efface aussi au clavier — même raison qu'au survol (§13) :
   le voile est translucide et l'initiale transparaîtrait derrière
   « VOIR PLUS ». Sans cette ligne, la tabulation donnait un rendu différent
   du survol sur les seules cartes sans photo. */
.pro__lien:focus-visible .pro__initiale { opacity: 0; }

/* « Voir plus » posé SUR la photo au survol.

   C'est le premier endroit du site où du texte repose sur une photo hors du
   hero. Le voile n'est donc pas un effet décoratif : c'est lui qui rend le
   texte lisible, et il est dosé exactement comme celui du hero — léger sur les
   bords pour ne pas éteindre l'image, resserré au centre là où le texte se
   trouve.

   DEUX COUCHES, et le dosage n'est pas arbitraire :
     — un voile uniforme à 0,42, la valeur d'ambiance, celle que l'œil perçoit
       sur les bords de la carte ;
     — un halo central à 0,40 par-dessus, soit 1 − 0,58 × 0,60 = 0,652 cumulés
       au centre.

   Le halo est LARGE (105 % × 78 %, avec un palier à 0,26 à mi-course) et non
   resserré sur le texte. Un halo étroit — première version, 62 % × 42 % — se
   lisait comme une tache sombre posée au milieu de la carte, pas comme un
   éclairage : la limite du dégradé se voyait. Étalé jusqu'aux bords, il
   redevient un vignettage, vocabulaire que la page emploie déjà
   (« .section--vignette »). Le contraste au centre, lui, est inchangé.

   L'ivoire y tient 5,03:1 sur le placeholder crème — qui est le PIRE fond
   possible, une vraie photo ne pouvant qu'assombrir davantage. Le voile
   uniforme à 0,42 seul le laissait à 2,25:1, illisible : c'est justement parce
   que le fond du cadre est clair, et non sombre comme on l'imagine d'un voile,
   que le halo central est nécessaire.

   Le voile porte le texte plutôt que l'inverse : une seule opacité à animer,
   donc fond et mention apparaissent rigoureusement ensemble. */
.pro__voile {
  position: absolute;
  inset: 0;
  z-index: 2;                 /* au-dessus du monogramme, qui est à 1 */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.62rem;
  background:
    radial-gradient(105% 78% at 50% 50%,
      rgba(26, 17, 11, 0.40) 0%,
      rgba(26, 17, 11, 0.26) 46%,
      transparent 100%),
    rgba(26, 17, 11, 0.42);
  opacity: 0;
  transition: opacity var(--t-douce);
}

.pro__lien:hover .pro__voile,
.pro__lien:focus-visible .pro__voile { opacity: 1; }

/* Ivoire et or clair en teintes brutes, sans passer par les rôles : ce sont
   les deux tokens documentés « sur fond sombre » en tête de fiche, et l'on est
   ici dans une zone sombre isolée, à l'intérieur d'une page claire. */
.pro__voir {
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(0.75rem, 1.35vw, 0.78rem);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  line-height: 1;
  /* L'interlettrage s'applique AUSSI après la dernière lettre : sans ce
     rattrapage, le mot paraît décalé d'un quart de cadratin vers la gauche
     dans un bloc centré. */
  text-indent: 0.28em;
  color: var(--ivoire);
}

/* Filet doré sous la mention. Un encadré complet entrerait en concurrence avec
   la bordure arrondie du cadre photo, à quelques pixels de là ; un filet seul
   reprend le vocabulaire de « .separateur » et des titres du pied de page,
   sans rien refermer. Ornement pur — non soumis au seuil de contraste, et de
   fait à 2,98:1 sur le pire fond. */
.pro__voile::after {
  content: '';
  width: 34px;
  height: 1px;
  background: var(--or-clair);
}

/* Écran tactile : PAS de règle « @media (hover: none) » ici, volontairement.
   Sans survol, le voile reste à opacité 0 et rien ne vient couvrir les douze
   photos — la carte est simplement cliquable. Poser la mention en permanence,
   comme le faisait l'ancien « Découvrir → » sous la carte, alourdirait la
   grille au lieu de la servir. */

/* --------------------------------------------------------------------------
   13 ter. Fiche d'une professionnelle — personnel/<slug>.html

   Douze pages générées par « node tools/generer-personnel.js » à partir de
   « js/personnel-data.js ». Deux colonnes en desktop : la galerie à gauche,
   la fiche de présentation à droite.
   -------------------------------------------------------------------------- */

/* Hero compact. Même parti que « .hero--sobre » des pages légales — crème
   d'appui, pas de photo — mais le titre y est un prénom seul, donc beaucoup
   plus grand. Pas de « .sur-photo » : on reste en thème clair. */
.hero--fiche {
  min-height: min(40vh, 400px);
  background-color: var(--creme-appui);
  border-bottom: 1px solid var(--filet);
}

.titre-fiche {
  margin: 0;
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(2.6rem, 8vw, 5rem);
  line-height: 1;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--or-texte);
}

/* Retour discret vers la grille. Discret par la taille et l'interlettrage,
   pas par le contraste : « --texte-doux » tient 5,2:1 sur le crème d'appui. */
.fiche__retour {
  margin: 0 0 clamp(1.2rem, 3vw, 1.8rem);
  text-align: left;
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(0.75rem, 1.4vw, 0.78rem);
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.fiche__retour a { color: var(--texte-doux); }
.fiche__retour a:hover { color: var(--or-texte-vif); }

.fiche {
  display: grid;
  grid-template-columns: 60fr 40fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}

/* ---- Galerie ---- */

/* Bornée en largeur : la colonne de gauche vaut ~660 px au maximum de page,
   ce qui donnerait une grande photo de 825 px de haut en 4/5 — plus haute que
   la plupart des fenêtres, et la fiche de droite disparaîtrait sous la ligne
   de flottaison. */
.galerie { max-width: 540px; }

.galerie__principale {
  position: relative;
  overflow: hidden;
  aspect-ratio: 4 / 5;
  border: 1px solid var(--carte-bordure);
  border-radius: 6px;
  background-color: var(--creme-carte);
}

/* Empilement dans le cadre : le placeholder occupe le fond (z-index auto),
   la photo passe au-dessus. Une photo manquante est effacée par
   js/personnel-galerie.js et redécouvre le placeholder — jamais un trou. */
.galerie__image {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity var(--t-galerie) var(--courbe-douce);
}

.galerie__image.est-en-transition { opacity: 0; }
.galerie__image.est-absente { display: none; }

/* Monogramme du placeholder. Même raisonnement qu'en §13 pour « .pro__initiale » :
   purement décoratif et « aria-hidden », le contraste faible est voulu et ne
   porte aucune information — le prénom est dans le hero, juste au-dessus. */
.galerie__initiale {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(5rem, 14vw, 10rem);
  line-height: 1;
  text-transform: uppercase;
  color: rgba(133, 98, 40, 0.42);
}

.galerie__vignettes {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(0.45rem, 1.2vw, 0.7rem);
  margin: clamp(0.55rem, 1.5vw, 0.85rem) 0 0;
  padding: 0;
  list-style: none;
}

/* La largeur porte sur le <li>, PAS sur le bouton : dans un conteneur flex,
   ce sont les enfants directs qui sont les éléments flexibles. Dimensionner
   le bouton laissait chaque <li> occuper toute la rangée, et les vignettes
   s'empilaient verticalement, une par ligne.

   Largeur fixée en clamp plutôt qu'en fraction de la rangée : le nombre de
   vignettes varie de 3 à 6 selon la fille, et un « 1fr » les ferait changer
   de taille d'une fiche à l'autre. */
.galerie__vignettes > li { width: clamp(56px, 14%, 82px); }

.galerie__vignette {
  display: block;
  position: relative;
  overflow: hidden;
  width: 100%;
  aspect-ratio: 3 / 4;
  padding: 0;
  border: 1px solid var(--carte-bordure);
  border-radius: 4px;
  background: none;
  cursor: pointer;
  transition: border-color var(--t-douce), box-shadow var(--t-douce);
}

.galerie__vignette img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.82;
  transition: opacity var(--t-douce);
}

.galerie__vignette:hover { border-color: var(--accent); }
.galerie__vignette:hover img { opacity: 1; }

.galerie__vignette[aria-current='true'] {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}
.galerie__vignette[aria-current='true'] img { opacity: 1; }

/* Vignettes de remplissage, quand aucune photo n'a encore été déposée : de
   simples cadres décoratifs, ni cliquables ni annoncés. */
.galerie__vignette--vide { cursor: default; }

/* ---- Fiche de présentation ---- */

/* Aligne la première capitale du libellé sur le haut du cadre photo, que la
   bordure de 1 px décale d'autant. */
.fiche__infos { padding-top: 0.3rem; }

.fiche__liste { margin: 0; }

/* Ce rembourrage est ACCORDÉ AU NOMBRE DE LIGNES de la fiche — six aujourd'hui.
   Mesuré à 1470 px de large, contre un cadre photo de 789 px :

     6 lignes à 1,2rem  → colonne de 756 px, soit 33 de moins que la photo ✔
     6 lignes à 0,95rem → 708 px, la colonne remonte trop haut
     7 lignes à 1,2rem  → 854 px, le texte déborde de 65 px sous la galerie

   Si le nombre de lignes change, revenir ici — et mesurer les DEUX colonnes
   côte à côte, le rendu d'une fiche isolée ne dit rien de leur équilibre. */
.fiche__ligne {
  padding: clamp(0.9rem, 2vw, 1.2rem) 0;
  border-bottom: 1px solid var(--filet);
}
.fiche__ligne:first-child { border-top: 1px solid var(--filet); }

.fiche__libelle {
  margin: 0 0 0.35rem;
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(0.75rem, 1.3vw, 0.78rem);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  line-height: 1.6;
  color: var(--or-texte);
}

.fiche__valeur {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(1.1rem, 2.2vw, 1.3rem);
  line-height: 1.6;
  color: var(--texte);
}

/* Champ non renseigné : le tiret cadratin est décoratif et « aria-hidden ».
   Le lecteur d'écran reçoit « Non renseigné » par « .hors-ecran » — un tiret
   seul, épelé, ne veut rien dire. */
.fiche__valeur--vide { color: var(--texte-doux); }

.fiche__bio {
  margin: clamp(1.6rem, 3.5vw, 2.3rem) 0 0;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.15rem, 2.4vw, 1.4rem);
  line-height: 1.6;
  color: var(--texte);
}

.fiche__bio--vide {
  font-size: clamp(1rem, 1.9vw, 1.05rem);
  color: var(--texte-doux);
}

.fiche__action { margin: clamp(1.9rem, 4vw, 2.8rem) 0 0; }

/* ---- ≤ 1024px : galerie au-dessus, fiche en dessous ----
   Même seuil que le passage au menu hamburger : c'est le point où le site
   entier bascule en lecture verticale. En dessous, la colonne de droite
   tomberait sous 350 px et les libellés espacés à 0,3em y casseraient. */
@media (max-width: 1024px) {
  .fiche {
    grid-template-columns: 1fr;
    gap: clamp(2.2rem, 6vw, 3.2rem);
  }

  .galerie {
    max-width: 460px;
    margin-inline: auto;
  }

  .galerie__vignettes { justify-content: center; }

  .fiche__infos {
    max-width: 460px;
    margin-inline: auto;
    padding-top: 0;
    text-align: center;
  }

  .fiche__retour { text-align: center; }
}

/* --------------------------------------------------------------------------
   14. Horaire
   -------------------------------------------------------------------------- */
/* Programme de la quinzaine : une liste verticale, pas une grille de cartes.
   Aucune boîte fermée, aucun fond de bloc — le rythme vient des filets. */
.programme + .programme { margin-top: clamp(3.5rem, 7vw, 5.5rem); }

.programme__semaine {
  margin: 0 0 clamp(1.4rem, 3vw, 2rem);
  text-align: center;
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(0.82rem, 1.7vw, 0.92rem);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--or-texte);
}

/* Ornement : un simple filet court, dans le vocabulaire du site. */
.programme__semaine::after {
  content: '';
  display: block;
  width: 46px;
  height: 1px;
  margin: 0.85rem auto 0;
  background: var(--trait);
  opacity: 0.75;
  --opacite-repos: 0.75;
}

.programme__liste {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Une rangée = « quand » à gauche, les deux plages à droite. */
.jour-ligne {
  display: grid;
  grid-template-columns: minmax(12rem, 0.9fr) 2fr;
  gap: clamp(0.9rem, 3vw, 2.5rem);
  align-items: baseline;
  padding: clamp(1.35rem, 2.7vw, 1.95rem) clamp(0.5rem, 1.5vw, 1.2rem);
  border-top: 1px solid var(--filet);
}

.programme__liste > li:last-child { border-bottom: 1px solid var(--filet); }

.jour-ligne__jour {
  display: block;
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(1.3rem, 2.4vw, 1.7rem);
  letter-spacing: 0.03em;
  color: var(--or-texte);
}

.jour-ligne__date {
  display: block;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.1rem, 1.9vw, 1.45rem);
  color: var(--brun);
}

.jour-ligne__plages {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1rem, 3vw, 2.5rem);
}

.plage__libelle {
  margin: 0 0 0.55rem;
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(0.75rem, 1.5vw, 0.82rem);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--or-texte);
}

.plage__noms {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.15rem, 2.2vw, 1.45rem);
  line-height: 1.65;
  color: var(--brun);
}

.plage__noms--vide {
  font-style: italic;
  color: var(--texte-doux);
}

/* Jour courant : fond d'appui très léger + mention en or. Les deux ensemble,
   parce que la couleur seule ne suffit pas comme unique porteur d'information. */
.jour-ligne--aujourdhui { background-color: var(--creme-appui); }

.jour-ligne__marqueur {
  display: block;
  margin-top: 0.45rem;
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(0.75rem, 1.45vw, 0.8rem);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  /* --or-texte-vif et non --or-texte : à 10,5 px sur le crème d'appui de la
     rangée, l'or courant tombait à 4,36:1 au bord de la vignette de section,
     sous le seuil de 4,5 exigé pour ce corps. Ici 7,2:1. */
  color: var(--or-texte-vif);
}

/* --------------------------------------------------------------------------
   15. Réservation — deux options
   -------------------------------------------------------------------------- */
.option {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 300px;
  padding: clamp(2.2rem, 4.5vw, 3.5rem);
}

.option__titre {
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(0.75rem, 1.6vw, 0.8rem);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--texte-doux);
  margin: 0 0 1.6rem;
}

.option__valeur {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(1.7rem, 4.4vw, 2.7rem);
  letter-spacing: 0.08em;
  color: var(--or-texte);
  transition: color var(--t-douce);
}
a.option:hover .option__valeur { color: var(--or-texte-vif); }

/* --------------------------------------------------------------------------
   15 bis. Formulaire de demande de rendez-vous

   Les deux options ne sont PAS de même poids et la mise en page l'assume :
   le téléphone est une carte compacte, la demande en ligne un bloc haut. Les
   aligner en hauteur aurait demandé soit d'étirer la carte téléphone sur
   800 px de vide, soit de comprimer le formulaire. « align-items: start »
   laisse chacune à sa taille naturelle.
   -------------------------------------------------------------------------- */
/* Hero de « reservation.html ». Plus court que celui des fiches (40vh) : cette
   page-là se contemple, celle-ci s'utilise. Le formulaire doit apparaître dans
   le premier écran, le hero ne fait que nommer l'endroit. */
.hero--action {
  min-height: min(34vh, 320px);
  background-color: var(--creme-appui);
  border-bottom: 1px solid var(--filet);
  /* Le rembourrage de « .hero » (4,5rem en haut et en bas, plus la hauteur de
     la barre) pousse ce hero à 380px en mobile, soit près de la moitié de
     l'écran : le formulaire tombait sous la ligne de flottaison alors que
     c'est la seule raison d'être de la page. Réduit à 2,5rem, le hero rentre
     dans les 34vh visés et le premier champ est visible d'emblée. */
  padding: calc(var(--hauteur-nav) + 2.5rem) 0 2.5rem;
}

.hero__action-ligne {
  max-width: 44ch;
  margin: 0 auto;
  font-size: clamp(1rem, 2vw, 1.15rem);
  line-height: 1.7;
  color: var(--texte-doux);
}

/* Le formulaire seul sur sa page : borné et centré. À pleine largeur de
   contenant (1280px) les champs deviendraient des rubans de 1180px, illisibles
   à parcourir de l'œil. */
.formulaire--page {
  max-width: 660px;
  margin: 0 auto;
}

.reservation { align-items: start; }

/* Le formulaire fait ~800 px de haut, la carte téléphone 300 : il reste
   500 px de colonne vide à gauche. Plutôt que d'étirer la carte sur ce vide —
   un cadre de 800 px contenant un numéro et rien d'autre — on la rend
   COLLANTE : elle accompagne le remplissage du formulaire et reste offerte au
   visiteur qui renonce en cours de route. Le vide devient une fonction.
   Uniquement en deux colonnes : en pile, la carte précède le formulaire et
   n'a rien à suivre. */
@media (min-width: 1025px) {
  .reservation .option {
    position: sticky;
    top: calc(var(--hauteur-nav) + 2rem);
  }
}

.formulaire {
  padding: clamp(1.8rem, 3.5vw, 2.8rem);
  text-align: left;
}

/* Le titre de la carte téléphone est centré ; celui du formulaire s'aligne
   sur ses champs. */
.formulaire .option__titre {
  text-align: left;
  margin-bottom: 1.9rem;
}

.champ { margin-bottom: 1.35rem; }

/* Deux champs courts côte à côte — date et heure vont ensemble, les séparer
   sur deux lignes allongeait le formulaire sans rien clarifier. */
.champ__paire {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

.champ__libelle {
  display: block;
  margin-bottom: 0.5rem;
  padding: 0;
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.75rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--or-texte);
}

/* 48px de haut au minimum : c'est la cible tactile confortable au pouce, et
   c'est aussi ce qui empêche iOS de zoomer à la mise au point — Safari le
   fait dès que le corps du champ descend sous 16px, d'où le « font-size:
   1rem » qui n'est pas négociable ici. */
.champ__saisie {
  display: block;
  width: 100%;
  min-height: 48px;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--carte-bordure);
  border-radius: 4px;
  background-color: var(--creme);
  color: var(--texte);
  font-family: var(--sans);
  font-weight: 300;
  font-size: 1rem;
  line-height: 1.5;
  transition: border-color var(--t-douce), box-shadow var(--t-douce);
  /* Retire le rendu natif iOS (coins arrondis, dégradé interne) qui jurait
     avec les filets du site. */
  -webkit-appearance: none;
  appearance: none;
}

.champ__saisie:hover { border-color: var(--or-texte); }

.champ__saisie:focus-visible {
  outline: none;
  border-color: var(--or-texte);
  box-shadow: 0 0 0 2px rgba(133, 98, 40, 0.28);
}

.champ__saisie--zone {
  min-height: 90px;
  resize: vertical;
  font-family: var(--sans);
}

/* Le gris pâle habituel des placeholders (0,45 d'alpha) ne donne que 2,57:1 :
   sous le seuil, et le placeholder du message porte l'information
   « (optionnel) ». On reprend « --texte-doux », qui tient 5,4:1 tout en
   restant nettement plus clair que la saisie réelle (12,97:1) — la hiérarchie
   entre indication et contenu se lit toujours. */
.champ__saisie::placeholder { color: var(--texte-doux); opacity: 1; }

/* Le select garde une flèche : sans « appearance: none » elle est native et
   dépareille, avec elle disparaît. On la redessine en SVG inline, à la teinte
   du site. */
select.champ__saisie {
  padding-right: 2.4rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%23856228' stroke-width='1.5' d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  cursor: pointer;
}

.champ__aide {
  margin: 0.45rem 0 0;
  font-family: var(--sans);
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--texte-doux);
}

/* Brun-rouge et non le rouge d'alerte habituel : 7,15:1 sur le crème, et il
   reste dans la famille chaude du site. */
.champ__erreur {
  margin: 0.45rem 0 0;
  font-family: var(--sans);
  font-size: 0.85rem;
  line-height: 1.5;
  color: #9A2C2C;
}

.champ__saisie[aria-invalid='true'] { border-color: #9A2C2C; }

/* ---- Durée : quatre boutons radio redessinés ---- */
.champ--duree {
  margin: 0 0 1.35rem;
  padding: 0;
  border: 0;
}

.duree {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.6rem;
}

.duree__choix { cursor: pointer; }

/* Le radio natif est retiré de l'affichage mais RESTE dans le flux et
   focusable — « display: none » l'aurait sorti de la navigation clavier et
   du groupe de boutons radio. */
.duree__choix input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.duree__cadre {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.2rem;
  min-height: 48px;
  padding: 0.7rem 0.4rem;
  border: 1px solid var(--carte-bordure);
  border-radius: 4px;
  background-color: var(--creme);
  text-align: center;
  transition: border-color var(--t-douce), background-color var(--t-douce),
              box-shadow var(--t-douce);
}

.duree__choix:hover .duree__cadre { border-color: var(--or-texte); }

.duree__choix input:focus-visible + .duree__cadre {
  border-color: var(--or-texte);
  box-shadow: 0 0 0 2px rgba(133, 98, 40, 0.28);
}

.duree__choix input:checked + .duree__cadre {
  border-color: var(--or-texte);
  background-color: var(--creme-appui);
  box-shadow: inset 0 0 0 1px var(--or-texte);
}

.duree__temps {
  font-family: var(--sans);
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--texte);
}

.duree__prix {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 1.15rem;
  color: var(--or-texte);
}

.duree[aria-invalid='true'] .duree__cadre { border-color: #9A2C2C; }

.formulaire__envoi { margin: 1.9rem 0 0; }

/* « min-height » explicite : sous 480px le bouton du site retombe à un
   padding réduit et ne mesurait plus que 44px de haut — sous la cible
   tactile de 48px que respectent tous les autres champs du formulaire.
   Le flex recentre le libellé une fois la hauteur imposée. */
.formulaire__envoi .bouton {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 48px;
}

.formulaire__etat {
  margin: 1rem 0 0;
  font-family: var(--sans);
  font-size: 0.9rem;
  line-height: 1.6;
}
.formulaire__etat--erreur  { color: #9A2C2C; }
.formulaire__etat--attente { color: var(--texte-doux); }

/* ---- Confirmation, à la place du formulaire ---- */
.confirmation {
  padding: clamp(1.5rem, 3vw, 2.2rem) 0;
  text-align: center;
}
.confirmation:focus { outline: none; }

.confirmation__titre {
  margin: 0;
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(1.5rem, 3vw, 1.9rem);
  line-height: 1.3;
  color: var(--or-texte);
}

.confirmation__texte {
  max-width: 34ch;
  margin: 0 auto;
  font-size: 1rem;
  line-height: 1.75;
  color: var(--texte);
}

/* Le rappel du stationnement : une note de service, pas une seconde phrase
   de confirmation. Plus petit et plus discret que « .confirmation__texte »,
   dont il ne doit pas voler la place. */
.confirmation__pratique {
  margin: 0.9rem auto 0;
  font-family: var(--sans);
  font-weight: 300;
  font-size: 0.88rem;
  color: var(--texte-doux);
}

.confirmation__tel {
  margin: 1.4rem 0 0;
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(1.4rem, 3vw, 1.8rem);
  letter-spacing: 0.06em;
}

/* ---- La mention « une professionnelle en particulier ? » ----
   Elle ne s'adresse qu'à une partie des visiteurs, mais celle-là doit la voir
   avant d'envoyer une demande qui ne pourrait pas être honorée. D'où le filet
   doré au-dessus : il l'isole du formulaire sans la reléguer en note de bas
   de page. */
.reservation__note {
  max-width: 62ch;
  margin: clamp(2.6rem, 5vw, 3.6rem) auto 0;
  padding-top: clamp(1.6rem, 3vw, 2.2rem);
  border-top: 1px solid var(--filet);
  text-align: center;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.1rem, 2.2vw, 1.3rem);
  line-height: 1.7;
  color: var(--texte);
}

.reservation__tel {
  font-style: normal;
  font-weight: 600;
  color: var(--or-texte);
  white-space: nowrap;
}
.reservation__tel:hover { color: var(--or-texte-vif); }

/* ---- ≤ 768px : le formulaire prend toute la largeur ---- */
@media (max-width: 768px) {
  .duree { grid-template-columns: repeat(2, 1fr); }
  .champ__paire { grid-template-columns: 1fr; gap: 0; }
  .champ__paire .champ { margin-bottom: 1.35rem; }
}

/* --------------------------------------------------------------------------
   16. Pied de page — identique sur les 7 pages.
   La vitrine (photo roses + invitation) n'en fait PAS partie : c'est du
   contenu, elle vit dans <main> et uniquement sur l'accueil.
   -------------------------------------------------------------------------- */
.pied {
  background-color: var(--creme);
  border-top: 1px solid var(--filet);
}

/* Trois colonnes de largeur strictement égale, gouttières identiques,
   contenu centré. Chaque colonne est une pile flex calée en haut : les
   trois titres tombent donc exactement sur la même ligne de base. */
.pied__colonnes {
  /* Hauteur commune aux blocs de contenu : la carte s'y aligne pour ne pas
     déséquilibrer la rangée face aux sept lignes d'horaire. */
  --pied-bloc: 11.5rem;

  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(2.5rem, 5vw, 4rem);
  padding: clamp(3.5rem, 7vw, 5.5rem) 0 0;
  text-align: center;
}

.pied__colonnes > * {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.pied__titre {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.75rem;   /* plancher des petites capitales : 12px */
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--or-texte);
  margin: 0 0 1.4rem;
}

/* Court filet sous chaque titre de colonne, centré */
.pied__titre::after {
  content: '';
  display: block;
  width: 34px;
  height: 1px;
  margin: 0.85rem auto 0;
  background: var(--or-texte);
  opacity: 0.55;
}

.pied__liste {
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--sans);
  font-weight: 300;
  font-size: 0.92rem;
  line-height: 2.05;
  color: var(--texte-doux);
}

/* Horaire : jour à gauche, plage à droite à l'intérieur d'un bloc
   lui-même centré dans la colonne. */
.pied__horaire {
  margin: 0 auto;
  width: min(100%, 15rem);
  height: var(--pied-bloc);
  display: grid;
  align-content: space-between;
  font-family: var(--sans);
  font-weight: 300;
  font-size: 0.92rem;
  color: var(--texte-doux);
}

.pied__horaire > div {
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
}

.pied__horaire dt { margin: 0; }
.pied__horaire dd { margin: 0; white-space: nowrap; }

/* La carte reçoit le même traitement de cadre que les photos du site.

   SA HAUTEUR EST UN ARBITRAGE DE COLONNE, pas un rapport d'image. Elle valait
   « --pied-bloc » — les sept lignes d'horaire — tant que la colonne ne
   contenait qu'elle. Les vignettes d'accès s'ajoutant en dessous, la colonne
   dépassait de loin les deux autres : la carte est donc ramenée à 8 rem, et
   ce qu'elle cède, les vignettes le reprennent. Le total retombe à hauteur
   des sept lignes.

   Ne pas lui rendre « --pied-bloc » sans retirer les vignettes : les trois
   colonnes se décaleraient de nouveau. */
.pied__carte {
  width: min(100%, 15rem);
  height: 8rem;
  border: 1px solid var(--carte-bordure);
  border-radius: 6px;
  filter: grayscale(0.3) sepia(0.14) contrast(1.02);
  transition: filter var(--t-douce);
}
.pied__carte:hover { filter: none; }

/* --------------------------------------------------------------------------
   Accès — la note et les deux vues, dans la colonne « Notre adresse »

   DE L'INFORMATION DE SERVICE dans un pied de page déjà dense. Tout est réglé
   pour qu'elle se consulte sans s'imposer : une ligne de texte, deux vignettes
   de la largeur de la carte, des légendes minuscules.
   -------------------------------------------------------------------------- */
.pied__acces-note {
  width: min(100%, 15rem);
  margin: -0.35rem auto 0.85rem;
  font-family: var(--sans);
  font-weight: 300;
  font-size: 0.8rem;
  line-height: 1.55;
  color: var(--texte-doux);
}

.pied__acces {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem;
  width: min(100%, 15rem);
  margin: 0.55rem auto 0;
  padding: 0;
  list-style: none;
}

/* Un BOUTON et non un lien : il n'y a pas de page au bout, seulement un
   agrandissement. On le dépouille de son habillage natif et on lui rend un
   anneau de focus visible — il est atteignable au clavier. */
.pied__acces-vue {
  display: block;
  width: 100%;
  padding: 0;
  font: inherit;
  color: inherit;
  text-align: center;
  background: none;
  border: 0;
  cursor: pointer;
}

.pied__acces-vue img {
  display: block;
  width: 100%;
  /* « height: auto » d'abord : les attributs width/height du HTML valent
     indication de présentation et fixeraient 900 px de haut, ce qui laisserait
     « aspect-ratio » sans dimension libre à résoudre. */
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border: 1px solid var(--carte-bordure);
  border-radius: 6px;
  /* Même intention que la carte juste au-dessus : faire entrer des photos
     utilitaires dans la palette crème et or. Les deux clichés ne partaient pas
     du même endroit — le stationnement baigne dans un coucher de soleil,
     l'entrée a un ciel bleu franc — et ce réglage sert autant à les réchauffer
     qu'à les rapprocher l'une de l'autre. */
  filter: sepia(0.16) saturate(0.88) brightness(0.97) contrast(1.02);
  transition: filter var(--t-douce), border-color var(--t-douce);
}

.pied__acces-vue:hover img,
.pied__acces-vue:focus-visible img {
  filter: none;
  border-color: var(--accent);
}

.pied__acces-vue:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 6px;
}

/* 0,75 rem = 12 px, le plancher que cette feuille s'impose partout ailleurs
   pour les intitulés en petites capitales (voir « .pied__titre » et
   « .sommaire__titre »). La valeur précédente, 0,62 rem, faisait de ces deux
   mots le plus petit texte du site — lisible sur un écran d'ordinateur à
   trente centimètres, beaucoup moins sur un téléphone tenu à bout de bras,
   qui est justement l'usage visé par ces deux vignettes. « Stationnement »,
   le plus long des deux, occupe environ 118 px dans une colonne qui en fait
   156 à 360 px de large : le passage à 12 px ne provoque aucun repli. */
.pied__acces-legende {
  display: block;
  margin: 0.34rem 0 0;
  font-family: var(--sans);
  font-weight: 300;
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texte-doux);
}

/* --------------------------------------------------------------------------
   Agrandissement d'une vue — sans bibliothèque

   Un simple calque : photo centrée, fond sombre, on ferme d'un clic n'importe
   où ou par Échap. « js/main.js » § 4 pose le focus dedans à l'ouverture et le
   rend à la vignette à la fermeture.
   -------------------------------------------------------------------------- */
/* ⚠ TROIS VERROUS, ET AUCUN N'EST DÉCORATIF — bogue vécu.

   « calque.hidden = true » ne masquait RIEN : la règle « display: flex »
   ci-dessous l'emporte sur le « [hidden] { display: none } » de la feuille du
   navigateur. Le calque restait donc en place, invisible (opacity 0) mais
   fixé, à z-index 200 et pointer-events auto — il interceptait tous les clics
   de la page. Refermer la photo gelait le site entier, et rien ne le laissait
   voir puisqu'il était transparent.

   Diagnostic qui a tranché : « document.elementFromPoint(milieu de l'écran) »
   renvoyait « div.agrandissement » alors que la photo était fermée.

   D'où trois protections indépendantes, chacune suffisante :
     1. « [hidden] » masque pour de bon — la règle explicite l'emporte enfin ;
     2. « pointer-events: none » hors ouverture — couvre les 300 ms du fondu,
        ET le cas où le « hidden » tarderait (minuterie ralentie par un onglet
        d'arrière-plan, par exemple) ;
     3. « opacity: 0 » pour l'œil.
   Ne pas en retirer une en croyant faire le ménage. */
.agrandissement {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: clamp(1.2rem, 4vw, 2.5rem);
  background: rgba(21, 13, 7, 0.92);
  cursor: zoom-out;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-douce);
}

/* Verrou 1 : sans cette ligne, « hidden » est inerte sur cet élément. */
.agrandissement[hidden] { display: none; }

/* Le calque ne redevient cliquable QUE pendant qu'il est ouvert. */
.agrandissement.est-ouvert {
  opacity: 1;
  pointer-events: auto;
}

.agrandissement__image {
  max-width: min(100%, 1100px);
  max-height: 78vh;
  object-fit: contain;
  border-radius: 6px;
  /* Ici, AUCUN filtre : c'est le moment où l'on veut voir les lieux tels
     qu'ils sont. L'harmonisation ne sert que la vignette, dans le pied. */
}

.agrandissement__legende {
  margin: 0;
  font-family: var(--sans);
  font-weight: 300;
  font-size: 0.88rem;
  letter-spacing: 0.06em;
  /* Crème sur brun-nuit : 13,9:1. */
  color: var(--creme);
}

.agrandissement__fermer {
  position: absolute;
  top: clamp(0.8rem, 2.5vw, 1.4rem);
  right: clamp(0.8rem, 2.5vw, 1.4rem);
  width: 2.75rem;
  height: 2.75rem;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--creme);
  background: none;
  border: 0;
  cursor: pointer;
  opacity: 0.75;
  transition: opacity var(--t-douce);
}
.agrandissement__fermer:hover,
.agrandissement__fermer:focus-visible { opacity: 1; }
.agrandissement__fermer:focus-visible {
  outline: 2px solid var(--or-clair);
  outline-offset: 2px;
}

/* Logo ATM, colonne « Réseaux et autres ».
   Le libellé texte « ATM » qui accompagnait l'ancien pictogramme a été retiré :
   le logo porte le mot lui-même, le répéter à côté faisait doublon. Le sens
   reste accessible par l'attribut alt.

   PAS d'opacité réduite ici, contrairement à l'ancien pictogramme. Les teintes
   du logo (corps #E8D0B8, lettres #C8A888) ne donnent déjà que 1,40:1 et
   2,11:1 sur le crème du pied de page : l'atténuer davantage l'effacerait. */
.pied__paiement {
  display: flex;
  justify-content: center;
  margin-top: 1.5rem;
}

.pied__paiement img {
  display: block;
  width: auto;
  height: 38px;
}

.pied__adresse {
  font-family: var(--sans);
  font-weight: 300;
  font-size: 0.92rem;
  line-height: 2.05;
  color: var(--texte-doux);
  margin: 0 0 1.1rem;
}

/* L'adresse est un LIEN vers l'itinéraire : sur un téléphone, un appui suffit
   pour que Maps prenne le relais. Le soulignement n'apparaît qu'au survol —
   dans un pied de page déjà dense, trois lignes soulignées en permanence
   feraient du bruit. Il reste que le bloc est nettement cliquable : il porte
   le curseur main et se colore au contact. */
.pied__adresse__lien {
  color: inherit;
  text-decoration: none;
  transition: color var(--t-douce);
}
/* --or-texte-vif et NON --or-clair : le pied de page est sur du CRÈME, pas
   sur du sombre. L'or clair y tombe à 1,87:1 — illisible. On fonce donc au
   lieu d'éclaircir : 8,72:1, contre 5,41:1 au repos. */
.pied__adresse__lien:hover,
.pied__adresse__lien:focus-visible {
  color: var(--or-texte-vif);
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

/* Micro-signature : une main qui signe une lettre, pas un titre */
.pied__signature-fine {
  margin: clamp(2.75rem, 6vw, 4.5rem) 0 clamp(2.5rem, 5vw, 3.5rem);
  text-align: center;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.15rem, 2.2vw, 1.5rem);
  letter-spacing: 0.06em;
  color: var(--or-texte);
}

.pied__bas {
  border-top: 1px solid var(--filet);
  padding: 1.6rem 0;
  text-align: center;
  font-family: var(--sans);
  font-weight: 300;
  font-size: 0.82rem;
  letter-spacing: 0.05em;
  /* 12 px : il faut 4,5:1. Un brun à 0,62 d'opacité tombait à 4,06:1. */
  color: var(--texte-doux);
}

.pied__bas a { color: var(--brun); }
.pied__bas a:hover { color: var(--or-texte); }

.pied__bas span { white-space: nowrap; }

/* --------------------------------------------------------------------------
   16 bis. Pages légales (politique de confidentialité, conditions)

   Deux pages de texte long, sans photo. Elles n'utilisent donc PAS « .sur-photo » :
   on reste sur les rôles du thème clair, texte brun sur crème.
   -------------------------------------------------------------------------- */

/* Hero compact et sobre. Le crème d'appui suffit à le détacher du corps de
   page ; pas de photo, qui n'apporterait rien à un texte réglementaire. */
.hero--sobre {
  min-height: min(38vh, 340px);
  background-color: var(--creme-appui);
  border-bottom: 1px solid var(--filet);
}

.hero--sobre .titre-hero {
  font-size: clamp(1.5rem, 3.8vw, 2.7rem);
  letter-spacing: 0.06em;
}

.hero__date {
  margin: 0;
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(0.75rem, 1.5vw, 0.84rem);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--texte-doux);
}

/* Sommaire : deux filets plutôt qu'un cadre. Le site n'encadre rien ailleurs,
   une boîte bordée y ferait tache. */
.sommaire {
  max-width: 70ch;
  margin: 0 auto clamp(3.5rem, 7vw, 5rem);
  padding: clamp(1.4rem, 3vw, 2rem) 0;
  border-top: 1px solid var(--filet);
  border-bottom: 1px solid var(--filet);
}

.sommaire__titre {
  margin: 0 0 1.1rem;
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.75rem;   /* plancher des petites capitales : 12px */
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--accent);
}

.sommaire__liste {
  margin: 0;
  padding-left: 1.35em;
  font-family: var(--serif);
  font-size: clamp(1rem, 1.6vw, 1.1rem);
  line-height: 1.75;
  color: var(--texte);
}

/* Deux colonnes en grand écran : neuf entrées sur une seule colonne
   étireraient inutilement le bloc avant le premier paragraphe. */
@media (min-width: 1025px) {
  .sommaire__liste { columns: 2; column-gap: clamp(2rem, 4vw, 3.5rem); }
}

.sommaire__liste li { margin-bottom: 0.15em; break-inside: avoid; }
.sommaire__liste a { text-decoration: none; }
.sommaire__liste a:hover { text-decoration: underline; }

/* Corps du texte */
.prose {
  /* 58ch et non 70ch. Le « ch » vaut l'avance du chiffre 0, pas celle d'un
     caractère moyen : en Cormorant Garamond le 0 fait 0,477 em quand le
     caractère moyen d'un texte français en fait 0,385. Un « ch » vaut donc
     1,24 caractère réel, et les 70ch demandés rendaient ~87 caractères par
     ligne — bien au-delà des 75 admis. 58ch en rend ~72.
     Sans effet en mobile : la fenêtre y est toujours plus étroite que la
     borne, qui ne mord jamais. */
  max-width: 58ch;
  margin: 0 auto;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.05rem, 1.7vw, 1.18rem);
  line-height: 1.85;
  color: var(--texte);
}

/* La barre de navigation est fixe : sans cette réserve, une ancre amènerait
   le titre de section SOUS la barre. */
.prose > section,
#options {
  scroll-margin-top: calc(var(--hauteur-nav) + 1.5rem);
}

.prose > section + section { margin-top: clamp(2.6rem, 5vw, 3.6rem); }

.prose h2 {
  margin: 0 0 0.9rem;
  font-size: clamp(1.2rem, 2.1vw, 1.55rem);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--or-texte);
}

.prose h3 {
  margin: 1.8rem 0 0.6rem;
  /* Était au corps EXACT du texte courant (même clamp que « .prose ») : les
     sous-titres ne se distinguaient que par la graisse et la couleur, et la
     hiérarchie des deux pages légales tombait à plat. */
  font-size: clamp(1.12rem, 1.85vw, 1.3rem);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--texte);
}

.prose p  { margin: 0 0 1.05em; }
.prose ul { margin: 0 0 1.05em; padding-left: 1.35em; }
.prose li { margin-bottom: 0.5em; }
.prose a  { text-decoration: underline; text-underline-offset: 0.18em; }

/* Mention de mise à jour, en bas de page */
.prose__note {
  max-width: 70ch;
  margin: clamp(3rem, 6vw, 4.5rem) auto 0;
  padding-top: 1.5rem;
  border-top: 1px solid var(--filet);
  font-family: var(--sans);
  font-weight: 300;
  font-size: 0.85rem;
  line-height: 1.7;
  color: var(--texte-doux);   /* 5,49:1 sur crème */
}

/* --------------------------------------------------------------------------
   17. Animations au défilement
   -------------------------------------------------------------------------- */
/* MASQUAGE CONDITIONNÉ À « .js-anim ».
   Cette classe est posée sur <html> par un script en ligne dans <head>, et
   retirée automatiquement au bout de 2,5 s si js/main.js n'a pas confirmé
   son démarrage. Conséquence : sans JavaScript, avec un main.js en échec
   ou en 404, RIEN n'est masqué et le site reste entièrement lisible.
   Ne jamais déclarer « opacity: 0 » sur .apparait hors de ce préfixe.

   Pas de « will-change » : la règle vise des dizaines d'éléments par page
   et les promouvoir tous en couche GPU permanente coûte de la mémoire sans
   rien accélérer une fois l'apparition jouée.

   ATTENTION (piège vécu) : « .est-visible » remet transform à « none ». Un
   élément porteur de .apparait ne doit donc JAMAIS dépendre d'un transform
   pour sa mise en page — sinon animer un parent enveloppant à la place.
   Le décalage des colonnes de tarifs passe par margin-top pour cette
   raison précise. */
.js-anim .apparait {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--t-apparition) var(--courbe-douce),
              transform var(--t-apparition) var(--courbe-douce);
}

/* Opacité d'arrivée : « --opacite-repos » et non 1 en dur. Un élément dont le
   design prévoit une opacité < 1 (le filet .separateur est à 0,8) verrait
   sinon sa valeur écrasée dès sa révélation — cette règle pèse (0,3,0) contre
   (0,1,0) pour la sienne. Tout futur .apparait translucide n'a qu'à déclarer
   « --opacite-repos » à côté de son « opacity ». */
.js-anim .apparait.est-visible {
  opacity: var(--opacite-repos, 1);
  transform: none;
}

.js-anim .apparait[data-delai='1'] { transition-delay: 0.08s; }
.js-anim .apparait[data-delai='2'] { transition-delay: 0.16s; }
.js-anim .apparait[data-delai='3'] { transition-delay: 0.24s; }
/* Ajouté avec la cinquième salle (services.html) : sans ce cran, la salle
   Noire portait « data-delai=4 » sans règle en face et démarrait donc en même
   temps que Sakura — la cascade s'arrêtait à la quatrième. */
.js-anim .apparait[data-delai='4'] { transition-delay: 0.32s; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
  /* Préfixé « .js-anim » à dessein : une media query n'ajoute PAS de
     spécificité, et « .apparait » seul (0,1,0) perdrait contre la règle de
     masquage « .js-anim .apparait » (0,2,0). Le filet doit peser autant et
     venir après. En pratique main.js retire déjà .js-anim dans ce cas ; cette
     règle couvre le scénario où il n'a pas pu s'exécuter. */
  .js-anim .apparait,
  .js-anim .apparait.est-visible { opacity: var(--opacite-repos, 1); transform: none; }
}

/* --------------------------------------------------------------------------
   17 bis. Accès et stationnement — « prendre-rendez-vous.html » seulement

   DE L'INFORMATION PRATIQUE DANS UN SITE QUI VEND UNE AMBIANCE. Le pari :
   qu'on la trouve sans peine en la cherchant, et qu'on ne la voie pas sinon.

   Tout ici va contre les réflexes du reste de la feuille de style. Pas de
   « .titre-section » de 3 rem, pas de rembourrage de section pleine hauteur,
   pas de photo qui occupe l'écran. Un filet, trois lignes, deux vignettes.
   Si un jour cette section paraît trop présente, c'est par les vignettes
   qu'il faut commencer : les réduire, ou les replier derrière un
   « details ».
   -------------------------------------------------------------------------- */
.acces {
  /* Rembourrage nettement resserré : la section des options qui précède
     respire déjà, celle-ci n'est qu'un post-scriptum. */
  padding: clamp(2.2rem, 5vw, 3.4rem) 0 clamp(2.8rem, 6vw, 4.2rem);
  background: var(--creme);
}

.acces__bloc {
  max-width: 46rem;
  margin: 0 auto;
  text-align: center;
}

/* Le seul séparateur. Même vocabulaire que « .separateur », posé au-dessus
   du titre plutôt qu'en dessous : il ferme les options, il n'ouvre pas une
   nouvelle promesse. */
.acces__filet {
  width: 92px;
  height: 1px;
  margin: 0 auto clamp(1.5rem, 3.5vw, 2rem);
  border: 0;
  background: linear-gradient(90deg, transparent, var(--filet), transparent);
}

/* Petites capitales espacées, taille modeste : le registre des intertitres du
   pied de page, pas celui des titres de section. C'est délibérément le plus
   petit titre du site. */
.acces__titre {
  margin: 0;
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.78rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--or-texte);
}

.acces__phrase {
  max-width: 34rem;
  margin: 0.9rem auto 0;
  font-family: var(--serif);
  font-size: clamp(1.08rem, 2.4vw, 1.28rem);
  line-height: 1.6;
  color: var(--brun);
}

/* --- LE DÉPLIANT ---
   Replié, la section tient en trois lignes et ne pèse rien. Déplié, il
   montre les lieux à qui veut les voir. C'est le seul « details » du site,
   et il porte donc son propre habillage plutôt qu'une classe partagée. */
.acces__depliant { margin: clamp(1.3rem, 3vw, 1.8rem) 0 0; }

.acces__declencheur {
  display: inline-block;
  padding: 0.5rem 0.2rem;
  font-family: var(--sans);
  font-weight: 300;
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  color: var(--or-texte);
  cursor: pointer;
  list-style: none;                 /* retire le triangle, navigateurs récents */
  transition: color var(--t-douce);
}
/* Safari garde son propre marqueur, que « list-style » n'atteint pas. */
.acces__declencheur::-webkit-details-marker { display: none; }

.acces__declencheur:hover,
.acces__declencheur:focus-visible { color: var(--or-texte-vif); }

/* Le chevron remplace le triangle du navigateur : même geste, dessiné dans
   le vocabulaire du site. Il pivote à l'ouverture. */
.acces__declencheur::after {
  content: '';
  display: inline-block;
  width: 0.42em;
  height: 0.42em;
  margin: 0 0 0.18em 0.6em;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: rotate(45deg);
  transition: transform var(--t-douce);
}
.acces__depliant[open] .acces__declencheur::after { transform: rotate(-135deg); }

.acces__vues {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 2.5vw, 1.6rem);
  max-width: 44rem;
  margin: clamp(1.2rem, 3vw, 1.7rem) auto 0;
}

.acces__vue { margin: 0; }

/* --- LE TRAITEMENT QUI LES FAIT ENTRER DANS LA PALETTE ---

   Les deux photos ne partaient pas du même endroit : celle du stationnement
   est déjà baignée d'un coucher de soleil, celle de l'entrée a un ciel bleu
   franc et un revêtement gris-bleu. Un filtre identique posé sur les deux les
   aurait laissées dépareillées l'une par rapport à l'autre.

   Le réglage vise donc deux choses à la fois : réchauffer vers le crème et
   l'or du site, et RAPPROCHER les deux photos. « sepia » fait le gros du
   travail en tirant les bleus vers l'ocre ; « saturate » en dessous de 1
   empêche le vert du gazon et le rouge de l'enseigne voisine de crier ;
   « brightness » sous 1 les assied, pour qu'elles ne sautent pas au visage à
   côté du crème.

   Dosage retenu après essais : au-delà de sepia(0,2) la photo a l'air d'une
   vieille carte postale — on voit le filtre, ce qui est raté. En dessous de
   0,1 le ciel reste franchement bleu et jure avec tout le reste. */
.acces__photo {
  display: block;
  width: 100%;
  /* « height: auto » est INDISPENSABLE, pas cosmétique : les attributs
     width/height du HTML valent indication de présentation et fixent une
     hauteur réelle. Sans cela « aspect-ratio » n'a aucune dimension libre à
     résoudre, et la vignette s'affiche à ses 675 px natifs. */
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border: 1px solid var(--carte-bordure);
  border-radius: 6px;
  filter: sepia(0.16) saturate(0.88) brightness(0.97) contrast(1.02);
}

.acces__legende {
  margin: 0.62rem 0 0;
  font-family: var(--sans);
  font-weight: 300;
  font-size: 0.68rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--texte-doux);
}

.acces__adresse {
  margin: clamp(1.4rem, 3vw, 1.9rem) 0 0;
  font-family: var(--sans);
  font-weight: 300;
  font-size: 0.9rem;
  color: var(--texte-doux);
}

.acces__adresse a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--filet);
  transition: color var(--t-douce), border-color var(--t-douce);
}
/* On FONCE au survol : sur du crème, l'or clair tombe sous le seuil. */
.acces__adresse a:hover,
.acces__adresse a:focus-visible {
  color: var(--or-texte-vif);
  border-color: var(--or-texte-vif);
}

/* ---- ≤ 700 px : les vignettes s'empilent ---- */
@media (max-width: 700px) {
  .acces__vues {
    grid-template-columns: 1fr;
    max-width: 22rem;
  }
}

/* --------------------------------------------------------------------------
   18. Adaptatif
   -------------------------------------------------------------------------- */

/* ---- ≤ 1024px : passage au menu hamburger ---- */
@media (max-width: 1024px) {
  /* CIBLES TACTILES — mesuré au doigt, pas déduit des déclarations.

     Le numéro de téléphone est l'action nº 1 du salon, et sur dix des onze
     emplacements où il apparaît sa boîte tapable allait de 21 à 43 px : dans
     le pied de page elle ne faisait que 22 px de haut. Même chose pour les
     courriels, les liens légaux, le retour des fiches et le sommaire des
     pages légales.

     On n'ajoute QUE du rembourrage vertical : ni le corps, ni l'approche, ni
     la couleur ne bougent, donc aucun réglage typographique documenté n'est
     touché. 0,8rem et non 0,7 : mesuré, 0,7 laissait le retour des fiches
     à 43 px — un pixel sous le seuil. Ça ne se déduit pas, ça se mesure.

     « .option » est exclu : c'est aussi un lien « tel: », mais c'est la carte
     de 350×240 de prendre-rendez-vous, en flex — lui imposer inline-block
     casserait sa mise en page, et elle dépasse déjà largement 44 px. */
  a[href^='tel:']:not(.option),
  .pied a[href^='mailto:'],
  .pied__bas a,
  .fiche__retour a,
  .sommaire__liste a {
    display: inline-block;
    padding-block: 0.8rem;
  }

  /* Le sommaire est une pile de liens : le rembourrage fournit désormais le
     pas vertical, la marge ferait double emploi. */
  .sommaire__liste li { margin-bottom: 0; }
  .sommaire__liste a { padding-inline: 0.4rem; }

  /* BARRE AUTO-MASQUANTE (défilement vers le bas = escamotée).

     Le bandeau garde son fond crème opaque EN TOUT TEMPS, hero compris : la
     transparence sur le hero a été retirée au profit du bandeau plein.

     La place n'est plus gagnée par la transparence mais par l'escamotage —
     défilement descendant, la barre s'efface ; le moindre retour vers le
     haut la ramène. Le drapeau vient de js/main.js § 4.

     PIÈGE — « transform » ne vit QUE sur l'état masqué.

     Un transform non nul fait de l'élément porteur le bloc conteneur de ses
     descendants « position: fixed » : la même mécanique que « backdrop-filter »
     (voir le commentaire de .nav::before). Or .nav__liste est justement un
     « fixed; inset: 0 » posé DANS .nav. Lui laisser un transform hérité
     l'enfermerait dans les 68 px de la barre au lieu du viewport.

     D'où la construction : l'état normal n'écrit aucun transform (donc
     « none », donc pas de bloc conteneur), et l'état « menu ouvert » le
     remet à none SANS transition — instantanément, pour qu'aucune frame
     d'animation résiduelle ne puisse rogner le panneau à l'ouverture.

     Et pas de « will-change: transform » ici : cette propriété crée elle
     aussi un bloc conteneur, en permanence cette fois. Elle écrasait le
     panneau à 68 px de haut au lieu du viewport — le piège refermé par la
     porte d'à côté. Le gain de compositing ne vaut pas ça. */
  .nav { transition: transform var(--t-douce); }

  body[data-nav-cachee='true'] .nav { transform: translateY(-100%); }

  /* Le clavier ramène la barre : un focus qui entre dans une barre escamotée
     laisserait l'utilisateur naviguer à l'aveugle. « :focus-within » ajoute
     une pseudo-classe, donc (0,3,1) contre (0,2,1) — il l'emporte sans
     « !important ».

     Menu ouvert : la barre ne s'escamote jamais, elle porte le bouton qui
     sert à refermer. Spécificité identique à la règle de masquage, placée
     après, donc gagnante par ordre de source. */
  body[data-nav-cachee='true'] .nav:focus-within { transform: none; }
  body[data-nav-ouvert='true'] .nav { transform: none; transition: none; }

  .nav__interieur { justify-content: flex-start; min-height: var(--hauteur-nav); }

  /* z-index supérieur au panneau : le bouton doit rester cliquable
     par-dessus pour pouvoir refermer le menu. */
  .nav__burger { display: block; z-index: 95; }

  /* « pointer-events » n'est PAS un raffinement ici, c'est le verrou.
     « visibility » est une propriété discrète : en transition vers
     « hidden », elle reste « visible » pendant TOUTE la durée de
     l'animation et ne bascule qu'à la fin. Sans la ligne ci-dessous, ce
     panneau plein écran (« fixed », « inset: 0 ») continue donc d'attraper
     les touchers pendant les 300 ms qui suivent la fermeture du menu.

     Au doigt, cela ne ressemble pas à un bug : on referme le menu, on tape
     aussitôt un lien, et rien ne se passe — le site paraît simplement ne
     pas répondre. C'est le même mécanisme qui avait figé la page entière
     via « .agrandissement » (voir le commentaire de cette règle) ; ici il
     est seulement borné dans le temps. Le calque doit être transparent aux
     touchers dès l'instant où il n'est plus le menu ouvert. */
  .nav__liste {
    position: fixed;
    inset: 0;
    z-index: 90;
    flex-direction: column;
    justify-content: center;
    gap: 0;
    padding: 0;
    background-color: var(--creme);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateY(-8px);
    transition: opacity var(--t-douce), transform var(--t-douce),
                visibility var(--t-douce);
  }

  .nav__liste[data-ouvert='true'] {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: none;
  }

  .nav__liste li { width: 100%; text-align: center; }

  .nav__lien {
    display: block;
    padding: 1.15rem 1.5rem;
    font-size: 14px;
    letter-spacing: 0.22em;
  }

  .nav__lien::after { left: 50%; right: 50%; }
  .nav__lien:hover::after,
  .nav__lien[aria-current='page']::after {
    left: 30%;
    right: 30%;
    transform: scaleX(1);
  }

  body[data-nav-ouvert='true'] { overflow: hidden; }

  .grille--4 { grid-template-columns: repeat(2, 1fr); }
  .equipe    { grid-template-columns: repeat(3, 1fr); }

  /* Sommaire des pages légales : une seule colonne sous 1024 px, la mesure
     devenant trop courte pour couper les intitulés proprement. */
  .sommaire__liste { columns: 1; }

  /* Programme : la colonne « quand » se resserre avant l'empilement. */
  .jour-ligne { grid-template-columns: minmax(10rem, 0.8fr) 2fr; }

  /* Rituels : deux colonnes plutôt que trois, la mesure de 45ch devenant
     trop serrée en dessous de ~340 px de colonne. */
  .rituels-nus { grid-template-columns: repeat(2, 1fr); }
  .rituels-nus--paire { max-width: none; }

  /* --- Hero « lumière chaude » : la colonne de gauche n'a plus lieu d'être --
     Deux raisons cumulées, pas une :
     1. « CANDIDATURE » ne rentre plus. À 1024 px, 22 % font 225 px et le corps
        plancher en demande déjà 216 : la marge est nulle.
     2. Sous ce format le viewport passe souvent sous 1,502 de rapport, et
        « cover » bascule d'un débordement vertical à un débordement
        HORIZONTAL. Le cadrage en X n'est alors plus inerte, la fenêtre visible
        se resserre et la colonne de gauche se retrouve sur la chevelure.
     Le bloc descend donc en bas, pleine largeur, sur un fondu vertical.
     C'est le seul hero du site à basculer à 1024 et non à 768. */
  .hero--lumiere {
    justify-content: center;
    align-items: flex-end;
    padding-bottom: clamp(2.5rem, 7vh, 4rem);
  }

  /* En mobile « cover » ajuste sur la HAUTEUR : à 390 × 844 l'échelle vaut
     0,825, l'image rendue fait 1268 × 844 et on ne voit que 31 % de sa
     largeur. Le cadrage en X redevient le seul réglage utile ; 46 % garde les
     deux yeux dans le cadre. */
  .hero__fond--lumiere { background-position: 46% 50%; }

  /* Fondu BEAUCOUP plus léger que sur les autres heros mobiles, et ce n'est
     pas de la générosité : le bas de la fenêtre visible en mobile est occupé
     par la masse de cheveux, déjà presque noire. Profil brut relevé par
     bandes de 5 % de hauteur (moyenne / maximum) :

       y 50–55 %  0,149 / 0,450     ← encore le menton et la mâchoire
       y 75–80 %  0,031 / 0,161
       y 80–85 %  0,028 / 0,193     ← bande du titre
       y 90–95 %  0,029 / 0,161     ← bande du numéro
       y 95–100 % 0,028 / 0,140

     L'ivoire tiendrait 3:1 sur cette bande SANS aucun voile. Le fondu ne sert
     donc qu'à deux choses : donner au numéro en or clair sa marge et asseoir
     le bas de l'image. 0,44 au ras du cadre contre 0,74 sur « pampas ». */
  .hero--lumiere .hero__fond::after {
    background: linear-gradient(180deg,
      transparent 0%,
      transparent 58%,
      rgba(12, 6, 3, 0.08) 72%,
      rgba(12, 6, 3, 0.22) 84%,
      rgba(12, 6, 3, 0.36) 93%,
      rgba(12, 6, 3, 0.44) 100%);
  }

  .hero__bloc--lumiere {
    width: auto;
    margin: 0;
    padding: 0 clamp(1.25rem, 5vw, 3rem);
    text-align: center;
  }

  .hero--lumiere .titre-hero { font-size: clamp(2rem, 8.5vw, 3.2rem); }
  .hero--lumiere .separateur { margin: 1.2rem auto; }

  /* --- Hero « téléphone vintage » : même bascule, à 1024 également ----------

     Sous ce format le viewport passe sous 1,502 de rapport et « cover » bascule
     d'un débordement VERTICAL à un débordement HORIZONTAL. La boiserie de
     gauche sort du cadre : à 390 × 844 l'échelle vaut 0,825, l'image rendue
     fait 1268 × 844 et l'on ne voit plus que 30,8 % de sa largeur.

     Corollaire : pour tout viewport plus étroit que 1,502, la hauteur rendue
     égale exactement celle du viewport. Il n'y a AUCUN débord vertical en
     mobile — « background-position-y » y est inerte à son tour — et le
     téléphone à cadran est donc toujours calé au bas de l'écran, dans la bande
     même où doit aller le texte. C'est le conflit central de cette mise en
     page mobile. */
  .hero--telephone {
    justify-content: center;
    align-items: flex-end;
    padding-bottom: clamp(2.5rem, 7vh, 4rem);
  }

  /* X à 74 %. La fenêtre visible vaut alors x 51,3–82,0 % de la source, ce qui
     retient dans l'ordre : le visage (54–66 %) entier, le combiné noir
     (62–71 %) entier, le cordon, et les deux tiers gauches du téléphone à
     cadran (70–82 %) — cadran compris, qui est ce qui le rend reconnaissable.
     Descendre à 70 % rejetait le cadran hors champ ; monter à 78 % coupait le
     bord gauche du visage. */
  .hero__fond--telephone { background-position: 74% 50%; }

  /* ÉCLAIRCISSEMENT et non assombrissement : l'exact symétrique du voile
     sombre des heros clairs-sur-photo, en crème plutôt qu'en brun — même
     recette que « solaire » en mobile. Le texte reste FONCÉ, comme en desktop.

     La densité n'est pas dictée par le fond moyen — robe et guéridon sont
     clairs — mais par un objet unique : le CORDON SPIRALÉ, diagonale noire
     (L 0,008) qui traverse le cadre et passe exactement au milieu du bloc de
     texte. Pour lui faire tenir 3:1 avec le brun il faut 0,44 de crème ; à
     0,40 il n'en donne que 2,84. Tout le reste du dégradé en découle. */
  .hero--telephone .hero__fond::after {
    background: linear-gradient(180deg,
      rgba(253, 248, 236, 0) 32%,
      rgba(253, 248, 236, 0.34) 50%,
      rgba(253, 248, 236, 0.56) 60%,
      rgba(253, 248, 236, 0.72) 74%,
      rgba(253, 248, 236, 0.84) 88%,
      rgba(253, 248, 236, 0.90) 100%);
  }

  .hero__bloc--telephone {
    width: auto;
    margin: 0;
    padding: 0 clamp(1.25rem, 5vw, 3rem);
    text-align: center;
  }

  /* Le titre retrouve une échelle de hero : la réduction desktop servait à le
     faire tenir dans la colonne de gauche, colonne qui n'existe plus ici.
     Plafond : à 390 px de large, moins 2 × 19,5 de réserve, il reste 351 px, et
     « NOUS CONTACTER » coûte 9,359 × le corps — soit 37,5 px. On tient à 35,2. */
  .hero--telephone .titre-hero { font-size: clamp(2.2rem, 8.4vw, 3.2rem); }

  .hero--telephone .separateur { margin: 1.1rem auto; }

  .hero--telephone .hero__sous-titre {
    margin-left: auto;
    margin-right: auto;
  }
}

/* --- ≤ 1024 px ET viewport HAUT : on rend sa lumière à la photo -------------

   Le dégradé ci-dessus est exprimé en POURCENTAGES, donc indexé sur la hauteur
   du hero, alors que le bloc est ancré EN BAS et haut d'environ 230 px quelle
   que soit la hauteur d'écran. Sa position en FRACTION du cadre remonte donc
   quand le viewport raccourcit :

     390 × 844   →  titre à y 72–76 %   (une ligne)
     390 × 800   →  titre à y 69–75 %
     360 × 640   →  titre à y 58–71 %   (le titre passe à deux lignes)
     1024 × 768  →  titre à y 65–73 %

   Un seul dégradé doit donc être calibré sur le CAS LE PLUS COURT, et il
   sur-voile alors les écrans hauts — c'est-à-dire la quasi-totalité des
   téléphones actuels, sur lesquels le téléphone à cadran s'effaçait. On rend
   ici 0,12 de densité à partir de 780 px de haut : le cadran redevient
   franchement lisible et le titre garde 4,2:1 au pire (mesuré à 390 × 800, le
   cas le plus défavorable de cette tranche).

   Doit rester APRÈS le bloc ≤ 1024 px : à spécificité égale, c'est l'ordre
   d'écriture qui tranche, et une media query n'ajoute aucune spécificité. */
@media (max-width: 1024px) and (min-height: 780px) {
  .hero--telephone .hero__fond::after {
    background: linear-gradient(180deg,
      rgba(253, 248, 236, 0) 38%,
      rgba(253, 248, 236, 0.32) 56%,
      rgba(253, 248, 236, 0.60) 72%,
      rgba(253, 248, 236, 0.78) 86%,
      rgba(253, 248, 236, 0.84) 100%);
  }
}

/* ---- ≤ 768px ---- */
@media (max-width: 768px) {
  .grille--3 { grid-template-columns: 1fr; }

  /* --- Hero « solaire » en mobile -------------------------------------
     Ici « cover » ajuste sur la HAUTEUR : on ne voit qu'environ 31 % de la
     largeur de la photo, et cette bande est entièrement occupée par la
     silhouette. Le mur dégagé de droite n'est tout simplement pas à
     l'écran — la composition en colonne n'a plus d'objet.

     Le texte descend donc en bas, pleine largeur. Et comme le bas de cette
     bande est à 0,388 de luminance avec des minima à 0 (le drapé et son
     ombre), il faut un ÉCLAIRCISSEMENT localisé — l'exact symétrique du
     voile sombre des heros clairs-sur-photo, en crème plutôt qu'en brun.
     La photo semble se fondre dans le crème de la page. */
  .hero--solaire {
    align-items: flex-end;
    justify-content: center;
    padding-bottom: clamp(2.5rem, 7vh, 4rem);
  }

  .hero__fond--solaire {
    /* Centre la fenêtre visible sur le visage et le buste (x 28–59 % de la
       source) plutôt que sur le milieu géométrique. */
    background-position: 42% 50%;
  }

  .hero--solaire .hero__fond::after {
    background: linear-gradient(180deg,
      rgba(253, 248, 236, 0) 40%,
      rgba(253, 248, 236, 0.46) 58%,
      rgba(253, 248, 236, 0.78) 72%,
      rgba(253, 248, 236, 0.90) 86%,
      rgba(253, 248, 236, 0.94) 100%);
  }

  .hero__bloc {
    width: auto;
    margin: 0;
    padding: 0 clamp(1.25rem, 5vw, 3rem);
    text-align: center;
    transform: none;   /* le bloc est calé en bas ici, pas de décalage */
  }

  /* Le titre retrouve une échelle de hero : la réduction desktop servait à le
     faire tenir dans la colonne de droite, colonne qui n'existe plus ici. Le
     plafond reste dicté par « PROFESSIONNELLES » : à 414 px de large, moins
     les marges, il reste 374 px, soit 39 px de corps maximal. */
  .hero--solaire .titre-hero { font-size: clamp(2rem, 9vw, 2.4rem); }

  .hero--solaire .separateur { margin-left: auto; margin-right: auto; }

  /* Rituels empilés, respiration conservée entre les blocs. */
  .rituels-nus,
  .rituels-nus--paire {
    grid-template-columns: 1fr;
    gap: clamp(3.25rem, 11vw, 4.5rem);
  }

  /* Programme : la rangée s'empile — jour et date en haut, les deux plages
     en dessous — mais les filets restent, ce sont eux qui portent le rythme. */
  .jour-ligne {
    grid-template-columns: 1fr;
    gap: 0.9rem;
    align-items: start;
  }
  .jour-ligne__marqueur { display: inline-block; margin: 0 0 0 0.7rem; }

  /* --- Hero « pampas » en mobile ---------------------------------------
     « cover » ajuste ici sur la HAUTEUR : on ne voit qu'environ 37 % de la
     largeur. Le cadrage se centre donc sur le visage (x 40–64 % de la source)
     plutôt que sur le milieu géométrique, et le texte descend en bas, pleine
     largeur — la colonne de gauche n'existe plus à cette échelle. */
  /* En mobile le bloc RESTE en bas : le remonter le poserait sur le visage,
     puisque la fenêtre visible ne montre presque que lui. */
  .hero--pampas {
    justify-content: center;
    align-items: flex-end;
    padding-bottom: clamp(2.5rem, 7vh, 4rem);
  }

  .hero__fond--pampas { background-position: 53% 50%; }

  .hero--pampas .hero__fond::after {
    background: linear-gradient(180deg,
      transparent 0%,
      transparent 42%,
      rgba(12, 6, 3, 0.26) 58%,
      rgba(12, 6, 3, 0.58) 76%,
      rgba(12, 6, 3, 0.74) 100%);
  }

  /* --- Hero « portrait » en mobile --------------------------------------
     C'est le seul hero dont la source est VERTICALE : en mobile le format
     colle enfin au cadre, on voit toute la hauteur et 65 % de la largeur.
     Plus besoin de contourner la boucle d'oreille — le bloc descend en bas,
     pleine largeur, sur un fondu classique. */
  .hero--portrait {
    justify-content: center;
    padding-bottom: clamp(2.5rem, 7vh, 4rem);
  }

  .hero__fond--portrait { background-position: 44% 50%; }

  /* Rampe remontée depuis l'ajout du bouton : le bloc a grandi de 7 points et
     le titre est passé de y 68 % à y 61 %, là où l'ancien fondu ne donnait que
     0,28 d'opacité — le titre y tombait à 2,60:1. */
  .hero--portrait .hero__fond::after {
    background: linear-gradient(180deg,
      transparent 0%,
      transparent 38%,
      rgba(12, 6, 3, 0.30) 55%,
      rgba(12, 6, 3, 0.56) 70%,
      rgba(12, 6, 3, 0.68) 84%,
      rgba(12, 6, 3, 0.78) 100%);
  }

  .hero__bloc--droite {
    width: auto;
    margin: 0;
    padding: 0 clamp(1.25rem, 5vw, 3rem);
    text-align: center;
  }

  .hero--portrait .separateur { margin: 1rem auto; }
  .hero--portrait .hero__sous-titre { margin-left: auto; margin-right: auto; }

  .hero__bloc--gauche {
    width: auto;
    margin: 0;
    padding: 0 clamp(1.25rem, 5vw, 3rem);
    text-align: center;
    /* Le décalage vers le haut ne vaut que pour la colonne de gauche du
       desktop. Sans cette remise à zéro il remontait aussi le bloc mobile,
       hors de la zone où le fondu du bas est le plus dense. */
    transform: none;
  }

  .hero--pampas .separateur,
  .hero--pampas .hero__sous-titre { margin-left: auto; margin-right: auto; }

  .equipe { grid-template-columns: repeat(2, 1fr); }

  .pied__colonnes {
    grid-template-columns: 1fr;
    gap: clamp(2.5rem, 8vw, 3.5rem);
  }

  /* LES COLONNES SONT EMPILÉES ICI — la contrainte d'équilibre qui tenait les
     vignettes à la largeur de la carte n'a plus lieu d'être. On leur rend donc
     de l'ampleur : ~170 px chacune au lieu de 116, ce qui donne au pouce une
     cible confortable et rend les lieux réellement lisibles avant même
     l'agrandissement. La carte, elle, garde sa largeur. */
  .pied__acces { width: min(100%, 22rem); }

  .option { min-height: 240px; }

  /* Le viewport d'un téléphone est plus étroit que la photo : « cover »
     ajuste alors sur la HAUTEUR, ne déborde que sur la largeur, et le
     visage entier réapparaît, yeux compris. On force un débordement
     vertical par un zoom explicite pour retrouver le cadrage
     bouche / menton du grand écran. */
  .tarifs-photo__fond {
    background-size: auto 200%;
    background-position: 50% 66%;
  }

  /* Tarifs en 2 × 2, sans décalage : la rangée de quatre ne rentre pas. */
  .tarifs {
    grid-template-columns: repeat(2, 1fr);
    width: min(430px, 86%);
    gap: clamp(1.5rem, 5vw, 2.5rem) 0;
    top: 44%;
  }
  .tarif:nth-child(2),
  .tarif:nth-child(3),
  .tarif:nth-child(4) { margin-top: 0; }

  /* Vitrine : photo pleine largeur au-dessus, fondu vers le BAS, texte
     centré dessous — même effet, basculé à la verticale. */
  .vitrine {
    display: block;
    min-height: 0;
    padding: 0 0 clamp(3.5rem, 9vw, 5.5rem);
  }
  .vitrine__media {
    position: relative;
    width: 100%;
    height: min(52vh, 420px);
    -webkit-mask-image: linear-gradient(180deg,
      #000 0%, #000 44%, rgba(0, 0, 0, 0.30) 74%, transparent 100%);
    mask-image: linear-gradient(180deg,
      #000 0%, #000 44%, rgba(0, 0, 0, 0.30) 74%, transparent 100%);
  }

  /* La bouffée chaude doit basculer avec le fondu : horizontale en
     grand écran, verticale ici. Sans cette bascule elle réchaufferait
     le mauvais bord. */
  .vitrine__media::after {
    background: linear-gradient(180deg,
      rgba(214, 176, 132, 0) 30%,
      rgba(214, 176, 132, 0.24) 62%,
      rgba(214, 176, 132, 0.09) 82%,
      rgba(214, 176, 132, 0) 96%);
  }
  .vitrine__grille { grid-template-columns: 1fr; }
  .vitrine__corps {
    grid-column: 1;
    text-align: center;
    margin-top: clamp(-3.5rem, -7vw, -2rem);
  }
}

/* ---- ≤ 480px ---- */
@media (max-width: 480px) {
  .grille--2,
  .grille--4 { grid-template-columns: 1fr; }

  .surtitre { letter-spacing: 0.3em; }
  .titre-hero { letter-spacing: 0.03em; }
  .titre-section { letter-spacing: 0.1em; }

  /* Le corps N'EST PAS réduit ici : à 0,7rem le libellé du bouton tombait à
     11,2 px, sous le plancher de 12 px des petites capitales. C'est le padding
     et l'approche qui compriment le bouton sur les petits écrans, pas le
     texte. */
  .bouton {
    padding: 0.95rem 1.9rem;
    letter-spacing: 0.2em;
  }

  .hero__dispo { gap: 1rem; }

  .tarifs-photo__titre { letter-spacing: 0.06em; }

  .pied__bas { font-size: 0.82rem; }
}

/* --------------------------------------------------------------------------
   18 bis. Appel flottant — mobile uniquement

   L'action nº 1 du salon est un appel, et elle sort du champ dès le premier
   écran passé : sur l'accueil le numéro figure au hero (y 475) puis plus rien
   jusqu'au pied de page (y 3 630) — 3 155 px sans aucune prise. Sur les douze
   fiches il n'apparaît qu'une fois, dans le pied.

   VOCABULAIRE EMPRUNTÉ AU BURGER, pas au bouton flottant habituel : même
   carré, même filet or, aucune ombre portée, aucune pastille, aucune
   pulsation. Burger en haut à droite, appel en bas à droite — le pouce trouve
   les deux au même endroit, et l'objet ne se lit pas comme un widget collé
   sur la page.

   z-index 80 : sous le panneau de menu (90) et sous le burger (95). Menu
   ouvert, le bouton disparaît derrière le panneau plein.
   -------------------------------------------------------------------------- */
.appel-flottant { display: none; }

@media (max-width: 1024px) {
  .appel-flottant {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    right: clamp(1rem, 4vw, 1.5rem);
    /* env() : au-dessus de la barre de geste iOS, jamais collé au bord. */
    bottom: calc(clamp(1rem, 4vw, 1.5rem) + env(safe-area-inset-bottom, 0px));
    z-index: 80;
    width: 52px;
    height: 52px;
    border: 1px solid rgba(201, 160, 92, 0.55);
    border-radius: 6px;
    background-color: rgba(26, 17, 11, 0.88);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    color: var(--or);
    opacity: 0;
    visibility: hidden;
    /* Même verrou que « .nav__liste » : « visibility » ne bascule qu'à la fin
       de sa transition, si bien qu'en disparaissant le bouton resterait
       tactile 300 ms de plus. Il est petit, mais il occupe le coin où le
       pouce se repose — autant qu'il soit franchement absent. */
    pointer-events: none;
    transform: translateY(10px);
    transition: opacity var(--t-douce), transform var(--t-douce),
                visibility var(--t-douce);
  }

  /* Absent tant que le hero est à l'écran : le numéro y figure déjà en toutes
     lettres, le doubler d'un bouton serait redondant. */
  body[data-hors-hero='true'] .appel-flottant {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: none;
  }

  /* Sans JavaScript, « data-hors-hero » n'est jamais posé et le bouton
     resterait invisible pour toujours. Même filet que « .js-anim » : c'est le
     script en ligne du <head> qui pose « .js-appel », donc son absence rend le
     bouton visible d'emblée plutôt que de le supprimer. */
  html:not(.js-appel) .appel-flottant {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: none;
  }

  .appel-flottant:active { background-color: rgba(26, 17, 11, 0.96); }
  .appel-flottant:focus-visible { outline: 2px solid var(--or); outline-offset: 3px; }
}

/* --------------------------------------------------------------------------
   19. Impression
   -------------------------------------------------------------------------- */
@media print {
  .nav, .hero__fond, .pied__carte,
  .tarifs-photo__fond, .tarifs-photo__peinture, .tarifs-photo__grain { display: none; }
  .vitrine { padding: 2rem 0; min-height: 0; }
  .vitrine__media { display: none; }
  .tarifs-photo { min-height: 0; padding: 2rem 0; }
  .tarifs-photo__titre, .tarifs { position: static; transform: none; width: auto; }
  body { background: #fff; color: #000; }
  /* Même raison qu'en « reduced-motion » : sans le préfixe, ce filet est
     dominé par la règle de masquage et l'impression sortirait blanche pour
     tout ce qui n'avait pas encore été atteint au défilement. */
  .js-anim .apparait,
  .js-anim .apparait.est-visible { opacity: var(--opacite-repos, 1); transform: none; }
  .tarif__prix, .tarif__duree,
  .tarifs-photo__titre, .vitrine__titre { color: #000; }
}
