/* ─────────────────────────────────────────────────
   DESIGN TOKENS
───────────────────────────────────────────────── */
:root {
  --bg:           #0a0a0a;
  --bg-mid:       #111111;
  --text:         #F0EDE8;
  --muted:        rgba(240, 237, 232, 0.5);
  --accent-start: #FEA062;
  --accent-end:   #F45E7C;
  --gradient:     linear-gradient(135deg, #FEA062, #F45E7C);
  --font-display: 'Sora', sans-serif;
  --font-body:    'Sora', sans-serif;
  --nav-h:        72px;
  --section-px:   clamp(1.5rem, 7vw, 8rem);

  /* ── L'echelle des boutons ──────────────────────
     Trois hauteurs, une seule personnalite de rayon. Le rapport rayon sur
     hauteur vaut 0,250 aux trois rangs : 16/64, 12/48, 8/32. Ce n'est pas un
     gout, c'est le registre du produit lui-meme (css/phones.css:73 dessine le
     bouton de l'application a 52px de haut et 15 de rayon, soit 0,288) et la
     mediane de douze concurrents mesures le 11 aout (releve dans la revue des
     CTA). La page etait a 0,500, dans le quart le plus rond du terrain. */
  --radius-sm:    8px;
  --radius-md:    12px;
  --radius-lg:    16px;
  --radius-xl:    24px;
  --radius-full:  999px;
  --btn-h1:       64px;
  --btn-h2:       48px;
  --btn-h3:       32px;
  /* Ce que gagne le mot pile au centre de la colonne du CTA. Sur le noir, on
     l'eclaircit d'un cinquieme. Le mode jour renverse le signe, voir light.css. */
  --cta-eclat:    1.2;
  /* Le fond du bouton du hero : le degrade de la marque, l'ambre vers le
     corail. Il est declare ICI et nulle part ailleurs, donc il vaut la meme
     chose dans les deux modes et sur l'ilot noir du pied : c'est ce bouton la
     qu'on reconnait, et il ne change pas de peau selon l'heure. Il ne suit
     donc PAS --gradient, que le mode jour assombrit de deux marches pour que
     l'ambre reste lisible en TEXTE sur la creme. Un aplat n'a pas ce probleme.
     L'encre qui se pose dessus est sombre : le blanc tombe a 2,02 sur l'ambre,
     ou l'encre monte a 9,17. */
  --cta-fond:     linear-gradient(135deg, #FEA062, #F45E7C);
  --cta-encre:    #14140F;
  --filet-btn:    rgba(240, 237, 232, .37);
}

/* ─────────────────────────────────────────────────
   RESET
───────────────────────────────────────────────── */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* Required by Lenis */
html { height: auto; overflow: auto; }

/* Le canevas, c'est-a-dire ce que le navigateur peint SOUS la page : rebond
   elastique en haut et en bas, lisiere sous-pixel, et sur iPhone la zone que
   la barre de Safari libere en se repliant. Sans consigne, il heritait du fond
   de page, un noir gris a 10, alors que le pied est un noir pur. D'ou la bande
   plus claire visible a la toute fin du pied. Il porte desormais le noir du
   pied ; le fond de page continue de peindre le corps, rien ne change ailleurs. */
html { background-color: #000; }

body {
  background-color: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

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

/* ─────────────────────────────────────────────────
   UTILITY
───────────────────────────────────────────────── */
.gradient-text {
  background: var(--gradient);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

/* ─────────────────────────────────────────────────
   NAV
───────────────────────────────────────────────── */
.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--section-px);
  transition: background 0.45s ease, backdrop-filter 0.45s ease;
}

.nav--scrolled {
  background: rgba(10, 10, 10, 0.72);
  backdrop-filter: blur(22px);
  -webkit-backdrop-filter: blur(22px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}

.nav__logo {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  /* 19px et non 21,6 : a l'ancienne taille les capitales montaient a 22,4 alors
     que l'icone mesure 20, le mot ecrasait donc la marque. A 19 les capitales
     tombent a 19,7 et l'icone reprend le dessus, comme chez Fanvue ou le signe
     domine le nom (cf. docs/references_externes.md). */
  font-size: 1.1875rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-decoration: none;
  color: #fff;
}

.nav__links {
  display: flex;
  gap: clamp(1.5rem, 3vw, 3rem);
  list-style: none;
}

.nav__link {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--muted);
  text-decoration: none;
  letter-spacing: 0.02em;
  transition: color 0.2s;
}

.nav__link:hover { color: var(--text); }

/* ─────────────────────────────────────────────────
   BUTTONS
───────────────────────────────────────────────── */
/* Le socle ne porte AUCUNE couleur et AUCUNE forme : il ne sait que se mettre
   en ligne et se centrer. Tout le reste vient du rang. Avant, ce bloc portait
   un rayon de 56px, un degrade et du blanc, et six boutons de la page en
   heritaient : la page repetait six fois son niveau 1, donc elle n'en avait
   aucun. La graisse descend de 700 a 600, 700 etant reserve a l'emphase rare,
   et l'interlettre positive tombe a zero : elle ne se justifie que sur des
   capitales, jamais sur du bas de casse. */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-body);
  font-weight: 600;
  letter-spacing: 0;
  text-decoration: none;
  border: none;
  transition: opacity 0.2s, transform 0.2s;
  cursor: pointer;
}

/* La cible du doigt deborde du dessin sans rien changer a la composition.
   48px satisfait Apple (44) ET Material (48). Sur un bouton a libelle on ne
   deborde QUE vers le haut et le bas : il fait deja plus de 48 de large, et
   une jupe horizontale ferait chevaucher deux voisins. */
.btn::after {
  content: '';
  position: absolute;
  inset: -8px 0;
}

/* LE RANG DONNE LA TAILLE, LA PEAU DONNE LA COULEUR. Les deux sont separes
   depuis que le couple du hero s'est trouve depareille : le primaire tenait sa
   couleur de son rang, donc lui donner un voisin de meme taille obligeait a
   dupliquer la geometrie dans une classe fantome, et les deux ont derive de
   16px de haut, d'un point de corps et de 4px de rayon. Un rang ne parle plus
   que de dimensions, une peau ne parle plus que de couleur, et un couple ne
   peut plus se depareiller par construction. */

/* ── RANG 1 : le premier ecran ──
   Les deux boutons du hero, et rien d'autre sur la page. */
.btn--r1 {
  height: var(--btn-h1);
  padding: 0 32px;
  font-size: 17px;
  border-radius: var(--radius-lg);
}

/* ── RANG 2 : l'action de section ──
   Le CTA de section, le CTA final, le pied et le menu plein ecran. */
.btn--r2 {
  height: var(--btn-h2);
  padding: 0 24px;
  font-size: 1rem;
  border-radius: var(--radius-md);
}

/* ── RANG 3 : le chrome ──
   Le bouton d'inscription de la barre, Fermer, le selecteur de langue.
   32px est le rang exact du terrain pour un CTA de barre persistant :
   Framer 30, Linear 32, Substack 32. */
.btn--r3 {
  height: var(--btn-h3);
  padding: 0 16px;
  font-size: 13px;
  border-radius: var(--radius-sm);
}

/* ── LES TROIS PEAUX ── */
/* Le degrade : la seule surface coloree de la page, portee par le seul bouton
   qui rapporte au premier ecran, et le seul objet du site qui ne change pas
   d'un mode a l'autre. Il tient sa couleur de --cta-fond et non de --gradient,
   parce que le mode jour assombrit --gradient de deux marches : necessaire
   pour du TEXTE en degrade sur creme, ou l'ambre d'origine ne mesure que 1,89,
   inutile pour un aplat de 64px de haut.
   Ce qui ne revient pas de l'ancien bouton, c'est l'encre : le blanc tombait a
   2,02 sur l'ambre, c'est-a-dire un libelle qu'on devine plus qu'on ne le lit.
   L'encre sombre monte a 9,17 exactement la, et ne descend jamais sous 5,93
   sur toute la course. */
.btn--degrade { background: var(--cta-fond); color: var(--cta-encre); }

/* L'encre : la page inversee, creme sur noir la nuit et noir sur creme le
   jour. Aucune couleur inventee, et 16,96 de contraste. */
.btn--encre  { background: var(--text); color: var(--bg); }

/* Le fantome : le secondaire ne perd QUE son remplissage, jamais un pixel de
   sa boite. Le filet est pose en ombre interne et non en bordure, pour que la
   boite ne gagne pas 2px et reste alignee au pixel sur son voisin plein. */
.btn--fantome {
  background: transparent;
  color: var(--text);
  box-shadow: inset 0 0 0 1px var(--filet-btn);
}

/* ── OU LE DEGRADE A LE DROIT D'ALLER ──
   Par defaut il ne va nulle part ailleurs que dans le hero : une accentuation
   repetee six fois n'accentue plus rien. Les deux autres portees existent pour
   etre COMPAREES sur la meme page, via ?corail=barre et ?corail=tout. Une fois
   la portee tranchee, ce bloc et son lecteur d'URL disparaissent. */
:root[data-corail="barre"] .btn--nav,
:root[data-corail="tout"] .btn--encre {
  background: var(--cta-fond);
  color: var(--cta-encre);
}

.nav__right {
  display: flex;
  align-items: center;
  /* 16px et non 10 : les jupes tactiles debordent de 8px de chaque cote, il
     faut ecarter les voisins AVANT de les poser, sinon un rate au milieu
     declenche l'action d'a cote au lieu de ne rien faire. */
  gap: 16px;
}

/* Le couple du hero. Sous 620px la paire s'empile en colonne pleine largeur :
   le francais y demande 213,89px de libelle pour un budget de 240. */
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

/* ── Selecteur de langue ──────────────────────────
   Meme silhouette que l'interrupteur jour/nuit a cote : meme hauteur, meme
   filet, meme survol. Deux lettres et un chevron, parce qu'un menu doit tenir
   a cinq langues (l'allemand et le portugais sont prevus) et que trois boutons
   cote a cote ne tiendraient pas. Les langues sont ecrites dans leur propre
   langue : c'est la seule facon d'etre lisible par qui ne lit pas la page. */
.lang { position: relative; flex: none; }

.lang__btn {
  position: relative;
  height: var(--btn-h3);
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 0 16px;
  border-radius: var(--radius-sm);
  background: transparent;
  /* Le filet passe de 1,38 a 3,06 de contraste : c'est le seuil que demande
     WCAG 1.4.11 pour la limite d'un controle, l'ancien etait sous la moitie. */
  border: 1px solid var(--filet-btn);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  /* La chasse reste : ce sont deux CAPITALES, le seul cas ou elle se justifie. */
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: border-color 0.25s ease;
}
.lang__btn::after { content: ''; position: absolute; inset: -8px 0; }
.lang__btn:hover { border-color: rgba(255, 255, 255, 0.3); }
.lang__chevron {
  width: 12px;
  height: 12px;
  opacity: 0.5;
  transition: transform 0.28s cubic-bezier(0.32, 0.72, 0, 1);
}
.lang.on .lang__chevron { transform: rotate(180deg); }

.lang__menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 150px;
  margin: 0;
  /* 4px et non 6 : les coins interieurs doivent etre paralleles aux exterieurs,
     donc 16 moins l'ecart de 4 donne 12 sur les options. */
  padding: 4px;
  list-style: none;
  background: var(--bg-mid);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--radius-lg);
  box-shadow: 0 18px 40px -20px rgba(0, 0, 0, 0.7);
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  transition: opacity 0.2s ease-out, transform 0.28s cubic-bezier(0.32, 0.72, 0, 1);
  z-index: 10;
}
.lang.on .lang__menu {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

.lang__opt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 34px;
  padding: 0 10px;
  border-radius: var(--radius-md);
  color: var(--muted);
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease;
}
.lang__opt:hover { background: rgba(255, 255, 255, 0.06); color: var(--text); }
.lang__opt.on { color: var(--text); }
/* Le point n'apparait que sur la langue courante : un seul accent, discret. */
.lang__opt.on::after {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gradient);
}

