/* =========================================================================
   Droper — feuille de style unique.

   Organisation :
     1. Polices          @font-face
     2. Tokens           couleurs, typographie, espacement, motion
     3. Base             reset ciblé, éléments natifs
     4. Primitives       .container, .btn, .eyebrow, .reveal
     5. Composants       header, hero, carousel, features, steps…
     6. Utilitaires
   ========================================================================= */

/* 1. Polices ------------------------------------------------------------- */

@font-face {
  font-family: "Hedvig Letters Serif";
  src: url("../fonts/hedvig-letters-serif-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("../fonts/inter-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("../fonts/inter-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* 2. Tokens -------------------------------------------------------------- */

:root {
  /* Couleurs. Le fond n'est pas un noir pur mais un noir très légèrement
     cyan : c'est ce qui fait tenir l'accent turquoise sans le faire vibrer. */
  --bg: #000000;
  --surface: #001111;
  --surface-raised: #041a1a;

  --accent: #2bece8;
  --accent-soft: #d4f1be;
  --accent-dim: rgb(43 236 232 / 0.6);
  /* Dégradé de marque : fond du CTA final, des cartes de résultats, et des
     chiffres posés sur fond sombre. */
  --gradient-accent: linear-gradient(110deg, #2bece8 0%, #7fe8cf 42%, #dcf2bc 100%);

  --text: #ffffff;
  --text-muted: rgb(255 255 255 / 0.6);
  --text-faint: rgb(255 255 255 / 0.4);

  --border: rgb(255 255 255 / 0.1);
  --border-strong: rgb(255 255 255 / 0.18);
  --scrim: rgb(0 0 0 / 0.6);

  /* Typographie. Les titres sont en serif à interlignage très serré (1em) :
     c'est le contraste serif large / grotesque discret qui porte la page. */
  --font-display: "Hedvig Letters Serif", ui-serif, Georgia, serif;
  --font-body: "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif;

  /* Échelle fluide : les bornes reprennent les paliers mobile → desktop.
     clamp() évite trois jeux de media queries pour la seule taille de texte. */
  --step-display: clamp(2.5rem, 1.1rem + 6.2vw, 5rem);      /* 40 → 80 */
  --step-h2: clamp(2rem, 1.3rem + 3.1vw, 3.5rem);           /* 32 → 56 */
  --step-h3: clamp(1.75rem, 1.4rem + 1.6vw, 2.5rem);        /* 28 → 40 */
  --step-h4: clamp(1.25rem, 1.15rem + 0.4vw, 1.5rem);       /* 20 → 24 */
  --step-lead: clamp(1.25rem, 1.15rem + 0.4vw, 1.5rem);     /* 20 → 24 */
  --step-body: clamp(0.9375rem, 0.92rem + 0.1vw, 1rem);     /* 15 → 16 */
  --step-body-lg: clamp(1rem, 0.95rem + 0.2vw, 1.125rem);   /* 16 → 18 */
  --step-small: 0.875rem;                                   /* 14 */

  --leading-tight: 1;
  --leading-snug: 1.1;
  --leading-normal: 1.5;
  --tracking: -0.02em;

  /* Espacement — échelle de 4px, nommée par usage plutôt que par taille. */
  --space-2xs: 0.5rem;
  --space-xs: 0.75rem;
  --space-sm: 1rem;
  --space-md: 1.5rem;
  --space-lg: 2rem;
  --space-xl: 3rem;
  --space-2xl: 4rem;
  --space-3xl: 6rem;
  --section-y: clamp(4rem, 2rem + 8vw, 8rem);

  --container: 76rem;
  --container-narrow: 44rem;
  --radius-sm: 0.5rem;
  --radius-md: 1rem;
  --radius-lg: 1.5rem;
  --radius-panel: 2.5rem;
  --radius-pill: 999px;
  /* Encart des grands panneaux par rapport au bord de la fenêtre. */
  --panel-inset: 1rem;

  /* Motion. Le ressort de Framer (bounce 0, ~0.5s) se traduit par une courbe
     qui décélère franchement sans dépasser — d'où un ease-out marqué. */
  --ease-spring: cubic-bezier(0.16, 1, 0.3, 1);
  --dur-fast: 160ms;
  --dur-med: 320ms;
  --dur-slow: 560ms;
  /* Titres découpés. Valeurs calées sur l'original au chronomètre : le
     décalage se déduit de l'étalement total (~440 ms sur 25 unités), pas de
     l'écart entre deux unités — plusieurs partent dans la même image. */
  --split-dur: 320ms;
  --split-step: 18ms;
}

/* 3. Base ---------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--step-body);
  line-height: var(--leading-normal);
  letter-spacing: var(--tracking);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: var(--tracking);
  text-wrap: balance;
}

h1 {
  font-size: var(--step-display);
  line-height: var(--leading-tight);
}
h2 {
  font-size: var(--step-h2);
  line-height: var(--leading-snug);
}
h3 {
  font-size: var(--step-h3);
  line-height: var(--leading-snug);
}
h4 {
  font-size: var(--step-h4);
  line-height: 1.2;
}

p {
  margin: 0;
  text-wrap: pretty;
}

a {
  color: inherit;
  text-decoration: none;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

/* `[hidden]` doit l'emporter : la règle du navigateur est plus faible que
   n'importe quel `display` posé ici, et les commandes du carrousel comme le
   menu mobile reposent dessus. */
[hidden] {
  display: none !important;
}

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

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

.skip-link {
  position: absolute;
  inset-inline-start: var(--space-sm);
  inset-block-start: -4rem;
  z-index: 100;
  padding: var(--space-2xs) var(--space-sm);
  background: var(--accent);
  color: #000;
  border-radius: var(--radius-sm);
  transition: inset-block-start var(--dur-fast);
}
.skip-link:focus {
  inset-block-start: var(--space-sm);
}

/* 4. Primitives ---------------------------------------------------------- */

.container {
  width: min(100% - 2.5rem, var(--container));
  margin-inline: auto;
}
.container--narrow {
  max-width: var(--container-narrow);
}

.section {
  padding-block: var(--section-y);
}

/* Grand panneau arrondi. C'est la brique de mise en page du site : le hero,
   la section « How it works » et le CTA sont des cartes détachées du fond,
   pas des bandes pleine largeur. `overflow: clip` est structurel — c'est lui
   qui découpe la nappe lumineuse au bord arrondi. */
.panel {
  position: relative;
  margin-inline: var(--panel-inset);
  border-radius: var(--radius-panel);
  background: var(--surface);
  overflow: clip;
}

.muted {
  color: var(--text-muted);
}
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  padding: 0.8125rem 1.5rem;
  border-radius: var(--radius-pill);
  font-size: var(--step-body);
  font-weight: 400;
  white-space: nowrap;
  transition: background var(--dur-fast), color var(--dur-fast),
    border-color var(--dur-fast), transform var(--dur-fast);
}
.btn:active {
  transform: translateY(1px);
}

.btn--primary {
  background: var(--accent);
  color: #000;
}
.btn--primary:hover {
  background: #6df3f0;
}

.btn--ghost {
  border: 1px solid var(--border-strong);
  color: var(--text);
}
.btn--ghost:hover {
  border-color: var(--text);
  background: rgb(255 255 255 / 0.06);
}

.btn--sm {
  padding: 0.5rem 1rem;
  font-size: var(--step-small);
}

.link-underline {
  text-decoration: underline;
  text-underline-offset: 0.25em;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--text-faint);
  transition: text-decoration-color var(--dur-fast);
}
.link-underline:hover {
  text-decoration-color: currentColor;
}

/* Nappe lumineuse.

   Un seul dégradé radial elliptique fait tout : son cœur transparent découpe
   l'arc, ses arrêts successifs portent la couleur. Une bande linéaire + un
   masque ne suffisaient pas — la lumière restait horizontale alors qu'elle
   doit épouser la courbe, et s'éteignait dès qu'on s'écartait des bords.

   L'ellipse est ajustée numériquement sur la courbe relevée de l'original
   (0,6 px d'erreur moyenne), et les arrêts sont convertis depuis la rampe
   mesurée au pixel, exprimés en fraction du rayon.

   Au défilement la nappe se contracte *et* remonte : dans l'original la
   lumière se situe sous le centre de l'élément, si bien qu'elle remonte plus
   que ne l'expliquerait la seule mise à l'échelle. */
.glow {
  --arc-rx: 84%;
  --arc-ry: 100%;
  --arc-cy: -29.5%;

  position: absolute;
  /* Plus large que la carte : la contraction ne doit jamais décoller la
     nappe des bords arrondis. */
  inline-size: 146%;
  inset-inline-start: 50%;
  inset-block-start: var(--glow-top, 42%);
  z-index: 0;
  pointer-events: none;
  block-size: var(--glow-height, 107%);

  background: radial-gradient(
    ellipse var(--arc-rx) var(--arc-ry) at 50% var(--arc-cy),
    transparent 0 60.5%,
    #cfeec2 63%,
    var(--glow-core, #c0e9c0) 65.8%,
    #90d1b8 69.7%,
    #4ea79e 73.7%,
    #1d7e7c 77.9%,
    #0f5e5d 82.3%,
    #094342 86.8%,
    #062d2c 91.4%,
    #001e1e 96%,
    #001212 105%,
    transparent 112%
  );

  filter: blur(12px);
  scale: var(--glow-scale, 1);
  translate: -50% var(--glow-shift, 0px);
}

/* Maquette téléphone : le châssis est un PNG à écran découpé, la capture est
   posée derrière et transparaît.

   Les insets sont relevés sur la découpe réelle du PNG, en scannant une
   colonne qui évite l'encoche : au centre, le balayage bute sur l'écouteur et
   donne un bord haut à 6,3 % au lieu de 2,49 %. La capture s'arrêtait alors
   sous l'encoche et laissait paraître le fond de la carte en haut de l'écran.

   Avec la bonne hauteur, le rapport de la découpe (1794/3891 = 0,461) tombe
   exactement sur celui des captures — aucun recadrage. */
.phone {
  position: relative;
  margin: 0;
  aspect-ratio: 2022 / 4096;
}
.phone__frame {
  position: relative;
  z-index: 1;
  inline-size: 100%;
}
.phone__screen {
  position: absolute;
  z-index: 0;
  inset: 2.4902% 5.5885% 2.4902% 5.638%;
  inline-size: 88.724%;
  block-size: 94.995%;
  object-fit: cover;
  object-position: top;
  border-radius: 11% / 5.1%;
}

/* Révélation au scroll. L'état de départ reprend celui du template :
   opacité quasi nulle + translation verticale, relâchées ensemble. */
/* Durées et amplitudes reprises telles quelles du JSON d'animations publié
   par Framer : opacité 0.001 → 1, translation de 10 px (40 px pour les gros
   blocs), ressort sans rebond de 0,5 s — 0,6 s pour les blocs à 40 px. */
.reveal {
  opacity: 0.001;
  /* `translate` plutôt que `transform` : la propriété reste libre pour la
     bascule 3D de la maquette, qui vit sur le même élément. */
  translate: 0 var(--reveal-y, 10px);
  transition: opacity var(--reveal-dur, 500ms) var(--ease-spring),
    translate var(--reveal-dur, 500ms) var(--ease-spring);
  transition-delay: var(--reveal-delay, 0ms);
}
.reveal.is-visible {
  opacity: 1;
  translate: none;
}
.reveal--far {
  --reveal-y: 40px;
  --reveal-dur: 600ms;
}

/* Sans JS, rien ne doit rester invisible. */
.no-js .reveal {
  opacity: 1;
  translate: none;
}

/* Titres découpés. Les unités reprennent l'état de départ du template :
   opacité quasi nulle, flou 10 px, décalage de 10 px vers le bas. Le retard
   entre unités (~38 ms, mesuré sur l'original) est porté par `--i`, posé en
   JS au moment du découpage. */
.split__word {
  white-space: nowrap;
}
.split__unit {
  display: inline-block;
  opacity: 0.001;
  filter: blur(10px);
  translate: 0 10px;
  transition: opacity var(--split-dur) var(--ease-spring),
    filter var(--split-dur) var(--ease-spring),
    translate var(--split-dur) var(--ease-spring);
  transition-delay: calc(var(--split-lead, 0ms) + var(--i, 0) * var(--split-step));
}
.split-ready.is-visible .split__unit {
  opacity: 1;
  filter: blur(0);
  translate: none;
}

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

/* 5. Composants ---------------------------------------------------------- */

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

/* L'en-tête n'est pas collant : il défile avec la page, comme sur la maquette.
   Visuellement il forme le haut de la carte du hero — même encart, même fond,
   coins arrondis en haut — mais il reste un frère de <main>, pour que le
   landmark de bannière ne se retrouve pas imbriqué dans le contenu. */
.site-header {
  position: relative;
  z-index: 5;
  margin-inline: var(--panel-inset);
  padding-block: var(--space-md);
  background: var(--surface);
  border-start-start-radius: var(--radius-panel);
  border-start-end-radius: var(--radius-panel);
}
/* La carte du hero prolonge l'en-tête : elle ne réarrondit pas le haut. */
.hero.panel {
  border-start-start-radius: 0;
  border-start-end-radius: 0;
}

.nav {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-sm);
}

/* La marque est une image : on cale sa hauteur, la largeur suit le rapport
   intrinsèque du SVG (366 × 119). */
.nav__brand {
  display: block;
  grid-column: 2;
  justify-self: center;
  order: 2;
}
.nav__brand img {
  block-size: 1.5rem;
  inline-size: auto;
}

.nav__list {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  grid-column: 1;
  order: 1;
}
.nav__list a {
  font-size: var(--step-body);
  color: var(--text-muted);
  transition: color var(--dur-fast);
}
.nav__list a:hover,
.nav__list a[aria-current="page"] {
  color: var(--text);
}

.nav__actions {
  grid-column: 3;
  justify-self: end;
  order: 3;
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
}

/* Doublon assumé de « Se connecter » : bouton dans la barre au-dessus de
   810 px, entrée de menu en dessous. Une seule des deux est rendue. */
.nav__only-mobile {
  display: none;
}
@media (max-width: 809px) {
  .nav__only-mobile {
    display: block;
  }
}

.nav__toggle {
  display: none;
  padding: 0.5rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  font-size: var(--step-small);
}

@media (max-width: 809px) {
  .nav {
    grid-template-columns: auto 1fr;
  }
  .nav__brand {
    grid-column: 1;
    justify-self: start;
    order: 1;
  }
  .nav__actions {
    grid-column: 2;
    order: 2;
  }
  .nav__toggle {
    display: inline-flex;
  }
  .nav__list {
    grid-column: 1 / -1;
    order: 3;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-sm);
    padding-block: var(--space-md) var(--space-2xs);
  }
    /* Trois boutons ne tiennent pas dans la barre à 390 px : la connexion
     bascule dans le menu déroulant, l'inscription reste visible. */
  .nav__login {
    display: none;
  }
  /* Sous 810 px la marque est dans une colonne `auto` : sans ce garde-fou
     elle se comprime pour laisser passer le bouton, jusqu'à 3 px de large à
     320 px. */
  .nav__brand {
    flex: none;
  }
  .nav__brand img {
    min-inline-size: 4.5rem;
  }
}

/* Sous 420 px, l'inscription ne tient plus à sa taille normale sans écraser
   la marque : elle rétrécit. Sous 360 px elle ne tient plus du tout et sort de
   la barre — le même appel à l'action est immédiatement dessous, dans le hero. */
@media (max-width: 419px) {
  .nav__actions .btn--primary {
    padding-inline: 0.875rem;
    font-size: var(--step-small);
  }
}
@media (max-width: 359px) {
  .nav__actions .btn--primary {
    display: none;
  }
}

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

.hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(3rem, 1rem + 7vw, 6rem) 0;
  text-align: center;
}
.hero__glow {
}
.hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  justify-items: center;
  gap: var(--space-md);
}
.hero__title {
  max-inline-size: 24ch;
}
.hero__sub {
  max-inline-size: 46ch;
  font-size: var(--step-body-lg);
}
/* Le conteneur ne réserve en hauteur que la *part visible* du téléphone :
   celui-ci déborde par le bas et la carte du hero le rogne, exactement comme
   sur l'original (260 px coupés au repos). Sans ça, la carte s'étirerait pour
   contenir la maquette entière et rien ne serait coupé.

   D'où le rapport 2022/2690 au lieu de 2022/4096 : même largeur, hauteur
   réduite à la portion qui reste dans le cadre. */
