/* ==========================================================================
   Mattdouuu — Coaching EVA · direction « La lampe »
   Salle noire, une seule source verte qui désigne, hero cinétique en tête,
   listes en lignes plutôt qu'en cartes, pilules pour tout ce qui se clique.
   ========================================================================== */

:root {
  --bg:          #08090a;
  --text:        #f2f0ec;
  --text-soft:   rgba(242, 240, 236, .62);
  --text-dim:    rgba(242, 240, 236, .58);
  --text-faint:  rgba(242, 240, 236, .16);

  --line:        rgba(242, 240, 236, .14);
  --line-strong: rgba(242, 240, 236, .3);
  --surface:     rgba(242, 240, 236, .03);

  /* Repli sRGB d'abord : un navigateur sans oklch ignore la ligne suivante
     et garde l'hexadécimal, au lieu de perdre la couleur.

     Deux rouges, et la raison est mesurée. Le rouge de l'affiche, #cf1d20,
     tient 3,65:1 sur le noir d'arène — en dessous du seuil AA, aussi bien
     comme texte que comme fond de bouton à texte sombre. Sur fond clair il
     passe (4,79:1 sous du crème), ce qui explique qu'il fonctionne sur
     l'affiche imprimée et pas ici. L'accent est donc la même teinte (27°)
     relevée en clarté jusqu'à 5,08:1 dans les deux sens ; la valeur exacte
     de l'affiche est gardée pour l'atmosphère, où elle ne porte aucun texte. */
  --accent:      #E8453F;
  --accent:      oklch(0.63 0.201 27);
  --accent-deep: #CF1D20;
  --accent-deep: oklch(0.55 0.209 27);

  --font:  "Space Grotesk", "Space Grotesk repli", Helvetica, Arial, sans-serif;
  --mono:  "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Echelle typographique : un role par pas, jamais une valeur au cas par
     cas. Le plancher est 11px — sous cette taille, un texte fonctionnel
     n'est plus lisible sur un fond noir, quel que soit le soin du reste. */
  --t-label:    11px;  /* mono capitales : labels, nav, meta, cite, erreurs */
  --t-action:   12px;  /* mono capitales des boutons */
  --t-small:    14px;  /* corps secondaire : etapes, infos, notes, alertes */
  --t-body:     16px;  /* corps courant, champs de saisie, listes */
  --t-lede:     18px;  /* chapo de hero */
  --t-title:    21px;  /* intertitres — un seul role pour tous les h3 */
  --t-lead:     26px;  /* citations, nom d'offre */
  --t-figure:   36px;  /* chiffres cles et prix */
  --t-numeral:  64px;  /* numero d'etape, purement decoratif */

  --t-row:       clamp(19px, 2.2vw, 26px);
  --t-heading:   clamp(22px, 2.8vw, 32px);
  --t-statement: clamp(24px, 3.4vw, 42px);

  /* Approche des grands titres. Le resserrement est optique : il ne vaut
     que la ou les lettres sont assez grandes pour l'absorber. Sous 900px de
     large, le titre passe sous ~90px et retrouve une approche normale. */
  --track-display:  -.025em;
  --lead-statement: 1.32;

  --col:      780px;   /* colonne de lecture */
  --col-wide: 900px;   /* grilles à deux ou trois colonnes */
  --gap-section: 120px;

  --ease: cubic-bezier(.16, 1, .3, 1);
  /* La courbe longue des références : ça glisse et ça s'arrête sans à-coup. */
  --glide: cubic-bezier(.19, 1, .22, 1);

  /* Alimentées image par image par motion.js. Le JS ne fournit que des
     nombres : toute la mise en forme reste ici. */
  --bx: 0px; --by: 0px;      /* dérive de la photo dans les lettres */
  --lampx: 50vw; --lampy: 30vh;
  --p: 0;                    /* progression dans le hero d'accueil, 0 → 1 */
}

/* Repli metriquement compatible de Space Grotesk. Sans lui, la page s'affiche
   d'abord en Arial — plus large de 2,3 % et plus haute de x-height — puis
   saute au moment ou la fonte arrive (`display=swap`). Les valeurs viennent
   des tables des deux fontes : largeur moyenne 0.566 contre 0.5796 em,
   ascendante 0.984, descendante 0.292, sans interligne additionnel. */
