/* ============================================================
   Cabinet Aveline - maquette de demonstration Atelier du Site
   Secteur : praticiens du bien-etre.
   Stack : HTML / CSS / JS natif. Zero dependance, zero build.
   Se deploie tel quel sur Netlify.

   Ce fichier est la seule feuille de style des cinq pages.
   Pour personnaliser un prospect, on ne touche pas ici :
   tout ce qui change est dans le HTML.
   ============================================================ */

/* ---------- 1. Palette ----------
   Deux echelles seulement : Lin (neutres chauds) et Sauge (accent
   unique). Regle : un seul accent sur tout le site, jamais deux
   couleurs vives cote a cote.

   Le sauge est le cliche du secteur quand il est pastel, pose en aplat
   sur des sections entieres et marie a une serif ronde. Celui-ci est
   profond et desature, et ne couvre jamais plus de 10 % de la surface.
   C'est cet emploi-la qui le rend utilisable, pas la teinte.

   Les neutres sont chauds et non gris-bleu : sur un site de soin, un
   gris froid donne le ton d'un cabinet dentaire.

   Tous les ratios ci-dessous sont mesures, jamais estimes. 28 couples
   verifies le 2026-09-06, pire couple 4.61, donc tout passe AA.      */
:root {
  color-scheme: light dark;

  /* Echelle Lin : neutres chauds */
  --lin-50:  #FAF9F5;
  --lin-100: #F2F1EA;
  --lin-200: #E6E5DC;
  --lin-300: #D2D2C6; /* 10.35 sur lin-900, liens du pied de page */
  --lin-400: #A5A79C; /*  6.46 sur lin-900, texte secondaire sur fond fonce */
  --lin-500: #6B6D62; /*  5.00 sur lin-50 */
  --lin-600: #545C54; /*  6.57 sur lin-50 */
  --lin-700: #3C4239;
  --lin-800: #2A2E27;
  --lin-900: #1F2420; /* 14.97 sur lin-50, texte principal */
  --lin-950: #141710;

  /* Echelle Sauge */
  --sauge-50:  #EDF1EC;
  --sauge-100: #DCE5DB;
  --sauge-200: #BFCFC0;
  --sauge-300: #A9C0AC; /* 8.13 sur lin-900, accent en theme sombre */
  --sauge-400: #7E9885;
  --sauge-500: #5A7360; /* accent de reference, 5.18 sous le blanc */
  --sauge-600: #4A6150; /* 6.40 sur lin-50, pour le petit texte */
  --sauge-700: #3B4E40;
  --sauge-800: #2D3B31;

  /* Roles, theme clair */
  --paper:      var(--lin-50);
  --surface:    #FFFFFF;
  --surface-2:  var(--lin-100);
  --deep:       var(--lin-900);
  --on-deep:    var(--lin-50);
  --ink:        var(--lin-900);
  --ink-2:      var(--lin-600);
  --ink-3:      var(--lin-500);
  --line:       var(--lin-200);
  --line-2:     var(--lin-300);
  --accent:     var(--sauge-500);
  --accent-hover:var(--sauge-600);
  --accent-text:var(--sauge-600);
  --accent-wash:var(--sauge-50);
  --on-accent:  #FFFFFF;

  /* Ombres teintees a la teinte du fond, jamais du noir pur */
  --shadow-sm: 0 1px 2px rgba(31,36,32,.05);
  --shadow:    0 2px 6px rgba(31,36,32,.05), 0 14px 34px rgba(31,36,32,.07);
  --shadow-lg: 0 4px 10px rgba(31,36,32,.06), 0 26px 60px rgba(31,36,32,.11);

  /* Typographie. La serif porte les titres : une grotesque, meme bien
     dessinee, dit studio de design la ou il faut dire cabinet de soin. */
  --display: "Newsreader", Georgia, "Times New Roman", serif;
  --body:    "Instrument Sans", "Helvetica Neue", Arial, sans-serif;

  /* Rayons. Regle unique du site :
     boutons et pastilles en pilule, blocs et images a 20px,
     champs de formulaire a 12px. Aucune autre valeur. */
  --r-block: 20px;
  --r-field: 12px;

  /* Courbe unique pour tout le mouvement du site. Le site vend le calme :
     le mouvement est ample et lent plutot que vif et nombreux.        */
  --ease: cubic-bezier(.16, 1, .3, 1);

  --wrap: 1240px;

  /* Fleche des liens de renvoi, posee en masque pour suivre la couleur
     du texte sans avoir a repeter un SVG dans chaque lien du HTML. */
  --fleche: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 7.1h8.2L8 3.9 9 2.9 14 8l-5 5.1-1-1 3.2-3.2H3z'/%3E%3C/svg%3E");

  /* Hauteur minimale d'une cible tactile. 44px est le seuil au-dessous
     duquel un doigt rate la cible une fois sur trois.                 */
  --touche: 44px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper:      var(--lin-950);
    --surface:    #1B1F19;
    --surface-2:  #232720;
    --deep:       #232720;
    --on-deep:    var(--lin-100);
    --ink:        #EAEDE7; /* 15.32 sur paper */
    --ink-2:      #ADB3AB; /*  8.46 sur paper */
    --ink-3:      #8B928A; /*  5.67 sur paper */
    --line:       #2C312A;
    --line-2:     #3C4239;
    --accent:     var(--sauge-300);
    --accent-hover:var(--sauge-200);
    --accent-text:var(--sauge-300); /* 9.33 sur paper */
    --accent-wash:#1C2620;
    --on-accent:  var(--lin-950); /* 9.33 sur sauge-300 */
    --shadow-sm: 0 1px 2px rgba(0,0,0,.34);
    --shadow:    0 2px 6px rgba(0,0,0,.36), 0 14px 34px rgba(0,0,0,.34);
    --shadow-lg: 0 4px 10px rgba(0,0,0,.4), 0 26px 60px rgba(0,0,0,.46);
  }
}

