/* ═══════════════════════════════════════════════════════════════
   Sacha Barchechath — Kinésithérapeute · Uccle
   Design « cabinet éditorial, chaleureux », aux couleurs de la carte de
   visite (reference/carte-de-visite.webp) : vert profond, crème et or.
     · le vert (--ink)    → l'encre, les fonds sombres, les boutons,
                            l'action : c'est la couleur de la carte
     · l'or    (--brass)  → l'éditorial, le précieux : filets, numéros,
                            dates, labels, signature
     · la crème (--paper) → le papier
   Fraunces / Instrument Sans / Spline Sans Mono, et Mrs Saint Delafield
   pour la signature manuscrite.
   ═══════════════════════════════════════════════════════════════ */

:root {
  /* Fonds — la crème de la carte, du plus clair au plus profond.
     Jamais de blanc pur : la carte n'en a pas. */
  --paper:      #F3EDDF;   /* crème : le papier de la carte */
  --paper-2:    #E9E0CC;   /* beige : les sections teintées */
  --paper-3:    #FBF8F1;   /* crème claire : les respirations */

  /* Encres — le vert profond de la carte, jamais un noir */
  --ink:        #063E40;   /* texte, fonds sombres, boutons */
  --ink-2:      #164B4C;   /* texte secondaire */
  --ink-3:      #032A2B;   /* le plus profond : appel final, pied de page */
  --ink-soft:   rgba(6, 62, 64, .09);   /* le vert en teinte : puces, fonds d'icônes */
  --muted:      #4E6866;   /* gris-vert : tient 4,5:1 jusque sur le beige */

  /* Or — le précieux de la carte : filets, numéros, dates, labels,
     signature. Trois tons, calés sur le contraste et non sur le goût.
     L'or imprimé de la carte (#B8944C) ne tient que 2,4:1 sur la crème :
     à l'écran, il faut l'assombrir dès qu'il porte du texte.
       --brass       grands caractères et interface sur fond clair
                     (3,1:1 sur la crème, 3,4:1 sur la crème claire) ;
       --brass-deep  petit texte sur fond clair (4,6:1 jusque sur le beige,
                     le fond clair le plus exigeant du site) ;
       --brass-light petit texte sur le vert (6,3:1) : c'est là que l'or
                     brille, comme la signature au recto de la carte. */
  --brass:       #A28243;
  --brass-deep:  #775F31;
  --brass-light: #D6B979;
  --brass-soft:  rgba(162, 130, 67, .15);

  --line:       rgba(6, 62, 64, .16);
  --line-dark:  rgba(243, 237, 223, .18);
  --paper-on-dark: #F3EDDF;
  --muted-on-dark: rgba(243, 237, 223, .72);

  --font-display: "Fraunces", "Georgia", serif;
  --font-body:    "Instrument Sans", "Segoe UI", system-ui, sans-serif;
  --font-mono:    "Spline Sans Mono", "Consolas", monospace;
  --font-script:  "Mrs Saint Delafield", "Brush Script MT", cursive;

  --fs-hero: clamp(2.7rem, 7vw + .6rem, 5.4rem);
  --fs-h2:   clamp(1.9rem, 3.2vw + .8rem, 3.1rem);
  --fs-h3:   clamp(1.12rem, .6vw + 1rem, 1.3rem);

  --wrap: 1160px;
  --pad-section: clamp(4.5rem, 10vw, 8.5rem);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
}

/* ── Base ─────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

/* Les grands titres se portent en Fraunces très léger : c'est là que se joue
   l'élégance éditoriale. Les h3, plus petits, gardent du corps pour rester
   lisibles. */
h1, h2, h3 { margin: 0; font-family: var(--font-display); font-weight: 420; line-height: 1.08; letter-spacing: -.015em; }
h1, h2 { font-weight: 330; letter-spacing: -.022em; line-height: 1.06; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
em { font-style: italic; }
strong { font-weight: 600; }
svg { display: block; }

::selection { background: var(--ink); color: var(--paper); }

:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 3px;
  border-radius: 2px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: fixed; top: -100%; left: 1rem; z-index: 200;
  padding: .6rem 1rem;
  background: var(--ink); color: var(--paper);
  border-radius: 0 0 .5rem .5rem;
  font-size: .9rem;
  transition: top .25s var(--ease-out);
}
.skip-link:focus { top: 0; }

.wrap {
  width: min(var(--wrap), 100% - clamp(2.5rem, 8vw, 5rem));
  margin-inline: auto;
}

/* Grain — texture papier sur tout le site (statique : coût nul) */
.grain {
  position: fixed; inset: 0; z-index: 90;
  pointer-events: none;
  opacity: .055;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Barre de progression de lecture */
.progress {
  position: fixed; top: 0; left: 0; right: 0; z-index: 150;
  height: 2px;
  background: transparent;
}
.progress span {
  display: block; height: 100%; width: 100%;
  background: var(--brass);
  transform: scaleX(0);
  transform-origin: 0 50%;
}

/* ── Éléments partagés ───────────────────────────────────── */

.eyebrow {
  display: flex; align-items: center; gap: .65rem;
  font-family: var(--font-mono);
  font-size: .78rem;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
}
.eyebrow-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--brass);
  animation: dot-pulse 2.4s ease-in-out infinite;
}
@keyframes dot-pulse {
  0%, 100% { box-shadow: 0 0 0 0 var(--brass-soft); }
  50%      { box-shadow: 0 0 0 7px var(--brass-soft); }
}
.sec-num {
  display: inline-block;
  margin-right: .8rem; padding-right: .8rem;
  border-right: 1px solid var(--line);
  color: var(--brass-deep);
}
.title-dot { color: var(--brass); }
.q-mark { color: var(--brass); font-style: italic; }

.sec-head { max-width: 40rem; margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.sec-head h2 { font-size: var(--fs-h2); margin-top: 1.1rem; text-wrap: balance; }
.sec-lede { margin-top: 1.2rem; color: var(--muted); max-width: 34rem; }

.section { padding-block: var(--pad-section); position: relative; }
.section > .wrap { position: relative; z-index: 1; }
.section-white { background: var(--paper-3); }
.section-tint { background: var(--paper-2); }
/* Les sections vertes portent, en filigrane, une forme crème comme celles
   de la carte : une présence, pas un décor. Un halo or les réchauffe en
   haut, pour que le vert ne tombe jamais dans le froid. */
.section-dark {
  background:
    radial-gradient(80rem 40rem at 85% -12%, rgba(214, 185, 121, .12), transparent 62%),
    var(--ink);
  color: var(--paper-on-dark);
}
.section-dark::before,
.section-tint::before {
  content: "";
  position: absolute; z-index: 0;
  pointer-events: none;
  background-repeat: no-repeat;
  background-size: 100% 100%;
}
/* La forme qui descend du coin supérieur droit, comme au dos de la carte */
.section-dark::before {
  top: 0; right: 0;
  width: min(48vw, 640px); aspect-ratio: 3 / 4;
  opacity: .055;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 400'%3E%3Cpath fill='%23F3EDDF' d='M300,0V400C226,400,124,336,148,236C168,152,92,86,52,0Z'/%3E%3C/svg%3E");
}
/* Sur le beige, la même idée en vert, depuis le bas à gauche */
.section-tint::before {
  bottom: 0; left: 0;
  width: min(44vw, 560px); aspect-ratio: 4 / 3;
  opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cpath fill='%23063E40' d='M0,300V60C70,40,120,120,190,110C280,98,330,180,400,300Z'/%3E%3C/svg%3E");
}
.section-dark .eyebrow, .section-dark .sec-lede { color: var(--muted-on-dark); }
.section-dark .sec-num { border-color: var(--line-dark); color: var(--brass-light); }
.section-dark ::selection { background: var(--paper); color: var(--ink); }

/* Étiquette « à personnaliser » sur les données fictives. Orange, hors
   palette, exprès : c'est un marqueur de travail, il doit se voir. */
.a-completer {
  font-family: var(--font-mono);
  font-size: .72em;
  letter-spacing: .04em;
  color: #C2512D;
  border-bottom: 1px dashed currentColor;
  white-space: nowrap;
}

/* ── Photos ──────────────────────────────────────────────── */
/* Ajoutées le 28 septembre 2026. En attendant le shooting de Sacha, des
   photos libres de droits (Unsplash), à remplacer une par une
   (SHOOTING.md). Leur étiquette « Photo provisoire » a été retirée le
   1er octobre, à la demande de Sacha : les commentaires du HTML disent
   encore lesquelles sont provisoires. */

/* La respiration : une photo pleine largeur entre les infos pratiques et la
   méthode. En haut, un bord crème ondulé, comme les formes de la carte ; en
   bas, la photo se fond dans le vert de la section suivante. */
.photo-band {
  position: relative;
  margin: 0;
  height: clamp(17rem, 42vw, 36rem);
  /* clip, pas hidden : hidden ferait du bandeau un conteneur de défilement,
     et la photo y chercherait son défilement au lieu de celui de la page. */
  overflow: clip;
  background: var(--ink);
}
.photo-band img {
  display: block;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 30%;
  transform-origin: 50% 30%;
}
.photo-band::before,
.photo-band::after {
  content: "";
  position: absolute; left: 0; right: 0; z-index: 1;
  pointer-events: none;
}
.photo-band::before {
  top: -1px;
  height: clamp(2.2rem, 6vw, 5.5rem);
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 120' preserveAspectRatio='none'%3E%3Cpath fill='%23FBF8F1' d='M0,0H1440V14C1250,74,1060,104,800,78C560,54,330,30,0,102Z'/%3E%3C/svg%3E") no-repeat top / 100% 100%;
}
.photo-band::after {
  bottom: 0;
  height: 38%;
  background: linear-gradient(to bottom, rgba(6, 62, 64, 0), rgba(6, 62, 64, .45) 55%, var(--ink));
}
/* La photo se resserre doucement pendant qu'on la traverse (Chrome, Edge,
   Safari récent ; ailleurs elle reste simplement immobile). */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .photo-band img {
      animation: band-drift linear both;
      animation-timeline: view();
    }
  }
}
@keyframes band-drift {
  from { transform: scale(1.12); }
  to   { transform: scale(1); }
}