.hero__media {
  position: relative;
  z-index: 1;
  margin-block-start: clamp(2rem, 1rem + 4vw, 4rem);
  margin-inline: auto;
  inline-size: min(100%, 23.4rem);
  aspect-ratio: 2022 / 2690;
}

/* La maquette grossit et bascule vers le lecteur au fil du défilement, puis se
   fige. `--p` (0 → 1) est posé en JS ; tout le reste est déclaratif, et la
   transformation ne touche pas la mise en page. */
.hero__media .phone {
  position: absolute;
  inset-block-start: 0;
  inline-size: 100%;
  transform: perspective(1200px) rotateX(calc(var(--p, 0) * 24deg))
    scale(calc(1 + var(--p, 0) * 0.16));
  transform-origin: 50% 30%;
  will-change: transform;
}

/* --- Bandeau de positionnement ------------------------------------------ */

.statement {
  text-align: center;
}
.statement__proof {
  margin-block-start: var(--space-2xl);
  font-size: var(--step-small);
}

/* --- Promesse ----------------------------------------------------------- */

/* La phrase de positionnement est posée sur le fond noir, sans carte : à la
   taille des grands titres, c'est le vide autour d'elle qui la met en avant.
   C'est le dernier argument avant l'offre, il ne doit pas passer pour une
   légende. */