/* ---------- 2. Base ---------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 400;
  font-variation-settings: "opsz" 44;
  letter-spacing: -.012em;
  line-height: 1.12;
  margin: 0;
  text-wrap: balance;
}
h1 { font-size: clamp(2.6rem, 6.2vw, 4.4rem); }
h2 { font-size: clamp(2rem, 4.4vw, 3.1rem); }
h3 { font-size: clamp(1.2rem, 2vw, 1.45rem); line-height: 1.25; }
p  { margin: 0; }

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

/* ---------- Grain ----------
   Un bruit tres faible pose sur toute la page. Personne ne le voit
   consciemment, mais il casse la surface parfaitement lisse de l'ecran :
   c'est ce qui donne l'impression de matiere plutot que de rendu. Il ne
   capte aucun clic et se pose au-dessus de tout, menu compris, sinon la
   texture s'arreterait au bord des blocs et ca se verrait.            */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 100;
  pointer-events: none;
  opacity: .038;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* Sur fond sombre, un bruit noir se voit deux fois plus : on l'allege. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) body::after { opacity: .05; mix-blend-mode: screen; }
}

/* ---------- 3. Primitives de mise en page ---------- */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: 24px;
}
@media (max-width: 767px) { .wrap { padding-inline: 20px; } }

.section { padding-block: clamp(72px, 11vw, 132px); }
.section--tight { padding-block: clamp(56px, 7vw, 88px); }

.lede {
  font-size: clamp(1.08rem, 1.5vw, 1.25rem);
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 58ch;
}
.body-copy { color: var(--ink-2); max-width: 62ch; }
.body-copy + .body-copy { margin-top: 1.1em; }

.eyebrow {
  display: inline-block;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: 22px;
}


/* ---------- 4. Boutons ----------
   Pilule, avec la fleche logee dans son propre disque au ras du
   bord interieur. Au survol le disque part en diagonale, ce qui
   donne la tension interne sans deformer le bouton.             */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 11px 11px 11px 26px;
  border: 0;
  border-radius: 999px;
  font-family: var(--body);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -.005em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color .5s var(--ease), color .5s var(--ease), transform .2s var(--ease);
}
.btn__ico {
  display: grid;
  place-items: center;
  width: 32px; height: 32px;
  flex: 0 0 32px;
  border-radius: 999px;
  transition: transform .5s var(--ease), background-color .5s var(--ease);
}
.btn__ico svg { width: 15px; height: 15px; }
.btn:hover .btn__ico { transform: translate3d(3px, -2px, 0); }
.btn:active { transform: scale(.978); }

.btn--primary { background: var(--accent); color: var(--on-accent); }
.btn--primary .btn__ico { background: rgba(255,255,255,.2); }
.btn--primary:hover { background: var(--accent-hover); }

.btn--ghost {
  background: transparent;
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--line-2);
}
.btn--ghost .btn__ico { background: var(--surface-2); }
.btn--ghost:hover { background: var(--surface-2); }


.btn-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }

/* Lien de renvoi. Pastille a filet fin plutot que lien souligne : le corps
   de texte ne bouge pas, mais la forme le rend reperable dans une page
   longue au lieu de se fondre dans le paragraphe voisin. La fleche avance
   au survol, comme sur les boutons, pour que le site n'ait qu'un geste.  */
.tlink {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-height: var(--touche);
  padding: 9px 18px;
  border-radius: 999px;
  color: var(--accent-text);
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
  box-shadow: inset 0 0 0 1px var(--line-2);
  transition: box-shadow .45s var(--ease), background-color .45s var(--ease);
}
.tlink::after {
  content: "";
  width: 13px; height: 13px;
  flex: none;
  background: currentColor;
  transition: transform .45s var(--ease);
  -webkit-mask: var(--fleche) center / contain no-repeat;
  mask: var(--fleche) center / contain no-repeat;
}
.tlink:hover {
  box-shadow: inset 0 0 0 1px var(--accent);
  background: var(--accent-wash);
}
.tlink:hover::after { transform: translate3d(3px, 0, 0); }

/* ---------- 5. En-tete flottante ----------
   Barre detachee du haut, en pilule. Elle se condense au
   defilement grace a une sentinelle observee, pas a un
   ecouteur de scroll.                                          */
.sentinel { position: absolute; top: 0; height: 1px; width: 100%; pointer-events: none; }

.nav-shell {
  position: sticky;
  top: 0;
  z-index: 40;
  padding: 18px 24px 0;
  transition: padding .55s var(--ease);
}
.nav-shell.is-stuck { padding-top: 10px; }
@media (max-width: 767px) { .nav-shell { padding: 12px 16px 0; } }