@media (max-width: 900px) {
  /* La hauteur ne bouge plus : une seule valeur a toutes les largeurs, sinon
     la barre porte deux hauteurs qui ne s'alignent jamais. */
  .lang__menu { min-width: 138px; }
}
/* En dessous de 620px la barre du haut porte deja le logo, le bouton
   d'inscription et le menu : un objet de plus la fait deborder et passe
   par-dessus le logo. Les commandes descendent donc dans le menu plein ecran,
   ou elles tiennent a l'aise et se touchent du pouce.
   L'interrupteur jour/nuit suit la meme regle que les langues : mesure dans
   WebKit (le moteur des iPhone, qui rend Sora plus large que Chrome), a 375px
   sa lune touchait le Y de TALKIFY, et a 320px la barre sortait de l'ecran. */
@media (max-width: 768px) {
  .nav__right > .lang { display: none; }
  .nav__right > .theme-toggle { display: none; }
  /* Le bouton d'inscription, LUI, reste. Mesure du 11 aout : entre le hero et
     le CTA de section, un visiteur sur telephone parcourait 5 990px sans un
     seul bouton joignable. Il tient maintenant en rang 3, a 32px, ce qui est
     exactement ce que font Framer, Linear et Substack pour un CTA de barre
     persistant : petit et plein, jamais grand. */
  .nav__right > .btn--nav { display: inline-flex; }
}

/* ── Les langues dans le menu plein ecran ─────── */
.mobile-menu__langues {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 22px;
}
.lang-chip {
  height: var(--btn-h3);
  padding: 0 16px;
  border-radius: var(--radius-sm);
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: var(--muted);
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.25s ease, color 0.25s ease;
}
.lang-chip.on {
  color: var(--text);
  border-color: transparent;
  background: rgba(255, 255, 255, 0.08);
}
@media (prefers-reduced-motion: reduce) {
  .lang__chevron, .lang__menu { transition: none; }
}

/* Le declencheur du menu et le bouton Fermer. Rang 3 a filet : la pastille
   pleine de #222 etait le dernier objet plein d'un bandeau transparent, et le
   seul de la barre a 40px de haut. La hauteur ne depend plus d'aucun point de
   rupture, donc la marche de 7px au franchissement de 400px ne peut plus
   reapparaitre. */