.claim {
  display: grid;
  place-items: center;
  text-align: center;
}
.claim__text {
  max-inline-size: 28ch;
  font-family: var(--font-display);
  font-size: var(--step-h2);
  line-height: var(--leading-snug);
}
/* Les segments mis en avant sont dans la teinte claire de la palette : c'est
   le seul endroit du site où l'accent porte du texte long. */
.claim__text em {
  font-style: normal;
  color: var(--accent-soft);
}

/* --- Démonstration vocale ------------------------------------------------ */

/* La démo occupe la place du bandeau de positionnement, au-dessus de la preuve
   sociale : même centrage, même largeur de lecture que le reste de la bande. */
.voice__title {
  margin-inline: auto;
  max-inline-size: 26ch;
  font-family: var(--font-display);
  font-size: var(--step-h3);
  line-height: var(--leading-snug);
}
.voice__caption {
  margin-block-start: var(--space-sm);
  color: var(--text-muted);
  font-size: var(--step-small);
}

/* Le lecteur reprend la carte du carrousel : fond de surface, filet, halo
   posé derrière. Il ne se distingue du reste du site que par sa rangée de
   barres. */
.player {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: var(--space-md);
  max-inline-size: 44rem;
  margin-block-start: var(--space-lg);
  margin-inline: auto;
  padding: var(--space-md) var(--space-lg);
  text-align: start;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
}
@media (max-width: 559px) {
  .player {
    padding-inline: var(--space-md);
    gap: var(--space-sm);
  }
}