.nav {
  max-width: var(--wrap);
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 9px 9px 9px 22px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--paper) 78%, transparent);
  box-shadow: inset 0 0 0 1px var(--line);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  transition: box-shadow .55s var(--ease), background-color .55s var(--ease);
}
.nav-shell.is-stuck .nav {
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  box-shadow: inset 0 0 0 1px var(--line), var(--shadow);
}
@supports not (backdrop-filter: blur(1px)) {
  .nav { background: var(--paper); }
}

.brand {
  display: inline-flex;
  align-items: center;
  /* Le nom est coupe en deux par un <span> pour teinter la seconde
     moitie. En flex, l'espace entre les deux mots disparait : il est
     rendu par le gap.                                              */
  gap: .3em;
  min-height: var(--touche);
  font-family: var(--display);
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -.01em;
  text-decoration: none;
  color: var(--ink);
  margin-right: auto;
  white-space: nowrap;
}
.brand span { color: var(--accent-text); }

.nav__links { display: flex; align-items: center; gap: 4px; }
.nav__links a {
  padding: 8px 14px;
  border-radius: 999px;
  font-size: 14.5px;
  font-weight: 500;
  color: var(--ink-2);
  text-decoration: none;
  white-space: nowrap;
  transition: color .35s var(--ease), background-color .35s var(--ease);
}
.nav__links a:hover { color: var(--ink); background: var(--surface-2); }
.nav__links a[aria-current="page"] { color: var(--ink); }

.nav .btn { padding: 9px 9px 9px 20px; font-size: 14.5px; }
.nav .btn__ico { width: 28px; height: 28px; flex-basis: 28px; }

/* Bouton d'appel, visible uniquement quand la navigation est repliee.
   Sur un site de cabinet, appeler est l'action la plus demandee depuis
   un telephone, et l'en-tete repliee ne laissait que le bouton menu :
   il fallait ouvrir le menu, aller sur Contact, puis chercher le numero. */
.nav__call {
  display: none;
  place-items: center;
  width: var(--touche); height: var(--touche);
  flex: 0 0 var(--touche);
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  text-decoration: none;
  transition: background-color .35s var(--ease), transform .2s var(--ease);
}
.nav__call svg { width: 18px; height: 18px; }
.nav__call:hover { background: var(--accent-hover); }
.nav__call:active { transform: scale(.94); }

/* Bouton menu : les deux barres pivotent pour former une croix */
.burger {
  display: none;
  width: var(--touche); height: var(--touche);
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--surface-2);
  cursor: pointer;
  position: relative;
}
.burger i {
  position: absolute;
  left: 14px;
  width: 16px; height: 1.5px;
  background: var(--ink);
  border-radius: 2px;
  transition: transform .5s var(--ease), opacity .3s var(--ease);
}
.burger i:nth-child(1) { top: 19px; }
.burger i:nth-child(2) { top: 24px; }
.burger[aria-expanded="true"] i:nth-child(1) { transform: translateY(2.5px) rotate(45deg); }
.burger[aria-expanded="true"] i:nth-child(2) { transform: translateY(-2.5px) rotate(-45deg); }

.drawer {
  position: fixed;
  inset: 0;
  z-index: 39;
  display: grid;
  align-content: center;
  gap: 4px;
  padding: 96px 28px 32px;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(28px);
  -webkit-backdrop-filter: blur(28px);
  visibility: hidden;
  opacity: 0;
  transition: opacity .45s var(--ease), visibility .45s var(--ease);
}
.drawer.is-open { visibility: visible; opacity: 1; }
.drawer a {
  font-family: var(--display);
  font-size: clamp(1.9rem, 8vw, 2.5rem);
  font-weight: 400;
  letter-spacing: -.012em;
  color: var(--ink);
  text-decoration: none;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
  opacity: 0;
  transform: translate3d(0, 22px, 0);
  transition: opacity .5s var(--ease), transform .5s var(--ease);
}
.drawer.is-open a { opacity: 1; transform: none; }
.drawer.is-open a:nth-child(1) { transition-delay: .07s; }
.drawer.is-open a:nth-child(2) { transition-delay: .12s; }
.drawer.is-open a:nth-child(3) { transition-delay: .17s; }
.drawer.is-open a:nth-child(4) { transition-delay: .22s; }
.drawer.is-open a:nth-child(5) { transition-delay: .27s; }

@media (max-width: 1023px) {
  .nav__links, .nav > .btn { display: none; }
  .burger, .nav__call { display: grid; }
  /* Deux pastilles de 44px cote a cote : l'ecart de 24px de l'ordinateur
     pousserait la barre au-dela de la largeur d'un telephone. */
  .nav { gap: 8px; padding: 8px 8px 8px 18px; }
}

/* ---------- 6. Cadres a double bord ----------
   Une coque exterieure avec son filet, un noyau interieur avec
   son propre rayon calcule pour que les courbes restent
   concentriques. C'est ce qui donne l'impression de matiere.    */
.frame {
  padding: 8px;
  border-radius: calc(var(--r-block) + 8px);
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line), var(--shadow);
}
.frame > * {
  border-radius: var(--r-block);
  overflow: hidden;
  display: block;
}
.frame img { width: 100%; height: 100%; object-fit: cover; }