@font-face {
  font-family: "Space Grotesk repli";
  src: local("Liberation Sans"), local("Arial"), local("Helvetica Neue"), local("Helvetica");
  size-adjust: 97.66%;
  ascent-override: 100.76%;
  descent-override: 29.9%;
  line-gap-override: 0%;
}

* { box-sizing: border-box; }

html {
  background: var(--bg);
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--t-body);
  /* Un cran au-dessus de l'usage : un texte clair sur fond noir grossit
     optiquement et se referme plus vite qu'un texte sombre sur blanc. */
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

a { color: inherit; text-decoration: none; transition: color .25s var(--ease); }
a:hover { color: var(--accent); }

/* Un lien au fil du texte ne peut pas se signaler par la seule couleur : il
   porte un trait, pose assez bas pour ne pas toucher les jambages. */
p a:not(.btn) {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .22em;
  text-decoration-color: oklch(0.63 0.201 27 / .45);
  transition: text-decoration-color .25s var(--ease);
}
p a:not(.btn):hover { text-decoration-color: var(--accent); }

::selection { background: var(--accent); color: var(--bg); }

/* Les surfaces que le navigateur dessine a notre place appartiennent aussi
   a la direction. */
html { scrollbar-color: var(--line-strong) var(--bg); }
input, textarea { caret-color: var(--accent); }

input, select, textarea, button { font-family: inherit; }

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

@keyframes mc-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes mc-bob  { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(8px); } }

/* ------------------------------------------------------------ Fond global */

/* Trame de points + deux halos, tous en `fixed` : l'ambiance ne défile pas
   avec le contenu, ce qui donne la sensation de profondeur. */
.grain, .halo {
  position: fixed;
  z-index: 0;
  pointer-events: none;
}

.grain {
  inset: 0;
  opacity: .5;
  background-image: radial-gradient(rgba(255, 255, 255, .045) 1px, transparent 1px);
  background-size: 3px 3px;
}

.halo {
  border-radius: 999px;
  filter: blur(30px);
}
.halo--a {
  top: -25%;
  left: -12%;
  width: 70vw;
  height: 70vw;
  background: radial-gradient(circle, oklch(0.63 0.201 27 / .13), transparent 62%);
}
.halo--b {
  bottom: -32%;
  right: -16%;
  width: 65vw;
  height: 65vw;
  background: radial-gradient(circle, oklch(0.55 0.209 27 / .15), transparent 62%);
}

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

.site-head {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 32px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: var(--t-body);
  letter-spacing: -.01em;
}
.brand:hover { color: var(--text); }
.brand__dot {
  width: 9px;
  height: 9px;
  border-radius: 999px;
  background: var(--accent);
  flex: none;
}

.pill-nav {
  position: relative;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px;
  border-radius: 999px;
  border: 1px solid rgba(242, 240, 236, .16);
  background: rgba(8, 9, 10, .7);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  list-style: none;
  margin: 0;
}

.pill-nav a {
  display: block;
  padding: 9px 16px;
  border-radius: 999px;
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(242, 240, 236, .68);
  transition: background .25s var(--ease), color .25s var(--ease);
  white-space: nowrap;
}
.pill-nav a:hover { color: var(--text); }

/* Sans JavaScript, la pilule active garde son fond : c'est le repli. */
.pill-nav a.is-active { background: var(--accent); color: var(--bg); }

/* Avec JavaScript, un seul curseur glisse d'un onglet à l'autre — y compris
   au survol, qui le fait venir en avant-première avant de revenir en place. */
.pill-nav--glide a.is-active { background: none; color: rgba(242, 240, 236, .65); }
.pill-nav--glide a.is-lit,
.pill-nav--glide a.is-lit:hover { color: var(--bg); }

.pill-nav__glider {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
  border-radius: 999px;
  background: var(--accent);
  pointer-events: none;
  transition: transform .42s var(--ease), width .42s var(--ease), height .42s var(--ease);
}
/* Au premier placement, le curseur ne doit pas traverser l'écran. */
.pill-nav__glider--placing { transition: none; }

.pill-nav li { position: relative; z-index: 1; }