.player__glow {
  position: absolute;
  z-index: 0;
  inset-block-start: -180%;
  inset-inline-start: -10%;
  inline-size: 26rem;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(
    circle at 50% 50%,
    rgb(212 241 190 / 0.45) 0%,
    rgb(43 236 232 / 0.16) 45%,
    transparent 70%
  );
  filter: blur(40px);
  opacity: 0.55;
  transition: opacity var(--dur-slow) var(--ease-spring);
  pointer-events: none;
}
.player.is-playing .player__glow {
  opacity: 1;
}

/* Le lecteur natif ne sert que de repli : dès que le script a monté l'interface
   sur mesure, il sort du flux. */
.player--ready .player__audio {
  display: none;
}
.player__audio {
  inline-size: 100%;
}

.player__ui {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: var(--space-md);
  inline-size: 100%;
}

.player__toggle {
  flex: none;
  display: grid;
  place-items: center;
  inline-size: 3rem;
  block-size: 3rem;
  border-radius: 50%;
  background: var(--accent);
  color: #001111;
  transition: transform var(--dur-fast) var(--ease-spring),
    background var(--dur-fast);
}
.player__toggle:hover {
  transform: scale(1.06);
}
/* L'icône affichée suit l'état : une seule des deux est dans le flux. */
.player__icon--pause,
.player.is-playing .player__icon--play {
  display: none;
}
.player.is-playing .player__icon--pause {
  display: block;
}