.card {
  padding: 30px;
  border-radius: var(--r-block);
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line), var(--shadow-sm);
}
@media (max-width: 767px) { .card { padding: 24px; } }

/* ---------- 7. Banniere d'accueil ---------- */
.hero { padding-block: clamp(48px, 7vw, 92px) clamp(72px, 10vw, 118px); }
.hero__grid {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  gap: clamp(32px, 5vw, 68px);
  align-items: center;
}
.hero h1 { max-width: 13ch; }
.hero .lede { margin-top: 24px; max-width: 44ch; }
.hero .btn-row { margin-top: 34px; }
.hero__media { position: relative; }
.hero__media .frame > div { aspect-ratio: 4 / 5; }
/* La banniere porte desormais le portrait de la praticienne et non une photo
   de geste : c'est un visage qui regarde l'objectif qui fait qu'on reste, sur
   un site ou l'on choisit quelqu'un avant de choisir un soin. La proportion
   passe donc en 4/5, et la colonne de texte s'est allongee d'autant.       */

/* La pastille posee sur le bord de la photo */
.badge {
  position: absolute;
  left: -22px;
  bottom: 34px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 20px 13px 15px;
  border-radius: 999px;
  background: var(--deep);
  color: var(--on-deep);
  box-shadow: var(--shadow-lg);
}
.badge svg { width: 19px; height: 19px; flex: none; color: var(--sauge-300); }
.badge b { font-size: 14px; font-weight: 600; letter-spacing: -.01em; }
.badge span { display: block; font-size: 12.5px; color: var(--lin-400); }

@media (max-width: 899px) {
  .hero__grid { grid-template-columns: 1fr; gap: 40px; }
  .hero h1 { max-width: 18ch; }
  .hero__media .frame > div { aspect-ratio: 5 / 5; }
  .badge { left: 12px; bottom: 12px; }
}

/* ---------- 10. La praticienne ----------
   Sur un site de soin, c'est la personne qu'on choisit avant la
   prestation : on ne cherche pas un massage, on cherche quelqu'un a
   qui confier son dos. Le bloc porte donc un visage, un nom, un
   parcours verifiable et une phrase signee, et non un paragraphe
   anonyme au milieu d'une page.

   Pour un cabinet a plusieurs praticiens, voir le README : le bloc se
   duplique et la grille passe en colonnes.                          */
.praticien {
  display: grid;
  grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr);
  gap: clamp(30px, 5vw, 68px);
  align-items: center;
}
.praticien__media .frame > div { aspect-ratio: 4 / 5; }
.praticien__nom {
  font-family: var(--display);
  font-size: clamp(1.7rem, 3vw, 2.2rem);
  font-weight: 400;
  letter-spacing: -.012em;
  line-height: 1.1;
  margin: 0;
}
.praticien__role {
  display: block;
  margin-top: 8px;
  font-size: 15px;
  color: var(--accent-text);
}
.praticien .body-copy { margin-top: 22px; }
.praticien .facts { margin-top: 30px; }
@media (max-width: 899px) {
  .praticien { grid-template-columns: 1fr; gap: 32px; }
  /* En une colonne, un portrait en 4/5 occupe presque tout l'ecran
     avant que le texte commence. On le recadre plus large.        */
  .praticien__media .frame > div { aspect-ratio: 5 / 4; }
}

/* Signature d'une prise de parole a la premiere personne. Le site est
   ecrit en "je" d'un bout a l'autre : sans signature, ce "je" flotte. */
.signature {
  margin-top: 20px;
  font-size: 15px;
  font-weight: 500;
  color: var(--accent-text);
}

/* ---------- 11. Fin de page ---------- */
.closing { background: var(--surface-2); text-align: center; }
.closing .mot { text-align: left; background: var(--surface); }
@media (max-width: 599px) { .closing .mot { text-align: center; } }
.closing h2 { max-width: 15ch; margin-inline: auto; }
.closing .lede { margin: 22px auto 0; text-align: center; }
.closing .btn-row { justify-content: center; margin-top: 34px; }

/* ---------- 12. En-tete de page interieure ---------- */
.pagehead { padding-block: clamp(44px, 6vw, 76px) clamp(36px, 5vw, 56px); }
.pagehead h1 { max-width: 15ch; font-size: clamp(2.3rem, 5vw, 3.6rem); }
.pagehead .lede { margin-top: 22px; }

/* ---------- 13. Les soins ---------- */
.soin {
  display: flex;
  flex-direction: column;
  border-radius: var(--r-block);
  overflow: hidden;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line), var(--shadow-sm);
  transition: box-shadow .55s var(--ease);
}
.soin:hover { box-shadow: inset 0 0 0 1px var(--line-2), var(--shadow); }
.soin__img { aspect-ratio: 16 / 10; overflow: hidden; }
.soin__img img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.1s var(--ease); }
.soin:hover .soin__img img { transform: scale(1.04); }
.soin__body { padding: 26px 28px 28px; display: flex; flex-direction: column; flex: 1; }
.soin__meta { font-size: 13px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 10px; }
.soin p { font-size: 15.5px; color: var(--ink-2); margin-top: 10px; }
.soin__price {
  margin-top: auto;
  padding-top: 20px;
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 500;
  letter-spacing: -.01em;
}
.soin__price em { font-family: var(--body); font-size: 14px; font-style: normal; font-weight: 400; color: var(--ink-3); }
.soin--wide { flex-direction: row; }
.soin--wide .soin__img { flex: 0 0 44%; aspect-ratio: auto; }
.soin--wide .soin__body { padding: 34px 38px; justify-content: center; }
@media (max-width: 899px) {
  .soin--wide { flex-direction: column; }
  .soin--wide .soin__img { flex: none; aspect-ratio: 16 / 10; }
  .soin--wide .soin__body { padding: 26px 28px 28px; }
}

