/* ===========================================================
   PAGES.CSS — Mises en page propres à chaque section
   Le socle commun vit dans main.css.
   =========================================================== */

/* ═══════════════════════════════════════════════════════════
   1 · LE SEUIL
   ═══════════════════════════════════════════════════════════ */
.seuil {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 100svh;
  padding-top: calc(var(--header-h) + var(--sp-xl));
  padding-bottom: 0;
  background: var(--panneau-fort);
  overflow: hidden;
  isolation: isolate;
}

/* La photo tient TOUT le cadre. Coupée à 62 % avec un masque, elle
   n'existait presque plus : la moitié gauche était un aplat clair et il
   ne restait qu'une bande d'image à droite. Ce qui protège le texte,
   c'est le voile ci-dessous, pas l'absence de photo. */
.seuil__fond {
  position: absolute;
  inset: 0;
  z-index: -2;
}
/* La vidéo se pose sur la photo, jamais à sa place : la photo reste
   l'image peinte en premier, celle qui porte le srcset et sur laquelle
   le contraste a été mesuré. La vidéo n'apparaît qu'une fois prête, en
   fondu, et si elle échoue on ne voit rien passer. */
.seuil__video {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 1.2s var(--ease-sortie);
  pointer-events: none;
}
.seuil__video.est-prete { opacity: 1; }

/* Le seuil garde sa propre hauteur d'image : la règle générique de
   .cadre-parallaxe la mettrait à 116 %, ce qui recadrerait la photo. */
.seuil__fond.cadre-parallaxe img { height: 112%; }
.seuil__fond img { width: 100%; height: 112%; object-fit: cover; outline: none;
                   /* Pas d'étalonnage CSS ici : l'image fixe est tirée de la
                      boucle vidéo avec le même étalonnage cuit dedans (voir
                      public/video/PROVENANCE.txt). Un filtre appliqué à l'une
                      et pas à l'autre ferait un saut au fondu d'apparition. */
                   filter: none; }

/* Le lavis relève la photo au lieu de la voiler. Sur la nuit, cette
   couche assombrissait ; ici elle éclaircit, et c'est ce qui permet au
   texte sombre de passer sur le bord gauche de l'image. */
.seuil__fond::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  /* Le lavis du seuil est deux fois plus léger que celui des photos : la
     boucle du 14 septembre 2026 (grandes chutes, ciel, écume) est déjà
     très claire (luminance moyenne 153 sur 255, contre 69 pour l'ancienne).
     Le lavis complet la rendait blanche ; c'est l'ellipse du voile texte
     qui protège la lecture, pas cette couche. */
  background: linear-gradient(178deg,
                rgba(240, 247, 244, .06) 0%,
                rgba(239, 247, 243, .10) 44%,
                rgba(237, 246, 242, .16) 100%);
}

/* Le voile qui porte le texte : une ellipse posée à gauche, là où vit le
   titre, qui s'éteint avant le bord droit. Un dégradé linéaire couvrait
   toute la hauteur et éteignait le ciel comme le sous-bois ; l'ellipse
   ne protège que ce qui a besoin de l'être et rend le reste à la photo. */
.seuil__voile-texte {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(ellipse 86% 126% at 20% 50%,
    rgba(241, 247, 248, .95) 0%, rgba(241, 247, 248, .88) 42%,
    rgba(241, 247, 248, .44) 72%, rgba(241, 247, 248, .10) 88%,
    transparent 100%);
}

/* En colonne unique le texte passe AU MILIEU de la photo, pas à côté :
   le voile ne peut plus s'ouvrir sur un côté, il se referme en ellipse
   autour du bloc de texte et laisse les bords clairs.

   L'ellipse est posée sur la SECTION, pas sur le conteneur. Sur le
   conteneur, sa boîte s'arrêtait avant le bas du bandeau et le dégradé
   n'avait pas atteint la transparence : le bord se voyait, net et
   horizontal. */
@media (max-width: 899px) {
  .seuil > .conteneur { position: relative; z-index: 1; }
  .seuil__voile-texte {
    background:
      radial-gradient(ellipse 120% 56% at 24% 42%,
        rgba(241, 247, 248, .95) 0%, rgba(241, 247, 248, .90) 44%,
        rgba(241, 247, 248, .54) 72%, rgba(241, 247, 248, .16) 89%, transparent 100%),
      linear-gradient(180deg, transparent 62%, rgba(241, 247, 248, .34) 84%,
        rgba(241, 247, 248, .52) 100%);
  }
}

/* ─── Le flux ───────────────────────────────────────────────────────
   Elle demandait « quelque chose d'un peu plus anime ». Une cascade
   bouge : c'est la lumiere sur l'eau qui le dit, pas l'image entiere.

   Deux voiles clairs traversent lentement la chute, en sens contraire
   et a des vitesses differentes. Ils ne touchent pas au `transform` de
   la photo, deja pris par le defilement et la souris : ils vivent dans
   leur propre couche. */
.seuil__flux {
  position: absolute;
  inset: -10% -20%;
  z-index: -1;
  pointer-events: none;
  opacity: .62;
}
.seuil__flux span {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 34% 62% at 62% 46%,
    rgba(255, 253, 246, .46), rgba(255, 253, 246, .16) 46%, transparent 72%);
  mix-blend-mode: soft-light;
  will-change: transform, opacity;
  animation: flux 19s ease-in-out infinite;
}
.seuil__flux span:nth-child(2) {
  background: radial-gradient(ellipse 26% 48% at 72% 62%,
    rgba(210, 236, 240, .40), rgba(210, 236, 240, .13) 44%, transparent 70%);
  animation-duration: 27s;
  animation-direction: reverse;
  animation-delay: -8s;
}
@keyframes flux {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); opacity: .55; }
  50%      { transform: translate3d(-2.5%, 3.5%, 0) scale(1.09); opacity: .95; }
}
@media (prefers-reduced-motion: reduce) {
  .seuil__flux span { animation: none; }
}

