/* ============================================================
   DERM EVASION — feuille de style unique

   La charte était fournie : quatre couleurs, trois caractères, un
   logotype et son monogramme. Elle est reprise telle quelle, et la
   page est construite autour de ses deux formes — l'arche du
   monogramme et la goutte du logotype.

   Le parti pris : pas de cartes à ombre portée, pas de grille
   symétrique, pas de coins arrondis partout. Des filets fins, des
   arches, de grands blancs, et des titres en romaine très ouverte.
   ============================================================ */

/* ---------- Polices servies avec le site ----------
   Cormorant Garamond (titres, variable 300-600) et Questrial (texte),
   toutes deux sous licence SIL Open Font License 1.1 et citées par la
   charte. Maginia, le caractère du logotype, est commercial : il n'est
   pas ici, et le logotype reste une image.
   Voir outils/polices.sh pour les rafraîchir. */

@font-face {
  font-family: 'Titres'; font-style: normal; font-weight: 300 600; font-display: swap;
  src: url('../fonts/titres-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Titres'; font-style: normal; font-weight: 300 600; font-display: swap;
  src: url('../fonts/titres-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Titres'; font-style: italic; font-weight: 400; font-display: swap;
  src: url('../fonts/titres-italique-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Texte'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('../fonts/texte-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Texte'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('../fonts/texte-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* Les quatre couleurs de la charte, sans en ajouter une seule. */
  --creme:  #f8f2e8;
  --sable:  #efe0ca;
  --sauge:  #b2b89c;
  --foret:  #365445;

  /* Trois dérivées, et seulement pour des raisons de contraste. La
     teinte et la saturation de la charte sont conservées, seule la
     clarté bouge, de quoi passer le niveau AA et rien de plus :
     - l'encre foncée sert au texte courant posé sur l'aplat sauge,
       où le vert forêt ne tient qu'à 4,1 : 1 ;
     - le gris-vert est le texte secondaire sur crème (5,1 : 1) et sur
       sable (4,5 : 1 — #5a6b5f n'y tenait qu'à 4,37) ;
     - la sauge écrite est la sauge de la charte éclaircie de 4 %,
       parce que la sauge telle quelle ne fait que 4,1 : 1 sur le
       forêt. La sauge de la charte reste celle des filets et des
       aplats, où aucun seuil ne s'applique. */
  --encre:       #2c4237;
  --gris:        #58695d;
  --sauge-texte: #bbc1a8;

  /* Posées sur un fond sombre — aplat forêt, pied, fenêtre de rendez-vous
     — ce sont les deux encres claires. Elles valent le crème et le sable
     de la charte : ces deux-là nomment une couleur, celles-ci nomment un
     emploi. La distinction compte dès qu'une variante inverse la page :
     le crème y devient un fond, mais l'encre claire doit rester claire. */
  --sur-sombre:      var(--creme);
  --sur-sombre-doux: var(--sable);

  --filet:       #e2d6c2;
  --filet-foret: rgba(248, 242, 232, .26);
  --filet-sauge: rgba(44, 66, 55, .28);

  /* Hauteur de l'en-tête, mesurée et non devinée : l'accueil s'en sert
     pour occuper exactement le reste de l'écran. Elle change avec la
     mise en page de l'en-tête — deux rangées au-dessus de 1000 px, une
     seule en dessous — donc elle est redéfinie dans chaque cas. */
  --entete: 86px;

  --titres: 'Titres', 'Cormorant Garamond', Garamond, 'Times New Roman', serif;
  --texte:  'Texte', 'Questrial', 'Helvetica Neue', Arial, sans-serif;

  --serre:  1220px;
  --etroit: 760px;
  --marge:  clamp(20px, 5vw, 56px);
  --section: clamp(96px, 13vw, 224px);

  /* L'arche : la forme du monogramme, ouverte en bas. Elle sert de
     cadre aux photographies et de silhouette aux blocs figurés. Elle
     remplace l'arrondi uniforme, qui est la silhouette par défaut de
     tout le web. */
  --arche: 999px 999px 8px 8px;
}

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

html { scroll-behavior: smooth; scroll-padding-top: 86px; }

body {
  margin: 0;
  background: var(--creme);
  color: var(--foret);
  font-family: var(--texte);
  font-size: 17.5px;
  line-height: 1.78;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}

/* ---------- Titres ----------
   Cormorant Garamond est une romaine de titrage : elle vit en grand
   corps, en graisse légère, et supporte mal d'être tassée. Les titres
   sont donc grands, en 300-400, et l'italique sert d'accent — jamais
   la graisse. */

h1, h2, h3, h4 {
  font-family: var(--titres);
  font-weight: 400;
  line-height: 1.08;
  margin: 0;
  letter-spacing: -.005em;
}

h1 {
  font-size: clamp(2.8rem, 7.4vw, 5.6rem);
  font-weight: 300;
  line-height: .98;
  letter-spacing: -.018em;
}

h2 {
  font-size: clamp(2.25rem, 5vw, 4.1rem);
  font-weight: 300;
  line-height: 1.02;
  letter-spacing: -.014em;
  margin-bottom: .6em;
}

h3 { font-size: clamp(1.35rem, 2.2vw, 1.7rem); }
h4 { font-size: 1.16rem; }

h1 em, h2 em, h3 em {
  font-style: italic;
  font-weight: 400;
}

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

a { color: inherit; }

strong { font-weight: 400; color: var(--foret); border-bottom: 1px solid var(--sauge); }

/* Le surtitre : capitales très espacées, en Questrial. C'est le seul
   endroit où la grotesque prend la parole, et elle sert de contrepoint
   aux romaines. */
.surtitre {
  font-family: var(--texte);
  font-size: .64rem;
  letter-spacing: .34em;
  text-transform: uppercase;
  margin: 0 0 2em;
  color: var(--gris);
}
.foret .surtitre { color: var(--sur-sombre-doux); }
.sauge .surtitre { color: var(--encre); }
/* Les deux classes ci-dessous restent tolérées dans le HTML : elles ne
   servent plus à rien, le fond décidant seul. */
.surtitre-clair, .surtitre-sauge { color: inherit; }
.foret .surtitre-clair { color: var(--sur-sombre-doux); }

/* Les chapeaux de section passent en romaine : c'est le changement qui
   déplace le plus le registre, bien avant les espacements. La grotesque
   reste pour le texte de service, les listes et les étiquettes. */
.intro {
  max-width: 44ch;
  font-family: var(--titres);
  font-size: clamp(1.18rem, 1.55vw, 1.42rem);
  font-weight: 300;
  line-height: 1.55;
  color: var(--gris);
  margin-bottom: clamp(44px, 4.6vw, 76px);
}
.intro-sauge { color: var(--encre); }

/* ---------- Trame ---------- */

.bloc {
  width: min(100% - var(--marge) * 2, var(--serre));
  margin-inline: auto;
}
.bloc-etroit { max-width: var(--etroit); }

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

.clair { background: var(--creme); }
.clair .liste-goutte li, .clair-alt .liste-goutte li, .sable .liste-goutte li {
  border-top-color: var(--filet);
}
.clair-alt { background: var(--sable); }
.sable { background: var(--sable); }

.foret {
  background: var(--foret);
  color: var(--sur-sombre);
}
.foret .intro { color: var(--sur-sombre-doux); }
.foret strong { color: var(--sur-sombre); border-bottom-color: rgba(248, 242, 232, .45); }

.sauge {
  background: var(--sauge);
  color: var(--encre);
}
.sauge strong { color: var(--encre); border-bottom-color: rgba(44, 66, 55, .4); }

/* Le pied de page est vert lui aussi, mais il ne porte pas la classe
   « foret » : sans cette règle, un <strong> y reste en vert forêt sur vert
   forêt — invisible, et seul son filet se voit. */
.pied strong { color: var(--sur-sombre); border-bottom-color: rgba(248, 242, 232, .45); }

/* Un filet de goutte entre deux sections claires : la séparation ne
   passe pas par une bordure d'un bord à l'autre, mais par la marque,
   centrée. */
.clair + .clair::before {
  content: '';
  position: absolute;
  top: 0; left: 50%;
  width: 46px; height: 1px;
  transform: translateX(-50%);
  background: var(--filet);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--foret);
  color: var(--sur-sombre);
  padding: 12px 20px;
  z-index: 60;
}
.skip-link:focus { left: 12px; top: 12px; }

:focus-visible {
  outline: 2px solid var(--foret);
  outline-offset: 3px;
}
.foret :focus-visible, .sauge :focus-visible { outline-color: var(--sur-sombre); }

/* ---------- En-tête ---------- */

.entete {
  position: sticky;
  top: 0;
  z-index: 50;
  /* Fond plein, et surtout pas de backdrop-filter : un filtre de fond
     fait de l'en-tête le bloc conteneur de ses descendants en position
     fixe, et le menu mobile — qui en est un — se retrouverait enfermé
     dans la hauteur de la barre au lieu de couvrir l'écran. */
  background: var(--creme);
  transition: box-shadow .3s;
}
.entete.defile { box-shadow: 0 1px 0 var(--filet); }

.entete-inner {
  width: min(100% - var(--marge) * 2, var(--serre));
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 14px 0;
}

.logo { display: block; line-height: 0; }
.logo img { width: 128px; height: auto; }

/* En-tête centrée : le logotype sur sa ligne, la navigation sous lui.
   C'est la composition des maisons de soin plutôt que celle des
   applications — symétrique, sans hiérarchie gauche-droite, et elle
   laisse au logotype la place de se lire. En dessous de 1000 px on
   revient à la barre classique avec le menu déroulant. */
@media (min-width: 1001px) {
  /* Réserve seulement : main.js mesure la vraie hauteur et la réécrit.
     Deux rangées coûtent une centaine de pixels de plus qu'une barre
     classique, et c'est autant de pris sur l'accueil — d'où un logotype
     et des marges plus serrés qu'ils n'y paraissent. */
  :root { --entete: 166px; }
  .entete-inner {
    flex-direction: column;
    justify-content: center;
    gap: 10px;
    padding: 14px 0 12px;
  }
  .logo img { width: 146px; }
  .nav { justify-content: center; gap: clamp(16px, 2vw, 30px); }
  /* Le bouton est posé au bout de la rangée, comme un lien de plus. À sa
     taille courante il pèse deux fois un intitulé et tire la rangée vers
     la droite alors qu'elle est centrée : on le ramène au même corps. */
  .nav .bouton {
    margin-left: clamp(4px, .8vw, 12px);
    padding: 9px 18px;
    font-size: .66rem;
  }
}

.nav {
  display: flex;
  align-items: center;
  gap: clamp(14px, 1.9vw, 30px);
}
.nav a {
  text-decoration: none;
  font-size: .72rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris);
  padding: 6px 0;
  position: relative;
}
.nav a:not(.bouton)::after {
  content: '';
  position: absolute;
  left: 0; right: 100%; bottom: 2px;
  height: 1px;
  background: var(--sauge);
  transition: right .3s;
}
.nav a:not(.bouton):hover::after,
.nav a:not(.bouton):focus-visible::after { right: 0; }

/* « .nav a » l'emporte sur « .bouton » : le bouton de la barre doit donc
   redemander ses propres marges intérieures. */
.nav a.bouton { padding: 15px 28px; }

.nav a.bouton::after { content: none; }

.burger {
  display: none;
  width: 44px; height: 40px;
  background: none;
  border: 0;
  padding: 9px 8px;
  cursor: pointer;
}
.burger span {
  display: block;
  height: 1px;
  background: var(--foret);
  margin: 6px 0;
  transition: transform .3s, opacity .3s;
}

/* ---------- Boutons ---------- */

/* Un bouton plein est une promesse de clic. Trois par écran, c'est une
   page de vente ; un seul, c'est une invitation. Le reste des appels
   passe par « lien-majuscule », qui a la même autorité sans le poids. */
.bouton {
  display: inline-block;
  font-family: var(--texte);
  font-size: .72rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 17px 34px;
  border: 1px solid transparent;
  border-radius: 2px;
  cursor: pointer;
  transition: background .3s, color .3s, border-color .3s;
}
.bouton-plein {
  background: var(--foret);
  color: var(--sur-sombre);
}
.bouton-plein:hover, .bouton-plein:focus-visible { background: var(--encre); }

/* Le seul appel permanent de la page : un filet, pas un aplat. Un bouton
   plein en haut de chaque écran appartient aux pages de vente. */
.bouton-contour {
  border-color: var(--foret);
  color: var(--foret);
}
.bouton-contour:hover, .bouton-contour:focus-visible {
  background: var(--foret);
  color: var(--sur-sombre);
}

.bouton-fantome {
  border-color: var(--sauge);
  color: var(--foret);
}
.bouton-fantome:hover, .bouton-fantome:focus-visible {
  background: var(--sauge);
  color: var(--encre);
}

.bouton-clair {
  background: var(--creme);
  color: var(--foret);
}
.bouton-clair:hover, .bouton-clair:focus-visible { background: var(--sable); }

.bouton-fantome-clair {
  border-color: rgba(248, 242, 232, .55);
  color: var(--sur-sombre);
}
.bouton-fantome-clair:hover, .bouton-fantome-clair:focus-visible {
  background: rgba(248, 242, 232, .12);
}

/* ---------- Accueil ----------
   Un demi-écran de texte, un demi-écran d'image qui va d'un bord à
   l'autre de sa moitié et de haut en bas. Pas de cadre, pas d'arrondi,
   pas de marge : c'est la pleine page qui fait la différence de registre
   avec une photographie posée dans une colonne. */

/* ---------- L'accueil ----------

   Pas de photographie. Ce n'est pas un renoncement, c'est le résultat de
   quatre essais : le portrait de la praticienne, le soin du visage, la
   pièce à main du laser, le mur végétal. Aucune des onze photographies du
   tournage ne tient en plein écran — ce sont des gros plans et des pièces
   encombrées, prises pour illustrer, pas pour porter une page.

   Ce qui reste est ce que la marque a de plus solide : un logotype
   dessiné, une romaine à déliés, et le vert de la charte en aplat. Les
   soins se montrent douze centimètres plus bas, dans les quatre tuiles,
   où les mêmes photographies font très bien l'affaire. */

.hero {
  /* Le sauge, le plus clair des quatre verts de la charte. Le forêt
     faisait une couverture franche mais fermée ; le sauge ouvre. */
  background: var(--sauge);
  position: relative;
  isolation: isolate;
  display: grid;
  place-items: center;
  min-height: min(calc(100svh - var(--entete)), 660px);
  padding: clamp(22px, 4vh, 96px) 0;
  overflow: hidden;
}

/* Un halo crème, très ouvert, posé au-dessus du titre : c'est ce qui
   empêche l'aplat de rester plat. Des ombres de fougère ont été essayées
   ici — dessinées, puisqu'aucun détourage de la photographie du mur ne
   tenait. Elles ont été retirées : une ombre dessinée reste un dessin, et
   à cette échelle cela se voit. Le halo suffit à dire la lumière. */
.hero::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  background: radial-gradient(120% 90% at 50% 8%,
              rgba(248, 242, 232, .34), rgba(248, 242, 232, 0) 62%);
  pointer-events: none;
}

.hero-texte {
  position: relative;
  z-index: 1;
  max-width: none;
  padding-inline: var(--marge);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Le monogramme ouvre la page. C'est la seule image de l'accueil, et
   c'est la marque. */
.hero-texte::before {
  content: '';
  display: block;
  width: clamp(38px, min(5vw, 6vh), 64px);
  aspect-ratio: 1;
  margin-bottom: clamp(10px, 1.5vh, 34px);
  background: url('../img/logo/monogramme-foret.svg') center / contain no-repeat;
}

/* Sur l'aplat sauge, le vert forêt ne tient qu'à 4,07 : 1 — assez pour le
   grand corps du titre, pas pour le reste. C'est la règle que la charte
   pose depuis le début, et c'est l'encre foncée qui s'applique ici. */
.hero .surtitre { color: var(--encre); margin-bottom: min(2em, 1.9vh); }
.hero h1 {
  color: var(--foret);
  /* Le plafond en vh compte autant que celui en vw : l'accueil doit
     tenir dans la fenêtre, bouton compris, sur un portable de 768 px de
     haut comme sur un écran de 1080. */
  font-size: clamp(2.4rem, min(7.4vw, 7.7vh), 6rem);
  max-width: 16ch;
  margin-bottom: min(.5em, 2.4vh);
}
/* Le chapeau s'est scindé. La machine est ce qu'on vient chercher : elle
   prend le corps d'un sous-titre, pas celui d'une légende. Le reste de
   l'offre suit en dessous, plus petit, parce qu'il ne décide de rien au
   premier écran. */
.hero-chapeau {
  font-family: var(--titres);
  font-size: clamp(1.3rem, min(2.6vw, 3.1vh), 2.1rem);
  font-weight: 300;
  line-height: 1.32;
  /* L'encre et non le forêt : c'est la plus sombre des deux sur le sauge,
     donc la plus lisible, et le but était justement de la faire sortir. */
  color: var(--encre);
  max-width: 23ch;
  margin: 0 0 min(.5em, 1.4vh);
}
.hero-chapeau-suite {
  font-family: var(--titres);
  font-size: clamp(1.02rem, 1.3vw, 1.18rem);
  font-weight: 300;
  line-height: 1.5;
  color: var(--encre);
  max-width: 40ch;
  margin: 0 0 clamp(16px, min(2.8vw, 2.9vh), 44px);
}
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(20px, 2.4vw, 38px);
  margin: 0;
}
.hero .bouton-clair { background: var(--foret); color: var(--creme); }
.hero .bouton-clair:hover, .hero .bouton-clair:focus-visible { background: var(--encre); }
/* .lien-majuscule est défini plus bas dans la feuille : à spécificité
   égale il gagnerait. On le qualifie par l'accueil. */
.hero .lien-sur-photo {
  color: var(--encre);
  border-bottom-color: rgba(44, 66, 55, .45);
}
.hero .lien-sur-photo:hover,
.hero .lien-sur-photo:focus-visible { border-bottom-color: var(--encre); }

/* ---------- Les formes et les photographies ---------- */

.arche {
  border-radius: var(--arche);
  overflow: hidden;
  position: relative;
  aspect-ratio: 3 / 4;
}
.arche img.photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.arche-petite { aspect-ratio: 4 / 5; }

/* La photographie du laser tient toute la largeur du bloc, au-dessus des
   deux colonnes : dans la colonne de droite, elle la rendait plus haute
   que celle des étapes et le vert se vidait sous la dernière. */
.laser-visuel {
  margin: 0 0 clamp(44px, 5vw, 76px);
  line-height: 0;
}
.laser-visuel img {
  width: 100%;
  height: auto;
  aspect-ratio: 2 / 1;
  object-fit: cover;
  border-radius: 24px 24px 8px 8px;
}

.soin-photo {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 45 / 31;
  object-fit: cover;
  border-radius: 18px 18px 6px 6px;
  margin: clamp(26px, 3vw, 40px) 0 0;
}

.visage-visuel {
  margin: clamp(32px, 3.4vw, 52px) 0 0;
  max-width: 340px;
  /* Cette figure porte aussi la classe « arche », qui lui donne un
     rapport de forme et rogne son contenu. Les deux sont faits pour une
     image seule ; ici il y a une légende dessous, qui doit rester
     visible ET compter dans la hauteur.

     Le rapport de forme n'est pas un détail de rendu. Chrome laisse le
     contenu l'emporter quand il dépasse ; Safari enferme la figure à la
     hauteur calculée, et la légende se retrouve par-dessus la liste qui
     suit. C'est ce qui s'est vu sur iPhone et qu'aucune vérification ne
     pouvait montrer ici, le navigateur de contrôle étant Chromium.
     C'est la photographie qui porte le rapport de forme, pas la figure. */
  aspect-ratio: auto;
  overflow: visible;
}
.visage-visuel .photo {
  border-radius: var(--arche);
  aspect-ratio: 4 / 5;
  width: 100%;
  height: auto;
  object-fit: cover;
  display: block;
}
.visage-visuel figcaption {
  margin-top: 14px;
  font-size: .85rem;
  color: var(--gris);
}

/* La bande pleine largeur : elle sort de la trame, d'un bord à l'autre. */
.bande-photo { margin: 0; line-height: 0; }
.bande-photo img {
  width: 100%;
  height: clamp(240px, 34vw, 460px);
  object-fit: cover;
  display: block;
}

/* ---------- Le bandeau défilant ---------- */

/* Deux pistes identiques côte à côte, translatées de la moitié de leur
   largeur totale : quand la première sort, la seconde est exactement à
   sa place, et la boucle ne se voit pas. La seconde est en aria-hidden,
   sinon un lecteur d'écran lirait tout deux fois. */
.reperes-bande {
  padding: clamp(22px, 2.4vw, 34px) 0;
  border-top: 1px solid var(--filet);
  border-bottom: 1px solid var(--filet);
  overflow: hidden;
}
.defilant { display: flex; width: max-content; animation: defile 46s linear infinite; }
.defilant-piste {
  display: flex;
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}
.defilant-piste li {
  font-family: var(--texte);
  font-size: .68rem;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--gris);
  white-space: nowrap;
  padding: 0 clamp(26px, 3.4vw, 54px);
  position: relative;
}
/* La goutte du logotype sépare les mentions, à la place d'une puce. */
.defilant-piste li::after {
  content: '';
  position: absolute;
  right: -3px;
  top: 50%;
  width: 6px;
  height: 6px;
  margin-top: -3px;
  background: var(--sauge);
  border-radius: 999px 999px 999px 1px;
  transform: rotate(-45deg);
}
@keyframes defile {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .defilant { animation: none; }
}

/* ---------- Les prestations, en tuiles ---------- */

/* Un titre centré, puis quatre images de même format avec leur légende
   dessous. Pas d'encadré, pas d'ombre : ce sont les photographies qui
   tiennent la grille, et la régularité du cadrage qui fait le calme. */
/* Le bandeau défilant sépare déjà l'accueil de ce qui suit : la marge
   pleine de section laisserait au-dessus du titre un vide que rien ne
   remplit. */
.prestations { padding-top: clamp(66px, 8.4vw, 140px); }
.titre-centre {
  text-align: center;
  margin: 0 0 clamp(40px, 4.4vw, 68px);
}
.titre-centre + .tuiles { margin-top: 0; }

.tuiles {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(18px, 2.4vw, 40px);
}
.tuile {
  display: block;
  text-decoration: none;
  text-align: center;
}
.tuile-image {
  display: block;
  overflow: hidden;
  margin-bottom: clamp(16px, 1.6vw, 24px);
  /* L'arche du monogramme, ouverte vers le bas, comme partout ailleurs. */
  border-radius: 999px 999px 8px 8px;
  background: var(--sable);
}
.tuile-image img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 760 / 950;
  object-fit: cover;
  transition: transform .9s cubic-bezier(.2, .7, .3, 1);
}
.tuile:hover .tuile-image img,
.tuile:focus-visible .tuile-image img { transform: scale(1.035); }
.tuile strong {
  display: block;
  font-family: var(--titres);
  font-size: clamp(1.22rem, 1.6vw, 1.5rem);
  font-weight: 400;
  line-height: 1.15;
  border: 0;
  color: var(--foret);
}
.tuile-note {
  display: block;
  margin-top: 6px;
  font-size: .84rem;
  color: var(--gris);
}