@media (max-width: 640px) {
  .site-head { padding: 14px 16px; }
  /* Sous 640px, seul le point vert reste visible — mais le libellé doit rester
     lisible par un lecteur d'écran, sinon le lien vers l'accueil n'a plus
     aucun nom accessible (le point, lui, est aria-hidden). */
  .brand {
    min-width: 44px;
    min-height: 44px;
    justify-content: center;
  }
  .brand__label {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }
  .pill-nav { gap: 2px; padding: 4px; }
  /* 44px de haut au doigt : 13px de padding vertical + 18px de hauteur de
     ligne. Le padding horizontal se resserre pour que les quatre onglets
     tiennent toujours a 360px de large. */
  /* 44 px de haut au doigt, et la barre doit tenir dans 390 px : au-delà,
     `overflow-x: clip` rognait silencieusement l'onglet « Réserver ». */
  .pill-nav a { padding: 14px 9px; font-size: var(--t-label); letter-spacing: .05em; }
}

/* ---------------------------------------------------------------- Hero */

/* Les anneaux ont disparu : la signature du site est maintenant le bloc
   typographique et la photo qui vit à l'intérieur des lettres. */

.hero {
  position: relative;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 130px 32px 70px;
}
.hero > * { position: relative; z-index: 2; }

.hero--about { min-height: 62vh; padding: 150px 32px 50px; }
.hero--contact { min-height: 54vh; padding: 160px 32px 40px; }
.hero--book { min-height: 52vh; padding: 160px 32px 30px; }

/* -------------------------------------------------- Hero d'accueil (A+) --

   La scène est plus haute que l'écran et le hero y adhère : il tient en place
   pendant qu'on descend, le temps que le titre se retire et que la photo
   s'ouvre. C'est un seul geste joué en sens inverse entre le texte et l'image.
   -------------------------------------------------------------------------- */

.stage { position: relative; height: 210vh; }

.hero--home {
  position: sticky;
  top: 0;
  height: 100vh;
  min-height: 0;
  display: block;
  padding: 0;
  overflow: hidden;
  text-align: left;
}

.hero__bed,
.hero__veil,
.hero__lamp { position: absolute; inset: 0; pointer-events: none; }

.hero__bed {
  z-index: 1;
  background-image: url("../img/arene-eva.webp");
  background-size: cover;
  background-position: center;
  /* L'image attend que le titre soit parti pour s'ouvrir : sans ce retard,
     les deux rampes se superposent et le milieu du geste est illisible. */
  opacity: calc(.13 + max(0, var(--p) - .3) * 1.0572);
  transform: scale(calc(1.04 + var(--p) * .1));
  filter: grayscale(calc(.55 - var(--p) * .55)) contrast(1.08);
}

.hero__veil {
  z-index: 2;
  background: radial-gradient(125% 85% at 50% 6%,
    transparent 18%, rgba(8, 9, 10, .88) 66%, var(--bg) 100%);
  opacity: calc(1 - var(--p) * .72);
}

/* La lampe suit la main avec du retard. Au-dessus du voile pour éclairer
   vraiment, sous le texte pour ne pas le laver. */
.hero__lamp {
  z-index: 3;
  inset: auto;
  left: 0; top: 0;
  width: 820px; height: 820px;
  margin: -410px 0 0 -410px;
  border-radius: 50%;
  mix-blend-mode: screen;
  background: radial-gradient(circle,
    oklch(0.55 0.209 27 / .24), oklch(0.55 0.209 27 / .08) 42%, transparent 68%);
  transform: translate3d(var(--lampx), var(--lampy), 0);
  opacity: calc(1 - var(--p) * 2.2);
}

.hero--home.is-faded .hero__wrap {
  visibility: hidden;
  pointer-events: none;
}

.hero__wrap {
  position: relative;
  z-index: 10;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  max-width: 1500px;
  margin: 0 auto;
  padding: 110px clamp(20px, 4vw, 56px) 90px;
  /* Le retrait est terminé à --p .42, et le mouvement s'arrête avec lui :
     un titre invisible qui continue de bouger consomme des frames pour rien. */
  /* Le titre ne se dissout pas sur place : il monte et sort. Un fondu de blanc
     sur noir traverse forcément une zone de contraste basse, donc l'opacité
     reste pleine tant que le texte est lisible à l'écran (jusqu'à --p .30) et
     ne tombe qu'une fois le bloc largement remonté hors cadre. Le mouvement
     s'arrête à .42, avec la disparition : un titre invisible qui continue de
     bouger consomme des frames pour rien. */
  transform: translate3d(0, calc(min(var(--p), .42) * -1050px), 0)
             scale(calc(1 - min(var(--p), .42) * .167));
  transform-origin: left center;
}