.seuil__halo {
  top: -12%; right: -14%;
  width: clamp(360px, 52vw, 820px);
  aspect-ratio: 1;
  z-index: -1;
  background: var(--halo-petrole);
}
.seuil__halo--mauve {
  top: auto; bottom: -22%; right: 22%;
  width: clamp(280px, 34vw, 540px);
  background: var(--halo-mauve);
  animation-delay: -4s;
}

.seuil__marque {
  width: clamp(56px, 6vw, 76px);
  margin-bottom: var(--sp-md);
  outline: none;
  opacity: .92;
}

.seuil__titre { margin: 0; }
.seuil__titre .titan { display: block; max-width: min(600px, 100%); }
.seuil__chapo { margin-top: var(--sp-md); max-width: 44ch; }
/* `margin-top: auto` pousse le bandeau de faits vers le bas tant qu'il
   reste de la place ; dès que le seuil dépasse la hauteur de l'écran il
   vaut zéro et le filet vient toucher les boutons. Le minimum se garantit
   donc ici, par le bas des actions, qui ne s'évapore jamais. */
.seuil__actions { margin-top: var(--sp-lg); margin-bottom: var(--sp-md); }
@media (min-width: 900px) { .seuil__actions { margin-bottom: var(--sp-lg); } }

/* ─── Le bandeau de faits ──────────────────────────────────────────────
   Trois choses que le visiteur cherche de toute façon — où, comment,
   depuis quand — plutôt qu'un espace vide sous les boutons. */
/* Le bandeau traverse toute la largeur, y compris la moitié droite où le
   voile du seuil s'est ouvert pour laisser passer le paysage. Il lui faut
   donc son propre fond, sinon ses libellés tombent à 2,56:1 dès que le
   sous-bois passe derrière eux. C'est aussi ce qui lui donne son assise :
   il se lit comme un socle sous le titre, pas comme une ligne flottante. */
.seuil__faits {
  position: relative;
  z-index: 2;
  margin-top: auto;
  border-top: 1px solid var(--filet);
  padding-block: var(--sp-md);
  background: var(--panneau-fort);
  -webkit-backdrop-filter: blur(14px) saturate(1.08);
          backdrop-filter: blur(14px) saturate(1.08);
}
.seuil__grille { display: grid; gap: var(--sp-sm) var(--sp-md); margin: 0; }
@media (min-width: 860px) {
  .seuil__grille { grid-template-columns: repeat(3, minmax(0, 1fr)) auto; align-items: center; }
}
.fait dt {
  margin-bottom: 5px;
  font-size: var(--fs-nano);
  font-weight: var(--fw-semi);
  letter-spacing: var(--ls-max);
  text-transform: uppercase;
  color: var(--mauve-500);
}
.fait dd { margin: 0; font-size: var(--fs-small); color: var(--texte-doux); }

/* Sa lune en filigrane, au bout du bandeau. */
.seuil__lune {
  width: 50px;
  opacity: .45;
  outline: none;
  justify-self: end;
  transition-property: opacity;
  transition-duration: var(--t-lent);
  transition-timing-function: var(--ease);
}
.seuil__faits:hover .seuil__lune { opacity: .8; }
@media (max-width: 859px) { .seuil__lune { display: none; } }


/* ═══════════════════════════════════════════════════════════
   2 · L'ÉCOUTE — sa phrase, seule
   ═══════════════════════════════════════════════════════════ */
.ecoute { overflow: hidden; }
.ecoute__halo {
  top: -30%; right: -10%;
  width: clamp(320px, 44vw, 680px);
  aspect-ratio: 1;
  z-index: 0;
}
.ecoute .grille { position: relative; z-index: 1; }
/* Le seuil et le pied en portaient, le milieu de la page etait immobile.
   Deux nappes tres clairsemees suffisent a le faire respirer. */
.ecoute__lucioles, .rendezvous__lucioles { z-index: 0; }

/* Sa phrase est le seul endroit du site où Grenze porte autre
   chose qu'un titre. Elle a droit à la taille et au silence. */
.ecoute__citation {
  margin: var(--sp-md) 0 0;
  font-family: var(--font-titre);
  font-size: clamp(28px, 3.9vw, 56px);
  font-weight: var(--fw-titre);
  line-height: 1.2;
  letter-spacing: var(--ls-serre);
  color: var(--encre);
  text-wrap: balance;
}
.ecoute__signature { margin-top: var(--sp-md); color: var(--mauve-500); opacity: .9; }
.ecoute__texte p + p { margin-top: var(--sp-sm); }

/* ═══════════════════════════════════════════════════════════
   3 · LES SOINS — liste éditoriale, pas grille de cartes
   ═══════════════════════════════════════════════════════════ */
.soins__entete { margin-bottom: var(--section-y-dense); }
.soins__entete h2 { margin-block: var(--sp-xs) var(--sp-sm); }

.soins__liste { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--filet); }

/* Une ligne par soin. Le chiffre romain, l'emblème, le nom, le
   tarif : c'est la lecture d'une carte de praticien, pas d'un
   catalogue. Cinq cartes égales dans une grille auraient dit
   « gabarit » avant même qu'on lise les noms. */
.soin {
  position: relative;
  display: grid;
  grid-template-columns: 28px 1fr;
  grid-template-areas:
    "num  entete"
    "num  corps";
  gap: var(--sp-2xs) var(--sp-sm);
  padding-block: var(--sp-md);
  border-bottom: 1px solid var(--filet);
  transition-property: background-color;
  transition-duration: var(--t-base);
  transition-timing-function: var(--ease);
}
@media (min-width: 900px) {
  .soin {
    grid-template-columns: 34px 54px minmax(0, 1fr) auto;
    grid-template-areas: "num embleme corps tarif";
    align-items: center;
    gap: var(--sp-md) var(--sp-lg);
    padding-block: var(--sp-lg);
  }
}
/* Le fond ne s'allume pas d'un bloc : il déborde dans la
   gouttière, ce qui donne à la ligne l'air d'être saisie. */