/* ---------- Le laser ---------- */

.laser-grille {
  display: grid;
  grid-template-columns: 1.1fr .9fr;
  gap: clamp(36px, 5vw, 80px);
  align-items: start;
}

.etapes {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: etape;
}
.etape {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: clamp(22px, 2.6vw, 38px);
  padding: clamp(28px, 3vw, 42px) 0;
  border-top: 1px solid var(--filet-foret);
}
.etape:first-child { border-top: 0; padding-top: 0; }
.etape-num {
  font-family: var(--titres);
  font-size: clamp(2.4rem, 3.4vw, 3.2rem);
  font-weight: 300;
  font-variant-numeric: lining-nums;
  line-height: .9;
  color: var(--sauge-texte);
  min-width: 2ch;
}
.etape h3 { margin-bottom: .35em; }
.etape p { color: var(--sur-sombre-doux); margin: 0; font-size: 1rem; }

/* Les consignes ne sont pas dans une carte : un encadré arrondi sur fond
   translucide est le gabarit de l'« info box », et il enferme ce qui
   devrait se lire d'une traite. Un filet au-dessus suffit à dire que
   c'est une colonne à part. */
.preparation {
  border-top: 1px solid var(--filet-foret);
  padding-top: clamp(24px, 2.6vw, 36px);
}
.preparation h3 {
  font-family: var(--texte);
  font-size: .62rem;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--sauge-texte);
  margin-bottom: 2em;
}