/* ---------- 14. Liste des soins et des prix ----------
   Remplace les cartes a photo sur les pages qui doivent rester sobres.
   Le filet du haut suffit a separer, sans cadre ni ombre : c'est ce qui
   permet d'aligner cinq soins sans que la page double de longueur.       */
.tarifs { display: grid; }
.tarifs__ligne {
  display: grid;
  gap: .3rem 1.5rem;
  padding: 22px 0;
  border-top: 1px solid var(--line);
  align-items: baseline;
}
.tarifs__ligne:last-child { border-bottom: 1px solid var(--line); }
@media (min-width: 760px) {
  .tarifs__ligne { grid-template-columns: 1.05fr 1.5fr auto; }
}
.tarifs__nom { font-family: var(--display); font-size: 1.24rem; font-weight: 500; letter-spacing: -.01em; }
.tarifs__duree { display: block; font-family: var(--body); font-size: 13px; font-weight: 400; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); margin-top: 5px; }
.tarifs__quoi { color: var(--ink-2); font-size: 15.5px; }
.tarifs__prix { font-family: var(--display); font-size: 1.24rem; font-weight: 500; letter-spacing: -.01em; white-space: nowrap; }

/* ---------- 15. Forfaits ---------- */
.forfaits { display: grid; grid-template-columns: 1.25fr 1fr; gap: 18px; align-items: stretch; }
.forfait--lead { background: var(--accent-wash); box-shadow: inset 0 0 0 1px var(--sauge-100); }
@media (prefers-color-scheme: dark) {
  /* Sans cette regle, la carte garde le lisere clair du theme clair et
     tranche violemment sur le fond sombre. Mesure avant correction :
     rgb(220,229,219) sur rgb(28,38,32), quand la carte voisine a
     rgb(44,49,42).                                                    */
  :root:not([data-theme="light"]) .forfait--lead { box-shadow: inset 0 0 0 1px var(--line-2); }
}
.forfait__price { font-family: var(--display); font-size: 2.5rem; font-weight: 400; letter-spacing: -.012em; line-height: 1; margin: 16px 0 6px; }
.forfait__was { font-size: 14px; color: var(--ink-3); }
/* Sur le lavis sauge, --ink-3 donne 4.61 : il passe, mais c'est le couple
   le plus serre du site. On garde --ink-2 ici, qui donne 6.06, pour que la
   marge ne depende pas d'un arrondi.                                       */
.forfait--lead .forfait__was { color: var(--ink-2); }
@media (max-width: 899px) { .forfaits { grid-template-columns: 1fr; } }

/* ---------- 16. Deroule de la seance ---------- */
.steps { display: grid; gap: 0; margin-top: 8px; }
.step {
  display: grid;
  grid-template-columns: 168px minmax(0, 1fr);
  gap: clamp(20px, 4vw, 56px);
  padding-block: 34px;
  border-top: 1px solid var(--line);
}
.step:last-child { border-bottom: 1px solid var(--line); }
.step__when { font-size: 14px; font-weight: 500; color: var(--accent-text); padding-top: 4px; }
.step h3 { margin-bottom: 10px; }
@media (max-width: 767px) { .step { grid-template-columns: 1fr; gap: 8px; padding-block: 26px; } }

/* ---------- 17. Questions frequentes ---------- */
.faq { border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 24px 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--display);
  font-size: clamp(1.1rem, 1.7vw, 1.3rem);
  font-weight: 400;
  letter-spacing: -.008em;
  transition: color .35s var(--ease);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--accent-text); }
.faq summary::after {
  content: "";
  margin-left: auto;
  flex: none;
  width: 11px; height: 11px;
  border-right: 1.6px solid currentColor;
  border-bottom: 1.6px solid currentColor;
  transform: translateY(-3px) rotate(45deg);
  transition: transform .45s var(--ease);
}
.faq details[open] summary::after { transform: translateY(1px) rotate(-135deg); }
.faq__answer { padding: 0 0 26px; color: var(--ink-2); max-width: 66ch; }
.faq details[open] .faq__answer { animation: unfold .5s var(--ease) both; }
@keyframes unfold { from { opacity: 0; transform: translate3d(0, -8px, 0); } }
@media (prefers-reduced-motion: reduce) { .faq details[open] .faq__answer { animation: none; } }

/* ---------- 18. Galerie du cabinet ---------- */
.gallery { display: grid; grid-template-columns: repeat(6, 1fr); gap: 16px; }
.gallery figure { margin: 0; border-radius: var(--r-block); overflow: hidden; }
.gallery img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.2s var(--ease); }
.gallery figure:hover img { transform: scale(1.05); }
/* Trois cellules : une large en tete, deux en dessous. Les proportions
   different d'une cellule a l'autre pour que la galerie ne ressemble pas
   a une planche contact.                                                */