.soin::before {
  content: '';
  position: absolute;
  inset: 0 calc(var(--sp-sm) * -1);
  background: linear-gradient(90deg,
    rgba(129, 95, 124, 0) 0%,
    rgba(129, 95, 124, .13) 7%,
    rgba(129, 95, 124, .07) 34%,
    rgba(129, 95, 124, 0) 68%);
  opacity: 0;
  transition-property: opacity;
  transition-duration: var(--t-base);
  transition-timing-function: var(--ease);
  pointer-events: none;
}
.soin:hover::before,
.soin:focus-within::before { opacity: 1; }

/* Un filet qui se déplie sur le bord gauche. Il dit « cette ligne-là »
   mieux qu'un aplat, et il ne peut pas jurer avec le coin arrondi de
   l'encart puisqu'il n'a pas de coin. */
.soin::after {
  content: '';
  position: absolute;
  left: calc(var(--sp-sm) * -1);
  top: 14%;
  bottom: 14%;
  width: 2px;
  border-radius: 2px;
  background: var(--mauve-500);
  opacity: 0;
  transform: scaleY(.35);
  transition-property: opacity, transform;
  transition-duration: var(--t-base);
  transition-timing-function: var(--ease-sortie);
  pointer-events: none;
}
.soin:hover::after,
.soin:focus-within::after { opacity: .8; transform: scaleY(1); }

.soin__num {
  grid-area: num;
  text-align: right;
  font-family: var(--font-titre);
  font-size: clamp(19px, 2vw, 28px);
  font-weight: var(--fw-titre);
  letter-spacing: var(--ls-large);
  color: var(--or-500);
  opacity: .5;
  transition-property: opacity, color;
  transition-duration: var(--t-base);
  transition-timing-function: var(--ease);
}
.soin:hover .soin__num { opacity: 1; color: var(--or-700); }

.soin__embleme {
  grid-area: embleme;
  display: none;
  width: 52px; height: 52px;
  color: var(--mauve-500);
  transition-property: transform, color;
  transition-duration: var(--t-lent);
  transition-timing-function: var(--ease-sortie);
}
@media (min-width: 900px) { .soin__embleme { display: block; } }
.soin__embleme svg { width: 100%; height: 100%; }
.soin:hover .soin__embleme { transform: translateY(-3px); color: var(--or-700); }

.soin__corps { grid-area: corps; }
.soin__nom { margin-bottom: var(--sp-2xs); }
.soin__resume { max-width: 62ch; font-size: var(--fs-small); line-height: var(--lh-aere); color: var(--texte-doux); }
.soin__pourqui {
  margin-top: var(--sp-xs);
  font-size: var(--fs-micro);
  line-height: 1.65;
  color: var(--texte-faible);
}

.soin__tarif { grid-area: tarif; }
@media (max-width: 899px) {
  .soin__tarif { grid-area: entete; display: flex; gap: var(--sp-sm); align-items: baseline; }
}
@media (min-width: 900px) { .soin__tarif { text-align: right; min-width: 116px; } }
.soin__prix {
  display: block;
  font-family: var(--font-titre);
  font-size: var(--fs-h3);
  font-weight: var(--fw-titre);
  font-variant-numeric: tabular-nums;
  color: var(--encre);
  white-space: nowrap;
}
.soin__duree {
  display: block;
  margin-top: 2px;
  font-size: var(--fs-nano);
  font-weight: var(--fw-semi);
  letter-spacing: var(--ls-plus);
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--texte-faible);
}
.soin__lieu {
  display: block;
  margin-top: var(--sp-2xs);
  font-size: var(--fs-nano);
  letter-spacing: var(--ls-large);
  color: var(--mauve-500);
  opacity: .85;
}

.soins__pied {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-md);
  align-items: flex-start;
  justify-content: space-between;
  margin-top: var(--sp-lg);
}
.soins__note {
  max-width: 56ch;
  padding-left: var(--sp-sm);
  border-left: 1px solid var(--filet-or);
  font-size: var(--fs-small);
  line-height: var(--lh-aere);
  color: var(--texte-faible);
}

/* ═══════════════════════════════════════════════════════════
   4 · LE DÉROULÉ — quatre temps sur un fil
   ═══════════════════════════════════════════════════════════ */
.deroule__entete { margin-bottom: var(--section-y-dense); }
.deroule__entete h2 { margin-top: var(--sp-xs); }

.etapes {
  position: relative;
  display: grid;
  gap: var(--sp-lg) var(--sp-md);
  margin: 0; padding: 0;
  list-style: none;
}
@media (min-width: 860px) {
  .etapes { grid-template-columns: repeat(4, 1fr); gap: var(--sp-md); }
  /* Le fil qui relie les quatre temps : il dit que ce sont des
     étapes dans un ordre, pas quatre cases indépendantes. */
  /* Le fil traverse toute la largeur. Ce sont les repères qui
     l'interrompent, en masquant le trait derrière eux — sans quoi il
     passait sous les chiffres, ce qui se lit comme une rature. */
  .etapes::before {
    content: '';
    position: absolute;
    top: 5px;
    left: 4px;
    right: 0;
    height: 1px;
    background: linear-gradient(90deg,
      var(--filet-mauve), var(--filet-mauve) 92%, transparent);
    /* Le fil se trace au lieu d'apparaitre : c'est une section qui parle
       de remettre du mouvement, autant que la frise le fasse. Le trace
       precede les quatre etapes, qui arrivent ensuite en cascade. */
    transform-origin: left center;
    transition: transform 1.15s var(--ease-sortie) .1s;
  }
  .js .etapes:not(.est-tracee)::before { transform: scaleX(0); }
}
/* Le point et le chiffre partagent une seule ligne de référence, haute
   de la taille du point. Les caler séparément — l'un sur top:3px, l'autre
   sur top:0 — les désalignait quelle que soit la fonte. */