/* Les listes passent en rangées séparées par un filet. Une colonne de
   gouttes devant chaque ligne faisait « liste à puces » ; un filet fait
   « index ». La goutte de la marque reste, mais seulement là où une
   liste n'a que deux ou trois entrées (voir .liste-serree). */
.liste-goutte {
  list-style: none;
  margin: 0 0 clamp(24px, 2.4vw, 36px);
  padding: 0;
}
.liste-goutte li {
  position: relative;
  padding: 14px 0;
  font-size: .97rem;
  border-top: 1px solid var(--filet-foret);
}
.liste-goutte li:first-child { border-top: 0; padding-top: 0; }
/* La goutte du logotype, dessinée en CSS : trois coins ronds, le
   quatrième pointu, tournée de 45°. Elle ne sert plus que dans les
   listes courtes, où une rangée de filets serait lourde. */
.liste-serree li {
  border-top: 0;
  padding: 0 0 .7em 26px;
  font-size: .95rem;
}
.liste-serree li:last-child { padding-bottom: 0; }
.liste-serree li::before {
  content: '';
  position: absolute;
  left: 2px; top: .58em;
  width: 8px; height: 8px;
  background: var(--sauge);
  border-radius: 999px 999px 999px 2px;
  transform: rotate(-45deg);
}