.gallery figure:nth-child(1) { grid-column: span 6; aspect-ratio: 21 / 9; }
.gallery figure:nth-child(2) { grid-column: span 2; aspect-ratio: 3 / 4; }
.gallery figure:nth-child(3) { grid-column: span 4; aspect-ratio: 3 / 2; }
@media (max-width: 767px) {
  .gallery { grid-template-columns: 1fr 1fr; }
  .gallery figure { grid-column: span 1 !important; aspect-ratio: 1 / 1 !important; }
}

/* ---------- 19. Colonnes de texte ---------- */
.duo {
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  gap: clamp(28px, 5vw, 76px);
  align-items: start;
}
.duo--even { grid-template-columns: 1fr 1fr; }
@media (max-width: 899px) { .duo, .duo--even { grid-template-columns: 1fr; gap: 28px; } }

.facts { display: grid; gap: 0; }
.facts div { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 20px; padding-block: 15px; border-top: 1px solid var(--line); font-size: 15.5px; }
.facts div:last-child { border-bottom: 1px solid var(--line); }
.facts dt { color: var(--ink-3); margin: 0; }
.facts dd { margin: 0; color: var(--ink); }
@media (max-width: 599px) { .facts div { grid-template-columns: 1fr; gap: 2px; } }

/* ---------- 20. Formulaire ---------- */
.form { display: grid; gap: 18px; }
.field { display: grid; gap: 7px; }
.field label { font-size: 14px; font-weight: 500; color: var(--ink); }
.field .hint { font-size: 13.5px; color: var(--ink-3); }
.field input, .field select, .field textarea {
  font-family: var(--body);
  font-size: 16px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-field);
  padding: 12px 14px;
  width: 100%;
  transition: border-color .35s var(--ease), box-shadow .35s var(--ease);
}
.field textarea { min-height: 132px; resize: vertical; }
.field input::placeholder, .field textarea::placeholder { color: var(--ink-3); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
.field--pair { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 599px) { .field--pair { grid-template-columns: 1fr; } }
.form__note { font-size: 13.5px; color: var(--ink-3); max-width: 52ch; }

/* ---------- 21. Pied de page ---------- */
.foot { background: var(--deep); color: var(--on-deep); padding-block: clamp(56px, 7vw, 82px) 34px; }
.foot__grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: clamp(28px, 4vw, 56px); }
.foot .brand { color: var(--on-deep); font-size: 20px; }
.foot h4 { font-size: 13px; letter-spacing: .14em; text-transform: uppercase; color: var(--lin-400); font-weight: 500; margin: 0 0 16px; }
.foot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.foot a { color: var(--lin-300); text-decoration: none; font-size: 15px; transition: color .35s var(--ease); }
.foot a:hover { color: var(--on-deep); }
.foot__note { margin-top: 44px; padding-top: 22px; border-top: 1px solid rgba(255,255,255,.1); display: flex; flex-wrap: wrap; gap: 8px 22px; font-size: 13.5px; color: var(--lin-400); }
@media (max-width: 767px) {
  .foot__grid { grid-template-columns: 1fr; gap: 32px; }
  /* Mesures a 19px de haut : au doigt, on tombe entre deux liens. La
     hauteur vient de la zone touchable, l'ecart de la liste disparait
     donc pour ne pas etirer le pied de page.                          */
  .foot ul { gap: 0; }
  .foot li a { display: inline-flex; align-items: center; min-height: var(--touche); }
  .foot__note { font-size: 14px; }
}

/* ---------- 22. Entrees au defilement ----------
   La classe n'est posee que si le JavaScript tourne, sinon
   tout reste visible. Elle ne touche que transform et opacity. */
.js .reveal { opacity: 0; transform: translate3d(0, 26px, 0); }
@media (prefers-reduced-motion: no-preference) {
  .js .reveal { transition: opacity .8s var(--ease), transform .8s var(--ease); }
}
.js .reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .js .reveal { opacity: 1; transform: none; } }

/* ---------- 23. Divers ---------- */
.skip {
  position: absolute; left: 12px; top: -60px; z-index: 60;
  display: inline-flex; align-items: center; min-height: var(--touche);
  padding: 10px 18px; border-radius: 999px;
  background: var(--accent); color: var(--on-accent);
  font-size: 14px; font-weight: 600; text-decoration: none;
  transition: top .3s var(--ease);
}
.skip:focus { top: 12px; }

/* ---------- 24. Telephone ----------
   Ce que la mise en page fluide ne regle pas toute seule. Les valeurs
   viennent d'une mesure au navigateur en 375px de large, pas d'une
   estimation : chaque ligne corrige un element qui tombait sous le
   seuil tactile de 44px ou sous 14px de corps.                       */