.etape { position: relative; padding-top: var(--sp-lg); }
.etape__repere {
  position: absolute;
  top: 0; left: 0;
  height: 10px;
  display: flex;
  align-items: center;
  gap: var(--sp-2xs);
  /* Le repère porte le fond de sa section : c'est lui qui perce le trait,
     plutôt que le trait qui passe derrière lui. */
  padding-right: var(--sp-xs);
  background: var(--panneau-mauve);
}
.etape__repere::before {
  content: '';
  flex: none;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--panneau-mauve);
  box-shadow: 0 0 0 1px var(--mauve-500);
}
.etape__num {
  font-family: var(--font-titre);
  font-size: var(--fs-micro);
  font-weight: var(--fw-semi);
  letter-spacing: var(--ls-plus);
  line-height: 1;
  color: var(--mauve-500);
}
.etape h3 { margin-bottom: var(--sp-2xs); }
.etape p { font-size: var(--fs-small); line-height: var(--lh-aere); color: var(--texte-doux); }

/* Une liste editoriale ne se survole pas comme une carte : rien ne se
   souleve, rien ne s'ombre. Le chiffre avance d'un cheveu et l'embleme
   s'eclaire, c'est tout ce qu'il faut pour dire « ceci repond ». */
.soin__num, .soin__embleme {
  transition-property: transform, opacity, color;
  transition-duration: var(--t-base);
  transition-timing-function: var(--ease-sortie);
}
.soin:hover .soin__num,
.soin:focus-within .soin__num { transform: translateX(4px); color: var(--or-700); }
.soin:hover .soin__embleme,
.soin:focus-within .soin__embleme { transform: translateX(4px) scale(1.06); opacity: 1; }

.deroule__note {
  max-width: 74ch;
  margin-top: var(--section-y-dense);
  padding-left: var(--sp-sm);
  border-left: 2px solid var(--filet-or);
  font-size: var(--fs-small);
  line-height: var(--lh-aere);
  color: var(--texte-faible);
}

/* ═══════════════════════════════════════════════════════════
   5 · LAURENCE
   ═══════════════════════════════════════════════════════════ */
/* Un portrait ne se recadre pas en paysage : sur mobile le cadre reste
   vertical, sinon la photo perd le haut du visage et le bas du bureau. */
.laurence__media .cadre { aspect-ratio: 4 / 5; }
/* En colonne unique, on lit d'abord qui elle est, on voit ensuite son
   visage : le portrait passe sous le texte. En deux colonnes, il
   retrouve sa place à gauche. */
.laurence__media { order: 2; }
@media (min-width: 900px) { .laurence__media { order: 0; } }
/* Le recadrage vise un peu au-dessus du centre : quel que soit le format
   du cadre, c'est le visage qu'il faut garder, pas le plateau de la table. */
/* Le portrait du 11 septembre 2026 tient tout entre le haut de la coiffure
   et le pendentif à la lune : dans un cadre 4/5 il ne reste que 150 px de
   source à rogner, et la parallaxe en mange encore 2 % de chaque côté. À
   55 % la fenêtre descend juste assez pour garder le pendentif, la tête
   conserve sa marge. Le réglage précédent (32 %) visait l'ancien portrait,
   où le visage était haut. */
.laurence__media .cadre img { height: 100%; object-position: 50% 55%; }
@media (min-width: 900px) {
  /* C'est le texte qui donne la hauteur du bloc, pas la photo. Tant que
     le cadre restait dans le flux, son format portrait (2:3) imposait sa
     mesure et l'image dépassait le texte de deux cents pixels. Sorti du
     flux, il ne compte plus dans le calcul de la ligne : la figure est
     étirée par la grille à la hauteur du texte, et le cadre la remplit. */
  .laurence .grille { align-items: stretch; }
  .laurence__media { position: relative; min-height: 440px; }
  .laurence__media .cadre {
    position: absolute;
    inset: 0 auto 0 0;
    /* La hauteur vient du texte ; la largeur en découle par le format 4/5,
       sans jamais dépasser la colonne. Un cadre plus large que 4/5 rognait
       le portrait en hauteur, et le pendentif sortait du bas. Quand le texte
       est très haut, le cadre devient plus étroit que 4/5 et ne rogne plus
       que les côtés : rien d'important ne s'y trouve. */
    width: auto;
    max-width: 100%;
    aspect-ratio: 4 / 5;
  }
}

.laurence__texte p + p { margin-top: var(--sp-sm); }
.laurence h2 { margin-block: var(--sp-xs) var(--sp-md); }

/* L'année dans la marge. Un repère de crédibilité qui se lit
   avant le paragraphe, sans l'alourdir. */
.laurence__depuis {
  display: flex;
  align-items: baseline;
  gap: var(--sp-xs);
  margin-top: var(--sp-lg);
  padding-top: var(--sp-sm);
  border-top: 1px solid var(--filet);
}
.laurence__annee {
  font-family: var(--font-titre);
  font-size: clamp(30px, 3.4vw, 46px);
  font-weight: var(--fw-titre);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--or-500);
}
.laurence__annee-label {
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-large);
  color: var(--texte-faible);
}
.laurence__action { margin-top: var(--sp-md); }

/* ═══════════════════════════════════════════════════════════
   6 · PRENDRE RENDEZ-VOUS
   ═══════════════════════════════════════════════════════════ */
.rendezvous { overflow: hidden; isolation: isolate; }
.rendezvous__halo {
  top: 50%; left: 50%;
  --halo-x: -50%; --halo-y: -50%;
  width: min(900px, 118vw);
  aspect-ratio: 1;
  z-index: -1;
}
.rendezvous h2 { margin-block: var(--sp-xs) var(--sp-sm); }
.rendezvous__actions { justify-content: center; margin-top: var(--sp-lg); }

.praticiel {
  display: grid;
  gap: var(--sp-md);
  max-width: 760px;
  margin: var(--section-y-dense) auto 0;
  text-align: left;
}
@media (min-width: 700px) { .praticiel { grid-template-columns: 1fr 1fr; } }
.praticiel__bloc { padding-top: var(--sp-sm); border-top: 1px solid var(--filet); }
.praticiel dt {
  margin-bottom: var(--sp-2xs);
  font-size: var(--fs-nano);
  font-weight: var(--fw-semi);
  letter-spacing: var(--ls-max);
  text-transform: uppercase;
  color: var(--mauve-500);
}
.praticiel dd { margin: 0; font-size: var(--fs-small); line-height: var(--lh-aere); color: var(--texte-doux); }