/* Boutons */
.btn {
  display: inline-flex; align-items: center; gap: .6rem;
  padding: .95rem 1.7rem;
  border-radius: 99px;
  font-weight: 600; font-size: .98rem;
  letter-spacing: .01em;
  transition: transform .35s var(--ease-out), box-shadow .35s var(--ease-out), background-color .25s;
  will-change: transform;
}
.btn svg { width: 15px; height: 15px; transition: transform .35s var(--ease-out); }
.btn:hover svg { transform: translateX(4px); }
/* Le halo or autour de l'appel à l'action : un anneau fin, et une lueur qui
   respire une fois par cycle, juste après le passage du reflet. --glow est
   une propriété enregistrée pour pouvoir être animée ; un navigateur qui ne
   connaît pas @property garde l'anneau, sans la lueur. */
@property --glow { syntax: "<length>"; inherits: false; initial-value: 0px; }
.btn-solid {
  background: var(--ink); color: var(--paper);
  box-shadow:
    0 0 0 3px var(--brass-soft),
    0 0 var(--glow, 0px) 2px rgba(162, 130, 67, .32),
    0 1px 0 rgba(6, 62, 64, .3);
  animation: halo 7s ease-in-out infinite;
}
.btn-solid:hover {
  transform: translateY(-2px);
  box-shadow:
    0 0 0 3px var(--brass-soft),
    0 0 var(--glow, 0px) 2px rgba(162, 130, 67, .32),
    0 12px 28px -12px rgba(6, 62, 64, .55);
}
@keyframes halo {
  0%, 52% { --glow: 0px; }
  76%     { --glow: 22px; }
  100%    { --glow: 0px; }
}
.btn-ghost {
  border: 1px solid var(--line);
  background: transparent;
}
.btn-ghost:hover { transform: translateY(-2px); border-color: var(--ink); }

/* Le jeu de lumière sur l'appel à l'action : un reflet traverse le bouton
   toutes les sept secondes (le rythme que Sacha a validé), en trois secondes
   environ, entre le fond et le texte. Discret : il attire l'œil sans crier.
   Le bouton du menu ne le reçoit qu'une fois la page défilée, pour ne pas
   scintiller en même temps que celui du héros. */
.btn-solid, .menu-cta { position: relative; overflow: hidden; isolation: isolate; }
.btn-solid::after, .site-head.is-scrolled .menu-cta::after {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(105deg, transparent 38%, rgba(243, 237, 223, .3) 50%, transparent 62%);
  transform: translateX(-130%);
  animation: sheen 7s ease-in-out infinite;
  pointer-events: none;
}
.site-head.is-scrolled .menu-cta::after { animation-delay: 2.5s; }
@keyframes sheen {
  0%, 58% { transform: translateX(-130%); }
  100%    { transform: translateX(130%); }
}
/* Une fois la page défilée, le bouton du menu prend le même halo, décalé */
.site-head.is-scrolled .menu-cta {
  box-shadow: 0 0 0 3px var(--brass-soft), 0 0 var(--glow, 0px) 2px rgba(162, 130, 67, .32);
  animation: halo 7s ease-in-out 2.5s infinite;
}

/* ── En-tête ─────────────────────────────────────────────── */

/* Toujours crème, depuis le 19 septembre 2026 : les formes de la carte
   remontent jusqu'au bord supérieur du héros et passent sous l'en-tête, qui
   les coupe comme le bord de la carte coupe les siennes. Transparent, il
   laisserait le menu et son bouton sur du vert. */