.btn--menu {
  display: none;
  position: relative;
  align-items: center;
  justify-content: center;
  height: var(--btn-h3);
  padding: 0 16px;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  box-shadow: inset 0 0 0 1px var(--filet-btn);
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.btn--menu::after { content: ''; position: absolute; inset: -8px 0; }

/* Mobile fullscreen menu - hidden by default */
.mobile-menu {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  /* Sur iPhone, 100vh vaut la fenetre BARRES CACHEES. Au premier clic, la barre
     de Safari est encore la : le menu mesurait donc plus haut que le visible et
     son bas etait coupe. Il fallait fermer et rouvrir, une fois la barre
     repliee, pour tout voir. 100dvh suit la fenetre reellement visible. */
  height: 100vh;
  height: 100dvh;
  background: #000;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 80px 30px 40px;
  transform: translateY(-100%);
  transition: transform 0.5s ease;
  visibility: hidden;
  /* Un mot d'une future langue qui depasserait ne doit jamais rendre le menu
     glissable sur le cote : il se coupe, et le controle i18n le signale. */
  overflow-x: hidden;
}
.mobile-menu.open {
  transform: translateY(0);
  visibility: visible;
}

.mobile-menu button {
  -webkit-tap-highlight-color: transparent;
  outline: none;
}

.mobile-menu__top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: var(--nav-h);
  padding: 0 var(--section-px);
}
.mobile-menu__top .btn--menu {
  display: inline-block;
}
/* L'interrupteur jour/nuit vit aussi ici : le menu ouvert recouvre la barre,
   la commande ne doit pas disparaitre avec elle. */
.mobile-menu__controls {
  display: flex;
  align-items: center;
  gap: 10px;
}

.mobile-menu__links {
  display: flex;
  flex-direction: column;
}
.mobile-menu__link {
  font-family: var(--font-display);
  font-size: clamp(3rem, 12vw, 5rem);
  font-weight: 800;
  color: #fff;
  text-decoration: none;
  line-height: 1.2;
  padding: 0.4em 0;
  border-bottom: 1px solid #333;
  transition: color 0.2s;
}
.mobile-menu__link:last-child { border-bottom: none; }
.mobile-menu__link:hover { color: var(--accent-start); }
/* "Fonctionnalites" ne tient pas a 12vw sur un ecran de telephone : a 390px
   le s sort du cadre et le menu devient glissable sur le cote. Le francais
   descend a 10vw (mesure : 318px pour 330 disponibles a 390px d'ecran), les
   autres langues gardent la taille dessinee. */
html[lang="fr"] .mobile-menu__link { font-size: clamp(2rem, 10vw, 4.5rem); }

.mobile-menu__bottom {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
}
/* La forme du MENU, pas celle de la page. Quand le bouton d'inscription quitte
   la barre, Stripe et Vercel le posent en pied de menu de la meme facon : pleine
   largeur, couleur de marque, coins doux. La pastille de la page ferait un objet
   de passage la ou il faut un bloc qui appartient au panneau. */
.mobile-menu__cta {
  width: 100%;
  text-align: center;
}
.mobile-menu__socials {
  display: flex;
  gap: 1.5rem;
}
.mobile-menu__socials a::after { content: ''; position: absolute; inset: -13px; }
.mobile-menu__socials a {
  position: relative;
  color: rgba(255, 255, 255, 0.5);
  text-decoration: none;
  transition: color 0.2s;
}
.mobile-menu__socials a:hover { color: #fff; }

.btn:hover { opacity: 0.86; }
.btn:active { transform: translateY(1px); }

/* ─────────────────────────────────────────────────
   HERO
───────────────────────────────────────────────── */
.hero {
  position: relative;
  height: 100svh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Radial glow behind title */
.hero__glow {
  position: absolute;
  top: 42%;
  left: 50%;
  translate: -50% -50%;
  width: 80vw;
  height: 65vh;
  background: radial-gradient(ellipse at center,
    rgba(254, 160, 98, 0.11) 0%,
    rgba(244, 94, 124, 0.07) 45%,
    transparent 72%);
  pointer-events: none;
  z-index: 0;
}

.hero__content {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--nav-h) var(--section-px) 0;
  gap: 1.75rem;
  position: relative;
  z-index: 1;
}

.hero__title {
  font-family: var(--font-display);
  font-size: clamp(4rem, 8vw, 8rem);
  font-weight: 800;
  line-height: 1.0;
  letter-spacing: -0.04em;
  color: var(--text);
}

/* GSAP sets opacity on individual .word spans - keep container visible */
.hero__title .word {
  display: inline-block;
  will-change: transform, opacity;
}

.hero__sub {
  font-size: clamp(1rem, 1.8vw, 1.2rem);
  font-weight: 400;
  color: var(--muted);
  max-width: 460px;
  line-height: 1.65;
  will-change: transform, opacity;
}

/* ─────────────────────────────────────────────────
   MARQUEE
───────────────────────────────────────────────── */
.marquee-wrap {
  position: relative;
  width: 100%;
  overflow: hidden;
  padding-bottom: 2.5rem;
  z-index: 1;
  will-change: opacity;
}

/* Fade edges */
.marquee-wrap::before,
.marquee-wrap::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  width: 12%;
  z-index: 2;
  pointer-events: none;
}
.marquee-wrap::before {
  left: 0;
  background: linear-gradient(to right, var(--bg), transparent);
}
.marquee-wrap::after {
  right: 0;
  background: linear-gradient(to left, var(--bg), transparent);
}

.marquee {
  display: flex;
  width: max-content;
  will-change: transform;
  /* La duree reelle est posee par js/i18n.js, qui la calcule depuis la largeur
     pour que la vitesse ne change pas d'une langue a l'autre. Celle-ci ne sert
     que pour la premiere image, avant que le calcul ne passe : 9s, c'est la
     valeur anglaise depuis que le bandeau ne porte plus que deux copies. */
  animation: marquee-scroll 9s linear infinite;
}

.marquee__item {
  font-family: var(--font-display);
  font-size: 10vw;
  font-weight: 800;
  line-height: 1.05;
  white-space: nowrap;
  letter-spacing: -0.02em;
  background: var(--gradient);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  opacity: 0.35;
}

@keyframes marquee-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ─────────────────────────────────────────────────
   INTRO SECTION
───────────────────────────────────────────────── */
.intro {
  position: relative;
  overflow: hidden;
  background: var(--bg-mid);
  padding: clamp(6rem, 12vw, 12rem) var(--section-px);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 1.75rem;
}

.intro__heading {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4.5vw, 4rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.03em;
  max-width: 800px;
}

.intro__body {
  font-size: clamp(1rem, 1.6vw, 1.15rem);
  color: var(--muted);
  max-width: 580px;
  line-height: 1.75;
}

/* Floating creator images */
.floating-images-wrapper {
  position: absolute;
  inset: 0;
  pointer-events: none;
  will-change: transform;
}
.floating-img {
  position: absolute;
  width: 180px;
  pointer-events: none;
  z-index: 1;
  will-change: transform;
}
.floating-img--1 { top: 8%;  left: 6%;  }
.floating-img--2 { top: 5%;  right: 6%; }
.floating-img--3 { bottom: 12%; right: 10%; }
.floating-img--4 { bottom: 10%; left: 8%;   }

/* ─────────────────────────────────────────────────
   BENTO / STEPS SECTION
───────────────────────────────────────────────── */
.steps {
  background: var(--bg);
  /* height set by JS for card stacking scroll distance */
}

/* ── Sticky viewport container ── */
.steps__sticky {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;     /* clips cards outside the viewport frame */
  will-change: transform;
}

/* ── Base grid layout (shared) ── */
.step {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: clamp(2rem, 5vw, 6rem);
  padding: clamp(5rem, 10vw, 10rem) var(--section-px);
  min-height: 100vh;
}

/* ── Card stacking variant (steps 1-4) ── */
.step--card {
  position: absolute;
  inset: 0;
  height: 100svh;
  min-height: unset;
  padding: clamp(2rem, 5vw, 5rem) var(--section-px);
  background: var(--bg);
  will-change: transform;
  box-shadow: 0 -20px 60px rgba(0, 0, 0, 0.5);
}