/* L'échelle affiche : interlignage écrasé, capitales, chasse resserrée. */
.mega {
  margin: 0;
  /* Sort d'abord, s'efface ensuite : voir « La Règle du Croisement ». */
  opacity: calc(1 - max(0, var(--p) - .3) * 8.34);
  font-weight: 700;
  font-size: clamp(56px, 13.2vw, 208px);
  line-height: .80;
  letter-spacing: -.04em;
  text-transform: uppercase;
}
/* À .80 d'interligne, le masque des lignes rognait l'accent des capitales
   (ARRÊTE) : on agrandit la zone visible vers le haut et on la rattrape en
   marge, donc l'interlignage ne bouge pas. */
.mega .ln {
  display: block;
  overflow: hidden;
  padding-top: .18em;
  margin-top: -.18em;
}
.mega .ln > span { display: block; }

.js-motion .mega .ln > span {
  transform: translateY(105%);
  animation: mc-rise 1.15s var(--glide) forwards;
  animation-delay: var(--d, 0s);
}
@keyframes mc-rise { to { transform: translateY(0); } }

/* La photo ne vit qu'à l'intérieur de cette ligne, et elle bouge : dérive
   lente en fond, décalage supplémentaire donné par le curseur. Elle est
   éclaircie avant d'être teintée, sinon la jungle vire au vert boueux. */
.shot-type {
  background-image:
    linear-gradient(oklch(0.63 0.201 27 / .4), oklch(0.63 0.201 27 / .4)),
    url("../img/arene-eva.webp");
  background-size: 180% auto;
  background-position: calc(50% + var(--bx)) calc(45% + var(--by));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: brightness(1.5) contrast(1.3) saturate(1.25);
}

.hero__under {
  /* Course supplémentaire : le chapô et le bouton démarrent ~650 px sous le
     titre, donc les 441 px du bloc ne suffisent pas à les sortir du cadre. */
  transform: translate3d(0, calc(min(var(--p), .42) * -950px), 0);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(20px, 4vw, 56px);
  margin-top: clamp(28px, 4vw, 52px);
}
.js-motion .hero__under {
  opacity: 0;
  animation: mc-fade 1.1s var(--glide) 1.05s forwards;
}
@keyframes mc-fade { to { opacity: 1; } }

.hero__under > * { opacity: calc(1 - max(0, var(--p) - .36) * 16.7); }
.hero__under .lede { margin: 0; max-width: 38ch; text-align: left; }

@media (max-width: 720px) {
  .stage { height: 190vh; }
  /* Pas de curseur à suivre : la lampe descend avec le défilement. Le concept
     survit au téléphone au lieu d'être une exclusivité de bureau. */
  .hero__lamp {
    width: 132vw;
    height: 132vw;
    margin: -66vw 0 0 -66vw;
    --lampx: 50vw;
    --lampy: calc(26vh + var(--p) * 34vh);
  }
}

.eyebrow {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 26px;
}

.display {
  margin: 0;
  font-size: clamp(46px, 8.4vw, 138px);
  line-height: .88;
  letter-spacing: var(--track-display);
  font-weight: 700;
  max-width: 13ch;
  text-wrap: balance;
}
.display--sm { font-size: clamp(42px, 7.4vw, 116px); max-width: 14ch; }
.display--xs { font-size: clamp(38px, 6.6vw, 104px); line-height: .9; max-width: 14ch; }

.accent { color: var(--accent); }

/* Mot souligné d'un trait qui se dessine quand la section se révèle. Un peu
   plus lent que l'entrée des blocs : le trait doit se lire comme un geste,
   pas comme un effet de plus.
   `nowrap` garde le mot d'un seul tenant — un trait en position absolue sur
   un mot coupé en deux lignes se déforme. */
.mark {
  position: relative;
  white-space: nowrap;
}
.mark::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -.14em;
  height: .05em;
  border-radius: 999px;
  background: currentColor;
  transform-origin: left center;
}

/* Sans JavaScript, le trait est simplement là. */
.js-motion .mark::after { transform: scaleX(0); }
.js-motion .is-in .mark::after {
  transform: scaleX(1);
  transition: transform .95s var(--ease) .4s;
}
/* Space Grotesk n'a pas d'italique : `font-style: italic` forcait le
   navigateur a en synthetiser un en penchant les glyphes, ce qui casse leur
   dessin. Le contraste de graisse (400 dans un titre a 700) et la couleur
   isolent deja le mot. */
.accent-soft { font-weight: 400; color: var(--accent); }