.site-head {
  position: fixed; top: 0; left: 0; right: 0; z-index: 120;
  background: var(--paper);
  transition: background-color .3s, box-shadow .3s, backdrop-filter .3s;
}
.site-head.is-scrolled {
  background: color-mix(in srgb, var(--paper) 86%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  backdrop-filter: blur(14px) saturate(1.3);
  box-shadow: 0 1px 0 var(--line);
}
.head-in {
  display: flex; align-items: center; justify-content: space-between;
  padding-block: .9rem;
  transition: padding .3s var(--ease-out);
}
.site-head.is-scrolled .head-in { padding-block: .55rem; }

.brand { display: inline-flex; align-items: center; gap: .85rem; }
/* Le monogramme prend la forme d'un galet, en écho aux formes de la carte */
.brand-mark {
  display: grid; place-items: center;
  width: 42px; height: 42px;
  background: var(--ink); color: var(--paper);
  border-radius: 58% 42% 55% 45% / 48% 55% 45% 52%;
  font-family: var(--font-display);
  font-style: italic; font-weight: 500;
  font-size: 1.05rem;
  letter-spacing: -.04em;
  transition: transform .35s var(--ease-out), border-radius .35s var(--ease-out);
}
.brand:hover .brand-mark { transform: rotate(-8deg); border-radius: 50%; }
/* Le bloc-titre de la carte de visite : prénom en romain, nom en gras,
   un filet or, puis le titre en capitales espacées. */
.brand-name {
  display: flex; flex-direction: column; align-items: flex-start;
  white-space: nowrap;
  font-family: var(--font-body);
  font-size: 1.04rem; font-weight: 400;
  line-height: 1.15;
  letter-spacing: -.005em;
}
.brand-name b { font-weight: 700; }
.brand-name em {
  font-family: var(--font-mono);
  font-style: normal;
  font-size: .6rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin-top: .3rem;
}
.brand-name em::before {
  content: "";
  display: block;
  width: 1.9rem; height: 1.5px;
  background: var(--brass);
  margin-bottom: .32rem;
}

.menu {
  display: flex; align-items: center; gap: clamp(1rem, 2.2vw, 2rem);
  font-size: .95rem; font-weight: 500;
}
.menu li { white-space: nowrap; }
/* Entre le menu déroulant et le grand écran, tout doit tenir sur une ligne */
@media (max-width: 1100px) {
  .menu { font-size: .88rem; gap: .9rem; }
  .menu-cta { padding-inline: .95rem; }
}
.menu a[data-nav] {
  position: relative;
  padding-block: .35rem;
  color: var(--muted);
  transition: color .25s;
}
.menu a[data-nav]::after {
  content: "";
  position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1.5px;
  background: var(--brass);
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform .35s var(--ease-out);
}
.menu a[data-nav]:hover, .menu a[data-nav].is-active { color: var(--ink); }
.menu a[data-nav]:hover::after, .menu a[data-nav].is-active::after {
  transform: scaleX(1);
  transform-origin: 0 50%;
}
.menu-cta {
  padding: .6rem 1.2rem;
  border-radius: 99px;
  background: var(--ink); color: var(--paper);
  font-weight: 600;
  transition: transform .3s var(--ease-out), background-color .25s;
}
.menu-cta:hover { transform: translateY(-2px); background: var(--ink-3); }

.nav-toggle {
  display: none;
  align-items: center; gap: .6rem;
  font-family: var(--font-mono);
  font-size: .78rem; letter-spacing: .14em; text-transform: uppercase;
  padding: .5rem .2rem;
}
.nav-toggle-box { display: inline-flex; flex-direction: column; gap: 5px; width: 22px; }
.nav-toggle-box span {
  height: 1.6px; background: var(--ink);
  transition: transform .3s var(--ease-out), width .3s var(--ease-out);
  transform-origin: center;
}
.nav-toggle[aria-expanded="true"] .nav-toggle-box span:first-child { transform: translateY(3.3px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-box span:last-child  { transform: translateY(-3.3px) rotate(-45deg); }

/* ── Héros ───────────────────────────────────────────────── */

.hero {
  --hero-pt: clamp(7rem, 13vh, 8.5rem);
  --hero-pb: 6rem;
  position: relative;
  min-height: 100svh;
  display: flex; align-items: center;
  padding-block: var(--hero-pt) var(--hero-pb);
  overflow: clip;
}
/* La colonne du héros : texte, forme, boutons. Elle prend toute la hauteur
   pour que la forme puisse s'y accrocher à droite, sur grand écran. */
/* Le contenu part du haut (Sacha, 19 septembre : trop d'espace au-dessus de la
   signature quand il était centré) ; le héros garde sa hauteur d'écran, et
   les formes de la carte occupent le reste. */
.hero-grid {
  position: relative; z-index: 2;
  align-self: stretch;
  display: flex; flex-direction: column; align-items: flex-start;
  justify-content: flex-start;
}
.hero-in {
  max-width: 46rem;
  display: flex; flex-direction: column; align-items: flex-start;
}

/* Les formes de la carte de visite (les formes crème du recto, en vert),
   la carte entière. En dessous de 1200px, elles tapissent tout le héros,
   derrière le texte (Sacha, 26 septembre 2026 : la bande entre le texte et
   les boutons les coupait) ; à partir de 1200px, elles s'accrochent à droite
   du texte. Étirées au format de leur boîte (preserveAspectRatio="none") :
   ce sont des formes libres, elles supportent la déformation.
   L'en-tête, crème et fixe, les coupe en haut comme le bord de la carte. */
.hero-art {
  position: absolute; z-index: -1;
  top: calc(-1 * var(--hero-pt)); bottom: calc(-1 * var(--hero-pb));
  left: calc((100% - 100vw) / 2);
  right: calc((100% - 100vw) / 2);
  pointer-events: none;
}
.hero-form {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  overflow: hidden;   /* les formes collent hors cadre : le cadre les coupe */
}
/* Derrière le texte, les formes ne sont qu'un filigrane (7 %) ; elles
   prennent tout leur vert sous le titre. 7 %, c'est le plafond : au-delà,
   la pastille gris-vert et l'accroche or foncé passent sous 4,5:1.
   --veil-end (la fin du titre) est mesuré par script.js. */
.hero-form-fills {
  --veil: linear-gradient(to bottom,
    rgb(0 0 0 / .07) var(--veil-end, 45%),
    #000 calc(var(--veil-end, 45%) + 4.5rem));
  -webkit-mask-image: var(--veil);
  mask-image: var(--veil);
}

/* L'arrivée : les trois formes se dessinent l'une après l'autre. Un trait
   d'or suit le contour (pathLength="1" : le tiret fait toute la longueur),
   l'aplat vert monte derrière lui, puis le trait s'efface : il reste la
   carte. La volute, la langue, puis la masse, de haut en bas. Environ
   3 s en tout depuis le 27 septembre 2026 (4,5 s avant : Sacha aime le
   dessin mais le voulait plus rapide), mêmes proportions entre les temps. */
.hero-form-fill { fill: var(--ink); opacity: 0; }
.hero-form-line {
  fill: none;
  stroke: var(--brass);
  stroke-width: 2.2;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}
.hero-form-fill:nth-of-type(1), .hero-form-line:nth-of-type(1) { --d: .1s; }
.hero-form-fill:nth-of-type(2), .hero-form-line:nth-of-type(2) { --d: .65s; }
.hero-form-fill:nth-of-type(3), .hero-form-line:nth-of-type(3) { --d: 1.2s; }
body.is-loaded .hero-form-line {
  animation:
    trace 1.1s cubic-bezier(.55, .1, .35, 1) var(--d) forwards,
    fade-out .7s ease calc(var(--d) + 1.25s) forwards;
}
body.is-loaded .hero-form-fill {
  animation: fade .75s ease calc(var(--d) + .7s) forwards;
}
@keyframes trace { to { stroke-dashoffset: 0; } }
@keyframes fade-out { to { opacity: 0; } }

/* Le rappel de la carte en tête du héros : la signature et l'accroche du
   contact, mais en or sur crème, plus petites. Le nom a quitté la pastille
   en dessous : la signature le porte déjà. */
.hero-sign {
  display: flex; flex-direction: column; align-items: flex-start;
  margin-bottom: clamp(1.4rem, 3vw, 2.2rem);
  opacity: 0; animation: rise .9s var(--ease-out) 0s forwards;
}
.hero-sign .signature { color: var(--brass); font-size: clamp(2.4rem, 4vw, 3.4rem); }
.hero-sign .tagline { color: var(--brass-deep); margin-top: .8rem; font-size: .74rem; }
.hero-sign .tagline::before { background: var(--brass); width: 1.9rem; margin-bottom: .75rem; }
.hero-eyebrow { opacity: 0; animation: rise .9s var(--ease-out) .15s forwards; }
.hero-title {
  font-size: var(--fs-hero);
  font-weight: 320;
  margin-top: 1.4rem;
  text-wrap: balance;
  opacity: 0; animation: rise .9s var(--ease-out) .25s forwards;
}
.hero-title em {
  font-style: italic;
  font-weight: 400;
  color: var(--brass);
  white-space: nowrap;
}
.hero-sub {
  margin-top: 1.6rem;
  max-width: 33rem;
  font-size: 1.12rem;
  color: var(--muted);
  opacity: 0; animation: rise .9s var(--ease-out) .4s forwards;
}
.hero-actions {
  display: flex; flex-wrap: wrap; gap: .9rem;
  margin-top: 2.2rem;
  opacity: 0; animation: rise .9s var(--ease-out) .55s forwards;
}
.infos-chips {
  display: flex; flex-wrap: wrap; gap: .55rem;
  margin: -.6rem 0 2.8rem;
}
.infos-chips li {
  font-family: var(--font-mono);
  font-size: .74rem; letter-spacing: .1em; text-transform: uppercase;
  padding: .45rem .9rem;
  border: 1px solid var(--line);
  border-radius: 99px;
  color: var(--muted);
  background: color-mix(in srgb, var(--paper) 70%, transparent);
}
@keyframes rise {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: none; }
}

/* Badge circulaire rotatif, posé sur la crème à côté des formes, comme un
   sceau : or foncé et vert, les couleurs du fond clair. En dessous de
   1200px, il se loge sous la langue, à gauche du ruban, à mi-chemin entre
   le titre et les boutons (--badge-y, mesuré par script.js) ; s'il n'y a
   pas la place (téléphone couché), il se retire. */
.hero-badge {
  position: absolute; z-index: 2;
  top: var(--badge-y, 62%); left: 17%;
  translate: -50% -50%;
  width: clamp(104px, 22vw, 134px);
  aspect-ratio: 1;
  opacity: 0; animation: fade 1.2s ease 2.2s forwards;
}
.hero-art.badge-off .hero-badge { display: none; }

/* En dessous de 1200px, tout le texte passe devant les formes : le
   paragraphe d'introduction se retire (Sacha, 26 septembre 2026 : le titre
   suffit, les infos suivent juste en dessous), les boutons se posent en bas
   du héros, et ce qui touche le vert s'arrange pour rester lisible. */
@media (max-width: 1199.98px) {
  .hero { align-items: stretch; }
  .hero-sub { display: none; }
  .hero-actions { margin-top: auto; padding-top: 1.8rem; }
  /* L'or moyen ne tient que 2,8:1 sur le filigrane : l'or foncé, 4,6:1 */
  .hero-title em, .hero-title .title-dot { color: var(--brass-deep); }
  /* Le bouton secondaire passe sur le vert : il prend la crème */
  .hero-actions .btn-ghost { background: var(--paper); }
  /* L'indicateur de défilement tomberait sur le vert, invisible */
  .hero-scroll { display: none; }
}

/* À partir de 1200px, la carte est accrochée à droite du texte et remplit
   toute la hauteur du héros, jusqu'au bord droit de l'écran, en plein. */
@media (min-width: 1200px) {
  .hero-art { left: calc(46rem + clamp(2rem, 4vw, 5rem)); z-index: auto; }
  .hero-form-fills { -webkit-mask-image: none; mask-image: none; }
  /* Le badge se pose en haut à gauche du dessin : l'endroit du bloc-titre
     sur la carte. */
  .hero-badge {
    top: 19%; left: 26%;
    width: clamp(134px, 11vw, 170px);
  }
}
.hero-badge svg { width: 100%; height: 100%; overflow: visible; animation: spin 26s linear infinite; }
.badge-text {
  font-family: var(--font-mono);
  font-size: 8px;
  letter-spacing: .2em;
  text-transform: uppercase;
  fill: var(--brass-deep);
}
.badge-glyph { stroke: var(--ink); stroke-width: 2.2; stroke-linecap: round; }
@keyframes spin { to { transform: rotate(1turn); } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

/* Indicateur de défilement */
.hero-scroll {
  position: absolute; z-index: 2;
  left: 50%; bottom: 2.2rem;
  translate: -50% 0;
  width: 26px; height: 42px;
  border: 1.5px solid var(--line);
  border-radius: 99px;
  opacity: 0; animation: fade 1.2s ease 1.3s forwards;
}
.hero-scroll span {
  position: absolute; left: 50%; top: 7px;
  width: 4px; height: 4px;
  translate: -50% 0;
  border-radius: 50%;
  background: var(--brass);
  animation: scroll-hint 2s var(--ease-out) infinite;
}
@keyframes scroll-hint {
  0%   { transform: translateY(0); opacity: 1; }
  70%  { transform: translateY(18px); opacity: 0; }
  100% { transform: translateY(0); opacity: 0; }
}

/* ── Marquee des communes ────────────────────────────────── */

.marquee {
  border-block: 1px solid var(--line);
  padding-block: 1.05rem;
  overflow: clip;
  background: var(--paper);
}
.marquee-track {
  display: flex; width: max-content;
  animation: marquee 30s linear infinite;
}
.marquee:hover .marquee-track { animation-play-state: paused; }
.marquee-list { display: flex; }
.marquee-list li {
  display: flex; align-items: center;
  font-family: var(--font-mono);
  font-size: .8rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--muted);
  padding-inline: 1.4rem;
}
.marquee-list li::after {
  content: "";
  width: 5px; height: 5px;
  margin-left: 2.8rem;
  border-radius: 50%;
  background: var(--brass);
}
@keyframes marquee { to { transform: translateX(-50%); } }

/* ── 01 · Soins ──────────────────────────────────────────── */

.cards {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 1.2rem;
}
/* Trois soins par rangée, comme les techniques. Cinq soins depuis le
   1er octobre 2026 (la rééducation neurologique) : les deux derniers se
   centrent sur la seconde rangée au lieu de laisser un trou à droite. */
.cards > .card { grid-column: span 2; }
.cards > .card:nth-child(4):nth-last-child(2) { grid-column: 2 / span 2; }
.cards > .card:nth-child(5):last-child { grid-column: 4 / span 2; }
.card {
  --card-pad: clamp(1.6rem, 3vw, 2.4rem);
  position: relative;
  padding: var(--card-pad);
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--paper-3);
  transition: transform .45s var(--ease-out), box-shadow .45s var(--ease-out), border-color .3s;
}
.card:hover {
  transform: translateY(-5px);
  border-color: rgba(6, 62, 64, .32);
  box-shadow: 0 24px 44px -28px rgba(6, 62, 64, .35);
}
.card-icon {
  width: 52px; height: 52px;
  display: grid; place-items: center;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--paper);
  transition: background-color .3s, border-color .3s;
}
.card:hover .card-icon { background: var(--ink-soft); border-color: rgba(6, 62, 64, .35); }
.card-icon svg { width: 30px; height: 30px; }
/* La photo du soin, bord à bord en tête de carte ; l'icône se pose à cheval
   sur son bord, comme un cachet. */
.card-photo {
  position: relative;
  margin: calc(-1 * var(--card-pad)) calc(-1 * var(--card-pad)) 0;
  aspect-ratio: 16 / 9;
  border-radius: 19px 19px 0 0;
  overflow: hidden;
  background: var(--paper-2);
}
.card-photo img {
  display: block;
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform .9s var(--ease-out);
}
.card:hover .card-photo img { transform: scale(1.04); }
.card-photo + .card-icon {
  position: relative; z-index: 1;
  margin-top: -26px;
  background: var(--paper-3);
}
/* Au survol, la teinte verte de l'icône reste opaque : la photo ne doit pas
   transparaître dessous. */
.card:hover .card-photo + .card-icon {
  background: linear-gradient(var(--ink-soft), var(--ink-soft)) var(--paper-3);
}
.card-icon path, .card-icon circle[fill="none"] {
  stroke: var(--ink);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.card-icon circle:not([fill="none"]) { fill: var(--brass); }
.card:hover .card-icon [pathLength] {
  stroke-dasharray: 1;
  animation: draw 1s var(--ease-out) forwards;
}
@keyframes draw {
  from { stroke-dashoffset: 1; }
  to   { stroke-dashoffset: 0; }
}
.card h3 { font-size: var(--fs-h3); margin-top: 1.3rem; font-weight: 480; }
.card p { margin-top: .7rem; color: var(--muted); font-size: .99rem; }
.card-tags { display: flex; flex-wrap: wrap; gap: .45rem; margin-top: 1.2rem; }
.card-tags li {
  font-family: var(--font-mono);
  font-size: .68rem; letter-spacing: .09em; text-transform: uppercase;
  padding: .32rem .7rem;
  border-radius: 99px;
  background: var(--ink-soft);
  color: var(--ink);
}

/* ── 02 · Body map ───────────────────────────────────────── */

.bodymap {
  display: grid;
  grid-template-columns: minmax(260px, 380px) 1fr;
  gap: clamp(2.5rem, 6vw, 5.5rem);
  align-items: center;
  /* Deux intensités, réglées ici pour toute la scène. L'entrée est franche,
     le changement de zone reste discret : c'est du texte qui doit rester
     lisible pendant les 200 ms où il bouge. */
  --flou-entree: 11px;
  --flou-swap: 5px;
}
/* Tant qu'aucune zone n'est choisie, la silhouette occupe seule la scène, au
   centre : le panneau ne fait pas encore partie de la grille. Au premier clic,
   script.js pose .is-open, la grille reprend ses deux colonnes et la silhouette
   glisse vers la gauche. .is-js est posé par script.js : sans JavaScript,
   le panneau reste affiché et montre les dix zones à la suite. */
.bodymap.is-js:not(.is-open) { grid-template-columns: 1fr; }
.bodymap.is-js:not(.is-open) .zone-panel { display: none; }
.bodymap:not(.is-js) .zone-kicker { display: none; }
.bodymap:not(.is-js) .zone + .zone { margin-top: 2.4rem; }
.figure-stage {
  position: relative;
  aspect-ratio: 200 / 420;
  max-height: 560px;
  margin-inline: auto;
  width: 100%;
  max-width: 290px;
}
.figure { width: 100%; height: 100%; }
.figure-shape circle,
.figure-shape rect {
  fill: rgba(243, 237, 223, .07);
  stroke: rgba(243, 237, 223, .45);
  stroke-width: 1.4;
}

.spot {
  position: absolute;
  left: var(--x); top: var(--y);
  width: 30px; height: 30px;
  translate: -50% -50%;
  border-radius: 50%;
  display: grid; place-items: center;
  transition: transform .3s var(--ease-out);
}
.spot::before {
  content: "";
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--brass-light);
  box-shadow: 0 0 0 3.5px var(--ink), 0 0 0 4.5px rgba(214, 185, 121, .5);
  transition: transform .3s var(--ease-out), background-color .3s;
}
.spot::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: 50%;
  border: 1.5px solid var(--brass-light);
  opacity: 0;
  animation: spot-ping 3s ease-out infinite;
  animation-delay: calc(var(--d, 0) * 1s);
}
/* Dix points depuis le 3 octobre 2026 : les pulsations se suivent de haut en
   bas, à 0,3 s d'écart, sur le cycle de 3 s. */