/* ═══════════════════════════════════════════════════════════
   PAGES INTÉRIEURES
   ═══════════════════════════════════════════════════════════ */
.hero-page {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: clamp(320px, 46vh, 480px);
  padding-top: calc(var(--header-h) + var(--sp-lg));
  padding-bottom: var(--sp-xl);
  /* Aucun fond : le paysage passe, le voile ci-dessous porte le texte. */
  background: none;
  overflow: hidden;
  isolation: isolate;
}
.hero-page__halo { top: -34%; right: -6%; width: clamp(260px, 36vw, 520px); aspect-ratio: 1; z-index: -1; }
/* 17ch se calculait sur la taille du <h1>, pas sur celle du texte rendu :
   278 px pour 505 disponibles avant la photo, et un titre casse en cinq
   lignes. Meme mesure que le titan de l'accueil ; le masque diagonal laisse
   la photo commencer bien au-dela. */
.hero-page__titre { max-width: min(620px, 100%); }

/* ═══════════════════════════════════════════════════════════
   CONTACT
   ═══════════════════════════════════════════════════════════ */
.contact__wa { padding-bottom: var(--sp-md); border-bottom: 1px solid var(--filet); }
.contact__wa .btn { margin-top: var(--sp-2xs); }
.formulaire { display: grid; gap: var(--sp-sm); margin-top: var(--sp-md); }
.formulaire__duo { display: grid; gap: var(--sp-sm); }
@media (min-width: 620px) { .formulaire__duo { grid-template-columns: 1fr 1fr; } }
/* À .7 la mention tombait à 3,8:1 sur le panneau ; .85 la garde en retrait à 5,6:1. */
.champ__option { font-weight: var(--fw-normal); letter-spacing: var(--ls-large); opacity: .85; }
.consentement { display: flex; gap: var(--sp-2xs); align-items: flex-start; }
.consentement input { margin-top: 4px; accent-color: var(--mauve-300); }
.consentement label { font-size: var(--fs-small); line-height: var(--lh-normal); color: var(--texte-doux); }
.contact__merci {
  margin-top: var(--sp-md);
  padding: var(--sp-sm) var(--sp-md);
  border-left: 2px solid var(--filet-or);
  background: var(--panneau);
  border-radius: var(--r-doux);
  font-size: var(--fs-chapo);
  color: var(--encre);
}
.contact__infos { display: grid; gap: var(--sp-md); align-content: start; }
.contact__bloc { padding-top: var(--sp-sm); border-top: 1px solid var(--filet-mauve); }
.contact__bloc p { font-size: var(--fs-small); line-height: var(--lh-aere); color: var(--texte-doux); }

/* ═══════════════════════════════════════════════════════════
   PAGES LÉGALES
   ═══════════════════════════════════════════════════════════ */
.legal__maj { font-size: var(--fs-micro); letter-spacing: var(--ls-large); text-transform: uppercase; color: var(--texte-faible); }
.legal__bloc { padding-block: var(--sp-md); border-top: 1px solid var(--filet); }
.legal__bloc:first-of-type { border-top: 0; }
.legal__bloc h2 { margin-bottom: var(--sp-xs); font-size: var(--fs-h3); }
.legal__bloc p, .legal__bloc li { font-size: var(--fs-small); line-height: var(--lh-aere); color: var(--texte-doux); }
.legal__bloc ul { margin: 0 0 var(--sp-sm); padding-left: 1.2em; }
.legal__bloc a { color: var(--mauve-500); text-decoration: underline; text-underline-offset: 3px; }
.legal__bloc mark {
  background: rgba(201, 169, 97, .22);
  padding: 1px 5px;
  border-radius: var(--r-fin);
  color: var(--or-700);
}

/* ═══════════════════════════════════════════════════════════
   404
   ═══════════════════════════════════════════════════════════ */
.erreur {
  display: flex; align-items: center;
  min-height: 76svh;
  padding-top: var(--header-h);
  background: var(--panneau-fort);
  text-align: center;
}
.erreur__actions { justify-content: center; margin-top: var(--sp-lg); }

/* ═══════════════════════════════════════════════════════════
   REPÈRES COMMUNS
   ═══════════════════════════════════════════════════════════ */
/* Le duo sert à la page contact, qui n'a pas besoin de la grille
   éditoriale à douze colonnes : deux blocs, une respiration. */
.duo { display: grid; gap: clamp(var(--sp-lg), 5vw, var(--sp-2xl)); align-items: start; }
@media (min-width: 900px) {
  .duo { grid-template-columns: 1fr 1fr; }
  .duo--texte-large { grid-template-columns: 1.2fr 1fr; }
}

/* Le halo du pied. Son centrage passe par translate et non par transform :
   l animation de respiration anime transform, et ecrasait donc le
   translateX(-50%). Le halo se retrouvait pousse en bas a droite, avec un
   bord net la ou le degrade circulaire quittait sa boite. */
.pied__halo {
  bottom: -58%;
  left: 50%;
  --halo-x: -50%;
  width: min(1180px, 145vw);
  aspect-ratio: 5 / 2;
  opacity: .5;
}
.pied .conteneur { position: relative; z-index: 1; }
.pied__marque { margin: 0 0 var(--sp-2xs); color: var(--encre); }
.pied__logo { display: block; width: min(290px, 100%); height: auto; margin: 0 0 var(--sp-xs); outline: none; }
@media (max-width: 699px) { .pied__logo { width: 240px; } }

/* Le pied de la section des soins : la note à gauche, les deux actions à
   droite. Un lien-flèche seul ne suffisait pas — c'est la section qui
   porte l'offre, elle doit pouvoir se conclure. */