@media (max-width: 767px) {
  /* Sur un telephone tenu en paysage, l'encoche mange la marge laterale */
  .wrap { padding-inline: max(20px, env(safe-area-inset-left)) max(20px, env(safe-area-inset-right)); }

  /* Textes secondaires remontes : sous 14px, on lit en plissant les yeux */
  .eyebrow      { font-size: 12.5px; }
  .badge span   { font-size: 13.5px; }
  .soin__meta,
  .tarifs__duree { font-size: 13.5px; }
  .field .hint,
  .form__note   { font-size: 14px; }

  /* Un lien de texte dans un paragraphe reste une cible : on elargit
     la zone sans ecarter les lignes, en debordant sur les interlignes. */
  .tlink { display: inline-block; padding-block: 10px; }

  /* Le telephone et l'e-mail de la page Contact vivent dans une liste de
     faits, pas dans le pied de page : ils ont besoin de la meme hauteur.
     Ce sont les deux liens les plus cliques du site.                    */
  .facts dd a { display: inline-flex; align-items: center; min-height: var(--touche); }

  /* La pastille d'agrement chevauchait le bord de la photo */
  .badge { left: 10px; right: 10px; bottom: 10px; }
}

/* Sur les ecrans tactiles, l'agrandissement des images au survol ne se
   declenche jamais et laisse la photo figee a mi-course apres un appui. */
@media (hover: none) {
  .soin:hover .soin__img img,
  .gallery figure:hover img { transform: none; }
}

/* ---------- 25. Bandeau de chiffres ----------
   Quatre reperes, pas plus. Les nombres sont animes a l'entree, ce qui
   fait qu'on les lit : un chiffre fixe se saute, un chiffre qui monte
   retient l'oeil une seconde.                                        */
.chiffres {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(20px, 4vw, 48px);
  padding-block: clamp(34px, 4vw, 48px);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.chiffre__n {
  font-family: var(--display);
  font-size: clamp(2.1rem, 4vw, 2.9rem);
  font-weight: 400;
  letter-spacing: -.012em;
  line-height: 1;
  color: var(--accent-text);
}
.chiffre__q { display: block; margin-top: 9px; font-size: 14.5px; color: var(--ink-2); max-width: 22ch; }
@media (max-width: 767px) { .chiffres { grid-template-columns: 1fr 1fr; gap: 26px 20px; } }

/* ---------- 26. Avis ----------
   Une piste qui defile en continu, pleine largeur, placee juste apres
   les prix : c'est la que l'objection arrive, donc c'est la que la
   reponse doit etre. Elle s'arrete au survol et a la mise au point,
   sinon on ne peut pas lire une carte qui bouge.

   L'ecart est porte par la marge des cartes et non par un gap : avec
   un gap, la piste dupliquee ne boucle pas rond et le raccord saute
   a chaque tour.                                                     */
.avis-bande { overflow: hidden; padding-block: clamp(40px, 5vw, 60px); }
.avis-piste {
  display: flex;
  width: max-content;
  /* Le decalage est calcule a partir du nombre de cartes uniques et non
     pose a -50%. Sur un conteneur flex, la largeur max-content que le
     navigateur retient n'est pas la somme des largeurs fixes des cartes :
     mesure faite, 4656 px la ou la somme donne 4176, et le raccord sautait
     de 480 px a chaque tour. Ici la distance est exacte par construction. */
  --carte: 330px;
  --ecart: 18px;
  --uniques: 6;
}
.avis-piste > * { margin-right: var(--ecart); }
@media (prefers-reduced-motion: no-preference) {
  .avis-piste { animation: defile 78s linear infinite; }
  .avis-bande:hover .avis-piste,
  .avis-piste:focus-within { animation-play-state: paused; }
}
@keyframes defile {
  to { transform: translate3d(calc(-1 * var(--uniques) * (var(--carte) + var(--ecart))), 0, 0); }
}

.avis {
  width: var(--carte);
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 13px;
  padding: 24px 26px 22px;
  border-radius: var(--r-block);
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line), var(--shadow-sm);
}
.avis p { font-size: 15px; line-height: 1.6; color: var(--ink-2); }
.avis__qui { display: flex; align-items: center; gap: 11px; margin-top: auto; padding-top: 4px; }
.avis__rond {
  display: grid;
  place-items: center;
  width: 38px; height: 38px;
  flex: none;
  border-radius: 999px;
  background: var(--accent-wash);
  color: var(--accent-text);
  font-size: 13.5px;
  font-weight: 600;
}
.avis__nom { font-size: 14.5px; font-weight: 500; color: var(--ink); }
.avis__quoi { display: block; font-size: 13px; color: var(--ink-3); margin-top: 1px; }

@media (max-width: 480px) { .avis-piste { --carte: 272px; --ecart: 14px; } }