/* Ascending z-index so later cards slide OVER earlier ones */
#step-1 { z-index: 1; }
#step-2 { z-index: 2; }
#step-3 { z-index: 3; }
#step-4 { z-index: 4; }
#step-5 { z-index: 5; }

/* Step 2: reversed layout */
.step--reverse {
  direction: rtl;
}
.step--reverse > * {
  direction: ltr;
}

.step__text {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.step__label {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-start);
}

.step__title {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 4vw, 3.75rem);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.03em;
}

.step__list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.step__list li {
  font-size: clamp(0.95rem, 1.4vw, 1.05rem);
  color: var(--muted);
  line-height: 1.65;
  padding-left: 1.2rem;
  position: relative;
}

.step__list li::before {
  content: '·';
  position: absolute;
  left: 0;
  color: var(--accent-end);
  font-weight: 700;
}

/* App mockup placeholder */
.step__mockup {
  width: 100%;
  max-width: 300px;
  height: 652px;
  background: #1a1a1a;
  border-radius: 40px;
  margin: 0 auto;
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(255,255,255,0.06);
  box-shadow:
    0 40px 80px rgba(0,0,0,0.6),
    0 0 0 1px rgba(255,255,255,0.04) inset;
  will-change: transform;
}

.step__mockup img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  display: block;
}

/* Demo animation frames inside mockup */
.step__mockup--demo { position: relative; }
.demo-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  display: block;
  opacity: 0;
  pointer-events: none;
  border-radius: inherit;
}
.demo-frame--1 { opacity: 1; z-index: 1; }
.demo-frame--2 { z-index: 2; transform: translateY(100%); }
.demo-frame--3 { z-index: 3; }
.demo-frame--4 { z-index: 4; }
.demo-frame--5 { z-index: 0; }

/* Subtle inner glow on mockup */
.step__mockup::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(ellipse at 50% 0%,
    rgba(254, 160, 98, 0.08) 0%,
    transparent 65%);
}

/* ─────────────────────────────────────────────────
   STEP - SAFETY (full-width centered variant)
───────────────────────────────────────────────── */
.step--safety {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  overflow: hidden;
}

/* Radial glow centred on the lock icon (~40% from top) */
.step--safety::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse 70% 55% at 50% 40%,
    rgba(254, 160, 98, 0.13) 0%,
    rgba(244, 94, 124, 0.09) 35%,
    transparent 72%
  );
  pointer-events: none;
}

.step__safety-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2rem;
  max-width: 720px;
  position: relative;
  z-index: 1;
}

/* Bigger title - matches the weight of other bento steps */
.step--safety .step__title {
  font-size: clamp(3rem, 6vw, 6rem);
}

/* ── Lock icon ── */
.step__lock-wrap {
  position: relative;
  width: 80px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.step__lock {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 80px;
  height: 80px;
  border-radius: var(--radius-lg);
  background: rgba(254, 160, 98, 0.08);
  border: 1px solid rgba(254, 160, 98, 0.2);
  box-shadow:
    0 0 32px rgba(254, 160, 98, 0.18),
    0 0 64px rgba(244, 94, 124, 0.12);
}

/* ── Pulsing rings ── */
.lock-ring {
  position: absolute;
  border-radius: 50%;
  border: 1px solid;
  pointer-events: none;
  animation: lock-pulse 3.2s ease-out infinite;
}

.lock-ring--1 {
  width: 140px;
  height: 140px;
  border-color: rgba(254, 160, 98, 0.55);
  box-shadow: 0 0 14px rgba(254, 160, 98, 0.18);
  animation-delay: 0s;
}

.lock-ring--2 {
  width: 220px;
  height: 220px;
  border-color: rgba(254, 160, 98, 0.3);
  box-shadow: 0 0 22px rgba(244, 94, 124, 0.1);
  animation-delay: 1.05s;
}

.lock-ring--3 {
  width: 310px;
  height: 310px;
  border-color: rgba(244, 94, 124, 0.15);
  animation-delay: 2.1s;
}

@keyframes lock-pulse {
  0%   { transform: scale(0.88); opacity: 0; }
  12%  { opacity: 1; }
  100% { transform: scale(1.12); opacity: 0; }
}

/* ── List (centred, no dash bullets) ── */
.step__list--centered {
  align-items: center;
  text-align: center;
}

.step__list--centered li {
  padding-left: 0;
}

.step__list--centered li::before {
  display: none;
}

/* ─────────────────────────────────────────────────
   STATS SECTION
───────────────────────────────────────────────── */
.stats-section {
  background: rgba(0, 0, 0, 0.92);
  padding: clamp(6rem, 12vw, 12rem) var(--section-px);
  display: flex;
  flex-direction: column;
  gap: clamp(4rem, 7vw, 6rem);
}

.stats-section__header {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.stats-section__eyebrow {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-start);
}

.stats-section__title {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 5vw, 4.5rem);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.03em;
  max-width: 700px;
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.5rem, 3vw, 3rem);
}

.stat {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: clamp(1.5rem, 3vw, 2.5rem) 0;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  will-change: transform, opacity;
}

.stat__number {
  font-family: var(--font-display);
  font-size: clamp(3rem, 5vw, 5rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.04em;
  background: var(--gradient);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.stat__label {
  font-size: 1rem;
  font-weight: 700;
  color: var(--text);
  margin-top: 0.5rem;
}

.stat__desc {
  font-size: 0.85rem;
  font-weight: 400;
  color: #999;
}

/* ─────────────────────────────────────────────────
   WHO IT'S FOR
───────────────────────────────────────────────── */
.who {
  background: var(--bg-mid);
  padding: clamp(6rem, 12vw, 12rem) var(--section-px);
  /* Les cartes attendent leur tour couchees en arriere (rotateX 40 avec une
     perspective de 900). Une rotation en perspective projette une boite PLUS
     LARGE que l'element : sous 430px, les cartes depassaient de 9px et la page
     entiere glissait lateralement des le chargement, avant meme qu'on arrive
     a la section. On coupe au bord. `clip` et non `hidden` : hidden creerait
     un conteneur de defilement et casserait les epinglages de ScrollTrigger. */
  overflow-x: clip;
  display: flex;
  flex-direction: column;
  gap: clamp(3rem, 6vw, 5rem);
}

.who__header {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}

.who__eyebrow {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-start);
}

.who__title {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 5vw, 4.5rem);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.03em;
}

.who-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.25rem;
}

.who-card {
  border: 1px solid #333;
  border-radius: 16px;
  padding: clamp(1.5rem, 3vw, 2.5rem);
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  will-change: transform, opacity;
  transition: border-color 0.3s;
}

.who-card:hover {
  border-color: rgba(254, 160, 98, 0.4);
}

.who-card__num {
  font-family: var(--font-display);
  font-size: 0.8rem;
  font-weight: 800;
  letter-spacing: 0.1em;
}