.spot:nth-of-type(1) { --d: 0; }    .spot:nth-of-type(2) { --d: .3; }
.spot:nth-of-type(3) { --d: .6; }   .spot:nth-of-type(4) { --d: .9; }
.spot:nth-of-type(5) { --d: 1.2; }  .spot:nth-of-type(6) { --d: 1.5; }
.spot:nth-of-type(7) { --d: 1.8; }  .spot:nth-of-type(8) { --d: 2.1; }
.spot:nth-of-type(9) { --d: 2.4; }  .spot:nth-of-type(10) { --d: 2.7; }
@keyframes spot-ping {
  0%   { transform: scale(.4); opacity: .9; }
  55%  { transform: scale(1.25); opacity: 0; }
  100% { transform: scale(1.25); opacity: 0; }
}
.spot:hover { transform: scale(1.18); }
.spot[aria-pressed="true"]::before {
  background: var(--paper);
  transform: scale(1.25);
  box-shadow: 0 0 0 3.5px var(--ink), 0 0 0 5px var(--brass-light);
}
.spot[aria-pressed="true"]::after { animation: none; opacity: 0; }
.spot:focus-visible { outline-offset: 1px; }

.zone-panel {
  border-left: 1px solid var(--line-dark);
  padding-left: clamp(1.6rem, 3.5vw, 3rem);
  min-height: 300px;
  display: flex; flex-direction: column; justify-content: center;
  transition: opacity .3s ease, transform .3s var(--ease-out), filter .3s ease;
}
.zone-panel.is-swapping { opacity: 0; transform: translateY(10px); filter: blur(var(--flou-swap)); }
/* Le texte entre par la droite, un peu après que la silhouette a commencé à
   glisser. « backwards » et non « forwards » : une fois jouée, l'animation
   lâche prise au lieu de figer opacity et transform, ce qui rendrait
   .is-swapping sans effet pour tous les changements de zone suivants. */