.soins__actions { display: flex; flex-wrap: wrap; gap: var(--sp-xs); flex: none; }
@media (max-width: 760px) { .soins__actions { width: 100%; } }

/* Les lucioles du pied de page. Le pied est la nuit dans laquelle on
   redescend : c'est l'endroit du site où elles ont le plus de sens, et
   le seul où elles accompagnent une fin plutôt qu'un seuil. */
.pied__lucioles { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }

/* ═══════════════════════════════════════════════════════════
   EN-TÊTE DES PAGES INTÉRIEURES
   Le seuil de l'accueil en plus court. Même composition, même
   étalonnage : c'est ce qui fait que l'on reste sur le même site.
   ═══════════════════════════════════════════════════════════ */
.hero-page--photo { min-height: clamp(380px, 54vh, 540px); }
.hero-page__fond {
  position: absolute;
  inset: 0;
  z-index: -2;
}
.hero-page__fond img {
  width: 100%; height: 112%;
  object-fit: cover; outline: none;
  filter: var(--etalonnage-paysage);
}
.hero-page__fond::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  background: var(--lavis-paysage);
}
/* Le voile est plus fermé que sur le seuil : le bandeau est court, le
   titre y occupe une part bien plus grande de la surface. */
.hero-page__voile-texte {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(ellipse 84% 132% at 20% 50%,
    rgba(241, 247, 248, .96) 0%, rgba(241, 247, 248, .90) 44%,
    rgba(241, 247, 248, .48) 74%, rgba(241, 247, 248, .12) 89%,
    transparent 100%);
}
.hero-page__flux {
  position: absolute;
  inset: -10% -20%;
  z-index: -1;
  pointer-events: none;
  opacity: .52;
}
.hero-page__flux span {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 34% 62% at 66% 46%,
    rgba(255, 253, 246, .42), rgba(255, 253, 246, .14) 46%, transparent 72%);
  mix-blend-mode: soft-light;
  will-change: transform, opacity;
  animation: flux 21s ease-in-out infinite;
}
.hero-page__flux span:nth-child(2) {
  background: radial-gradient(ellipse 26% 48% at 74% 60%,
    rgba(210, 236, 240, .36), rgba(210, 236, 240, .12) 44%, transparent 70%);
  animation-duration: 29s;
  animation-direction: reverse;
  animation-delay: -9s;
}
.hero-page__lucioles { z-index: 0; }
@media (prefers-reduced-motion: reduce) {
  .hero-page__flux span { animation: none; }
}
/* Même principe et même précaution que sur le seuil : le voile couvre la
   section entière, sinon son bord se voit, net et horizontal. */
@media (max-width: 899px) {
  .hero-page > .conteneur { position: relative; z-index: 1; }
  .hero-page__voile-texte {
    background: radial-gradient(ellipse 124% 56% at 24% 52%,
      rgba(241, 247, 248, .96) 0%, rgba(241, 247, 248, .90) 40%,
      rgba(241, 247, 248, .52) 70%, rgba(241, 247, 248, .16) 88%, transparent 100%);
  }
}

/* ═══════════════════════════════════════════════════════════
   MES PRESTATIONS · les fiches
   ═══════════════════════════════════════════════════════════ */
/* `clip` et non `hidden` : `hidden` cree un conteneur de defilement, ce qui
   suffit a decaler la carte collante de sa colonne. `clip` contient le halo
   sans ce defaut. */
.fiche { position: relative; overflow: clip; isolation: isolate; }
.fiche__halo {
  top: -18%; right: -12%;
  width: clamp(300px, 40vw, 620px);
  aspect-ratio: 1;
  z-index: -1;
  opacity: .55;
}

/* Les faits ne sont pas une carte : pas de bordure fermée, pas de fond,
   pas de bouton pleine largeur. Un registre : des lignes séparées par des
   filets, comme une plaque gravée. */
.fiche__faits {
  padding-top: var(--sp-md);
  border-top: 1px solid var(--filet-appuye);
}
@media (min-width: 900px) {
  /* Elle suit le lecteur le long d'un texte qui peut faire trois écrans :
     le tarif reste sous les yeux au moment où l'on se décide. */
  .fiche__faits { position: sticky; top: calc(var(--header-h-sm) + var(--sp-lg)); }
}

.fiche__entete { display: flex; align-items: center; gap: var(--sp-sm); margin: 0 0 var(--sp-md); }
.fiche__num {
  font-family: var(--font-titre);
  font-size: clamp(26px, 3vw, 38px);
  font-weight: var(--fw-titre);
  line-height: 1;
  letter-spacing: var(--ls-plus);
  color: var(--or-500);
  opacity: .75;
}
.fiche__embleme {
  width: 34px; height: 34px;
  color: var(--mauve-500);
  opacity: .7;
}

/* Chaque ligne du registre : intitulé à gauche, valeur à droite, un filet
   dessous. C'est la lecture d'un tarif affiché, pas d'une fiche produit. */
.fiche__registre { display: grid; margin: 0; }
.fiche__registre > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-sm);
  padding-block: var(--sp-xs);
  border-bottom: 1px solid var(--filet);
}
.fiche__registre dt {
  font-size: var(--fs-nano);
  font-weight: var(--fw-semi);
  letter-spacing: var(--ls-max);
  text-transform: uppercase;
  color: var(--texte-faible);
}
.fiche__registre dd {
  margin: 0;
  font-size: var(--fs-small);
  line-height: var(--lh-normal);
  text-align: right;
  color: var(--texte-doux);
}
.fiche__prix {
  font-family: var(--font-titre);
  font-size: 26px;
  font-weight: var(--fw-titre);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  color: var(--or-700);
}

.fiche__action { margin: var(--sp-lg) 0 0; }

/* En colonne unique, les faits passent SOUS le texte : voir un tarif avant
   de savoir de quel soin il s'agit ne renseigne personne. */
.fiche__aside { order: 2; }
@media (min-width: 900px) { .fiche__aside { order: 0; } }

.fiche__texte h2 { margin-bottom: var(--sp-md); }
.fiche__texte p + p { margin-top: var(--sp-sm); }