.who-card__title {
  font-family: var(--font-display);
  font-size: clamp(1.2rem, 2vw, 1.5rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.who-card__desc {
  font-size: 0.95rem;
  color: var(--muted);
  line-height: 1.6;
}

.who__tagline {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 2.5vw, 2rem);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.02em;
  color: var(--muted);
  will-change: transform, opacity;
}

/* ─────────────────────────────────────────────────
   CTA SECTION
───────────────────────────────────────────────── */
/* La machine a ecrire tapait un mot a la fois, en boucle, sans rapport avec ce
   que faisait le visiteur : elle tournait dans le vide meme quand personne ne
   regardait. Ici c'est le defilement qui joue le film. Le verbe reste fige au
   milieu de l'ecran, la colonne des mots le traverse, chacun s'allume en
   passant sous lui, et le dernier reste allume quand le bouton arrive.
   Le principe vient du pen "you can scroll." de Jhey Tompkins (voir
   docs/references_externes.md). Lui le tient en CSS pur avec view-timeline ;
   nous le tenons en GSAP, parce que view-timeline n'existe pas encore chez la
   moitie de nos visiteurs, qui sont sur iPhone. */
.cta-section {
  position: relative;
  /* La hauteur est posee en pixels par js/app.js : autant d'ecrans que de mots
     a faire passer. Cette valeur n'est qu'un repli si le script ne tourne pas,
     et elle donne alors une section normale, lisible, sans animation. */
  min-height: 100vh;
}

.cta-section::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    135deg,
    rgba(254, 160, 98, 0.08) 0%,
    rgba(244, 94, 124, 0.08) 100%
  );
  pointer-events: none;
}

/* La scene ne bouge pas pendant que la piste defile. Elle porte tout : le
   verbe, la colonne, le sous-titre et le bouton. */
/* Une seule case de grille pour deux occupants : le titre s'y centre, le pied
   s'y colle en bas. C'est ce qui met le mot actif au MILIEU EXACT de l'ecran,
   comme dans la reference. Empiles l'un sur l'autre, le titre etait pousse vers
   le haut par le sous-titre et le bouton, et le mot tombait a 41 % de la
   hauteur : on lisait la colonne en levant les yeux. */
.cta-section__scene {
  position: sticky;
  top: 0;
  height: 100vh;
  display: grid;
  grid-template: 1fr / 1fr;
  /* Marges laterales bien plus courtes qu'ailleurs sur la page. Ici elles ne
     protegent aucune colonne de lecture : elles ne font que voler la place dont
     le titre a besoin pour se recentrer. Les rendre a la scene, c'est 122px de
     jeu gagnes de chaque cote a 1440. */
  padding: 0 clamp(12px, 3vw, 40px);
  text-align: center;
  overflow: hidden;
}

.cta-section__title,
.cta-pied { grid-area: 1 / 1; z-index: 1; }

.cta-pied {
  align-self: end;
  justify-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
  padding-bottom: clamp(2rem, 6vh, 4rem);
}

.cta-section__title {
  font-family: var(--font-display);
  /* Ces trois nombres ne sont pas un gout, ils sont dictes par la plus longue
     entree des trois langues. Sur une ligne, le titre ne fait pas la largeur
     d'un mot mais celle du verbe PLUS le plus long mot de la colonne, et un mot
     de cette colonne ne peut pas passer a la ligne : il prendrait la place du
     suivant. La phrase de fin, "Become whoever you want to be", a rallonge
     cette entree de cinq caracteres, donc le corps redescend d'autant.
     Mesure : 5vw laisse 254px de reserve a 1440 et 118px a 769 ; le plancher,
     qui ne gouverne qu'en dessous de 448px, laisse 24px a 320px de large.
     Cette reserve n'est pas du vide perdu : c'est elle qui permet au titre de
     se decaler vers le milieu, voir --cta-decal plus bas. */
  font-size: clamp(1.4rem, 5vw, 6.2rem);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.04em;
  /* Le verbe et la colonne sur la MEME ligne, comme dans la reference : le
     verbe tient sa place, la colonne defile a cote de lui. C'est cette
     juxtaposition qui fait l'effet ; l'un au-dessus de l'autre, on ne voit plus
     qu'un mot qui change. En dessous de 768px il n'y a pas la place pour les
     deux sur une ligne, le verbe passe donc au-dessus. */
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 0.28em;
  text-align: left;
  place-self: center;
  max-width: 100%;
  /* Le titre est centre comme BOITE, mais la boite fait la largeur du mot le
     plus long : les dix-huit autres flottent a gauche dedans, et le couple
     "verbe + mot" se lit a 262px du milieu. Ce decalage, mesure par js/app.js
     dans la langue et a la largeur du moment, ramene le mot median au centre.
     Il passe par `left` et non par une transformation : GSAP ecrit la sienne
     sur ce meme titre pour l'entree en scene, et l'ecraserait. */
  position: relative;
  left: var(--cta-decal, 0px);
}

.cta-verbe { flex: none; }

/* La fenetre par laquelle passent les mots. Elle est HAUTE, sept lignes, et
   c'est tout le sujet : on doit voir la colonne, pas un mot. A une ligne on
   voyait un mot en remplacer un autre, c'est-a-dire une machine a sous ; a
   trois on devinait un mouvement ; a sept on lit d'ou l'on vient et ou l'on va,
   et c'est exactement ce qui rend la reference lisible d'un coup d'oeil.
   Le voile aux deux bords evite le couperet : un mot ne disparait pas au ras
   d'une arete, il s'efface avant de sortir. */
.cta-defile {
  position: relative;
  display: block;
  /* Sept lignes, sauf sur un ecran bas ou la colonne viendrait toucher le
     sous-titre : elle cede alors de la hauteur plutot que de le chevaucher.
     Le plafond est mesure par js/app.js, qui seul connait la hauteur reelle du
     pied ; le repli en vh sert le temps que le script se lance. Le nombre de
     lignes visibles devient fractionnaire, ce que le voile absorbe et dont le
     centrage ne depend plus. */
  height: min(7.35em, var(--cta-dispo, 58vh));
  overflow: hidden;
  flex: none;
  -webkit-mask-image: linear-gradient(transparent 0%, #000 34%, #000 66%, transparent 100%);
          mask-image: linear-gradient(transparent 0%, #000 34%, #000 66%, transparent 100%);
}

.cta-mots {
  list-style: none;
  margin: 0;
  padding: 0;
  will-change: transform;
}

/* Chaque mot prend sa couleur entre les deux accents de la marque, du premier
   au dernier. Aucune teinte n'est inventee : c'est le degrade du logo, etale
   sur la colonne au lieu d'etre etale sur une surface. */
.cta-mots li {
  /* Le cran de la colonne ne depend PLUS du corps de l'entree : js/app.js le
     pose en pixels a partir du corps du TITRE. C'est ce qui autorise une entree
     trop longue a se resserrer pour tenir sur sa ligne sans raccourcir son cran,
     ce qui decalerait toute la colonne d'autant. Sans script, le repli en em
     redonne exactement le comportement d'avant.
     La hauteur de ligne en pixels centre le texte resserre dans son cran, sans
     rien changer pour les entrees qui gardent le corps plein. */
  height: var(--cta-ligne, 1.05em);
  line-height: var(--cta-ligne, 1.05);
  white-space: nowrap;
  color: color-mix(in oklab, var(--accent-start), var(--accent-end) calc(var(--i) / var(--n) * 100%));
  opacity: 0.18;
}

/* L'eclat du mot pile au centre, que la reference obtient avec un
   filter: brightness() pose a 50 % de sa plage. js/app.js ne fournit que deux
   choses : cette classe sur les deux ou trois mots qui touchent le centre, et
   --p, leur proximite de 0 a 1. L'intensite, elle, est un choix de couleur et
   vit ici : --cta-eclat vaut plus que 1 sur fond noir et MOINS que 1 sur la
   creme, parce qu'eclaircir un corail pose sur du papier le fait disparaitre
   dedans. Meme reflexe que la gamme assombrie de light.css.
   La classe n'est pas un detail : un filter pose sur les dix-neuf mots, meme a
   l'identite, demande au navigateur de traiter dix-neuf calques pour rien. */
.cta-mots li.cta-mots__proche {
  filter: brightness(calc(1 + (var(--cta-eclat) - 1) * var(--p, 0)));
}

/* Le verbe et le DERNIER mot sont une seule phrase, donc une seule encre. Chez
   la reference, le dernier element sort de la gamme de couleurs et reprend
   exactement le traitement du verbe : c'est ce qui fait lire la chute d'un
   bloc, "Devenez qui vous voulez", au lieu d'un dix-neuvieme element colore de
   plus. Et cette encre n'est pas plate : elle est pleine sur la moitie haute
   puis s'eteint vers le bas, ce qui donne du poids a une lettre de cette
   taille. Les deux valeurs viennent des jetons, donc le mode jour suit. */
.cta-verbe,
.cta-mots li:last-of-type {
  background: linear-gradient(var(--text) 50%, color-mix(in oklab, var(--bg), var(--text) 25%));
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
}

.cta-section__sub {
  font-size: clamp(1rem, 1.8vw, 1.25rem);
  color: var(--muted);
  font-weight: 400;
}

/* Le texte que seul un lecteur d'ecran entend : la colonne animee lui est
   masquee, il recoit la liste des mots d'une traite. */
.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;
}

/* ─────────────────────────────────────────────────
   FEATURES GUIDE
───────────────────────────────────────────────── */
.features {
  background: var(--bg);
  padding: clamp(6rem, 12vw, 12rem) 0;
  display: flex;
  flex-direction: column;
  gap: clamp(2.5rem, 5vw, 4rem);
  overflow: hidden;
}

.features__header {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: 0 var(--section-px);
}

.features__eyebrow {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-start);
}