/* Rangée de barres : les hauteurs viennent de l'analyse du fichier audio
   (`data-peaks`), pas d'un motif décoratif. La couche jouée est un calque
   identique, découpé à la position de lecture. */
.player__wave {
  position: relative;
  flex: 1 1 auto;
  min-inline-size: 0;
  block-size: 2.5rem;
}
.player__layer {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: 2px;
  color: var(--text);
  opacity: 0.28;
}
.player__layer--played {
  color: var(--accent);
  opacity: 1;
  clip-path: inset(0 calc(100% - var(--p, 0) * 100%) 0 0);
}
.player__bar {
  flex: 1 1 0;
  block-size: calc(12% + var(--h, 0.5) * 88%);
  min-inline-size: 2px;
  border-radius: var(--radius-pill);
  background: currentColor;
}

/* Le curseur natif est invisible mais présent : il apporte le glissé, le
   clavier et la sémantique de slider sans avoir à les réécrire. */
.player__scrub {
  position: absolute;
  inset: 0;
  z-index: 2;
  inline-size: 100%;
  block-size: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
}
.player__scrub:focus-visible + .player__layer,
.player__scrub:focus-visible ~ .player__layer {
  opacity: 0.5;
}
.player__scrub::-webkit-slider-thumb {
  -webkit-appearance: none;
  inline-size: 1rem;
  block-size: 2.5rem;
}

.player__time {
  flex: none;
  font-size: var(--step-small);
  font-variant-numeric: tabular-nums;
  color: var(--text-faint);
}
@media (max-width: 559px) {
  .player__time {
    display: none;
  }
}

/* --- Puce cochée -------------------------------------------------------- */

/* Une seule puce, dessinée en SVG inline dans le CSS plutôt que répétée dans
   le HTML. */
.plan__list li {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
}
.plan__list li::before {
  content: "";
  flex: none;
  inline-size: 1.125rem;
  block-size: 1.125rem;
  background: var(--check) center / contain no-repeat;
}
:root {
  --check: url('data:image/svg+xml;utf8,\
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18">\
<circle cx="9" cy="9" r="9" fill="%232bece8"/>\
<path d="M5 9.2l2.6 2.6L13 6.4" fill="none" stroke="%23001111" \
stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>');

  /* Sur fond clair, la pastille cyan disparaît : le modèle y pose la même
     coche pleine et sombre, la marque étant évidée pour laisser passer le
     dégradé de la carte. */
  --check-dark: url('data:image/svg+xml;utf8,\
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18">\
<path fill="%23001111" fill-rule="evenodd" d="M9 0a9 9 0 1 0 0 18A9 9 0 0 0 9 0Z\
M12.95 7.41 8.1 12.26a.92.92 0 0 1-1.3 0l-2.08-2.07a.92.92 0 0 1 1.3-1.3l1.43 1.42\
 4.2-4.2a.92.92 0 1 1 1.3 1.3Z"/></svg>');
}

/* --- Étapes ------------------------------------------------------------- */

/* Grande carte détachée : la capture de l'application à gauche, la colonne de
   texte à droite, les deux centrées l'une par rapport à l'autre. La hauteur
   suit le contenu — plus de hauteur imposée depuis que le visuel est une
   capture en paysage et non un téléphone qui débordait de la carte. */
.steps {
  display: grid;
  gap: var(--space-2xl);
  padding: var(--space-3xl) var(--space-lg);
}
@media (min-width: 810px) {
  .steps {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3xl);
    align-items: center;
    padding: var(--space-3xl) var(--space-2xl);
  }
}

/* Même nappe que le hero, mais cadrée sur son coin supérieur gauche : le
   disque déborde très largement en bas à droite, seule l'écharpe claire de
   l'arc traverse la carte. */