.aparte-note {
  font-size: .9rem;
  color: var(--sur-sombre-doux);
  border-top: 1px solid var(--filet-foret);
  padding-top: 1.2em;
  margin: 0;
}

/* ---------- Soins minceur ---------- */

.soins-duo {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(30px, 4vw, 68px);
}
.soin {
  border-top: 1px solid var(--filet);
  padding-top: 30px;
}
.soin h3 { margin-bottom: .6em; }
.soin h4 {
  margin: 2.2em 0 1.1em;
  font-family: var(--texte);
  font-size: .62rem;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--gris);
}
.soin p { color: var(--gris); font-size: 1rem; }
.soin-note {
  font-size: .85rem;
  font-style: italic;
  color: var(--gris);
}

/* ---------- Soins visage ---------- */

.visage-inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(36px, 5vw, 84px);
  align-items: start;
}
.visage-texte p { color: var(--gris); max-width: 50ch; }

.qualites {
  list-style: none;
  margin: 2em 0 0;
  padding: 0;
  display: grid;
  gap: 0;
}
.qualites li {
  padding: 13px 0 13px 28px;
  border-top: 1px solid var(--filet);
  font-size: .95rem;
  position: relative;
}
.qualites li:last-child { border-bottom: 1px solid var(--filet); }
.qualites li::before {
  content: '';
  position: absolute;
  left: 2px; top: 1.32em;
  width: 8px; height: 8px;
  background: var(--sauge);
  border-radius: 999px 999px 999px 2px;
  transform: rotate(-45deg);
}

/* La colonne courte reste en vue pendant qu'on parcourt la longue :
   sinon elle se fige en haut et laisse 600 px de sable sous elle. */
.protocole {
  position: sticky;
  top: 104px;
  background: var(--creme);
  border-radius: 999px 999px 10px 10px;
  padding: clamp(34px, 4vw, 56px) clamp(26px, 3vw, 48px) clamp(30px, 3.4vw, 48px);
  text-align: center;
}
.protocole-surtitre {
  font-size: .7rem;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--gris);
  margin-bottom: 1em;
}
.protocole h3 {
  font-size: clamp(1.9rem, 3.4vw, 2.6rem);
  font-weight: 300;
  margin-bottom: .3em;
}
.protocole-chapeau { color: var(--gris); font-size: .97rem; margin-bottom: 2.2em; }