.features__title {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4.5vw, 4rem);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.03em;
}

.features-carousel {
  display: flex;
  gap: 1.25rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  padding: 0.5rem var(--section-px) 1rem;
  cursor: grab;
}

.features-carousel::-webkit-scrollbar { display: none; }
.features-carousel:active { cursor: grabbing; }

.feature-card {
  scroll-snap-align: start;
  flex: 0 0 clamp(280px, 32vw, 400px);
  background: #1a1a1a;
  border: 1px solid #333;
  border-radius: 16px;
  padding: clamp(1.5rem, 3vw, 2rem);
  display: flex;
  flex-direction: column;
  gap: 1rem;
  transition: border-color 0.3s;
  will-change: transform, opacity;
}

.feature-card:hover {
  border-color: rgba(254, 160, 98, 0.35);
}

.feature-card::before {
  content: '';
  display: block;
  width: 32px;
  height: 2px;
  background: var(--gradient);
  border-radius: 2px;
}

.feature-card__title {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 800;
  letter-spacing: -0.02em;
}

.feature-card__desc {
  font-size: 0.95rem;
  color: var(--muted);
  line-height: 1.65;
}

.carousel-nav {
  display: flex;
  /* 24px : deux jupes de 8px voisines mangent 16px. Sans cet ecart, un rate
     entre les deux fleches ferait defiler dans le mauvais sens. */
  gap: 1.5rem;
  padding: 0 var(--section-px);
}

.carousel-nav__btn {
  position: relative;
  width: var(--btn-h3);
  height: var(--btn-h3);
  border-radius: var(--radius-sm);
  border: 1px solid var(--filet-btn);
  background: transparent;
  color: var(--text);
  /* Seul bloc de la page qui n'avait aucune police declaree : il tombait sur
     celle du systeme. */
  font-family: var(--font-body);
  font-size: 1.1rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.2s, background 0.2s;
}

.carousel-nav__btn::after { content: ''; position: absolute; inset: -8px; }

.carousel-nav__btn:hover {
  border-color: var(--accent-start);
  background: rgba(254, 160, 98, 0.08);
}

/* ─────────────────────────────────────────────────
   FAQ
───────────────────────────────────────────────── */
.faq {
  background: var(--bg-mid);
  padding: clamp(6rem, 12vw, 12rem) var(--section-px);
  display: flex;
  flex-direction: column;
  gap: clamp(3rem, 6vw, 5rem);
}

.faq__header {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}

.faq__eyebrow {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-start);
}

.faq__title {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4.5vw, 4rem);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.03em;
}

.faq-list {
  display: flex;
  flex-direction: column;
  max-width: 820px;
}

.faq-item {
  border-bottom: 1px solid #333;
}

.faq-question {
  width: 100%;
  background: none;
  border: none;
  color: var(--text);
  font-family: var(--font-body);
  font-size: clamp(1rem, 1.6vw, 1.15rem);
  font-weight: 700;
  text-align: left;
  padding: 1.5rem 0;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}

.faq-icon {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  position: relative;
  transition: transform 0.35s ease;
}

/* Plus icon drawn in CSS */
.faq-icon::before,
.faq-icon::after {
  content: '';
  position: absolute;
  background: var(--accent-start);
  border-radius: 2px;
  transition: transform 0.35s ease, opacity 0.35s ease;
}
.faq-icon::before {
  width: 14px; height: 1.5px;
  top: 50%; left: 50%;
  translate: -50% -50%;
}
.faq-icon::after {
  width: 1.5px; height: 14px;
  top: 50%; left: 50%;
  translate: -50% -50%;
}

.faq-item.is-open .faq-icon::after {
  transform: rotate(90deg);
  opacity: 0;
}

.faq-answer {
  overflow: hidden;
  height: 0;
}

.faq-answer p {
  padding-bottom: 1.5rem;
  font-size: clamp(0.9rem, 1.4vw, 1rem);
  color: #999;
  line-height: 1.75;
  max-width: 680px;
}

/* ─────────────────────────────────────────────────
   FINAL CTA
───────────────────────────────────────────────── */
.final-cta {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--bg);
  padding: clamp(8rem, 16vw, 16rem) var(--section-px);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.final-cta__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2rem;
  max-width: 860px;
  will-change: transform, opacity;
}

.final-cta__title {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 6vw, 6rem);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.035em;
}

.final-cta__tagline {
  font-size: 0.95rem;
  color: var(--muted);
  font-style: italic;
  letter-spacing: 0.02em;
}

/* ─────────────────────────────────────────────────
   FOOTER XXL
───────────────────────────────────────────────── */
/* ── LA REVELATION DU PIED ─────────────────────
   La derniere section reste en place et le pied glisse par-dessus, comme sur
   fanvue.com (cf. docs/references_externes.md).

   .final-cta etait deja declaree collante, et n'a jamais colle une seule fois :
   elle est le DERNIER enfant de <main>, donc le bas de son bloc conteneur
   tombe exactement sur son propre bas. Une position collante ne peut pas
   depasser ce bas : la course disponible valait zero, la regle ne faisait rien.

   On ajoute donc un vrai bloc vide d'une hauteur de fenetre apres elle, et on
   reprend cette hauteur sur le pied. Un remplissage n'aurait rien donne : le
   bloc conteneur d'un element collant est la boite de CONTENU du parent, pas
   sa boite de remplissage. Mesure faite, padding-bottom ne bougeait rien.

   La page ne s'allonge donc pas d'un pixel, mais la section a desormais de quoi
   rester en place pendant que le pied la recouvre. Le pied passe devant par son
   z-index, qui vaut deja 100 contre 50. */
main::after {
  content: '';
  display: block;
  height: 100vh;
}