.etoiles { display: inline-flex; gap: 2px; color: var(--accent); }
.etoiles svg { width: 15px; height: 15px; }
.note { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.note__n { font-family: var(--display); font-size: 1.7rem; font-weight: 400; letter-spacing: -.012em; }
.note__q { font-size: 14.5px; color: var(--ink-3); }

/* ---------- 27. Le mot de la fin ----------
   Une prise de parole signee, avec le visage a cote. Sans le visage,
   c'est un paragraphe de plus ; avec, c'est quelqu'un qui parle.     */
.mot {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: clamp(20px, 3vw, 34px);
  align-items: center;
  max-width: 720px;
  margin-inline: auto;
  padding: clamp(28px, 4vw, 42px);
  border-radius: var(--r-block);
  background: var(--accent-wash);
}
.mot img {
  width: 96px; height: 96px;
  border-radius: 999px;
  object-fit: cover;
  box-shadow: 0 0 0 4px var(--surface);
}
.mot p { font-size: clamp(1.02rem, 1.4vw, 1.14rem); line-height: 1.62; color: var(--ink); }
.mot__sign {
  display: block;
  margin-top: 14px;
  font-family: var(--display);
  font-style: italic;
  font-size: 1.22rem;
  color: var(--accent-text);
}
.mot__sign small { display: block; font-family: var(--body); font-style: normal; font-size: 13.5px; color: var(--ink-3); margin-top: 3px; }
@media (max-width: 599px) { .mot { grid-template-columns: 1fr; text-align: center; justify-items: center; } }

/* ---------- 28. Bandeau de demonstration ----------
   Le site ne porte le nom d'aucune cliente : il est livre tel quel a
   tout le monde. Cette bande dit ce qu'il est, sans casser la lecture. */
.demo-bande {
  background: var(--deep);
  color: var(--on-deep);
  font-size: 13.5px;
  text-align: center;
  padding: 11px 20px;
}
.demo-bande b { font-weight: 600; }
.demo-bande a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ---------- 29. Titre revele mot par mot ----------
   Chaque mot monte depuis sous une ligne de masque. Lent et ample :
   sur un site qui vend le calme, un mouvement vif dit l'inverse du
   propos. Sans JavaScript, aucune de ces classes n'existe et le titre
   s'affiche normalement.                                             */
.mot-env { display: inline-block; overflow: hidden; vertical-align: bottom; }
.mot-int { display: inline-block; transform: translate3d(0, 105%, 0); }
@media (prefers-reduced-motion: no-preference) {
  .mot-int { transition: transform 1.15s var(--ease); }
}
h1.est-la .mot-int { transform: none; }

/* ---------- 30. Parallaxe ----------
   Porte par la ligne de temps de defilement du navigateur, donc sans
   une seule ligne de JavaScript et sans ecouteur de scroll. La ou elle
   n'est pas reconnue, la photo ne bouge pas et rien d'autre ne change. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .praticien__media img,
    .gallery figure:nth-child(1) img {
      animation: glisse linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
    }
    @keyframes glisse {
      from { transform: translate3d(0, -3.5%, 0) scale(1.08); }
      to   { transform: translate3d(0,  3.5%, 0) scale(1.08); }
    }
  }
}

/* ---------- 31. Prise de rendez-vous en ligne ----------
   Demonstration de l'option facturee en supplement. Tout est local :
   aucun service exterieur, aucun traceur, et les dates sont calculees
   a l'ouverture de la page. Des creneaux ecrits en dur seraient perimes
   le mois suivant, sur un site qui reste en ligne des annees.        */
.rdv {
  padding: clamp(22px, 3vw, 30px);
  border-radius: var(--r-block);
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line), var(--shadow-sm);
}
.rdv__etape { font-size: 13px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 12px; }
.rdv__etape + * { margin-bottom: 26px; }

.rdv__soins { display: grid; gap: 8px; }
.rdv__soin {
  display: flex; align-items: baseline; gap: 10px;
  width: 100%;
  min-height: var(--touche);
  padding: 11px 16px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: transparent;
  font: inherit; font-size: 15px;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
  transition: border-color .4s var(--ease), background-color .4s var(--ease);
}
.rdv__soin small { margin-left: auto; color: var(--ink-3); font-size: 13.5px; white-space: nowrap; }
.rdv__soin:hover { border-color: var(--accent); }
.rdv__soin[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-wash); }
.rdv__soin[aria-pressed="true"] small { color: var(--accent-text); }

.rdv__jours { display: grid; grid-template-columns: repeat(auto-fit, minmax(78px, 1fr)); gap: 8px; }
.rdv__jour {
  display: grid; gap: 2px;
  min-height: 66px;
  padding: 10px 6px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-field);
  background: transparent;
  font: inherit;
  color: var(--ink);
  cursor: pointer;
  text-align: center;
  transition: border-color .4s var(--ease), background-color .4s var(--ease);
}
.rdv__jour b { font-family: var(--display); font-size: 1.25rem; font-weight: 500; line-height: 1; }
.rdv__jour span { font-size: 12px; color: var(--ink-3); text-transform: capitalize; }
.rdv__jour:hover { border-color: var(--accent); }
.rdv__jour[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-wash); }
.rdv__jour[aria-pressed="true"] span { color: var(--accent-text); }

.rdv__heures { display: flex; flex-wrap: wrap; gap: 8px; }
.rdv__heure {
  min-height: var(--touche);
  padding: 10px 18px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: transparent;
  font: inherit; font-size: 15px;
  color: var(--ink);
  cursor: pointer;
  transition: border-color .4s var(--ease), background-color .4s var(--ease), color .4s var(--ease);
}
.rdv__heure:hover { border-color: var(--accent); }
.rdv__heure[aria-pressed="true"] { border-color: var(--accent); background: var(--accent); color: var(--on-accent); }

.rdv__bilan {
  margin-top: 26px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
}
.rdv__bilan p { font-size: 15px; color: var(--ink-2); }
.rdv__bilan b { color: var(--ink); font-weight: 600; }
.rdv__bilan .btn { margin-left: auto; }
.rdv__bilan .btn[disabled] { opacity: .42; pointer-events: none; }
@media (max-width: 599px) { .rdv__bilan .btn { margin-left: 0; width: 100%; justify-content: space-between; } }