.bodymap.is-open .zone-panel { animation: zoneEntre .7s var(--ease-out) .2s backwards; }
@keyframes zoneEntre {
  from { opacity: 0; transform: translateX(22px); filter: blur(var(--flou-entree)); }
  /* Le flou est parti bien avant la fin : on lit le texte pendant qu'il finit
     de se poser, au lieu d'attendre que tout soit immobile. */
  40%  { opacity: 1; filter: blur(0); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}
.zone-kicker {
  font-family: var(--font-mono);
  font-size: .72rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--brass-light);
}
.zone-title {
  font-size: clamp(1.7rem, 2.6vw, 2.4rem);
  margin-top: .9rem;
  font-weight: 430;
}
.zone-text {
  margin-top: 1rem;
  max-width: 30rem;
  color: var(--muted-on-dark);
  font-size: 1.05rem;
}
.zone-tags { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1.4rem; }
.zone-tags li {
  font-family: var(--font-mono);
  font-size: .7rem; letter-spacing: .09em; text-transform: uppercase;
  padding: .38rem .8rem;
  border: 1px solid var(--line-dark);
  border-radius: 99px;
  color: var(--muted-on-dark);
}
.zone-note {
  margin-top: 2rem;
  padding-top: 1.2rem;
  border-top: 1px dashed var(--line-dark);
  font-size: .85rem;
  color: var(--muted-on-dark);
}

/* ── 03 · Méthode ────────────────────────────────────────── */

.steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.4rem, 3vw, 2.6rem);
  counter-reset: step;
}
.step {
  position: relative;
  padding-top: 1.6rem;
  --bar-off: var(--line);
  --bar-on: var(--ink);
}
/* La barre en quatre segments au-dessus de chaque étape : un segment allumé
   à l'étape 1, deux à la 2, trois à la 3, quatre à la 4. script.js pose
   data-fill quand la carte entre dans l'écran ; les segments s'allument en
   cascade, après le délai de révélation de la carte (--i), et restent
   allumés. Sans JS, rien ne s'allume mais la barre est là. */
.step-bar {
  position: absolute; top: 0; left: 0; right: 0;
  display: flex; gap: 6px;
  height: 2px;
}
.step-bar i {
  flex: 1;
  background: var(--bar-off);
  transition: background-color .5s ease;
  transition-delay: calc(var(--i, 0) * 95ms + var(--k, 0) * 140ms + 150ms);
}
.step-bar i:nth-child(1) { --k: 0; }
.step-bar i:nth-child(2) { --k: 1; }
.step-bar i:nth-child(3) { --k: 2; }
.step-bar i:nth-child(4) { --k: 3; }
.step[data-fill="1"] .step-bar i:nth-child(-n+1),
.step[data-fill="2"] .step-bar i:nth-child(-n+2),
.step[data-fill="3"] .step-bar i:nth-child(-n+3),
.step[data-fill="4"] .step-bar i:nth-child(-n+4) { background: var(--bar-on); }
.step-num {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 2.6rem;
  font-weight: 320;
  color: var(--brass);
  line-height: 1;
}
.step h3 { font-size: var(--fs-h3); font-weight: 480; margin-top: .9rem; }
.step p { margin-top: .65rem; color: var(--muted); font-size: .97rem; }
/* Depuis le 18 septembre 2026 la méthode est sur le vert : les numéros d'or
   sur le fond de la carte, et les segments allumés en or clair. */
.section-dark .step { --bar-off: var(--line-dark); --bar-on: var(--brass-light); }
.section-dark .step-num { color: var(--brass-light); }
.section-dark .step p { color: var(--muted-on-dark); }

/* ── 04 · Techniques & approches ─────────────────────────── */

.tech-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 1.2rem;
}
/* Chaque carte occupe deux des six colonnes : trois par rangée. Six cartes
   depuis l'arrivée de l'échographie (27 septembre 2026) : deux rangées
   pleines. Si l'on retombe un jour à cinq, les deux dernières se centrent au
   lieu de laisser un trou à droite (les deux règles ci-dessous). */
.tech { grid-column: span 2; }
.tech:nth-child(4):nth-last-child(2) { grid-column: 2 / span 2; }
.tech:nth-child(5):last-child { grid-column: 4 / span 2; }
.tech {
  display: flex; flex-direction: column;
  border: 1px solid var(--line);
  border-radius: 22px;
  overflow: hidden;
  background: var(--paper-3);
  transition: transform .45s var(--ease-out), box-shadow .45s var(--ease-out), border-color .3s;
}
.tech:hover {
  transform: translateY(-5px);
  border-color: rgba(6, 62, 64, .3);
  box-shadow: 0 26px 48px -30px rgba(6, 62, 64, .4);
}

/* L'emplacement de la photo. Tant qu'il n'y en a pas, il porte une
   illustration au trait — un parti pris, pas un trou. Le jour où Sacha
   fournit une vraie photo, on glisse un <img> ici et le décor s'efface. */
.tech-figure {
  margin: 0;              /* <figure> arrive avec 1em/40px du navigateur */
  position: relative;
  aspect-ratio: 4 / 3;
  display: grid; place-items: center;
  border-bottom: 1px solid var(--line);
  background:
    repeating-linear-gradient(-45deg,
      rgba(6, 62, 64, .04) 0 1px, transparent 1px 10px),
    var(--paper-2);
  overflow: hidden;
}
.tech-figure img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform .9s var(--ease-out);
}
.tech:hover .tech-figure img { transform: scale(1.04); }
/* Avec une photo (depuis le 28 septembre 2026), le dessin s'efface et le
   numéro passe sur une pastille crème, pour rester lisible sur l'image. */
.tech-figure:has(img) svg { display: none; }
.tech-figure:has(img) .tech-index {
  z-index: 1;
  top: .75rem; left: .75rem;
  padding: .28rem .65rem;
  border-radius: 99px;
  background: rgba(243, 237, 223, .92);
  line-height: 1.2;
}
.tech-figure svg {
  width: 44%; max-width: 130px; height: auto;
  overflow: visible;
}
.tech-figure svg [pathLength] {
  fill: none;
  stroke: var(--brass);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}
.tech-figure svg .is-accent { stroke: var(--ink); }
.tech-figure svg circle:not([pathLength]) { fill: var(--ink); }
.tech.in-view .tech-figure svg [pathLength] {
  animation: draw 1.5s var(--ease-out) forwards;
  animation-delay: calc(var(--i, 0) * 95ms + 250ms);
}