.protocole-temps {
  list-style: none;
  margin: 0 0 2em;
  padding: 0;
  text-align: left;
  display: grid;
  gap: 0;
}
.protocole-temps li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 18px;
  align-items: start;
  padding: 20px 0;
  border-top: 1px solid var(--filet);
}
.protocole-num {
  font-family: var(--titres);
  font-size: 1.5rem;
  font-weight: 300;
  font-variant-numeric: lining-nums;
  line-height: 1;
  /* Sur le crème, le sauge tombe à 2,6 : 1. Le gris-vert passe à 5,1 : 1
     sans peser davantage. */
  color: var(--gris);
  min-width: 2ch;
}
.protocole-temps > li > div { grid-column: 2; }
.protocole-temps h4 { margin: 0 0 .25em; }
.protocole-temps p { font-size: .93rem; color: var(--gris); margin: 0; }
.protocole-fin {
  font-family: var(--titres);
  font-style: italic;
  font-size: 1.24rem;
  line-height: 1.45;
  color: var(--foret);
  border-top: 1px solid var(--filet);
  padding-top: 1.4em;
  margin: 0;
}

/* ---------- Amélie ---------- */

.amelie-inner {
  display: grid;
  grid-template-columns: .8fr 1.2fr;
  gap: clamp(34px, 5vw, 84px);
  align-items: center;
}
.amelie-titre {
  font-size: .74rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris);
  margin: -.4em 0 1.8em;
}
.amelie-texte p { color: var(--gris); max-width: 56ch; }
.amelie-texte h2 { margin-bottom: .3em; }

.lien-goutte {
  display: inline-block;
  text-decoration: none;
  border-bottom: 1px solid var(--sauge);
  padding-bottom: 2px;
  font-size: .95rem;
  color: var(--foret);
  transition: border-color .25s;
}
.lien-goutte:hover, .lien-goutte:focus-visible { border-color: var(--foret); }

/* ---------- Tarifs ----------
   Une carte, au sens du restaurant : le nom à gauche, le prix à droite,
   un filet de conduite entre les deux. C'est la forme la plus lisible
   pour une grille, et la moins tapageuse.

   La grille est celle de la page de réservation, relevée au navigateur
   (voir .github/workflows/tarifs-dermevasion.yml). Elle compte une
   soixantaine de lignes : tout afficher d'un coup noierait les prix
   d'entrée, qui sont ceux qu'on vient chercher. D'où les replis — des
   <details>, donc rien à charger, et le contenu reste dans la page pour
   qui la cherche au clavier ou l'imprime. */

.tarifs-inner {
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  gap: clamp(40px, 6vw, 110px);
  align-items: start;
}
.tarifs-texte { position: sticky; top: calc(var(--entete) + 26px); }
.tarifs-note {
  font-size: .9rem;
  color: var(--gris);
  max-width: 34ch;
}

.tarifs-famille {
  font-family: var(--texte);
  font-size: .64rem;
  letter-spacing: .34em;
  text-transform: uppercase;
  color: var(--gris);
  margin: clamp(36px, 4vw, 58px) 0 1.4em;
}
.tarifs-grille > .tarifs-famille:first-child { margin-top: 0; }
/* La note de famille vient juste sous son titre : elle dit ce que le
   prix recouvre, et elle évite d'avoir à le répéter ligne à ligne. */
.tarifs-famille + .tarifs-precision {
  font-size: .86rem;
  line-height: 1.55;
  color: var(--gris);
  max-width: 54ch;
  margin: -1em 0 1.5em;
}

.tarif { margin: 0; }
.tarif > div {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 10px;
  padding: 15px 0;
  border-top: 1px solid var(--filet);
}
.tarif > div:last-child { border-bottom: 1px solid var(--filet); }
.tarif dt {
  font-family: var(--titres);
  font-size: clamp(1.04rem, 1.3vw, 1.22rem);
  font-weight: 400;
  line-height: 1.32;
  /* Le nom peut tenir sur deux lignes — « Aisselles + maillot intégral +
     jambes entières + bras complets » n'entre nulle part sur un
     téléphone. Il est donc son propre élément de boîte flexible, et le
     filet de conduite en est un second, qui mange la place restante et
     se range sur la dernière ligne. */
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0 10px;
  min-width: 0;
}
.tarif dt::after {
  content: '';
  flex: 1 0 18px;
  align-self: flex-end;
  height: 1px;
  margin-bottom: .36em;
  background-image: radial-gradient(circle, var(--sauge) 1px, transparent 1px);
  background-size: 6px 1px;
  background-repeat: repeat-x;
}
/* Ce que le prix comprend : « genoux et pieds offerts », « 160 € la
   séance ». En petit, sur sa propre ligne, et en gris — c'est une
   précision, pas une promesse de plus. */
.tarif-precision {
  flex: 1 0 100%;
  order: 1;
  font-family: var(--texte);
  font-size: .78rem;
  letter-spacing: .01em;
  color: var(--gris);
  margin-top: .3em;
}
.tarif dd {
  margin: 0;
  font-family: var(--titres);
  font-variant-numeric: lining-nums;
  font-size: clamp(1.04rem, 1.3vw, 1.22rem);
  color: var(--foret);
  white-space: nowrap;
}

/* Le repli. Le triangle natif est remplacé par une croix qui devient un
   tiret : c'est le même geste, dessiné dans la charte. */
.tarif-plus { margin-top: 14px; }
.tarif-plus > summary {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  list-style: none;
  font-family: var(--texte);
  font-size: .66rem;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--gris);
  padding: 4px 0;
  transition: color .25s;
}
.tarif-plus > summary::-webkit-details-marker { display: none; }
.tarif-plus > summary::before {
  content: '';
  width: 11px;
  height: 11px;
  flex: none;
  /* En sauge, la croix tombait à 1,8:1 sur le crème : un repère qu'on
     devine plutôt qu'on ne le voit. En gris, elle tient le 3:1 des
     éléments non textuels. */
  background:
    linear-gradient(var(--gris), var(--gris)) center / 11px 1px no-repeat,
    linear-gradient(var(--gris), var(--gris)) center / 1px 11px no-repeat;
  transition: transform .3s, background-size .3s;
}
.tarif-plus[open] > summary::before {
  background:
    linear-gradient(var(--foret), var(--foret)) center / 11px 1px no-repeat;
  transform: rotate(180deg);
}
.tarif-plus > summary:hover,
.tarif-plus > summary:focus-visible { color: var(--foret); }
.tarif-plus > summary:focus-visible { outline: 2px solid var(--foret); outline-offset: 4px; }
.tarif-replie { margin-top: 10px; }

/* ---------- Avis ----------
   Quatre citations en romaine, sur deux colonnes larges. Pas de carte,
   pas d'encadré, pas de rangée d'étoiles dorées : un filet au-dessus,
   le texte, le prénom en capitales espacées, la note en chiffres. */

.avis-section .bloc > h2 { margin-bottom: clamp(48px, 5vw, 80px); }