.lede {
  margin: 30px auto 40px;
  max-width: 46ch;
  font-size: var(--t-lede);
  line-height: 1.6;
  color: var(--text-soft);
  text-wrap: pretty;
}
.lede--tight { margin-bottom: 0; }

/* Indice de défilement : il s'efface dès que le geste du hero commence. */
.cue {
  position: absolute;
  z-index: 14;
  left: 50%;
  bottom: 30px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text-dim);
  opacity: calc(1 - var(--p) * 2.4);
  pointer-events: none;
}
.cue i {
  display: block;
  width: 1px;
  height: 34px;
  background: linear-gradient(var(--accent), transparent);
  animation: mc-cue 2.4s var(--glide) infinite;
}
@keyframes mc-cue {
  0%   { transform: scaleY(.3); transform-origin: top; opacity: 0; }
  40%  { transform: scaleY(1); opacity: 1; }
  100% { transform: scaleY(1); transform-origin: bottom; opacity: 0; }
}

.btn {
  display: inline-block;
  padding: 18px 34px;
  border-radius: 999px;
  border: 1px solid transparent;
  cursor: pointer;
  font-family: var(--mono);
  font-size: var(--t-action);
  letter-spacing: .14em;
  text-transform: uppercase;
  transition: background .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease);
}
.btn--accent { background: var(--accent); color: var(--bg); }
.btn--accent:hover { background: var(--text); color: var(--bg); }
.btn--ghost {
  background: none;
  border-color: var(--line-strong);
  color: var(--text);
}
.btn--ghost:hover { background: var(--text); color: var(--bg); }
.btn--lg { padding: 20px 38px; }
.btn--block { display: block; width: 100%; text-align: center; }

/* ------------------------------------------------------------- Sections */

.section {
  position: relative;
  z-index: 2;
  max-width: var(--col);
  margin: 0 auto;
  padding: var(--gap-section) 32px 0;
}
.section--first { padding-top: 40px; }
.section--wide { max-width: var(--col-wide); }
.section--center { text-align: center; }

.label {
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 400;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin: 0 0 34px;
}
.label--center { text-align: center; }

/* Le portrait est détouré : pas de cadre, pas de cercle. Un cercle voudrait
   dire « cliquable » dans ce système, et une boîte contredirait la règle du
   filet. La tête se pose simplement sur le fond. */