.tech-index {
  position: absolute; top: .9rem; left: 1rem;
  font-family: var(--font-mono);
  font-size: .72rem; letter-spacing: .16em;
  color: var(--brass-deep);
}
.tech-figure .a-completer {
  position: absolute; bottom: .85rem; left: 50%;
  translate: -50% 0;
  padding: .3rem .75rem;
  border: 1px dashed var(--line);
  border-bottom-width: 1px;
  border-radius: 99px;
  background: var(--paper);
  font-size: .66rem; letter-spacing: .12em; text-transform: uppercase;
}

.tech-body {
  display: flex; flex-direction: column;
  flex: 1;
  padding: clamp(1.4rem, 2.4vw, 1.8rem);
}
.tech h3 { font-size: var(--fs-h3); font-weight: 480; }
.tech p { margin-top: .7rem; color: var(--muted); font-size: .97rem; }
.tech-for {
  margin-top: auto;
  padding-top: 1.2rem;
  display: flex; flex-wrap: wrap; gap: .4rem .55rem;
  align-items: baseline;
}
.tech-for dt {
  font-family: var(--font-mono);
  font-size: .66rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--brass-deep);
  width: 100%;
}
.tech-for dd {
  margin: 0;
  font-family: var(--font-mono);
  font-size: .68rem; letter-spacing: .06em;
  padding: .32rem .7rem;
  border-radius: 99px;
  background: var(--ink-soft);
  color: var(--ink);
}

/* Le rappel déontologique qui ferme la section : on informe, on ne vend pas. */
.tech-note {
  margin-top: clamp(2rem, 4vw, 3rem);
  padding: 1.3rem 1.5rem;
  border-left: 2px solid var(--brass);
  background: var(--brass-soft);
  border-radius: 0 14px 14px 0;
  max-width: 46rem;
  font-size: .95rem;
  color: var(--ink-2);
}

/* ── Les techniques en carrousel ─────────────────────────── */

/* Demande de Sacha, 27 septembre 2026 : les fiches arrivent en glissant, une
   rangée par la droite, la suivante par la gauche. Le premier essai les
   pendait à une corde, comme des cintres : corde et cintres retirés le
   28 septembre (« juste les cases avec l'effet carrousel »). script.js pose
   .is-rail sur la grille, un repère invisible (.tech-row) en haut de chaque
   rangée, et le sens d'arrivée de chaque fiche (--from : 1 par la droite, -1
   par la gauche). Quand le repère entre dans l'écran, la rangée glisse
   (.is-pulled) de tout l'écran jusqu'à sa place. Une fois arrivée
   (.is-arrived), son dessin se trace, s'il n'y a pas de photo. Sans
   JavaScript, la grille reste une grille. */
/* La section coupe ce qui dépasse sur les côtés : les fiches en attente hors
   de l'écran ne doivent jamais rendre la page plus large (sur téléphone, on
   pourrait la faire glisser de côté). « hidden » pour les vieux navigateurs,
   « clip » pour les autres, qui ne crée pas de zone de défilement. */
#techniques { overflow-x: hidden; overflow-x: clip; }
.tech-grid.is-rail {
  --rail-ease: cubic-bezier(.2, .85, .25, 1);     /* lancé vite, freiné long */
  position: relative;
}
/* Le repère de rangée : invisible, c'est lui qu'on observe */
.tech-row {
  position: absolute; left: 0; right: 0;
  height: 1px;
  pointer-events: none;
}
.tech-grid.is-rail .tech {
  translate: calc(var(--from, 1) * 100vw) 0;      /* en attente, hors écran */
}
.tech-grid.is-rail .tech.is-pulled {
  translate: 0 0;
  animation: rail-in 1.5s var(--rail-ease) var(--delay, 0s) backwards;
}
@keyframes rail-in {
  from { translate: calc(var(--from, 1) * 100vw) 0; }
  to   { translate: 0 0; }
}
/* Le dessin attend que la fiche soit arrivée pour se tracer. On vise
   « svg > * » et non « [pathLength] » : Chrome ne recalcule pas les éléments
   visés par un attribut SVG à majuscule quand une classe change plus haut,
   et le dessin restait invisible. */
.tech-grid.is-rail .tech.in-view .tech-figure svg > * { animation: none; }
.tech-grid.is-rail .tech.is-arrived .tech-figure svg > * {
  animation: draw 1.5s var(--ease-out) forwards;
  animation-delay: .1s;
}

/* ── 05 · Engagements ────────────────────────────────────── */

.pledges {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.2rem;
}
.pledge {
  position: relative;
  padding: clamp(3rem, 4.5vw, 3.8rem) clamp(1.6rem, 3vw, 2.4rem) clamp(1.8rem, 3vw, 2.6rem);
  text-align: center;
  border: 1px solid var(--line-dark);
  border-radius: 22px;
  background: rgba(243, 237, 223, .035);
  overflow: hidden;
  transition: transform .45s var(--ease-out), border-color .3s, background-color .3s;
}
.pledge:hover {
  transform: translateY(-4px);
  border-color: rgba(243, 237, 223, .4);
  background: rgba(243, 237, 223, .06);
}
/* Le guillemet ouvrant, en or, centré au-dessus de la citation : c'est lui
   qui dit « citation », sans numéro ni signature (Sacha, 19 septembre 2026). */
.pledge::before {
  content: "“";
  position: absolute; top: .55rem; left: 50%;
  translate: -50% 0;
  font-family: var(--font-display);
  font-size: 4.6rem; font-weight: 300;
  line-height: 1;
  color: var(--brass-light);
  opacity: .55;
  pointer-events: none;
}
.pledge blockquote {
  margin: 0 auto;
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 1.5vw, 1.4rem);
  font-weight: 330;
  line-height: 1.45;
  max-width: 28rem;
  text-wrap: balance;
}

/* ── 06 · Parcours ───────────────────────────────────────── */

.parcours {
  display: grid;
  grid-template-columns: minmax(240px, 340px) 1fr;
  gap: clamp(2.5rem, 6vw, 5.5rem);
  align-items: start;
}
.portrait { position: sticky; top: 7rem; }
.portrait-frame {
  position: relative;
  aspect-ratio: 4 / 5;
  border: 1px solid var(--line);
  border-radius: 22px;
  overflow: hidden;
  display: grid; place-items: center;
  background:
    repeating-linear-gradient(-45deg,
      rgba(6, 62, 64, .05) 0 1px, transparent 1px 9px),
    var(--paper);
}
.portrait-frame img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.portrait-chips { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1rem; }
.portrait-chips li {
  font-family: var(--font-mono);
  font-size: .7rem; letter-spacing: .1em; text-transform: uppercase;
  padding: .4rem .85rem;
  border: 1px solid var(--line);
  border-radius: 99px;
  color: var(--muted);
}

.parcours-lede {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 1.6vw, 1.45rem);
  font-weight: 380;
  line-height: 1.5;
  max-width: 36rem;
  color: var(--ink-2);
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

.timeline { position: relative; }
.timeline::before {
  content: "";
  position: absolute; top: .5rem; bottom: .5rem; left: 0;
  width: 1px;
  background: var(--line);
}
.timeline li {
  position: relative;
  display: grid;
  /* Assez large pour « Février à mars 2025 » (stages, 1er octobre 2026) */
  grid-template-columns: minmax(92px, 10.5rem) 1fr;
  gap: 1.4rem;
  padding: 1.15rem 0 1.15rem 2rem;
}
.timeline li::before {
  content: "";
  position: absolute; left: -4px; top: 1.8rem;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--ink);
  box-shadow: 0 0 0 4px var(--paper);
}
.tl-date {
  font-family: var(--font-mono);
  font-size: .78rem; letter-spacing: .1em;
  color: var(--brass-deep);
  padding-top: .3rem;
  white-space: nowrap;
}
.timeline h3 { font-size: 1.1rem; font-weight: 500; font-family: var(--font-body); }
.timeline p { color: var(--muted); font-size: .95rem; margin-top: .25rem; }

/* ── 05 · Infos pratiques ────────────────────────────────── */

.infos-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.2rem;
}
.info {
  padding: clamp(1.4rem, 2.5vw, 2rem);
  border: 1px solid var(--line);
  border-radius: 18px;
  transition: border-color .3s, transform .4s var(--ease-out);
}
.info:hover { border-color: rgba(6, 62, 64, .3); transform: translateY(-3px); }
.info h3 {
  font-family: var(--font-body);
  font-size: .8rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--brass-deep);
}
.info p { margin-top: .8rem; color: var(--ink-2); font-size: .98rem; }
/* Les jours et les heures du cabinet, en gras sur leur propre ligne, après
   une petite horloge d'or : l'emploi du temps se lit d'un coup d'œil
   (Sacha, 3 octobre 2026). */