/* Les avis défilent latéralement. La piste sort de la trame à droite et
   file jusqu'au bord de la fenêtre : le témoignage suivant dépasse, ce
   qui dit qu'il y en a d'autres sans avoir à l'écrire. Le défilement est
   celui du navigateur — scroll-snap, pas de bibliothèque —, donc il
   marche au doigt, à la molette, au clavier et sans JavaScript ; les
   flèches ne font que l'accompagner. */
.carrousel {
  position: relative;
  margin-right: calc(-1 * max(var(--marge), (100vw - var(--serre)) / 2));
}

.avis {
  list-style: none;
  margin: 0 0 clamp(30px, 3vw, 44px);
  padding: 0 max(var(--marge), (100vw - var(--serre)) / 2) 4px 0;
  display: flex;
  gap: clamp(28px, 3.4vw, 58px);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  align-items: stretch;
  /* La barre de défilement native couperait le filet du haut des
     citations ; le défilement reste possible partout ailleurs. */
  scrollbar-width: none;
}
.avis::-webkit-scrollbar { display: none; }
.avis:focus-visible { outline: 2px solid var(--foret); outline-offset: 6px; }

.avis-item {
  /* Trois citations tiennent dans la trame, et la quatrième dépasse de
     quelques dizaines de pixels : c'est ce débord qui dit qu'on peut
     faire défiler, mieux que n'importe quelle flèche. */
  flex: 0 0 clamp(248px, 27.5vw, 380px);
  scroll-snap-align: start;
  border-top: 1px solid var(--filet);
  padding-top: clamp(22px, 2.4vw, 32px);
  /* Même hauteur pour toutes, signature en bas : sans cela les quatre
     filets du haut s'alignent mais les quatre prénoms flottent chacun à
     sa hauteur, et la rangée a l'air décousue. */
  display: flex;
  flex-direction: column;
}
.avis-item blockquote { flex: 1 1 auto; }

.carrousel-commandes {
  display: flex;
  gap: 12px;
  margin: 0;
}
.carrousel-fleche {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  background: none;
  border: 1px solid var(--filet-sauge);
  border-radius: 999px;
  color: var(--foret);
  cursor: pointer;
  transition: background .3s, border-color .3s, opacity .3s;
}
.carrousel-fleche svg { width: 17px; height: 17px; }
.carrousel-fleche:hover:not(:disabled) { background: var(--sable); border-color: var(--foret); }
.carrousel-fleche:disabled { opacity: .3; cursor: default; }
.clair-alt .carrousel-fleche:hover:not(:disabled) { background: var(--creme); }
/* Si tout tient dans la largeur, les flèches n'ont rien à commander. */
.carrousel-entier .carrousel-commandes { display: none; }
.avis-item blockquote {
  margin: 0 0 1.6em;
  font-family: var(--titres);
  font-size: clamp(1.14rem, 1.5vw, 1.34rem);
  font-weight: 300;
  line-height: 1.58;
  color: var(--foret);
}
.avis-item blockquote p { margin: 0 0 .8em; }
.avis-item blockquote p:last-child { margin-bottom: 0; }

.avis-signature {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
}
.avis-nom {
  font-size: .7rem;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--gris);
}
.avis-note {
  font-family: var(--titres);
  font-variant-numeric: lining-nums;
  font-size: 1rem;
  color: var(--gris);
  white-space: nowrap;
}
.avis-fin { text-align: center; margin: clamp(36px, 4vw, 60px) 0 0; }
.surtitre-centre { text-align: center; }

/* Un lien qui n'est pas un bouton : capitales espacées, filet dessous,
   qui s'efface au survol. */
.lien-majuscule {
  display: inline-block;
  font-size: .68rem;
  letter-spacing: .24em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--foret);
  padding-bottom: 6px;
  border-bottom: 1px solid var(--sauge);
  transition: border-color .3s, color .3s;
}
.lien-majuscule:hover, .lien-majuscule:focus-visible {
  border-bottom-color: var(--foret);
}
.lien-second { color: var(--gris); border-bottom-color: var(--filet); }
.lien-second:hover, .lien-second:focus-visible { border-bottom-color: var(--gris); }

/* ---------- Le cabinet ---------- */

.venir-inner {
  display: grid;
  grid-template-columns: 1.2fr .8fr;
  gap: clamp(34px, 5vw, 84px);
  align-items: center;
}

.coordonnees { margin: 0 0 2em; }
.coordonnees > div {
  display: grid;
  grid-template-columns: minmax(180px, 30%) 1fr;
  gap: 20px;
  align-items: baseline;
  padding: 20px 0;
  border-top: 1px solid var(--filet);
}
.coordonnees > div:last-child { border-bottom: 1px solid var(--filet); }
.coordonnees dt {
  font-size: .7rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--gris);
}
.coordonnees dd {
  margin: 0;
  font-variant-numeric: lining-nums;
  font-family: var(--titres);
  font-size: 1.28rem;
  line-height: 1.45;
}
.coordonnees dd a { text-decoration: none; border-bottom: 1px solid var(--sauge); }
.coordonnees dd .lien-goutte { display: block; margin-top: .4em; font-family: var(--texte); }
.dd-note {
  font-family: var(--texte);
  font-size: .88rem;
  color: var(--gris);
}

/* L'accès : deux entrées, métro et voiture, sous les coordonnées. Même
   gabarit que les repères de l'accueil — pastille à gauche, titre et
   ligne de texte à droite. */
.acces {
  list-style: none;
  margin: 0 0 2em;
  padding: 0;
  display: grid;
  gap: 22px;
}
.acces {
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(22px, 3vw, 44px);
  padding-top: 26px;
  border-top: 1px solid var(--filet);
}
.acces h3 {
  font-family: var(--texte);
  font-size: .7rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--gris);
  margin: 0 0 .7em;
}
.acces p {
  margin: 0;
  font-size: .95rem;
  color: var(--gris);
  max-width: 46ch;
}

.venir-note { font-size: .88rem; color: var(--gris); max-width: 54ch; }

/* ---------- Dépliants ---------- */

.depliant {
  border-top: 1px solid var(--filet);
}
.depliant:last-of-type { border-bottom: 1px solid var(--filet); }
.depliant summary {
  cursor: pointer;
  list-style: none;
  padding: 22px 44px 22px 0;
  position: relative;
  font-family: var(--titres);
  font-size: clamp(1.18rem, 2vw, 1.42rem);
  line-height: 1.3;
}
.depliant summary::-webkit-details-marker { display: none; }
.depliant summary::after {
  content: '';
  position: absolute;
  right: 6px; top: 50%;
  width: 11px; height: 11px;
  margin-top: -8px;
  border-right: 1px solid var(--sauge);
  border-bottom: 1px solid var(--sauge);
  transform: rotate(45deg);
  transition: transform .3s;
}
.depliant[open] summary::after { transform: rotate(-135deg); margin-top: -3px; }
.depliant-corps {
  padding: 0 clamp(0px, 4vw, 60px) 26px 0;
  color: var(--gris);
  font-size: .98rem;
}
.depliant-corps h3 {
  font-size: 1.1rem;
  margin: 1.5em 0 .4em;
  color: var(--foret);
}
.depliant-corps h3:first-child { margin-top: 0; }
.depliant-reserve { font-style: italic; }