.fiche__pour {
  margin-top: var(--sp-lg);
  padding-top: var(--sp-sm);
  border-top: 1px solid var(--filet);
}
.fiche__liste { list-style: none; margin: var(--sp-xs) 0 0; padding: 0; display: grid; gap: var(--sp-2xs); }
.fiche__liste li {
  position: relative;
  padding-left: var(--sp-sm);
  font-size: var(--fs-small);
  line-height: var(--lh-aere);
  color: var(--texte-doux);
}
/* Un losange plutôt qu'une puce ronde : le rond est le point de la frise,
   il dit « étape ». Ici on énumère, on ne progresse pas. */
.fiche__liste li::before {
  content: '';
  position: absolute;
  top: .62em; left: 0;
  width: 6px; height: 6px;
  rotate: 45deg;
  background: var(--filet-mauve);
}
.fiche__note {
  margin-top: var(--sp-md);
  padding-left: var(--sp-sm);
  border-left: 2px solid var(--filet-or);
  font-size: var(--fs-small);
  line-height: var(--lh-aere);
  color: var(--texte-faible);
}

/* ═══════════════════════════════════════════════════════════
   MES PRESTATIONS · à distance
   ═══════════════════════════════════════════════════════════ */
.distance { position: relative; overflow: hidden; isolation: isolate; }
.distance__halo {
  bottom: -40%; left: -8%;
  width: clamp(320px, 44vw, 660px);
  aspect-ratio: 1;
  z-index: -1;
  background: var(--halo-petrole);
}
.distance__lucioles { z-index: 0; }
.distance .distance__entete,
.distance .distance__duo,
.distance .distance__notes { position: relative; z-index: 1; }
.distance h2 { margin-top: var(--sp-xs); }

/* `conteneur--texte` ne porte que la largeur : le centrage vient de
   `.conteneur`, et cet en-tete est un enfant, pas le conteneur lui-meme.
   Sans cette ligne il restait cale a gauche, decale de 162 px. */
.distance__entete { max-width: var(--conteneur-texte); margin-inline: auto; }
.distance__entete .chapo { margin-top: var(--sp-md); }

/* Les deux precisions partagent la grille et la meme mesure. Chacune avec
   sa largeur et son centrage, elles ne s'alignaient ni entre elles ni sur
   le reste de la page. */
.distance__notes { display: grid; gap: var(--sp-md); margin-top: var(--sp-xl); }
@media (min-width: 900px) { .distance__notes { grid-template-columns: 1fr 1fr; gap: var(--sp-xl); } }
.note-filet {
  margin: 0;
  padding-left: var(--sp-sm);
  border-left: 2px solid var(--filet-or);
  font-size: var(--fs-small);
  line-height: var(--lh-aere);
  color: var(--texte-faible);
}

/* Deux colonnes qui se répondent. Le filet doré marque celle qui ouvre une
   possibilité, le mauve celle qui pose une condition. Pas d'encadré : ce
   sont deux réponses à une question, pas deux offres à comparer. */
.distance__duo {
  display: grid;
  gap: var(--sp-lg);
  margin-top: var(--section-y-dense);
}
@media (min-width: 780px) { .distance__duo { grid-template-columns: 1fr 1fr; gap: var(--sp-xl); } }

.modalite { position: relative; padding-left: var(--sp-md); }
.modalite::before {
  content: '';
  position: absolute;
  top: .3em; bottom: .2em; left: 0;
  width: 1px;
  background: linear-gradient(180deg, var(--filet-mauve), transparent);
}
.modalite--distance::before { background: linear-gradient(180deg, var(--filet-or), transparent); }
.modalite__tag {
  margin: 0 0 var(--sp-sm);
  font-size: var(--fs-nano);
  font-weight: var(--fw-semi);
  letter-spacing: var(--ls-max);
  text-transform: uppercase;
  color: var(--mauve-500);
}
.modalite--distance .modalite__tag { color: var(--or-700); }   /* petit texte en or : le 700, comme les jalons */
.modalite__soins { list-style: none; margin: 0 0 var(--sp-md); padding: 0; display: grid; gap: var(--sp-2xs); }
.modalite__soins li {
  font-family: var(--font-titre);
  font-size: clamp(19px, 2vw, 24px);
  font-weight: var(--fw-titre);
  line-height: var(--lh-serre);
  color: var(--encre);
}
.modalite__detail { margin: 0; font-size: var(--fs-small); line-height: var(--lh-aere); color: var(--texte-doux); }



/* ═══════════════════════════════════════════════════════════
   À PROPOS · le portrait
   ═══════════════════════════════════════════════════════════ */
.portrait__media .cadre { aspect-ratio: 4 / 5; }
.portrait__media .cadre img { height: 100%; object-position: 50% 55%; }   /* même réglage que l'accueil */
/* En colonne unique, on lit d'abord qui elle est, on voit ensuite son
   visage : le portrait passe sous le texte, comme sur l'accueil. En deux
   colonnes, il retrouve sa place a gauche. */
.portrait__media { order: 2; }
@media (min-width: 900px) {
  .portrait__media { order: 0; }
  /* Le cadre s'étirait sur toute la hauteur du texte : sept paragraphes
     lui donnaient 911 px, et un portrait de 460 par 911 n'est plus un
     portrait, c'est une bande. Il reprend son format et sa mesure.

     Et il suit la lecture : `sticky` plutôt qu'un cadre qui disparaît au
     premier paragraphe. Le visage reste là pendant qu'on lit ce qu'elle
     dit — c'est le seul endroit du site où le texte parle à la première
     personne sur cette longueur.

     Deux conditions, sans lesquelles `sticky` ne fait rien : la grille
     doit cesser d'étirer ses éléments, sinon le cadre occupe déjà toute
     la hauteur et n'a nulle part où glisser ; et aucun ancêtre ne doit
     être en `overflow: hidden`, qui créerait un conteneur de défilement.
     `.portrait` est en `clip` précisément pour cela. */
  .portrait .grille { align-items: start; }
  .portrait__media {
    position: sticky;
    top: calc(var(--header-h-sm) + var(--sp-lg));
    max-width: 360px;
  }
}
.portrait__texte p { margin-top: var(--sp-sm); }
.portrait__texte .sur-titre { margin-bottom: var(--sp-md); }