.info .info-horaire {
  display: flex; align-items: center; gap: .55rem;
  margin-top: .5rem;
  color: var(--ink);
  font-size: 1.02rem;
}
.info-horaire strong { font-weight: 600; }
.info-horaire svg {
  flex: none;
  width: 17px; height: 17px;
  fill: none;
  stroke: var(--brass);
  stroke-width: 1.4;
  stroke-linecap: round; stroke-linejoin: round;
}
.info-tel a {
  font-weight: 600; color: var(--ink);
  border-bottom: 1px solid color-mix(in srgb, var(--brass-deep) 45%, transparent);
  transition: border-color .25s;
}
.info-tel a:hover { border-bottom-color: var(--brass-deep); }

/* Le logo du cabinet, dans une tuile de la même famille que les icônes des
   soins. Chaque logo garde ses couleurs : c'est son identité, pas la nôtre.
   La hauteur d'affichage se règle logo par logo (--h sur l'image), pour
   équilibrer un mot compact et un logo à deux lignes. Depuis le 27 septembre
   2026 (Sacha) : la tuile prend toute la largeur de la carte et le logo s'y
   centre, un peu plus grand ; sur un petit écran, il rétrécit pour tenir. */
.info-logo {
  display: flex; align-items: center; justify-content: center;
  height: 80px; padding: 0 1.15rem;
  margin-bottom: 1.1rem;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--paper);
  transition: background-color .3s, border-color .3s;
}
.info:hover .info-logo { background: var(--paper-3); border-color: rgba(6, 62, 64, .3); }
.info-logo img { display: block; height: var(--h, 32px); width: auto; max-width: 100%; object-fit: contain; }

/* Fiche d'accès. La carte reste dans la carte du cabinet, sous l'adresse et les
   horaires : le patient a le « où », le « quand » et le « comment y aller » au
   même endroit, sans croiser deux blocs.
   loading="lazy" : rien n'est demandé à Google tant que le visiteur n'est pas
   descendu jusqu'ici. */
.info-map {
  margin-top: 1.1rem;
  aspect-ratio: 16 / 10;
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  background: color-mix(in srgb, var(--ink) 5%, transparent);
}
.info-map iframe { display: block; width: 100%; height: 100%; border: 0; }
.info-lien {
  display: inline-flex; align-items: center; gap: .35rem;
  margin-top: .85rem;
  font-family: var(--font-mono);
  font-size: .72rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--brass-deep);
  border-bottom: 1px solid color-mix(in srgb, var(--brass-deep) 40%, transparent);
  padding-bottom: 2px;
  transition: border-color .25s;
}
.info-lien::after { content: "↗"; font-size: .9em; }
.info-lien:hover { border-bottom-color: var(--brass-deep); }

/* Sur un écran étroit la carte s'allonge un peu : à 335px de large, du 16/10
   ne laisse pas assez de hauteur pour lire les rues autour du repère. */
@media (max-width: 720px) {
  .info-map { aspect-ratio: 4 / 3; }
}

.faq { max-width: 46rem; }
.faq-item { border-bottom: 1px solid var(--line); }
.faq-item:first-of-type { border-top: 1px solid var(--line); }
.faq-q {
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
  width: 100%;
  padding: 1.15rem .2rem;
  text-align: left;
  font-size: 1.04rem; font-weight: 500;
  transition: color .25s;
}
.faq-q:hover { color: var(--brass-deep); }
.faq-cross { position: relative; flex: 0 0 auto; width: 15px; height: 15px; }
.faq-cross::before, .faq-cross::after {
  content: "";
  position: absolute; top: 50%; left: 0;
  width: 100%; height: 1.8px;
  background: var(--brass);
  translate: 0 -50%;
  transition: rotate .35s var(--ease-out);
}
.faq-cross::after { rotate: 90deg; }
.faq-item.open .faq-cross::after { rotate: 0deg; }
.faq-item.open .faq-cross::before { rotate: 180deg; }
.faq-a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .45s var(--ease-out);
}
.faq-item.open .faq-a { grid-template-rows: 1fr; }
.faq-a-in { overflow: hidden; }
.faq-a-in p {
  padding: 0 .2rem 1.3rem;
  color: var(--muted);
  max-width: 40rem;
}

/* ── 06 · Contact ────────────────────────────────────────── */

/* L'appel final : le vert le plus profond du site, pour que la page se ferme
   sur un accord grave — c'est le seul endroit où l'on va aussi loin. */
.section-contact {
  background:
    radial-gradient(74rem 38rem at 88% -8%, rgba(214, 185, 121, .11), transparent 62%),
    var(--ink-3);
}
.contact-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.2rem;
}
.contact-card {
  display: flex; flex-direction: column; gap: .55rem;
  padding: clamp(1.6rem, 3vw, 2.2rem);
  border: 1px solid var(--line-dark);
  border-radius: 20px;
  transition: transform .4s var(--ease-out), border-color .3s, background-color .3s;
}
a.contact-card:hover {
  transform: translateY(-5px);
  border-color: rgba(243, 237, 223, .45);
  background: rgba(243, 237, 223, .045);
}
.contact-label {
  font-family: var(--font-mono);
  font-size: .72rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--brass-light);
}
.contact-value {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 1.8vw, 1.65rem);
  font-weight: 420;
  overflow-wrap: anywhere;
}
.contact-hint { font-size: .88rem; color: var(--muted-on-dark); line-height: 1.55; }

/* La carte agenda est le chemin principal : elle est crème sur le vert,
   comme le verso de la carte de visite sur son recto. C'est l'inversion qui
   la fait ressortir, pas une couleur de plus. */
.contact-card-primary {
  border-color: var(--paper);
  background: var(--paper);
  color: var(--ink);
}
a.contact-card-primary:hover {
  border-color: var(--paper-3);
  background: var(--paper-3);
}
.contact-card-primary .contact-label { color: var(--brass-deep); }
.contact-card-primary .contact-hint { color: var(--muted); }
.section-dark .a-completer { color: rgba(243, 237, 223, .55); }

/* La page se signe comme la carte : signature manuscrite en or, filet, et
   l'accroche en petites capitales serif. */
.contact-sign {
  margin-top: clamp(3.5rem, 7vw, 6rem);
  display: flex; flex-direction: column; align-items: flex-start;
}
.signature {
  font-family: var(--font-script);
  font-size: clamp(3rem, 5vw, 4.4rem);
  line-height: 1;
  color: var(--brass-light);
  rotate: -3deg;
  transform-origin: 0 100%;
  padding-inline: .2em;
}
.tagline {
  margin-top: 1.4rem;
  font-family: var(--font-display);
  font-size: .82rem; font-weight: 500;
  letter-spacing: .3em; text-transform: uppercase;
  color: var(--brass-light);
}
.tagline::before {
  content: "";
  display: block;
  width: 2.2rem; height: 1.5px;
  background: var(--brass-light);
  margin-bottom: 1.1rem;
}

/* ── Pied de page ────────────────────────────────────────── */

.site-foot {
  background: var(--ink-3);
  color: var(--paper-on-dark);
  padding-block: clamp(2.5rem, 5vw, 4rem);
  border-top: 1px solid var(--line-dark);
}
.foot-in {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2rem 3rem;
  align-items: start;
}
.foot-brand { display: flex; gap: .9rem; align-items: center; }
.foot-brand .brand-mark { background: var(--paper); color: var(--ink); }
.foot-brand .brand-name em { color: var(--muted-on-dark); }
.foot-brand .brand-name em::before { background: var(--brass-light); }
.foot-nav { display: flex; flex-wrap: wrap; gap: 1.4rem; font-size: .92rem; }
.foot-nav a { color: var(--muted-on-dark); transition: color .25s; }
.foot-nav a:hover { color: var(--paper-on-dark); }
.foot-legal {
  grid-column: 1 / -1;
  padding-top: 1.6rem;
  border-top: 1px solid var(--line-dark);
  font-size: .82rem;
  color: var(--muted-on-dark);
  display: grid; gap: .4rem;
}
.foot-sep { margin-inline: .6rem; opacity: .6; }
/* Les mentions légales (2 octobre 2026) : repliées sous un lien discret,
   ouvertes au clic. Même vocabulaire que la FAQ : un « + » qui tourne. */