.avertissement {
  margin-top: 3.4em;
  padding-top: 24px;
  border-top: 1px solid var(--filet);
}
.avertissement p { font-size: .92rem; color: var(--gris); margin: 0; }

/* ---------- Contact ---------- */

.contact-inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(36px, 5vw, 84px);
  align-items: start;
}
.contact-texte { position: sticky; top: 104px; }
.contact-texte p { color: var(--sur-sombre-doux); max-width: 44ch; }
.contact-texte .intro { color: var(--sur-sombre-doux); }
.contact-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin: 2em 0 2.4em;
}
.contact-liens {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 16px;
}
.contact-liens {
  border-top: 1px solid var(--filet-foret);
  padding-top: 24px;
}
.contact-liens li { font-size: .95rem; color: var(--sur-sombre-doux); }
.contact-liens a { text-decoration: none; border-bottom: 1px solid rgba(248, 242, 232, .4); }

/* Le formulaire n'est pas une carte posée sur la page : des champs
   soulignés d'un filet, alignés sur la colonne. Un encadré arrondi sur
   fond translucide est le gabarit de l'« info box », et il donne au
   formulaire l'air d'un module acheté ailleurs. */
.formulaire { padding-top: clamp(8px, 1vw, 16px); }
.cache { position: absolute; left: -9999px; }

.champ { margin: 0 0 clamp(22px, 2.4vw, 34px); display: grid; gap: 10px; }
.champ label {
  font-size: .62rem;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--sur-sombre-doux);
}
.facultatif { text-transform: none; letter-spacing: 0; opacity: .8; }

.champ input, .champ select, .champ textarea {
  font-family: var(--texte);
  font-size: 1rem;
  color: var(--sur-sombre);
  background: none;
  border: 0;
  border-bottom: 1px solid var(--filet-foret);
  border-radius: 0;
  padding: 10px 2px;
  width: 100%;
  transition: border-color .3s;
}
.champ input:hover, .champ select:hover, .champ textarea:hover {
  border-bottom-color: var(--sauge);
}
.champ textarea { resize: vertical; }
.champ select option { color: var(--foret); }
.champ input:focus, .champ select:focus, .champ textarea:focus {
  outline: none;
  border-bottom-color: var(--sur-sombre-doux);
  border-bottom-width: 2px;
  padding-bottom: 9px;
}

.champ-case label {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 12px;
  align-items: start;
  text-transform: none;
  letter-spacing: 0;
  font-size: .88rem;
  line-height: 1.6;
}
.champ-case input { width: 18px; height: 18px; margin-top: 3px; }

.champ-note {
  font-size: .84rem;
  color: var(--sur-sombre-doux);
  opacity: .85;
  margin-bottom: 1.6em;
}
.formulaire-retour { margin-top: 1.2em; font-size: .9rem; color: var(--sur-sombre-doux); }

/* ---------- Pied de page ---------- */

.pied {
  background: var(--foret);
  color: var(--sur-sombre);
  padding: var(--section) 0 40px;
}
.pied-haut {
  display: grid;
  grid-template-columns: 1.2fr .9fr .9fr;
  gap: clamp(30px, 4vw, 70px);
  padding-bottom: 46px;
  border-bottom: 1px solid var(--filet-foret);
}
.pied-marque img { width: 150px; height: auto; margin-bottom: 18px; }
.pied-marque p, .pied-contact p { color: var(--sur-sombre-doux); font-size: .95rem; }
.pied h2 {
  font-family: var(--texte);
  font-size: .72rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--sauge-texte);
  margin-bottom: 1.4em;
}
.pied-nav { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
.pied-nav a, .pied-contact a {
  text-decoration: none;
  font-size: .95rem;
  color: var(--sur-sombre-doux);
  border-bottom: 1px solid transparent;
  transition: border-color .25s;
}
.pied-nav a:hover, .pied-nav a:focus-visible,
.pied-contact a:hover, .pied-contact a:focus-visible { border-bottom-color: var(--sauge); }

.pied-mentions { padding: 36px 0 10px; }
.depliant-pied { border-color: var(--filet-foret); }
.depliant-pied:last-of-type { border-bottom-color: var(--filet-foret); }
.depliant-pied summary { font-size: 1.1rem; padding: 18px 44px 18px 0; }
.depliant-pied summary::after { border-color: var(--sauge); }
.depliant-pied .depliant-corps { color: var(--sur-sombre-doux); font-size: .92rem; }
.depliant-pied .depliant-corps h3 { color: var(--sur-sombre); }

.pied-bas {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 14px;
  padding-top: 26px;
  border-top: 1px solid var(--filet-foret);
  font-size: .8rem;
  letter-spacing: .06em;
  color: var(--sauge-texte);
  margin: 0;
}

/* ---------- Ce qui reste à compléter ----------
   Une valeur absente est signalée dans la page plutôt que remplie au
   hasard : un faux numéro ou une fausse adresse se retrouve en ligne
   sans que personne ne s'en aperçoive. Le repère disparaît en même
   temps que la classe, une fois la vraie valeur posée. */

.a-completer {
  border-bottom: 1px dashed var(--sauge);
  position: relative;
}
.a-completer::after {
  content: '*';
  font-size: .62em;
  vertical-align: super;
  margin-left: .25em;
  color: var(--sauge);
}
p.a-completer, blockquote.a-completer {
  border-bottom: 0;
  border-left: 2px dashed var(--sauge);
  padding-left: 18px;
}
p.a-completer::after, blockquote.a-completer::after { content: none; }
/* Sur un bouton, le filet tiré sous la pastille se lirait comme un
   défaut d'affichage : le repère se réduit à l'astérisque. */
.bouton.a-completer { border-bottom-color: transparent; }
.bouton.a-completer::after {
  content: '*';
  vertical-align: super;
  font-size: .7em;
  margin-left: .3em;
  opacity: .75;
}

@media (prefers-reduced-motion: no-preference) {
  .a-completer { transition: background .3s; }
}

/* ---------- La fenêtre de rendez-vous, flottante ----------
   Sur grand écran, une petite carte en bas à droite. Sur mobile, une
   barre pleine largeur collée en bas : c'est là que le pouce tombe, et
   une carte flottante y mangerait la moitié de l'écran.

   Elle reprend l'arche de la page — deux coins hauts très arrondis,
   deux coins bas presque droits. */

.rdv-flottant {
  position: fixed;
  right: clamp(16px, 2.4vw, 32px);
  bottom: clamp(16px, 2.4vw, 32px);
  z-index: 45;
  width: min(300px, calc(100vw - 32px));
  background: var(--foret);
  color: var(--sur-sombre);
  border-radius: 26px 26px 10px 10px;
  padding: 22px 24px 24px;
  box-shadow: 0 14px 40px rgba(31, 42, 44, .22);
  /* Au repos elle est posée un peu plus bas et transparente : elle
     monte en se révélant plutôt que d'apparaître d'un coup. */
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .45s ease, transform .45s cubic-bezier(.2, .7, .3, 1);
  pointer-events: none;
}
.rdv-flottant.vu { opacity: 1; transform: none; pointer-events: auto; }
.rdv-flottant[hidden] { display: none; }

.rdv-flottant-titre {
  font-family: var(--titres);
  font-size: 1.3rem;
  line-height: 1.2;
  margin: 0 0 .25em;
}
.rdv-flottant-note {
  font-size: .82rem;
  color: var(--sauge-texte);
  margin: 0 0 1.1em;
}
.rdv-flottant-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
}
.rdv-flottant .bouton { padding: 12px 22px; font-size: .74rem; }
.rdv-flottant-tel {
  font-family: var(--titres);
  font-variant-numeric: lining-nums;
  font-size: 1.1rem;
  text-decoration: none;
  color: var(--sur-sombre-doux);
  border-bottom: 1px solid rgba(248, 242, 232, .4);
  transition: border-color .25s;
}
.rdv-flottant-tel:hover, .rdv-flottant-tel:focus-visible { border-bottom-color: var(--sur-sombre-doux); }