.footer {
  margin-top: -100vh;
  /* Relatif et non collant : le pied glisse, il ne s'accroche pas. Colle en
     haut, il se figeait sur les 24 derniers pixels de la course. */
  position: relative;
  /* Le pied deborde de l'ecran des DEUX cotes, pour deux raisons distinctes.

     EN BAS, 3px repris par une marge negative : la page se termine ou le
     pied se termine, et l'arrondi sous-pixel de la hauteur de fenetre
     tombait du mauvais cote, laissant une lisiere du fond sous le noir.
     La marge annule les 3px, donc la hauteur de page ne bouge pas et le
     noir est peint sous la fin de la zone parcourable.

     EN HAUT, 24px de course en plus, eux NON repris : les coins arrondis
     laissaient voir le fond de page a travers l'arrondi une fois arrive
     tout en bas. Un element colle ne remonte jamais au-dessus de sa
     position naturelle, la seule facon de sortir l'arrondi de l'ecran est
     donc d'allonger la page. Le padding rend au contenu les 24px qu'il
     perdrait, la composition ne bouge pas d'un pixel. */
  min-height: calc(100vh + 27px);
  margin-bottom: -3px;
  padding-top: 24px;
  background: #000;
  z-index: 100;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  box-shadow: 0 -20px 60px rgba(0, 0, 0, 0.5);
}

.footer__top {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: clamp(3rem, 6vw, 8rem);
  align-items: start;
  padding: clamp(5rem, 10vw, 10rem) var(--section-px) clamp(4rem, 8vw, 8rem);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.footer__cta {
  display: flex;
  flex-direction: column;
  /* SANS cette ligne, l'enfant herite de stretch et le bouton allait chercher
     les 440px entiers de la colonne. C'est la seule raison pour laquelle le
     bouton du pied etait le plus grand de la page : personne ne l'avait
     decide. La meme classe epouse son libelle partout ailleurs. */
  align-items: flex-start;
  gap: 1.5rem;
  max-width: 440px;
}

.footer__cta-eyebrow {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-start);
}

.footer__cta-title {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 3.5vw, 3rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.03em;
}

.footer__cols {
  display: flex;
  gap: clamp(2rem, 4vw, 5rem);
  align-items: start;
}

.footer__col {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-width: 100px;
}

.footer__col-title {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(240, 237, 232, 0.35);
  margin-bottom: 0.25rem;
}

.footer__col-links {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}

.footer__col-links a {
  font-size: 0.9rem;
  font-weight: 400;
  color: rgba(240, 237, 232, 0.6);
  text-decoration: none;
  transition: color 0.2s;
}

.footer__col-links a:hover { color: var(--text); }

.footer__socials {
  display: flex;
  gap: 1.5rem;
}

/* Le dessin ne change PAS : ni filet, ni fond, ni forme, sinon on fabrique une
   soupe de petites boites. Seule la zone de contact passe a 48, et elle ne
   coute aucun pixel visible. L'ecart de 24px la rend sans chevauchement. */
.footer__social::after { content: ''; position: absolute; inset: -14px; }
.footer__social {
  position: relative;
  color: rgba(240, 237, 232, 0.5);
  text-decoration: none;
  display: flex;
  transition: color 0.2s;
}

.footer__social:hover { color: var(--text); }

/* Massive watermark - full viewport width */
.footer-brand {
  font-family: var(--font-display);
  font-size: 21vw;
  font-weight: 900;
  text-transform: uppercase;
  line-height: 0.85;
  color: #1a1a1a;
  width: 100vw;
  margin-left: calc(-50vw + 50%);
  overflow: visible;
  white-space: nowrap;
  letter-spacing: -0.02em;
  text-align: center;
  margin-top: auto;
  user-select: none;
  pointer-events: none;
  will-change: transform;
  padding: 0;
  display: block;
}

.footer__bottom {
  padding: 0.75rem var(--section-px) 1rem;
  text-align: center;
}

.footer__bottom p {
  font-size: 12px;
  color: #666;
}

/* ─────────────────────────────────────────────────
   RESPONSIVE
───────────────────────────────────────────────── */
/* Le couple du hero s'empile sous 620px : cote a cote, le francais demande
   213,89 + 169,89 + 12 d'ecart, soit 396px pour une colonne de 350 a 390px. */
@media (max-width: 620px) {
  .hero__actions { flex-direction: column; align-items: stretch; width: 100%; }
  .hero__actions .btn { width: 100%; }
}