.portrait {
  display: block;
  margin: 0 auto 34px;
  width: 250px;
  height: auto;
  /* Le doigt levé déporte le cadre : le centre de la tête est à 20 % de la
     largeur à droite du centre de l'image. Centrer la boîte ne centre donc
     pas le sujet. Le décalage remet la tête sur l'axe de la page, sans
     toucher à la mise en page — la boîte, elle, ne bouge pas. Recadrer à la
     place aurait voulu dire couper la main ou ajouter du vide à droite, donc
     rapetisser la tête. */
  transform: translateX(-19.9%);
  /* Le cadrage s'arrête au col : un dégradé éteint le maillot par le bas
     plutôt que de laisser l'image finir sur une ligne de coupe nette. Le
     départ à 78 % est calé sous le menton — plus haut, il mangerait le
     visage. */
  -webkit-mask-image: linear-gradient(to bottom, #000 78%, transparent 99%);
          mask-image: linear-gradient(to bottom, #000 78%, transparent 99%);
}


@media (min-width: 900px) {
  .portrait { width: 470px; }
}

/* Le logo du partenaire, calé sur la hauteur de capitale de la ligne qui
   l'annonce. Seul le mot est repris : le bloc de glyphes qui l'accompagne sur
   l'affiche devient illisible à cette taille. */
.foot-partner {
  display: inline-flex;
  align-items: center;
  gap: 9px;
}

.foot-partner img {
  width: auto;
  height: 12px;
  opacity: .8;
}

/* Les titres de section sont de vrais titres. Ils étaient en 11px gris à 58 %,
   donc le plan du document reposait sur le texte le plus pâle de la page. */
.section__title {
  margin: 0 0 38px;
  font-size: var(--t-heading);
  line-height: 1.2;
  letter-spacing: -.02em;
  font-weight: 500;
  text-align: center;
  text-wrap: balance;
}

/* Le palmarès en prose, pas en tuiles « grand chiffre + petit label ». */
.creds {
  margin: 26px auto 0;
  max-width: 48ch;
  font-size: var(--t-small);
  line-height: 1.6;
  color: var(--text-dim);
  text-wrap: pretty;
}

.statement {
  margin: 0;
  font-weight: 400;
  font-size: var(--t-statement);
  line-height: var(--lead-statement);
  letter-spacing: -.02em;
  text-wrap: balance;
}
.statement--sm {
  font-size: clamp(20px, 2.6vw, 30px);
  line-height: 1.38;
  letter-spacing: -.015em;
  color: rgba(242, 240, 236, .88);
}

/* Chiffres clés */
.stats {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 56px;
  margin-top: 56px;
}
.stat__value { font-size: var(--t-figure); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.stat__label {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-top: 8px;
}

/* Listes en lignes — jamais de cartes à ombre */
.rows { display: flex; flex-direction: column; }
.row {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr);
  gap: 20px;
  align-items: baseline;
  padding: 22px 0;
  border-top: 1px solid var(--line);
}
.rows .row:last-child { border-bottom: 1px solid var(--line); }
.row__num { font-family: var(--mono); font-size: var(--t-label); color: var(--accent); font-variant-numeric: tabular-nums; }
.row__text { font-size: var(--t-row); line-height: 1.3; letter-spacing: -.015em; }

.lines { display: flex; flex-direction: column; text-align: left; }
.lines > * {
  padding: 18px 0;
  border-top: 1px solid var(--line);
  font-size: var(--t-body);
  color: rgba(242, 240, 236, .78);
}
.lines > *:last-child { border-bottom: 1px solid var(--line); }

/* Offres en pilules */
.offers { display: flex; flex-direction: column; gap: 16px; }
.offer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
  padding: 28px 34px;
  border: 1px solid rgba(242, 240, 236, .16);
  border-radius: 999px;
  text-align: left;
  transition: border-color .25s var(--ease), background .25s var(--ease);
}
/* La ligne d'offre est un lien : le survol doit se voir autrement que par
   une bordure qui passe de 16 % a 30 % de blanc. */
.offer:hover {
  border-color: var(--line-strong);
  background: rgba(242, 240, 236, .04);
  color: inherit;
}
/* L'unite sous le chiffre : sans elle, « 40 € » sur deux lignes voisines
   comparait un mois a une seance d'1 h 30. */
.offer__unit {
  display: block;
  font-family: var(--font);
  font-size: var(--t-small);
  line-height: 1.45;
  /* Le resserrement du prix ne vaut que pour le chiffre : la ligne d'unité se
     lit, donc elle reprend une approche normale. */
  letter-spacing: normal;
  color: var(--text-dim);
  margin-top: 8px;
  white-space: normal;
}
.offer--featured .offer__unit { color: oklch(0.63 0.201 27 / .75); }

.offer__price { transition: transform .25s var(--ease); }
.offer:hover .offer__price { transform: translateX(4px); }
.offer__name { font-size: var(--t-lead); letter-spacing: -.015em; }
.offer__meta {
  display: block;
  font-family: var(--font);
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--text-dim);
  margin-top: 8px;
}
.offer__price {
  font-size: var(--t-figure);
  letter-spacing: -.02em;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  text-align: right;
  flex: none;
  max-width: 46%;
}

/* Mise en valeur discrete : l'etiquette mono en Vert Signal suffit a faire
   remarquer la ligne, sans lui disputer la mise en avant pleine du pack — la
   regle du Signal plafonne le vert a ~10 % d'un ecran. */
.offer__tag {
  display: block;
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 8px;
}
.offer--tagged { border-color: rgba(242, 240, 236, .3); }
.offer--tagged:hover { border-color: oklch(0.63 0.201 27 / .5); }

.offer--featured {
  border-color: oklch(0.63 0.201 27 / .5);
  background: oklch(0.63 0.201 27 / .06);
}
.offer--featured:hover { background: oklch(0.63 0.201 27 / .12); border-color: oklch(0.63 0.201 27 / .5); }
.offer--featured .offer__name,
.offer--featured .offer__price { color: var(--accent); }

@media (max-width: 560px) {
  .offer { flex-direction: column; align-items: flex-start; gap: 14px; border-radius: 22px; padding: 24px 26px; }
}

/* Étapes numérotées */
.steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 32px;
}
.step {
  border-top: 1px solid var(--line);
  padding-top: 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}