.foot-mentions summary {
  display: inline-flex; align-items: center; gap: .45rem;
  cursor: pointer; list-style: none;
  transition: color .25s;
}
.foot-mentions summary::-webkit-details-marker { display: none; }
.foot-mentions summary span {
  text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: rgba(243, 237, 223, .35);
  transition: text-decoration-color .25s;
}
.foot-mentions summary::after {
  content: "+";
  font-family: var(--font-mono);
  transition: transform .3s var(--ease-out);
}
.foot-mentions[open] summary::after { transform: rotate(45deg); }
.foot-mentions summary:hover { color: var(--paper-on-dark); }
.foot-mentions summary:hover span { text-decoration-color: var(--brass-light); }
.foot-mentions-in { display: grid; gap: .5rem; padding-top: .8rem; max-width: 46rem; }
.foot-mentions-in strong { color: var(--paper-on-dark); font-weight: 600; }
.foot-mentions-in a {
  color: var(--paper-on-dark);
  text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: var(--brass-light);
}

/* ── Barre d'action mobile ───────────────────────────────── */

/* Sur tous les écrans depuis le 19 septembre 2026 (demande de Sacha : le
   bouton doit rester dans le champ de vision, en bas, pendant tout le
   défilement) : une capsule flottante, centrée en bas, la même partout
   (Sacha préfère la bulle à une barre pleine largeur, « vachement plus
   professionnel »). Sur grand écran, le bouton du menu s'efface pendant
   qu'elle est là. Elle entre par le bas quand script.js pose .is-on ;
   visibility suit la transition pour que le lien ne soit ni tabulable ni lu
   tant qu'elle est rangée. */
.dock {
  position: fixed; left: 50%; bottom: calc(1rem + env(safe-area-inset-bottom, 0px)); z-index: 110;
  translate: -50% 0;
  display: flex; align-items: center; gap: .5rem;
  width: max-content; max-width: calc(100vw - 2rem);
  padding: .45rem;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  backdrop-filter: blur(14px) saturate(1.3);
  border: 1px solid var(--line);
  border-radius: 99px;
  box-shadow: 0 22px 44px -22px rgba(6, 62, 64, .5);
  transform: translateY(calc(100% + 2rem));
  visibility: hidden;
  transition: transform .45s var(--ease-out), visibility 0s .45s;
}
.dock.is-on {
  transform: none;
  visibility: visible;
  transition: transform .45s var(--ease-out), visibility 0s;
}
/* Un peu plus grande depuis le 27 septembre 2026 (Sacha la trouvait petite) */
.dock-cta { flex: 0 0 auto; justify-content: center; padding: 1rem 1.95rem; font-size: 1.04rem; }
.dock-tel {
  flex: 0 0 auto;
  width: 54px; height: 54px;
  display: grid; place-items: center;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--paper-3);
  color: var(--ink);
  transition: border-color .25s, transform .3s var(--ease-out);
}
.dock-tel:hover { border-color: var(--ink); transform: translateY(-2px); }
.dock-tel svg { width: 24px; height: 24px; }
/* Sur les plus petits téléphones (moins de 375px), le bouton resserre ses
   marges pour que la bulle tienne dans l'écran */
@media (max-width: 374px) { .dock-cta { padding-inline: 1.35rem; } }
@media (max-width: 339px) {
  .dock-cta { padding-inline: .85rem; font-size: .98rem; }
  .dock-tel { width: 48px; height: 48px; }
}
/* Le pied de page garde ses dernières lignes lisibles au-dessus de la barre */
.site-foot { padding-bottom: calc(clamp(2.5rem, 5vw, 4rem) + 4.8rem); }
@media (min-width: 861px) {
  .dock { bottom: 1.4rem; }
  .menu-cta {
    transition: transform .3s var(--ease-out), background-color .25s, opacity .3s, visibility 0s;
  }
  body.dock-on .menu-cta {
    opacity: 0; visibility: hidden;
    transform: translateY(-8px);
    transition: transform .3s var(--ease-out), opacity .3s, visibility 0s .3s;
  }
}

/* ── Révélations au scroll ───────────────────────────────── */

[data-reveal] {
  opacity: 0;
  transform: translateY(26px);
  transition:
    opacity .85s var(--ease-out),
    transform .85s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 95ms);
}
[data-reveal].in-view { opacity: 1; transform: none; }

/* ── Responsive ──────────────────────────────────────────── */

@media (max-width: 960px) {
  .cards { grid-template-columns: repeat(2, 1fr); }
  .cards > .card, .cards > .card:nth-child(4):nth-last-child(2), .cards > .card:nth-child(5):last-child { grid-column: auto; }
  .steps { grid-template-columns: repeat(2, 1fr); }
  .tech-grid { grid-template-columns: repeat(2, 1fr); }
  .tech, .tech:nth-child(4):nth-last-child(2), .tech:nth-child(5):last-child { grid-column: auto; }
  .parcours { grid-template-columns: 1fr; }
  .portrait { position: static; max-width: 320px; }
  .contact-grid { grid-template-columns: 1fr 1fr; }
  .contact-card-primary { grid-column: 1 / -1; }
}

@media (max-width: 860px) {
  .nav-toggle { display: inline-flex; }
  .eyebrow-city { display: none; }
  .menu {
    position: absolute;
    top: calc(100% + 0px); left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--paper);
    border-bottom: 1px solid var(--line);
    box-shadow: 0 30px 40px -30px rgba(6, 62, 64, .4);
    padding: .6rem clamp(1.25rem, 4vw, 2.5rem) 1.4rem;
    display: none;
  }
  .site-nav.open .menu { display: flex; }
  .site-head:not(.is-scrolled):has(.site-nav.open) { background: var(--paper); box-shadow: 0 1px 0 var(--line); }
  .menu li { border-bottom: 1px solid var(--line); }
  .menu li:last-child { border-bottom: 0; padding-top: 1rem; }
  .menu a[data-nav] { display: block; padding: .95rem .2rem; font-size: 1.05rem; }
  .menu a[data-nav]::after { display: none; }
  .menu-cta { display: block; text-align: center; padding: .9rem; }
}

@media (min-width: 721px) and (max-width: 960px) {
  .cards > .card:last-child:nth-child(odd) {
    grid-column: 1 / -1;
    justify-self: center;
    width: calc(50% - .6rem);
  }
}

@media (max-width: 720px) {
  body { font-size: 1rem; }
  .cards, .infos-grid, .contact-grid, .tech-grid, .pledges { grid-template-columns: 1fr; }
  .bodymap { grid-template-columns: 1fr; gap: 3rem; --flou-entree: 5px; --flou-swap: 2.5px; }
  .figure-stage { max-width: 240px; }
  .zone-panel { border-left: 0; padding-left: 0; border-top: 1px solid var(--line-dark); padding-top: 2rem; min-height: 280px; justify-content: flex-start; }
  .steps { grid-template-columns: 1fr; }
  .timeline li { grid-template-columns: 1fr; gap: .3rem; }
  .foot-in { grid-template-columns: 1fr; }
  /* L'indicateur de défilement est une affordance de bureau : au doigt il ne
     sert à rien, et il bloquait tout le bas du héros. */
  .hero-scroll { display: none; }
  .hero { --hero-pt: 6.5rem; --hero-pb: 3rem; }
  /* Le rappel de la carte se fait plus petit : le héros mobile est déjà long */
  .hero-sign { margin-bottom: 1.1rem; }
  .hero-sign .signature { font-size: 2.2rem; }
  .hero-actions .btn { flex: 1 1 auto; justify-content: center; }
}

/* ── Accessibilité : mouvement réduit ────────────────────── */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .hero-form-fill, body.is-loaded .hero-form-fill { opacity: 1; animation: none; }
  .hero-form-lines { display: none; }
  .hero-sign, .hero-eyebrow, .hero-title, .hero-sub, .hero-actions, .hero-badge, .hero-scroll { opacity: 1; animation: none; }
  [data-reveal] { opacity: 1; transform: none; }
  .marquee-track { animation: none; flex-wrap: wrap; }
  .marquee-list:last-child { display: none; }
}

/* ── Impression ──────────────────────────────────────────── */

@media print {
  .grain, .progress, .hero-badge, .hero-scroll, .marquee,
  .site-head, .spot, .hero-art, .dock { display: none !important; }
  body { background: #fff; color: #000; }
  .section, .hero { padding-block: 1.5rem; min-height: 0; }
  .section-dark, .section-contact, .site-foot { background: #fff; color: #000; }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
  .tech-grid.is-rail .tech { translate: none !important; animation: none !important; }
  .faq-a { grid-template-rows: 1fr; }
}