.rdv-flottant-fermer {
  position: absolute;
  top: 10px; right: 10px;
  width: 32px; height: 32px;
  display: grid;
  place-items: center;
  background: none;
  border: 0;
  border-radius: 999px;
  color: var(--sauge);
  cursor: pointer;
  transition: background .25s, color .25s;
}
.rdv-flottant-fermer svg { width: 15px; height: 15px; }
.rdv-flottant-fermer:hover, .rdv-flottant-fermer:focus-visible {
  background: rgba(248, 242, 232, .12);
  color: var(--sur-sombre);
}

/* Les deux libellés de la fenêtre : le long sur grand écran, le court
   sur la barre du bas, où « Prendre rendez-vous » et « Réserver en
   ligne » passaient chacun sur deux lignes. Un seul des deux est
   affiché, l'autre est retiré du flux — et des lecteurs d'écran. */
.rdv-serre { display: none; }

@media (max-width: 760px) {
  .rdv-ample { display: none; }
  .rdv-serre { display: inline; }

  .rdv-flottant {
    right: 0; left: 0; bottom: 0;
    width: auto;
    border-radius: 20px 20px 0 0;
    padding: 16px 18px calc(16px + env(safe-area-inset-bottom, 0px));
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    transform: translateY(100%);
  }
  .rdv-flottant-note { display: none; }
  .rdv-flottant-titre { font-size: 1.12rem; margin: 0; white-space: nowrap; }
  .rdv-flottant .bouton { padding: 13px 20px; letter-spacing: .14em; white-space: nowrap; }
  .rdv-flottant-actions { flex-direction: row; align-items: center; gap: 14px; }
  .rdv-flottant-tel { display: none; }
  .rdv-flottant-fermer { position: static; width: 28px; height: 28px; flex: none; order: 3; }
  /* La barre couvrirait la dernière ligne du pied de page : on rend au
     document la hauteur qu'elle occupe. */
  body.rdv-flottant-ouvert { padding-bottom: 78px; }
}

@media print { .rdv-flottant { display: none; } }

/* ---------- Apparition au défilement ---------- */

.anim {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .8s ease, transform .8s cubic-bezier(.2, .7, .3, 1);
}
.anim.vu { opacity: 1; transform: none; }

/* ---------- Mobile ---------- */

@media (max-width: 1000px) {
  .laser-grille, .visage-inner, .amelie-inner,
  .venir-inner, .contact-inner { grid-template-columns: 1fr; }
  .hero { min-height: min(calc(100svh - var(--entete)), 560px); }
  .hero h1 { max-width: 14ch; }
  .hero-chapeau { max-width: 22ch; }
  .hero-chapeau-suite { max-width: 34ch; }
  /* Le surtitre tient sur une ligne au-dessus de 1000 px ; en dessous il
     la déborde et vient toucher les deux marges. On le laisse se couper,
     et on resserre son interlettrage, qui lui coûte ici une ligne. */
  .hero .surtitre { white-space: normal; letter-spacing: .18em; }
  .soins-duo { grid-template-columns: 1fr; }
  .tuiles { grid-template-columns: repeat(2, 1fr); }
  .amelie-portrait, .venir-arche { max-width: 420px; }
  /* En une seule colonne, un bloc collant n'a plus rien à accompagner. */
  .protocole, .contact-texte, .tarifs-texte { position: static; }
  .tarifs-inner { grid-template-columns: 1fr; }
  /* Sur un téléphone, la colonne est trop étroite pour un filet de
     conduite : il ne resterait qu'un ou deux points entre le nom et le
     prix, ce qui ressemble à une coquille. Le prix garde sa colonne à
     droite ; le nom s'enroule à sa gauche. */
  .tarif > div { gap: 14px; padding: 13px 0; }
  .tarif dt::after { content: none; }
  .tarifs-famille { margin-top: clamp(30px, 7vw, 46px); }
  .laser-visuel img { aspect-ratio: 16 / 9; }
  .laser-cote { max-width: 520px; }
  .visage-visuel { max-width: 300px; }
  .amelie-inner .amelie-portrait { order: 2; }
  .pied-haut { grid-template-columns: 1fr 1fr; }
  .pied-marque { grid-column: 1 / -1; }
}

@media (max-width: 760px) {
  body { font-size: 16.5px; }
  .burger { display: block; }
  .nav {
    position: fixed;
    inset: 0;
    background: var(--creme);
    flex-direction: column;
    justify-content: center;
    gap: 26px;
    transform: translateY(-100%);
    transition: transform .4s cubic-bezier(.3, .8, .3, 1);
    z-index: 40;
  }
  .nav.ouvert { transform: none; }
  .nav a { font-size: 1.05rem; letter-spacing: .14em; }
  .nav .bouton { margin-top: 10px; }
  .burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
  .burger[aria-expanded="true"] { position: relative; z-index: 45; }

  /* Deux tuiles par rangée jusqu'au bout : une seule par rangée
     donnerait quatre pleines pages à faire défiler avant le laser. */
  .tuiles { grid-template-columns: repeat(2, 1fr); gap: 14px; }

  /* Une citation par écran, la suivante qui dépasse. À 248 px — la
     largeur minimale héritée du bureau — la carte faisait un tiers de
     l'écran, le texte s'y pliait en vingt lignes et débordait en
     hauteur. Mieux vaut une carte large et courte qu'une étroite et
     haute : on défile dans un sens, pas dans les deux. */
  .avis-item { flex: 0 0 min(82vw, 330px); }
  .tuile strong { font-size: 1.05rem; }
  .tuile-note { font-size: .78rem; }
  .defilant-piste li { font-size: .6rem; padding: 0 20px; }

  .coordonnees > div { grid-template-columns: 1fr; gap: 8px; }
  .acces { grid-template-columns: 1fr; }
  .pied-haut { grid-template-columns: 1fr; }
  .etape { grid-template-columns: 1fr; gap: 8px; }
  .etape-num { font-size: 1.7rem; }
}

@media print {
  .entete, .burger, .hero-actions, .contact-actions, .formulaire { display: none; }
  body { background: #fff; color: #000; }
  .foret, .sauge, .sable { background: #fff !important; color: #000 !important; }
}