.step__num { font-size: var(--t-numeral); line-height: .8; letter-spacing: -.03em; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.step h3 { margin: 0; font-size: var(--t-title); line-height: 1.25; letter-spacing: -.01em; font-weight: 500; }
.step p { margin: 0; font-size: var(--t-small); line-height: 1.62; color: var(--text-dim); text-wrap: pretty; }

/* Témoignages */
.quotes { display: flex; flex-direction: column; gap: 60px; }
.quote { display: flex; flex-direction: column; gap: 20px; }
.quote p { margin: 0; font-size: var(--t-lead); line-height: 1.45; letter-spacing: -.012em; text-wrap: balance; }
.quote cite {
  font-family: var(--mono);
  font-size: var(--t-label);
  font-style: normal;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-dim);
}

/* Bloc d'appel final */
.cta {
  position: relative;
  z-index: 2;
  border-top: 1px solid var(--line);
  margin-top: var(--gap-section);
  padding: 110px 32px;
  text-align: center;
}
.cta h2 {
  margin: 0 auto 34px;
  font-size: clamp(40px, 8vw, 120px);
  line-height: .88;
  letter-spacing: var(--track-display);
  max-width: 11ch;
  text-wrap: balance;
}
.cta h2.cta__title--sm {
  font-size: clamp(36px, 6.4vw, 96px);
  line-height: .9;
  max-width: 14ch;
  margin-bottom: 30px;
}

/* Principes (page À propos) */
.principles { display: flex; flex-direction: column; gap: 48px; }
.principle {
  display: flex;
  flex-direction: column;
  gap: 12px;
  border-top: 1px solid var(--line);
  padding-top: 22px;
}
.principle__step {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent);
}
.principle h3 {
  margin: 0;
  font-size: var(--t-heading);
  line-height: 1.22;
  letter-spacing: -.02em;
  font-weight: 500;
}
.principle p { margin: 0; max-width: 62ch; font-size: var(--t-body); line-height: 1.62; color: var(--text-soft); text-wrap: pretty; }

/* Deux colonnes */
.duo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 48px;
}
.duo__label {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 18px;
}
.duo__label--accent { color: var(--accent); }
.duo__list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: var(--t-body);
  line-height: 1.55;
  color: rgba(242, 240, 236, .78);
  min-width: 0;
  overflow-wrap: anywhere;
}

/* ---------------------------------------------------------- Formulaire */

.form {
  display: flex;
  flex-direction: column;
  gap: 18px;
  max-width: 620px;
  margin: 0 auto;
}

.field { display: flex; flex-direction: column; gap: 8px; min-width: 0; }

.form input,
.form select,
.form textarea {
  width: 100%;
  min-width: 0;
  padding: 18px 24px;
  border-radius: 999px;
  border: 1px solid rgba(242, 240, 236, .18);
  background: var(--surface);
  color: var(--text);
  font-size: var(--t-body);
  outline: none;
  transition: border-color .25s var(--ease);
}
.form textarea { border-radius: 22px; resize: vertical; min-height: 130px; }
.form select { appearance: none; color: rgba(242, 240, 236, .7); }
.form select option { background: #101112; color: var(--text); }
/* Le libelle visible du champ EST son placeholder (le <label> est en
   sr-only) : il doit donc tenir le contraste d'un vrai texte. */
.form input::placeholder, .form textarea::placeholder { color: rgba(242, 240, 236, .58); }
.form input:focus, .form select:focus, .form textarea:focus { border-color: var(--accent); }

.field__error {
  display: none;
  padding-left: 24px;
  font-family: var(--mono);
  /* Un message d'erreur se lit vite ou ne se lit pas. En capitales espacees,
     44 caracteres deviennent une frise a dechiffrer : il garde sa casse. */
  font-size: var(--t-action);
  letter-spacing: .01em;
  color: var(--accent);
}
.field--invalid input,
.field--invalid textarea { border-color: var(--accent); }
.field--invalid .field__error { display: block; }

.form-note {
  margin: 0;
  text-align: center;
  max-width: 62ch;
  margin-inline: auto;
  font-size: var(--t-small);
  line-height: 1.55;
  color: var(--text-dim);
  text-wrap: pretty;
}

/* Espacements de rythme, nommes plutot qu'ecrits en dur dans le gabarit. */
.form-note--spaced { margin-top: 24px; }
.form-note--tight  { margin-top: 10px; }
.lines--spaced     { margin-top: 60px; }

.alert {
  padding: 16px 24px;
  border-radius: 22px;
  border: 1px solid var(--line);
  font-size: var(--t-small);
  line-height: 1.55;
}
.alert--ok { border-color: oklch(0.63 0.201 27 / .45); background: oklch(0.63 0.201 27 / .07); }
.alert--error { border-color: rgba(255, 120, 100, .45); background: rgba(255, 120, 100, .07); }

/* ----------------------------------------------------------------- FAQ */

.faq { display: flex; flex-direction: column; }
.faq__item { padding: 24px 0; border-top: 1px solid var(--line); }
.faq__item:last-child { border-bottom: 1px solid var(--line); }
.faq__item h3 { margin: 0 0 10px; font-size: var(--t-title); line-height: 1.25; letter-spacing: -.01em; font-weight: 500; }
.faq__item p { margin: 0; max-width: 62ch; font-size: var(--t-body); line-height: 1.62; color: var(--text-soft); text-wrap: pretty; }

/* Infos pratiques */
.infos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 36px;
}
.infos > div { border-top: 1px solid var(--line); padding-top: 18px; min-width: 0; }
.infos :is(h2, h3) { margin: 0 0 10px; font-size: var(--t-title); line-height: 1.25; letter-spacing: -.01em; font-weight: 500; }
.infos p { margin: 0; font-size: var(--t-small); line-height: 1.62; color: var(--text-dim); text-wrap: pretty; }

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