.steps__glow {
  --arc-rx: 50%;
  --arc-ry: 50%;
  --arc-cy: 50%;
  /* Centre et rayon relevés sur le template en suivant la crête lumineuse
     colonne par colonne : cercle de rayon ~1250 px centré à 80,4 % / 130,3 %
     de la carte. Le cœur de l'arc étant à 32,9 % du côté, il faut un carré de
     267,5 % de large pour l'y poser — calé au pixel sur la crête relevée. */
  inline-size: 267.5%;
  block-size: auto;
  aspect-ratio: 1;
  inset-inline-start: 80.4%;
  /* Décalage vertical exprimé sur la taille du disque, donc sur la largeur de
     la carte : la nappe garde le même tracé quelle que soit la hauteur du
     panneau, qui elle dépend du contenu. */
  inset-block-start: 0;
  translate: -50% -21.2%;

  /* Mêmes teintes que la nappe du hero, mais la descente est resserrée d'un
     tiers : à ce diamètre, les paliers d'origine étalaient le halo sur 900 px
     et noyaient tout le coin de la carte. Sur le template, l'écharpe s'éteint
     en 300 px. */
  background: radial-gradient(
    ellipse var(--arc-rx) var(--arc-ry) at 50% var(--arc-cy),
    transparent 0 64.6%,
    #cfeec2 65.2%,
    var(--glow-core, #c0e9c0) 65.8%,
    #90d1b8 67.6%,
    #4ea79e 69.4%,
    #1d7e7c 71.3%,
    #0f5e5d 73.2%,
    #094342 75.3%,
    #062d2c 77.3%,
    #001e1e 79.4%,
    #001212 83.4%,
    transparent 86.6%
  );
}
.steps > :not(.steps__glow) {
  position: relative;
  z-index: 1;
}

.steps__body {
  display: grid;
  align-content: start;
  gap: var(--space-2xl);
}
@media (min-width: 810px) {
  .steps__body {
    grid-column: 2;
    grid-row: 1;
  }
}
.steps__head {
  display: grid;
  gap: var(--space-sm);
}
.steps__eyebrow {
  font-family: var(--font-display);
  font-size: var(--step-h4);
  line-height: var(--leading-snug);
}

.step-list {
  display: grid;
  gap: var(--space-lg);
}
@media (min-width: 810px) {
  /* Hauteur de la liste au repos (une étape dépliée, trois repliées). Pendant
     la bascule, les deux sous-textes ne s'échangent pas exactement à la même
     image et la liste perdait une dizaine de pixels : la carte tressautait. */
  .step-list {
    min-block-size: 18.75rem;
  }
}

/* Une étape est un onglet : la pastille numérotée, puis l'intitulé. Seule
   l'étape sélectionnée est à pleine opacité — c'est ce qui indique laquelle
   des captures est affichée. */
.step {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-md);
  align-items: start;
  inline-size: 100%;
  /* le remplissage par défaut du bouton décalerait toute la ligne de 6 px */
  padding: 0;
  text-align: start;
  opacity: 0.4;
  /* 440 ms : durée relevée sur le template, plus lente que l'ouverture du
     sous-texte — c'est ce décalage qui donne le fondu. */
  transition: opacity 440ms var(--ease-spring);
}
.step[aria-selected="true"] {
  opacity: 1;
}
.step:hover:not([aria-selected="true"]) {
  opacity: 0.7;
}
.step__num {
  display: grid;
  place-items: center;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  border-radius: 50%;
  background: var(--text);
  color: #000;
  font-size: var(--step-h4);
  transition: background var(--dur-med);
}
.step[aria-selected="true"] .step__num {
  background: var(--accent);
}
/* Deux blocs et pas deux spans en ligne : sans ça, ni la marge verticale ni
   la largeur de mesure ne s'appliquent. */
.step__title {
  display: block;
  font-size: var(--step-h4);
  line-height: var(--leading-snug);
}
/* Le sous-texte s'ouvre et se referme en hauteur, comme sur le template :
   grid-template-rows 0fr → 1fr, donc sans mesure de hauteur en JS et sans
   recalcul au redimensionnement. Il reste dans le DOM une fois replié, donc
   lisible par les lecteurs d'écran et les moteurs. */
.step__body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-med) var(--ease-spring);
}
.step[aria-selected="true"] .step__body {
  grid-template-rows: 1fr;
}
.step__body > span {
  display: block;
  overflow: hidden;
  padding-block-start: 0.625rem;
  font-size: var(--step-body);
  line-height: var(--leading-normal);
}
/* Sans script, les quatre textes restent lisibles. */
.no-js .step__body {
  grid-template-rows: 1fr;
}

/* La capture de l'application occupe la colonne de gauche, calée sur la
   grille : son bord gauche tombe sur le retrait de la carte, comme le texte
   de la colonne de droite tombe sur le sien.

   La boîte a un rapport fixe, celui des captures : c'est ce qui empêche la
   carte de sauter en changeant d'onglet, la dernière étape montrant un
   téléphone en portrait et non une capture en paysage. */
.steps__media {
  display: grid;
  align-content: center;
  justify-items: center;
  aspect-ratio: 1440 / 901;
  /* sans quoi la taille minimale automatique de l'élément de grille laisserait
     le téléphone, plus haut que la boîte, repousser la carte */
  min-block-size: 0;
}
.steps__panel {
  display: grid;
  place-items: center;
  inline-size: 100%;
  block-size: 100%;
  min-block-size: 0;
}
/* Le téléphone part du haut de la boîte et sort par le bas, où le bord
   arrondi de la carte le coupe — le traitement du template. À la hauteur
   exacte de la boîte il serait deux fois trop petit pour qu'on y lise quoi
   que ce soit. */