/* ═══════════════════════════════════════════════════════════
   À PROPOS · le parcours
   ═══════════════════════════════════════════════════════════ */
.parcours__entete { margin-bottom: var(--section-y-dense); }
.parcours__entete h2 { margin-top: var(--sp-xs); }
.parcours__liste {
  position: relative;
  list-style: none;
  margin: 0; padding: 0;
  display: grid;
  gap: var(--sp-xl);
}
@media (min-width: 860px) {
  .parcours__liste { grid-template-columns: repeat(3, 1fr); gap: var(--sp-lg); }
}
.jalon { position: relative; padding-top: var(--sp-md); border-top: 1px solid var(--filet); }
.jalon__periode {
  margin: 0 0 var(--sp-xs);
  font-size: var(--fs-nano);
  font-weight: var(--fw-semi);
  letter-spacing: var(--ls-max);
  text-transform: uppercase;
  /* Seul emploi de l'or en petit texte. Depuis que les sections à
     lueur sont teintées, le 500 tombait à 4,7:1 sous la lueur mauve
     du parcours en mobile : un cran plus bas, il garde de la marge. */
  color: var(--or-700);
}
.jalon__titre {
  margin: 0 0 var(--sp-2xs);
  font-family: var(--font-titre);
  font-size: clamp(20px, 2.2vw, 26px);
  font-weight: var(--fw-titre);
  line-height: var(--lh-serre);
  color: var(--encre);
}
.jalon__texte { margin: 0; font-size: var(--fs-small); line-height: var(--lh-aere); color: var(--texte-doux); }

/* ═══════════════════════════════════════════════════════════
   À PROPOS · l'approche
   ═══════════════════════════════════════════════════════════ */
/* Section à photo depuis le 11 septembre 2026 (voir a-propos.ejs) : le halo
   qui montait derrière la lueur n'a plus d'objet sur une photo. */
.approche { position: relative; overflow: hidden; isolation: isolate; }
.approche__lucioles { z-index: 0; }
.approche .grille, .approche__liste { position: relative; z-index: 1; }
.approche h2 { margin-top: var(--sp-xs); }
.approche__liste {
  list-style: none;
  margin: var(--section-y-dense) 0 0; padding: 0;
  display: grid;
  gap: var(--sp-lg) var(--sp-xl);
}
@media (min-width: 780px) { .approche__liste { grid-template-columns: 1fr 1fr; } }
.approche__point { position: relative; padding-left: var(--sp-md); }
/* Un filet vertical plutôt qu'une carte : quatre cartes égales dans une
   grille, c'est le gabarit que tout le site évite. */
.approche__point::before {
  content: '';
  position: absolute;
  top: .35em; bottom: .2em; left: 0;
  width: 1px;
  background: linear-gradient(180deg, var(--filet-mauve), transparent);
}
.approche__point h3 {
  margin: 0 0 var(--sp-2xs);
  font-family: var(--font-titre);
  font-size: clamp(19px, 2vw, 24px);
  font-weight: var(--fw-titre);
  line-height: var(--lh-serre);
  color: var(--encre);
}
.approche__point p { margin: 0; font-size: var(--fs-small); line-height: var(--lh-aere); color: var(--texte-doux); }

/* ═══════════════════════════════════════════════════════════
   HALOS ET LUCIOLES DES PAGES INTÉRIEURES
   Sans `overflow`, un halo déborde de sa section et provoque un
   défilement horizontal ; sans `isolation`, il passe sous le fond
   de la section suivante. `clip` plutôt que `hidden` : `hidden`
   crée un conteneur de défilement, ce qui casserait la colonne
   collante des fiches.
   ═══════════════════════════════════════════════════════════ */
.intro-soins,
.portrait,
.parcours,
.contact { position: relative; overflow: clip; isolation: isolate; }

.intro-soins__halo {
  top: -34%; right: -10%;
  width: clamp(280px, 38vw, 560px);
  aspect-ratio: 1;
  z-index: -1;
  opacity: .5;
}
.portrait__halo {
  bottom: -32%; left: -12%;
  width: clamp(300px, 40vw, 600px);
  aspect-ratio: 1;
  z-index: -1;
  opacity: .5;
}
.contact__halo {
  top: -20%; right: -12%;
  width: clamp(300px, 42vw, 620px);
  aspect-ratio: 1;
  z-index: -1;
  background: var(--halo-petrole);
  opacity: .55;
}

/* Les nuées passent derrière le texte mais devant le fond. */
.intro-soins__lucioles,
.fiche__lucioles,
.portrait__lucioles,
.parcours__lucioles,
.contact__lucioles { z-index: 0; }

.intro-soins .conteneur,
.fiche .conteneur,
.portrait .conteneur,
.parcours .conteneur,
.contact .conteneur { position: relative; z-index: 1; }

/* ═══════════════════════════════════════════════════════════
   CONTACT · ce qui se passe ensuite
   Reprend les jalons du parcours d'À propos : trois temps dans
   un ordre, pas trois cases indépendantes.
   ═══════════════════════════════════════════════════════════ */
.ensuite { position: relative; overflow: clip; isolation: isolate; }
.ensuite__lucioles { z-index: 0; }
.ensuite .conteneur { position: relative; z-index: 1; }
.ensuite__entete { margin-bottom: var(--section-y-dense); }
.ensuite__entete h2 { margin-top: var(--sp-xs); }
.ensuite__liste {
  list-style: none;
  margin: 0; padding: 0;
  display: grid;
  gap: var(--sp-xl);
}
@media (min-width: 860px) {
  .ensuite__liste { grid-template-columns: repeat(3, 1fr); gap: var(--sp-lg); }
}
.ensuite__note { max-width: 62ch; margin-top: var(--sp-xl); }