.site-foot {
  position: relative;
  z-index: 2;
  border-top: 1px solid var(--line);
  margin-top: var(--gap-section);
  padding: 44px 32px;
  display: flex;
  flex-wrap: wrap;
  gap: 26px;
  justify-content: space-between;
  align-items: center;
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.site-foot span:first-child { color: var(--text); }
/* Une adresse email en capitales espacees ne se lit pas et ne se recopie
   pas : c'est la seule chaine du pied de page qui garde sa casse. */
.site-foot a {
  overflow-wrap: anywhere;
  text-transform: none;
  letter-spacing: .02em;
}

/* ---------------------------------------------------------- Utilitaires */

.spacer { height: 110px; }
.hidden { display: none !important; }
.mono-note { font-size: var(--t-small); color: var(--text-dim); }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Le resserrement optique n'est valide qu'a partir du moment ou le titre
   est vraiment grand : au-dela de 900px de large, le Display depasse ~90px
   et absorbe une approche negative que 46px ne supporterait pas. */
@media (min-width: 900px) {
  :root {
    --track-display: -.04em;
    --lead-statement: 1.25;
  }
}

@media (max-width: 720px) {
  :root { --gap-section: 84px; }
  .section { padding-left: 22px; padding-right: 22px; }
  .cta { padding: 84px 22px; }
  .site-foot { padding: 32px 22px; }
  .stats { gap: 34px; }
}

/* ------------------------------------------------------------ Mouvement */

/* L'état masqué dépend de .js-motion, posée par un script inline : si le
   JavaScript échoue, tout reste visible. */
@media (prefers-reduced-motion: no-preference) {
  .js-motion :is(
    .label, .statement, .stats, .rows, .offers, .steps, .quotes,
    .lines, .principles, .duo, .form, .faq, .infos,
    .cta h2, .cta .btn,
    .hero:not(.hero--home) :is(.eyebrow, .display, .lede, .btn)
  ) {
    opacity: 0;
    transform: translate3d(0, 22px, 0);
    will-change: opacity, transform;
  }

  .js-motion :is(
    .label, .statement, .stats, .rows, .offers, .steps, .quotes,
    .lines, .principles, .duo, .form, .faq, .infos,
    .cta h2, .cta .btn,
    .hero:not(.hero--home) :is(.eyebrow, .display, .lede, .btn)
  ).is-in {
    opacity: 1;
    transform: none;
    transition: opacity .8s var(--ease) var(--d, 0ms),
                transform .8s var(--ease) var(--d, 0ms);
    will-change: auto;
  }
}

/* Bouton aimanté : pas de transition pendant le suivi du curseur. */
.btn.is-pulled { transition: background .25s var(--ease), color .25s var(--ease); }

@media (prefers-reduced-motion: reduce) {
  /* Le geste ne joue pas, donc la course qui le portait n'a plus de raison
     d'être : sans cette règle, l'écran reste identique sur 990 px. */
  .stage { height: 100vh; }

  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }

  /* Couper l'animation ne suffit pas : il faut aussi défaire l'état de
     départ, sinon le contenu reste masqué pour de bon. */
  .js-motion .mega .ln > span { transform: none !important; }
  .js-motion .hero__under { opacity: 1 !important; }
  .hero__lamp { display: none; }
}