.steps__panel .phone {
  inline-size: 52%;
}
/* Le passe-partout translucide raccroche la capture claire au panneau sombre :
   sans lui, le rectangle blanc est posé sur le fond sans transition. */
.steps__shot {
  inline-size: 100%;
  border-radius: var(--radius-md);
  box-shadow: 0 0 0 0.5rem rgb(255 255 255 / 0.06);
}
@media (min-width: 810px) {
  .steps__media {
    grid-column: 1;
    grid-row: 1;
  }
}

/* --- Résultats ---------------------------------------------------------- */

/* Texte à gauche, chiffres à droite. Sous 810 px la colonne de droite passe
   dessous, comme les autres blocs à deux colonnes du site. */
.results__grid {
  display: grid;
  gap: var(--space-2xl);
  align-items: center;
}
@media (min-width: 810px) {
  .results__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

.results__body {
  display: grid;
  justify-items: start;
  gap: var(--space-md);
  max-inline-size: 46ch;
}
.results__body .lead {
  color: var(--text);
}

/* Deux colonnes de gabarit : la première carte en occupe une, la seconde les
   deux — d'où le rapport de largeur du simple au double. */
.stat-grid {
  display: grid;
  gap: var(--space-md);
}
@media (min-width: 810px) {
  .stat-grid {
    grid-template-columns: 1fr 1fr;
  }
  .stat-grid > :last-child {
    grid-column: span 2;
  }
}

/* Mêmes cartes que les plans tarifaires, sans filet : fond de surface pour la
   première, dégradé plein et texte sombre pour celle mise en avant. */
.stat {
  display: grid;
  gap: var(--space-2xs);
  padding: var(--space-xl) var(--space-lg);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
.stat--featured {
  background: var(--gradient-accent);
  color: #001111;
}

/* Le chiffre est traité comme le prix des cartes tarifaires : police display,
   grande taille, libellé en dessous dans la police de texte. */
.stat__value {
  font-family: var(--font-display);
  font-size: var(--step-display);
  line-height: var(--leading-tight);
  /* Chiffres à chasse fixe : sans ça, la carte tressaute pendant le comptage. */
  font-variant-numeric: tabular-nums;
}
/* Sur la carte sombre, le chiffre porte le dégradé lui-même. Le dégradé est
   découpé sur ce span et pas sur le bloc : sur toute la largeur de la carte,
   les glyphes n'en montraient que le premier tiers. */
.stat__figure {
  display: inline-block;
  color: var(--accent-soft);
  background: var(--gradient-accent);
  -webkit-background-clip: text;
  background-clip: text;
}
@supports (background-clip: text) or (-webkit-background-clip: text) {
  .stat__figure {
    color: transparent;
  }
}
/* La carte en dégradé, elle, garde son texte sombre : pas de dégradé sur
   dégradé. */
.stat--featured .stat__figure {
  color: inherit;
  background: none;
}
.stat__unit {
  display: block;
  margin-block-start: var(--space-2xs);
  font-family: var(--font-body);
  font-size: var(--step-body-lg);
  color: var(--text-muted);
}
.stat--featured .stat__unit {
  color: rgb(0 17 17 / 0.7);
}

/* --- Prix -------------------------------------------------------------- */

.plan__price {
  display: flex;
  align-items: baseline;
  gap: var(--space-2xs);
  font-family: var(--font-display);
  font-size: var(--step-h2);
  line-height: 1;
}
.plan__price span {
  font-family: var(--font-body);
  font-size: var(--step-small);
  color: var(--text-faint);
}
.plan__list {
  display: grid;
  gap: var(--space-xs);
  color: var(--text-muted);
  font-size: var(--step-small);
}
/* Prix et liste cochée sont posés sur le dégradé du panneau final : sans ça
   ils gardent les couleurs de texte du fond sombre et disparaissent. */
.cta .plan__price span {
  color: rgb(0 17 17 / 0.7);
}
.cta .plan__list {
  gap: var(--space-2xs);
  color: inherit;
  font-size: var(--step-body);
}
.cta .plan__list li::before {
  inline-size: 1.25rem;
  block-size: 1.25rem;
  background-image: var(--check-dark);
}

/* --- CTA ---------------------------------------------------------------- */

/* Le CTA inverse le contraste de toute la page : carte claire, texte sombre.
   C'est le seul bloc lumineux du site, ce qui suffit à en faire le point
   d'arrivée du parcours. */
.cta {
  position: relative;
  overflow: hidden;
  display: grid;
  justify-items: center;
  gap: var(--space-md);
  padding: var(--space-3xl) var(--space-lg) 0;
  text-align: center;
  color: #001111;
  background: var(--gradient-accent);
  border-radius: var(--radius-panel);
}
.cta__title {
  max-inline-size: 14ch;
}
.cta__sub {
  color: rgb(0 17 17 / 0.7);
  font-size: var(--step-body-lg);
}
.cta .btn--dark {
  background: #001111;
  color: #fff;
}
.cta .btn--dark:hover {
  background: #04292a;
}
/* La maquette est rognée par le bas de la carte. */
.cta__media {
  inline-size: min(100%, 17rem);
  margin-block-start: var(--space-xl);
  margin-block-end: -18%;
}

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

.site-footer {
  position: relative;
  overflow: hidden;
  padding-block: var(--space-2xl) var(--space-xl);
  border-block-start: 1px solid var(--border);
}
.footer-grid {
  position: relative;
  z-index: 1;
  display: grid;
  gap: var(--space-xl);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
}
.footer-brand__name {
  font-family: var(--font-display);
  font-size: var(--step-h4);
  max-inline-size: 12ch;
  line-height: 1.15;
}

/* Marque géante en pied de page : elle déborde volontairement du cadre, coupée
   par l'`overflow: hidden` du footer. Purement décorative, donc retirée de
   l'arbre d'accessibilité — le nom figure déjà dans le contenu. */
.footer-wordmark {
  display: block;
  inline-size: min(100%, 68rem);
  block-size: auto;
  margin-block-start: var(--space-2xl);
  /* Affleure le bas du footer : le logo touche le bord sans être tronqué —
     le rogner en pleine étincelle passerait pour un défaut. */
  margin-block-end: calc(-1 * var(--space-xl));
  margin-inline: auto;
  user-select: none;
}
.footer-col h2 {
  font-family: var(--font-body);
  font-size: var(--step-small);
  color: var(--text-faint);
  margin-block-end: var(--space-sm);
}
.footer-col li + li {
  margin-block-start: var(--space-2xs);
}
.footer-col a {
  font-size: var(--step-body);
  color: var(--text-muted);
  transition: color var(--dur-fast);
}
.footer-col a:hover {
  color: var(--text);
}
.footer-bottom {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-block-start: var(--space-2xl);
  padding-block-start: var(--space-md);
  border-block-start: 1px solid var(--border);
  color: var(--text-faint);
  font-size: var(--step-small);
}

/* --- Pages légales ------------------------------------------------------ */

/* Un texte de contrat ne se lit pas comme une page marketing : mesure courte,
   interlignage généreux, titres nettement plus petits que dans le reste du
   site — c'est la hiérarchie qui guide, pas la taille. */
.legal__h1 {
  max-inline-size: 30ch;
  font-size: var(--step-h2);
  line-height: var(--leading-snug);
}

.legal-toc {
  padding: var(--space-lg);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.legal-toc__title {
  font-size: var(--step-h4);
  margin-block-end: var(--space-sm);
}
.legal-toc ol {
  display: grid;
  gap: var(--space-2xs);
  margin: 0;
  padding-inline-start: 1.25rem;
  color: var(--text-muted);
  font-size: var(--step-small);
}
.legal-toc a:hover {
  color: var(--accent);
}

.legal__body {
  margin-block-start: var(--space-2xl);
  color: var(--text-muted);
}
.legal__body > h2 {
  margin-block: var(--space-2xl) var(--space-md);
  padding-block-start: var(--space-lg);
  border-block-start: 1px solid var(--border);
  font-size: var(--step-h3);
  color: var(--text);
}
.legal__body > h2:first-child {
  margin-block-start: 0;
  padding-block-start: 0;
  border-block-start: 0;
}
.legal__body h3 {
  margin-block: var(--space-lg) var(--space-xs);
  font-size: var(--step-h4);
  color: var(--text);
}
.legal__body h4 {
  margin-block: var(--space-md) var(--space-2xs);
  font-family: var(--font-body);
  font-size: var(--step-body);
  font-weight: 700;
  color: var(--text);
}
.legal__body p + p {
  margin-block-start: var(--space-sm);
}

.legal-list,
.legal__body dd ul {
  display: grid;
  gap: var(--space-2xs);
  margin-block: var(--space-sm);
  padding-inline-start: 1.25rem;
  list-style: disc;
}
ol.legal-list {
  list-style: decimal;
}

/* Chaque terme défini reste accroché à sa définition : liseré à gauche plutôt
   qu'un retrait, plus lisible sur une liste aussi longue. */
.legal-defs {
  margin: 0;
}
.legal-defs dt {
  margin-block-start: var(--space-md);
  color: var(--text);
  font-weight: 700;
}
.legal-defs dd {
  margin-inline-start: 0;
  padding-inline-start: var(--space-sm);
  border-inline-start: 1px solid var(--border);
}
.legal-defs dd p + ul {
  margin-block-start: var(--space-2xs);
}

/* Les renvois laissés en attente dans le texte source restent visibles :
   ils doivent sauter aux yeux tant qu'ils ne sont pas remplacés. */
.legal-todo {
  color: var(--accent-soft);
}

/* 6. Utilitaires --------------------------------------------------------- */

.visually-hidden {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