@media (max-width: 768px) {

  /* ── Nav ── */
  .nav__links { display: none; }
  .btn--menu { display: inline-flex; }

  /* ── Intro - allow images to scroll without clipping ── */
  .intro { overflow: visible; }

  /* Disable hover effects in mobile menu */
  .mobile-menu a {
    -webkit-tap-highlight-color: transparent;
  }
  .mobile-menu a:hover {
    color: inherit;
    background: none;
  }

  /* ── Hero ── */
  .hero__title { font-size: clamp(2.5rem, 8vw, 4rem); }

  /* ── Floating images - 3-column grid on mobile ── */
  .floating-images-wrapper {
    position: relative !important;
    inset: auto !important;
    display: flex;
    justify-content: center;
    gap: 8px;
    padding: 20px 15px;
    overflow: visible !important;
    margin-top: 2rem;
    transform: none !important;
  }
  .floating-img {
    position: relative !important;
    top: auto !important;
    left: auto !important;
    right: auto !important;
    bottom: auto !important;
    transform: none !important;
    flex-shrink: 1;
    width: 30%;
    height: auto;
    object-fit: cover;
    border-radius: 12px;
    animation: none !important;
  }
  .floating-img--4 { display: none; }
  .floating-img:nth-child(1) { margin-top: 0; }
  .floating-img:nth-child(2) { margin-top: 20px; }
  .floating-img:nth-child(3) { margin-top: -10px; }

  /* ── Marquee ── */
  .marquee__item { font-size: 15vw; }

  /* ── Steps bento - keep sticky + parallax, adapt layout ── */
  .step--card {
    padding: 80px 20px 40px;
  }
  .step {
    grid-template-columns: 1fr;
    text-align: left;
    gap: 30px;
  }
  .step--reverse { direction: ltr; }
  /* Le passage du bento en texte a gauche ne doit pas emporter la carte 005,
     la seule entierement centree : cadenas et label centres, titre a gauche,
     l'oeil le voit tout de suite (surtout en francais, Prive est bien plus
     court que par nature). */
  .step--safety { text-align: center; }
  .step__title { font-size: clamp(2rem, 7vw, 3rem); }
  .step__list li {
    font-size: 14px;
    line-height: 1.6;
  }
  .step__mockup { height: 609px; max-width: 280px; margin: 0 auto; }
  .step__mockup img { object-fit: cover; object-position: top; }

  /* ── Stats ── */
  .stats-grid { grid-template-columns: repeat(2, 1fr); gap: 20px; }

  /* ── Who it's for ── */
  .who-grid { grid-template-columns: 1fr; }

  /* ── CTA typewriter ── */
  /* La colonne reprend la largeur que la marge de section lui prenait : elle
     est centree et n'a pas de voisin, elle peut aller plus pres du bord. */
  .cta-section__scene { padding-left: 12px; padding-right: 12px; }
  /* Pas la place pour le verbe et la colonne sur une ligne de telephone : le
     verbe passe au-dessus, la colonne garde toute sa hauteur. Et comme ils ne
     sont plus cote a cote, la contrainte de largeur tombe de moitie : le titre
     n'a plus a tenir "Devenez" PLUS le plus long mot, seulement le plus long
     mot. D'ou un corps plus grand qu'en bureau rapporte a la largeur, sinon
     l'anglais, qui dicte le plancher commun, rapetisserait le titre francais
     sur tous les telephones sans aucune raison. */
  /* Et ce corps ne se regle plus sur l'entree la plus longue de la colonne.
     Cette entree est la PHRASE de chute, pas un mot, et elle coutait aux dix-
     huit autres la moitie de leur taille : mesure du 14/08 a 390px de large,
     "whoever you want to be" fait 11,5 corps de large quand l'entree suivante
     en fait 7,8. Un dix-neuvieme du contenu dictait donc la taille des
     dix-huit autres, et la section se lisait perdue au milieu d'un ecran noir.
     Le corps se regle desormais sur les MOTS ; js/app.js resserre la seule ou
     les deux entrees qui depassent, sans toucher a leur cran. Personne n'y
     perd : a 390px la chute passe de 25,7 a environ 30px, les mots de 25,7 a
     40,2px. Le plafond tient le saut du seuil des 768px dans le meme ordre de
     grandeur qu'avant. */
  .cta-section__title { display: block; position: relative; text-align: center;
                        font-size: clamp(1.95rem, 10.3vw, 3.5rem); }
  /* Le verbe sort du flux et se pose au-dessus de la fenetre. Sans ca, le bloc
     du titre vaut verbe + colonne, et centrer ce bloc descend le mot actif
     d'une demi-hauteur de verbe sous le milieu de l'ecran. Hors du flux, le
     titre vaut exactement la fenetre, donc le mot actif tombe pile au milieu,
     sur telephone comme sur bureau. */
  .cta-verbe { position: absolute; left: 0; right: 0; bottom: calc(100% + 0.05em); }
  /* La fenetre garde les SEPT lignes du bureau. Elle en montrait cinq, et
     c'etait la vraie difference de tenue entre les deux : mesure du 14/08, la
     colonne occupait 59 % de la hauteur d'ecran en bureau contre 25 % sur
     telephone, le reste etant du noir. On ne lisait plus une colonne qui
     traverse, on lisait trois mots poses au milieu d'un ecran vide.
     Rien a proteger en faisant moins : le plafond mesure par js/app.js
     (--cta-dispo) rend deja la hauteur au pied sur les ecrans bas, et c'est lui
     qui gouverne des que la place manque. */

  /* ── Features carousel ── */
  .features-carousel { gap: 16px; }
  .feature-card { flex: 0 0 clamp(260px, 80vw, 360px); }

  /* ── FAQ ── */
  .faq { padding: 40px 20px; }

  /* ── Final CTA ── */
  .final-cta__title { font-size: clamp(2rem, 8vw, 3rem); }

  /* ── Footer ── */
  .footer__top {
    grid-template-columns: 1fr;
    gap: 3rem;
    padding-left: 20px;
    padding-right: 20px;
    /* Sur large ecran ce filet separe deux colonnes et se lit comme une regle
       de composition. Sur telephone il n'a plus rien a separer : les colonnes
       sont passees l'une sous l'autre, il traverse donc toute la largeur et
       coupe le pied en deux blocs. Le noir doit courir d'un seul tenant.
       Le mode jour repeint ce filet avec sa propre valeur : il est eteint
       la-bas aussi, cf. css/light.css. */
    border-bottom: none;
  }
  .footer__cols { flex-wrap: wrap; gap: 2rem; }

  /* Le monogramme touche les deux bords, comme sur Fanvue. 23.5vw est mesure :
     TALKIFY fait 413,6px de large a 100px de corps dans ce dessin, donc 24,18vw
     remplit exactement la fenetre. On garde un cheveu de marge pour qu'un
     arrondi de rendu ne rogne jamais le Y. */
  .footer-brand { font-size: 23.5vw; }
}

/* ─────────────────────────────────────────────────
   SMALL MOBILE (iPhone 15 / SE / 390px and below)
───────────────────────────────────────────────── */
@media (max-width: 400px) {

  /* ── Nav ── */
  .nav__logo span { font-size: 14px; letter-spacing: 2px; }
  .nav__logo img { width: 20px; height: 20px; }
  /* Les hauteurs ne bougent PLUS : la marche de 7px du bouton Fermer venait
     de la. Seul l'ecart de la barre se resserre, l'arithmetique a 320px ne
     laissant pas 16px : logo 103,5 + Commencer 114,5 + Menu 78,8 = 296,8 pour
     272 de colonne utile. */
  .nav__right { gap: 12px; }
  .btn--r3, .btn--menu, .lang__btn { padding-left: 12px; padding-right: 12px; }

  /* Le rang 1 respire de 20 et non de 32 : le francais est la langue la plus
     longue du site et "Commencer gratuitement" mesure 217px de texte, pour
     208px utiles dans une boite de 272 a marge de 32. Il passait donc sur deux
     lignes DANS une boite de hauteur fixe, c'est-a-dire qu'il en sortait par le
     bas sans que rien ne grandisse. 20px rend 24px et laissent 15 de reserve. */
  .btn--r1 { padding-left: 20px; padding-right: 20px; }
  /* Meme cause au rang 2, dans le menu plein ecran : 260 de boite, 212 utiles,
     214 de texte. Deux pixels manquaient, et la ligne partait dessous. */
  .btn--r2 { padding-left: 16px; padding-right: 16px; }

  /* ── Hero ── */
  .hero__title { font-size: clamp(2rem, 9vw, 3rem); }
  .hero__sub { font-size: 0.9rem; }

  /* ── Intro ── */
  .intro__heading { font-size: clamp(1.8rem, 8vw, 2.5rem); }
  .floating-img { width: 28%; }
  .floating-img:nth-child(1) { margin-top: 0; }
  .floating-img:nth-child(2) { margin-top: 15px; }
  .floating-img:nth-child(3) { margin-top: -5px; }

  /* ── Bento ── */
  .step--card { padding: 70px 15px 30px; }
  .step__title { font-size: clamp(1.8rem, 7vw, 2.5rem); }
  .step__list li { font-size: 13px; }
  .step__mockup { max-width: 220px; height: 478px; }

  /* ── Stats ── */
  .stats-grid { gap: 15px; }
  .stat__number { font-size: clamp(2rem, 8vw, 2.5rem); }

  /* ── Who ── */
  .who-card__title { font-size: 1.1rem; }

  /* ── CTA ── */
  /* Sous 400px on ne redescend PAS le titre du CTA : le corps est deja calage
     sur la place disponible, et le rabaisser encore ferait un titre plus petit
     que le sous-titre qu'il coiffe. */

  /* ── Features ── */
  .feature-card { flex: 0 0 260px; }

  /* ── FAQ ── */
  .faq-question { font-size: 0.95rem; }

  /* ── Final CTA ── */
  .final-cta__title { font-size: clamp(1.8rem, 7vw, 2.5rem); }

  /* ── Footer ── */
  .footer-brand { font-size: 23.5vw; }
  .footer__top { padding-left: 15px; padding-right: 15px; }
  .footer__cta-title { font-size: clamp(1.5rem, 6vw, 2rem); }

  /* ── Global padding ── */
  /* La section CTA n'est PAS dans cette liste, et c'est voulu : sa scene pose
     deja ses propres 12px, et ces 15px de plus ne protegeaient rien. Ils
     volaient 30px de largeur a une colonne centree qui n'a aucun voisin, or
     c'est cette largeur qui decide du corps du titre. */
  .intro,
  .stats-section,
  .who,
  .faq,
  .final-cta { padding-left: 15px; padding-right: 15px; }
}
