/* ==========================================================================
   SECTIONS - un bloc de la page = un bloc de ce fichier, dans l'ordre du DOM.
   Aucune couleur en dur : tout passe par tokens.css.
   ========================================================================== */

/* ═══════════════════════════════════════════════════════ 01 · EN-TÊTE ═══ */

.entete-site {
  --k: 0;
  /* De combien la pilule se contracte vers le centre, une fois défilé. */
  --retrait: 480px;
  position: fixed;
  inset: calc(0.85rem - 0.3rem * var(--k)) 0 auto;
  z-index: 100;
  padding-inline: var(--gouttiere);
  pointer-events: none;
  transition: --k 700ms var(--courbe-sortie);
}

.entete-site.est-defilee {
  --k: 1;
}

/* Moteur natif : --k suit le défilement sur les 260 premiers pixels. */
@supports (animation-timeline: scroll()) {
  .entete-site {
    transition: none;
    animation: entete-morph linear both;
    animation-timeline: scroll(root);
    animation-range: 0 260px;
  }

  @keyframes entete-morph {
    from { --k: 0; }
    to { --k: 1; }
  }
}

.entete-site::before {
  content: "";
  position: absolute;
  inset: -0.85rem 0 auto;
  height: calc(100% + 3.2rem);
  background: linear-gradient(
    rgba(8, 9, 11, 0.94) 0%,
    rgba(8, 9, 11, 0.6) 55%,
    rgba(8, 9, 11, 0) 100%
  );
  pointer-events: none;
  z-index: -1;
}

/* Tout dérive de --k : en haut, une barre large et légère ; défilée, une
   pilule resserrée au centre, plus dense, posée sur une ombre. */
.entete-site__barre {
  max-width: calc(var(--largeur) - var(--retrait) * var(--k));
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: calc(1.5rem - 0.5rem * var(--k));
  padding: calc(0.6rem - 0.18rem * var(--k)) calc(0.6rem - 0.15rem * var(--k))
    calc(0.6rem - 0.18rem * var(--k)) calc(1.6rem - 0.5rem * var(--k));
  border-radius: var(--r-pill);
  background: rgb(13 15 19 / calc(0.55 + 0.33 * var(--k)));
  border: 1px solid rgb(255 255 255 / calc(0.08 + 0.06 * var(--k)));
  box-shadow: 0 12px 40px rgb(0 0 0 / calc(0.45 * var(--k)));
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  pointer-events: auto;
}

.logo__mot {
  display: inline-flex;
  align-items: center;
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: calc(1.3rem - 0.12rem * var(--k));
  letter-spacing: 0.02em;
  line-height: 1;
}

/* Le logo est un lien : 44 px de zone de touche, sans changer la barre. */
.logo {
  padding-block: 0.6rem;
  margin-block: -0.6rem;
}

/* Le O est le symbole de marque (components/LogoMark.tsx) : une boucle
   ouverte, jamais une lettre. Anneau = 1,08 x hauteur de capitale, calé sur
   la ligne de base. */
.logo__o {
  width: 0.8em;
  height: 0.8em;
  margin-inline: 0.03em;
  color: var(--accent);
  flex: none;
}

.entete-site__nav {
  display: flex;
  gap: calc(1.75rem - 0.65rem * var(--k));
  margin-inline-start: auto;
  font-size: 0.925rem;
  color: var(--texte-doux);
}

.entete-site__nav a {
  transition: color var(--d-court);
}

.entete-site__nav a:hover {
  color: var(--texte);
}

.entete-site__cta {
  padding: calc(0.95rem - 0.2rem * var(--k)) calc(1.8rem - 0.5rem * var(--k));
  font-size: 0.925rem;
}

.entete-site__burger {
  display: none;
  position: relative;
  width: 44px;
  height: 44px;
  flex: none;
  place-content: center;
  gap: 5px;
  border-radius: 50%;
  transition: background-color var(--d-court);
}

.entete-site__burger:hover {
  background: rgba(255, 255, 255, 0.06);
}

.entete-site__burger span {
  display: block;
  width: 20px;
  height: 2px;
  border-radius: 2px;
  background: var(--texte);
  transition: translate var(--d-moyen) var(--courbe),
    rotate var(--d-moyen) var(--courbe), opacity var(--d-court);
}

/* Le burger devient une croix : les deux barres externes pivotent sur la
   médiane, celle du milieu s'efface. */
.entete-site.est-ouvert .entete-site__burger span:nth-child(1) {
  translate: 0 7px;
  rotate: 45deg;
}

.entete-site.est-ouvert .entete-site__burger span:nth-child(2) {
  opacity: 0;
}

.entete-site.est-ouvert .entete-site__burger span:nth-child(3) {
  translate: 0 -7px;
  rotate: -45deg;
}

/* ── Panneau mobile : une pièce de verre sous la barre ── */
.entete-site__panneau {
  position: absolute;
  inset: calc(100% + 0.6rem) var(--gouttiere) auto;
  display: grid;
  gap: 0.2rem;
  padding: 0.65rem;
  border-radius: 24px;
  background-color: rgba(13, 15, 19, 0.82);
  background-image: var(--verre-spec);
  background-repeat: no-repeat;
  background-size: 100% 120px;
  -webkit-backdrop-filter: blur(var(--verre-flou));
  backdrop-filter: blur(var(--verre-flou));
  border: 1px solid var(--verre-rim);
  box-shadow: var(--ombre-flottante);
  pointer-events: auto;
  opacity: 0;
  translate: 0 -10px;
  visibility: hidden;
  transition: opacity var(--d-moyen) var(--courbe),
    translate var(--d-moyen) var(--courbe),
    visibility 0s var(--d-moyen);
}

.entete-site.est-ouvert .entete-site__panneau {
  opacity: 1;
  translate: 0 0;
  visibility: visible;
  transition: opacity var(--d-moyen) var(--courbe),
    translate var(--d-moyen) var(--courbe);
}

.entete-site__panneau a {
  padding: 0.9rem 1.1rem;
  border-radius: 15px;
  font-size: 1.02rem;
  transition: background-color var(--d-court);
}

.entete-site__panneau a:hover,
.entete-site__panneau a:focus-visible {
  background: rgba(255, 255, 255, 0.06);
}

@media (min-width: 701px) {
  .entete-site__panneau {
    display: none;
  }
}

/* Sur mobile, la barre porte trois pièces : logo, CTA, burger. Le budget
   est calculé pour tenir dès 320 px (iPhone SE) : à 375 px, l'ancien gap de
   1,5 rem entre trois éléments faisait déborder le burger de la pilule. */
/* ── Sélecteur de langue : un menu déroulant. Un <details> natif, donc
   accessible au clavier sans script ; le JS ne sert qu'à le refermer au clic
   extérieur et à Échap. Dans la barre au-delà de 900 px, dans le panneau
   sur mobile (où il s'ouvre en ligne), et au pied de page (vers le haut). ── */
.langues {
  position: relative;
  flex: none;
}

.langues__bouton {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.45rem 0.6rem 0.45rem 0.65rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--verre-rim);
  background: rgba(255, 255, 255, 0.03);
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--texte-doux);
  cursor: pointer;
  list-style: none;
  user-select: none;
  transition: color var(--d-court), background-color var(--d-court);
}

.langues__bouton::-webkit-details-marker {
  display: none;
}

.langues__bouton:hover,
.langues[open] .langues__bouton {
  color: var(--texte);
  background: rgba(255, 255, 255, 0.07);
}

.langues__globe {
  width: 15px;
  height: 15px;
}

.langues__chevron {
  width: 12px;
  height: 12px;
  transition: rotate var(--d-moyen) var(--courbe);
}

.langues[open] .langues__chevron {
  rotate: 180deg;
}

/* La liste : une petite pièce de verre sous le bouton. */
.langues__menu {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 60;
  min-width: 170px;
  margin: 0;
  padding: 0.4rem;
  list-style: none;
  border-radius: 16px;
  background-color: rgba(13, 15, 19, 0.88);
  background-image: var(--verre-spec);
  background-repeat: no-repeat;
  background-size: 100% 80px;
  -webkit-backdrop-filter: blur(var(--verre-flou));
  backdrop-filter: blur(var(--verre-flou));
  border: 1px solid var(--verre-rim);
  box-shadow: var(--ombre-flottante);
  animation: langues-ouvre var(--d-moyen) var(--courbe-sortie);
}

@keyframes langues-ouvre {
  from {
    opacity: 0;
    translate: 0 -6px;
  }
}

.langues__menu a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 0.75rem;
  border-radius: 10px;
  font-size: 0.9rem;
  color: var(--texte-doux);
  transition: background-color var(--d-court), color var(--d-court);
}

.langues__menu a:hover,
.langues__menu a:focus-visible {
  background: rgba(255, 255, 255, 0.07);
  color: var(--texte);
}

.langues__menu a[aria-current] {
  color: var(--texte);
}

.langues__menu a[aria-current]::after {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 10px var(--accent-halo);
}

/* La barre n'a la place du sélecteur qu'au-delà de 900 px ; en dessous, la
   langue se change au pied de page (ou dans le panneau sur mobile). */
@media (max-width: 900px) {
  .langues--barre {
    display: none;
  }
}

/* Dans le panneau mobile, la liste s'ouvre en ligne, sous le bouton. */
.langues--panneau {
  margin: 0.4rem 0.6rem 0.2rem;
  justify-self: start;
}

.langues--panneau .langues__menu {
  position: static;
  margin-top: 0.4rem;
  box-shadow: none;
}

/* Au pied de page, la liste s'ouvre vers le haut. */
.langues--pied .langues__menu {
  top: auto;
  bottom: calc(100% + 0.5rem);
  left: 0;
  right: auto;
}

/* ── CTA flottant, mobile seulement : apparaît une fois le hero passé, se
   retire devant le CTA final. C'est le bouton qui reste sous le pouce. ── */
.cta-flottant {
  display: none;
}

@media (max-width: 700px) {
  .cta-flottant {
    display: inline-flex;
    position: fixed;
    left: 50%;
    bottom: calc(1rem + env(safe-area-inset-bottom));
    z-index: 90;
    padding: 0.95rem 1.7rem;
    border-radius: var(--r-pill);
    background-color: var(--accent);
    background-image: linear-gradient(rgba(255, 255, 255, 0.3) 0%, rgba(255, 255, 255, 0.07) 45%, transparent 60%);
    color: var(--sur-accent);
    font-weight: 700;
    font-size: 0.95rem;
    line-height: 1;
    box-shadow: var(--glow-accent-fort), 0 12px 30px rgba(0, 0, 0, 0.5),
      inset 0 1px 0 rgba(255, 255, 255, 0.55);
    translate: -50% 140%;
    transition: translate 420ms var(--courbe-sortie);
  }

  .cta-flottant.est-visible {
    translate: -50% 0;
  }

  .entete-site {
    --retrait: 0px;
  }
  .entete-site__barre {
    gap: 0.5rem;
    padding: 0.4rem 0.4rem 0.4rem 1rem;
  }
  .entete-site__nav {
    display: none;
  }
  .entete-site__cta {
    margin-inline-start: auto;
    flex: none;
    padding: 0.8rem 1.1rem;
    font-size: 0.875rem;
    white-space: nowrap;
  }
  .entete-site__burger {
    display: grid;
    width: 42px;
    height: 42px;
  }
  .logo {
    flex: none;
  }
  .logo__mot {
    font-size: 1.15rem;
  }
}

@media (max-width: 360px) {
  .entete-site {
    padding-inline: 0.9rem;
  }
  .entete-site__cta {
    padding-inline: 0.85rem;
  }
  .entete-site__burger {
    width: 40px;
    height: 40px;
  }
  .logo__mot {
    font-size: 1.05rem;
  }
}

/* ═══════════════════════════════════════════════════════════ 02 · HERO ═══ */

.hero {
  position: relative;
  padding-block: clamp(8rem, 5rem + 12vw, 12rem) clamp(4rem, 2rem + 6vw, 7rem);
  overflow: hidden;
}

.hero__halo {
  top: -18%;
  right: 6%;
  width: min(52vw, 720px);
  aspect-ratio: 1;
  background: radial-gradient(
    circle,
    rgba(198, 255, 61, 0.16) 0%,
    rgba(198, 255, 61, 0.05) 45%,
    transparent 70%
  );
}

.hero__grille {
  position: relative;
  z-index: 1;
  /* Pour la pose en 3D du trio de téléphones. */
  perspective: 1400px;
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(2rem, 1rem + 4vw, 4rem);
}

.hero__texte {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.6rem;
}

.hero__chapeau {
  color: var(--texte-doux);
  font-size: clamp(1rem, 0.95rem + 0.4vw, 1.15rem);
  max-width: 46ch;
}

/* La mention d'âge, sous les badges : l'app est classée 18+. */
.hero__age {
  margin: 0.9rem 0 0;
  font-size: var(--t-petit);
  color: var(--texte-faible);
}

/* Les deux boutons stores partagent la même largeur : une grille à
   colonnes égales, chaque bouton étiré sur la sienne. */
.hero__actions {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 0.9rem;
  margin-top: 0.6rem;
  width: max-content;
  max-width: 100%;
}

.avatar {
  display: block;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  flex: none;
  background: var(--grad-carte);
}

/* Substituts d'avatars. À l'étape 2 : remplacer par de vraies photos. */
.avatar--1 {
  background: linear-gradient(140deg, var(--info), #3d4a8f);
}
.avatar--2 {
  background: linear-gradient(140deg, var(--calme), #2a6e63);
}
.avatar--3 {
  background: linear-gradient(140deg, var(--ambre), #8f6a1e);
}

/* -------------------------------------------------------------- téléphones */

.hero__visuel {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: clamp(400px, 46vw, 620px);
  perspective: 1600px;
  transform-origin: 50% 100%;
}

/* Le trio se pose : il arrive de plus bas, légèrement basculé, et se
   redresse en décélérant. Plus lent que le reste, c'est la pièce maîtresse. */
.js .hero__visuel[data-reveal] {
  transition-duration: 1.3s;
}

/* La pose d'entrée ne vaut qu'AVANT l'arrivée : sans le :not, cette règle,
   chargée après base.css à spécificité égale, gagnait aussi une fois le bloc
   révélé et figeait le trio dans sa pose de départ. */
.js .hero__visuel[data-reveal]:not(.est-visible) {
  transform: translateY(48px) rotateX(9deg) scale(0.96);
}

/* Puis ils respirent : un flottement lent, décalé d'un téléphone à l'autre
   pour ne pas se lire comme un mécanisme. */
.hero__visuel .tel__cadre {
  animation: flotte 7s ease-in-out infinite;
}

.hero__visuel .tel--gauche .tel__cadre {
  animation-duration: 8.5s;
  animation-delay: -2s;
}

.hero__visuel .tel--droite .tel__cadre {
  animation-duration: 9.5s;
  animation-delay: -4s;
}

@keyframes flotte {
  50% { transform: translateY(-9px); }
}

/* Parallaxe : le trio remonte moins vite que la page. Propriété `translate`
   séparée, pour ne pas entrer en conflit avec le `transform` de l'entrée. */
@supports (animation-timeline: scroll()) {
  .hero__visuel {
    animation: hero-parallaxe linear both;
    animation-timeline: scroll(root);
    animation-range: 0 120vh;
  }

  @keyframes hero-parallaxe {
    to { translate: 0 -90px; }
  }
}

.tel {
  --l: 232px;
  position: relative;
  width: var(--l);
  flex: none;
}

.tel__cadre {
  position: relative;
  aspect-ratio: 9 / 19.2;
  /* Rayon iPhone : ~14,5 % de la largeur, exprimé aussi en hauteur pour
     rester circulaire quelle que soit la taille du cadre. */
  border-radius: 14.5% / 6.8%;
  /* La tranche de titane : assez épaisse pour porter les boutons. */
  padding: 3.2%;
  background: var(--titane);
  box-shadow:
    /* L'arête polie du bord, puis le creux qui sépare le métal de la dalle. */
    inset 0 0 0 1px rgba(255, 255, 255, 0.3),
    inset 0 0 0 2.5px rgba(0, 0, 0, 0.55),
    var(--ombre-flottante);
}

/* Dynamic Island. Sa position est calée sur la pilule noire présente dans
   les captures d'écran de l'app (centre à 5,6 % de la hauteur, 31 % de la
   largeur de l'image), pour que les deux se superposent exactement. */
.tel__encoche {
  position: absolute;
  top: 3.9%;
  left: 50%;
  translate: -50% 0;
  width: 28%;
  height: 3.4%;
  border-radius: var(--r-pill);
  background: #040405;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.6);
  z-index: 3;
}

/* L'optique : concentrique avec l'arrondi droit de l'île, comme sur
   l'appareil. L'île fait 28 % de large pour 3,4 % de haut, soit un rapport
   h/w de 0,26 : un objectif de 54 % de la hauteur, centré à un rayon de
   pilule du bord droit, se place à 6 % de la largeur. Verre profond, anneau
   sombre, reflet en haut à gauche. */
.tel__encoche::after {
  content: "";
  position: absolute;
  right: 6%;
  top: 23%;
  height: 54%;
  aspect-ratio: 1;
  border-radius: 50%;
  background:
    radial-gradient(circle at 34% 30%, rgba(255, 255, 255, 0.28) 0%, rgba(255, 255, 255, 0) 28%),
    radial-gradient(circle at 50% 50%, #1c2033 0%, #0d1020 48%, #05060a 74%);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.12),
    0 0 0 1px rgba(0, 0, 0, 0.8),
    0 0 0 2px rgba(255, 255, 255, 0.03);
}

/* Boutons latéraux, posés SUR la tranche de titane : ils la chevauchent et
   n'en dépassent que d'un souffle, comme sur l'appareil. Action et volumes
   à gauche, marche à droite. Hauteurs en % de l'appareil, d'après le
   modèle Pro. */
.tel__bouton {
  position: absolute;
  width: 2.2%;
  border-radius: 999px;
  background: var(--titane-bouton);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    inset 0 -1px 0 rgba(0, 0, 0, 0.5),
    0 0 0 1px rgba(0, 0, 0, 0.55);
  z-index: 1;
}

.tel__bouton--action {
  left: -1.2%;
  top: 21.5%;
  height: 4.6%;
}

/* Les deux volumes : un conteneur invisible, ses deux pseudo-éléments. */
.tel__bouton--volume {
  left: -1.2%;
  top: 29%;
  height: 14%;
  background: none;
  box-shadow: none;
}

.tel__bouton--volume::before,
.tel__bouton--volume::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 42%;
  border-radius: 999px;
  background: var(--titane-bouton);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    inset 0 -1px 0 rgba(0, 0, 0, 0.5),
    0 0 0 1px rgba(0, 0, 0, 0.55);
}

.tel__bouton--volume::before {
  top: 0;
}

.tel__bouton--volume::after {
  bottom: 0;
}

.tel__bouton--marche {
  right: -1.2%;
  top: 31.5%;
  height: 9.5%;
  background: linear-gradient(90deg, #1d1e22, #3a3b41 48%, #6a6b72);
}

/* L'écran : une fine bordure noire, puis la dalle aux coins arrondis. */
.ecran {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 12.2% / 5.7%;
  background: #000;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.85);
  overflow: hidden;
  padding: 2.6rem 0.85rem 0.85rem;
  display: flex;
  flex-direction: column;
  font-size: 0.55rem;
  line-height: 1.35;
}

/* Capture réelle de l'app : le cadre et l'encoche restent, le contenu
   simulé disparaît. L'image est calée en haut - c'est le bas de l'écran
   qui se fait rogner par le cadre, jamais la barre de titre. */
.ecran--capture {
  padding: 1.6%;
}

.ecran-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  border-radius: 10.8% / 5%;
}

/* Position des trois téléphones du hero. Le central passe devant. */
.hero__visuel .tel--centre {
  z-index: 2;
  --l: min(46%, 268px);
}

.hero__visuel .tel--gauche,
.hero__visuel .tel--droite {
  --l: min(40%, 232px);
}

.hero__visuel .tel--gauche {
  margin-inline-end: -13%;
  rotate: y 20deg;
  translate: 0 3%;
}

.hero__visuel .tel--droite {
  margin-inline-start: -13%;
  rotate: y -20deg;
  translate: 0 3%;
}

/* ------------------------------------------------------- contenus d'écran */

/* ---------------------------------------------------------------- orbes
   Les orbes sont des conic-gradients : nets à toute taille, aucun asset. */

.planete {
  width: 118px;
  aspect-ratio: 1;
  border-radius: 50%;
  margin-inline: auto;
  position: relative;
  /* Le blend de la géographie ne doit pas déborder sur la carte. */
  isolation: isolate;
  /* Sphère éclairée en haut à gauche : lumière -> terrain -> limbe nuit. */
  background: radial-gradient(
    circle at 33% 29%,
    var(--p) 0%,
    color-mix(in srgb, var(--p) 55%, var(--s)) 40%,
    var(--s) 74%,
    color-mix(in srgb, var(--s) 45%, #000) 100%
  );
  box-shadow:
    0 0 36px color-mix(in srgb, var(--a) 30%, transparent),
    inset -14px -18px 34px rgba(0, 0, 0, 0.62),
    inset 3px 5px 14px color-mix(in srgb, var(--a) 45%, transparent);
}

/* La géographie : le même bruit fractal pour toutes, chaque planète le
   teinte par ses couleurs. */
.planete::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='0.028' numOctaves='4' seed='11'/><feColorMatrix type='saturate' values='0'/></filter><rect width='220' height='220' filter='url(%23g)'/></svg>");
  background-size: 210px;
  mix-blend-mode: soft-light;
  opacity: 0.9;
}

/* Le croissant d'atmosphère au limbe éclairé. */
.planete::after {
  content: "";
  position: absolute;
  inset: -2px;
  border-radius: 50%;
  border: 1.5px solid color-mix(in srgb, var(--a) 40%, transparent);
  border-bottom-color: transparent;
  border-right-color: transparent;
  filter: blur(1.2px);
  rotate: -8deg;
}

/* La piste Constance, couleurs de planets.ts (primary / secondary / atmo). */
.planete--aube      { --p: #ffffff; --s: #b8bfce; --a: #ffe7c4; }
.planete--vega      { --p: #fffdf6; --s: #c9b896; --a: #ffd79a; }
.planete--sirius    { --p: #fff6dc; --s: #d9c48e; --a: #ffc96b; }
.planete--antares   { --p: #ffc24a; --s: #8a4e12; --a: #ffa83c; }
.planete--polaris   { --p: #ffd97a; --s: #7a4a16; --a: #ffbe55; }
.planete--aldebaran { --p: #fff0c2; --s: #9a6a1e; --a: #ffdc94; }
.planete--alcyone   { --p: #fffdf2; --s: #6b4a12; --a: #ffe9b8; }

/* ══════════════════════════════════════════════════════ 03 · MANIFESTE ═══ */

/* Le manifeste se lit au défilement. La section est haute (220 svh) et sa
   scène collée en haut du viewport : le texte reste sous les yeux pendant
   que la page avance, et cette avance - la progression de la section dans
   le viewport - allume les mots un à un. La page ne repart qu'une fois la
   dernière phrase éclairée, avec un temps de pause sur le texte entier.

   Tout tient dans --lecture, un nombre de 0 à 1 (nom propre : --p est déjà la
   couleur primaire des planètes, et une propriété enregistrée comme nombre
   invalidait leur dégradé) : la timeline de vue l'anime
   pendant que la section couvre le viewport ; là où elle n'existe pas,
   app.js le calcule au défilement. Sans JS, pas de mots découpés et pas de
   scène collée : le texte est simplement là. */
@property --lecture {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

.js .manifeste {
  min-height: 220svh;
  padding-block: 0;
}

.js .manifeste__scene {
  position: sticky;
  top: 0;
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding-block: var(--sect-y);
}

@supports (animation-timeline: view()) {
  .js .manifeste {
    animation: manifeste-lecture linear both;
    animation-timeline: view();
    /* La lecture s'achève à 85 % de la course : les 15 % restants, le texte
       entier reste allumé avant de partir. */
    animation-range: contain 0% contain 85%;
  }
}

@keyframes manifeste-lecture {
  from { --lecture: 0; }
  to { --lecture: 1; }
}

.manifeste__texte {
  max-width: 34ch;
  margin-inline: auto;
  text-align: center;
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: var(--t-manifeste);
  line-height: 1.2;
  letter-spacing: var(--ls-titre);
  text-wrap: balance;
}

/* Chaque mot s'allume quand la lecture l'atteint, sur une fenêtre de trois
   mots pour que la vague soit douce. --i est l'indice du mot, --n leur
   nombre (posés par app.js). Éteint, un mot reste lisible en filigrane. */
.manifeste__texte .mot {
  --fenetre: 3;
  opacity: clamp(0.16, (var(--lecture) * (var(--n) + var(--fenetre)) - var(--i)) / var(--fenetre), 1);
}

@media (prefers-reduced-motion: reduce) {
  .js .manifeste {
    min-height: 0;
    padding-block: var(--sect-y);
    animation: none;
  }

  .js .manifeste__scene {
    position: static;
    min-height: 0;
    padding-block: 0;
  }

  .manifeste__texte .mot {
    opacity: 1;
  }
}

/* ═════════════════════════════════════════════════════════ 04 · STATS ═══ */

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

.stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
  max-width: 940px;
  margin-inline: auto;
  padding: clamp(2rem, 1rem + 3vw, 3.25rem) clamp(1rem, 0.5rem + 2vw, 2.5rem);
  border-radius: var(--r-bloc);
  position: relative;
  background-color: var(--verre-fond);
  background-image: var(--verre-spec),
    linear-gradient(var(--verre-teinte), var(--verre-teinte));
  -webkit-backdrop-filter: blur(var(--verre-flou));
  backdrop-filter: blur(var(--verre-flou));
  border: 1px solid var(--verre-rim);
}

.stats__item {
  text-align: center;
}

.stats__chiffre {
  display: block;
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: var(--t-chiffre);
  line-height: 1.1;
  letter-spacing: -0.03em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.stats__label {
  display: block;
  margin-top: 0.5rem;
  font-size: var(--t-petit);
  line-height: 1.45;
}

/* La source du chiffre, sous la carte : un chiffre publié se cite, sinon il
   ne vaut rien. Petite et discrète, mais lisible, avec le lien vers l'étude. */
.stats__source {
  max-width: 940px;
  margin: 0.9rem auto 0;
  padding-inline: 0.5rem;
  text-align: center;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--texte-faible);
  text-wrap: pretty;
}

.stats__source a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
  white-space: nowrap;
}

.stats__source a:hover {
  color: var(--texte-doux);
  text-decoration-color: currentColor;
}

@media (max-width: 620px) {
  .stats {
    grid-template-columns: 1fr;
    gap: 2rem;
  }
}

/* ═════════════════════════════════════════════ 05 · COMMENT ÇA MARCHE ═══ */

.fonctionnement {
  position: relative;
  overflow: hidden;
}

.fonctionnement__halo {
  top: 30%;
  left: -12%;
  width: min(46vw, 620px);
  aspect-ratio: 1;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.05) 0%, transparent 68%);
}

.rang {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: center;
  gap: clamp(1.5rem, 0.5rem + 4vw, 4.5rem);
  padding-block: clamp(1.5rem, 0.5rem + 3vw, 3rem);
}

/* L'inversion se fait par ordre de grille, pas par réécriture du DOM :
   l'ordre de lecture reste correct au clavier et en mobile. */
.rang--inverse .rang__visuel {
  order: 2;
}

.rang__visuel {
  display: flex;
  justify-content: center;
}

/* ── L'appareil incliné : un seul téléphone par rangée, grand, posé de biais
   en 3D comme un rendu d'appareil (le haut s'éloigne, le côté droit se
   rapproche, une légère rotation). L'épaisseur est une seconde plaque
   reculée sur l'axe Z ; le cadre porte un liseré métallique, l'écran un
   reflet oblique. Le sens s'inverse sur les rangées inversées. ── */
.rang__visuel {
  position: relative;
  isolation: isolate;
  perspective: 1500px;
  perspective-origin: 50% 40%;
  padding-block: 2rem;
}

/* Lueur de marque derrière l'appareil, très diffuse. */
.rang__visuel::before {
  content: "";
  position: absolute;
  width: 78%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(198, 255, 61, 0.11), transparent 64%);
  filter: blur(32px);
  z-index: -1;
}

.tel--incline {
  --l: min(100%, 300px);
  transform-style: preserve-3d;
  transform: rotateX(16deg) rotateY(-24deg) rotateZ(13deg);
  transition: transform 1.4s var(--courbe-sortie);
}

.rang--inverse .tel--incline {
  transform: rotateX(16deg) rotateY(24deg) rotateZ(-13deg);
}

/* Entrée : l'appareil arrive plus bas et plus penché, puis se pose. */
.js .rang[data-reveal]:not(.est-visible) .tel--incline {
  transform: translateY(48px) rotateX(26deg) rotateY(-34deg) rotateZ(20deg);
}

.js .rang--inverse[data-reveal]:not(.est-visible) .tel--incline {
  transform: translateY(48px) rotateX(26deg) rotateY(34deg) rotateZ(-20deg);
}

.tel--incline .tel__cadre {
  transform-style: preserve-3d;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.3),
    inset 0 0 0 2.5px rgba(0, 0, 0, 0.55),
    0 70px 110px rgba(0, 0, 0, 0.72);
}

/* L'épaisseur du corps : la même forme, reculée de 18 px sur Z, qui dépasse
   du bord éloigné une fois l'appareil tourné. */
.tel--incline .tel__cadre::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--titane-dos);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.1);
  transform: translateZ(-18px);
}

/* Sur l'appareil incliné, les boutons quittent la face avant pour se poser
   sur la tranche, là où ils sont sur l'objet : chaque bouton devient un pavé
   de l'épaisseur du corps (18 px, comme la plaque arrière), tourné de 90°
   sur la charnière du bord, qui dépasse du métal d'un souffle. Il occupe
   exactement la bande entre l'arête avant et la plaque, clair vers l'avant
   et sombre vers l'arrière ; sur le côté éloigné il passe derrière la face et
   disparaît tout seul, comme sur l'objet. */
.tel--incline .tel__bouton {
  width: 18px;
  left: 0;
  border-radius: 999px;
  transform-origin: left center;
  transform: translateX(-1.5px) rotateY(90deg);
  background: linear-gradient(90deg, #6e6f76 0%, #3c3d43 38%, #141519 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    inset 0 -1px 0 rgba(0, 0, 0, 0.5);
}

.tel--incline .tel__bouton--volume {
  background: none;
  box-shadow: none;
}

.tel--incline .tel__bouton--volume::before,
.tel--incline .tel__bouton--volume::after {
  border-radius: 999px;
  background: linear-gradient(90deg, #6e6f76 0%, #3c3d43 38%, #141519 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    inset 0 -1px 0 rgba(0, 0, 0, 0.5);
}

.tel--incline .tel__bouton--marche {
  left: auto;
  right: 0;
  transform-origin: right center;
  transform: translateX(1.5px) rotateY(-90deg);
  background: linear-gradient(270deg, #6e6f76 0%, #3c3d43 38%, #141519 100%);
}

/* Le reflet sur la vitre. */
.tel--incline .tel__cadre::after {
  content: "";
  position: absolute;
  inset: 3.2%;
  border-radius: 12.2% / 5.7%;
  background: linear-gradient(118deg, rgba(255, 255, 255, 0.13) 0%, rgba(255, 255, 255, 0.03) 26%, transparent 44%);
  pointer-events: none;
  z-index: 4;
}


/* Le texte est posé au-dessus de l'appareil. Sans cela, sur une colonne,
   la grande ombre portée du téléphone (70 px plus bas, 110 px de flou) se
   peignait par-dessus le titre : Chrome ne dessine pas l'ombre d'un élément
   en preserve-3d, Safari si, et il grisait la fin du titre. */
.rang__texte {
  position: relative;
  z-index: 1;
}

.rang__texte h3 {
  margin-bottom: 0.9rem;
}

.rang__texte p {
  color: var(--texte-doux);
  max-width: 46ch;
}

@media (max-width: 820px) {
  .rang,
  .rang--inverse {
    grid-template-columns: 1fr;
  }
  .rang--inverse .rang__visuel {
    order: 0;
  }
  .tel--incline,
  .rang--inverse .tel--incline {
    --l: min(68%, 236px);
  }
  .tel--incline {
    transform: rotateX(10deg) rotateY(-16deg) rotateZ(8deg);
  }
  .rang--inverse .tel--incline {
    transform: rotateX(10deg) rotateY(16deg) rotateZ(-8deg);
  }
}

/* ═══════════════════════════════════════════════ 08 · FONCTIONNALITÉS ═══ */

.fonctionnalites__grille {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.5rem;
}

@media (max-width: 720px) {
  .fonctionnalites__grille {
    grid-template-columns: 1fr;
  }
}

.fonc {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: transform var(--d-moyen) var(--courbe), border-color var(--d-moyen);
}

.fonc:hover {
  transform: translateY(-6px);
  border-color: var(--trait-accent);
}

.fonc__indice {
  position: absolute;
  top: 1.5rem;
  left: 1.75rem;
  z-index: 3;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texte-faible);
}

/* La scène : l'illustration animée derrière chaque carte. Elle est masquée
   en bas par un voile pour que le texte reste lisible. */
.fonc__scene {
  position: relative;
  flex: 1;
  overflow: hidden;
  display: grid;
  place-content: center;
}

.fonc__scene::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--grad-voile);
  pointer-events: none;
}

.fonc__texte {
  position: relative;
  z-index: 2;
  padding: 1.1rem 1.75rem 1.9rem;
}

.fonc__texte h3 {
  font-size: 1.6rem;
  margin-bottom: 0.5rem;
}

.fonc__texte p {
  color: var(--texte-doux);
  font-size: 0.95rem;
}

/* -- capture réelle dans la carte : un téléphone qu'on ne voit qu'en haut,
      rogné par le bord de la scène et fondu par son voile. On ne montre que
      ce qui compte - barre d'état, titre, premier contenu - en grand, plutôt
      qu'un appareil entier en petit. La scène a des proportions fixes (4:3,
      10:9 sur une colonne) et le téléphone est un pourcentage de sa largeur :
      des unités que tous les navigateurs calculent de la même façon. ------ */

.fonc__scene--capture {
  display: block;
  flex: none;
  aspect-ratio: 4 / 3;
  padding: 3.6rem 2.2rem 0;
  /* Safari applique place-content aux blocs : sans ceci, il centrait le
     téléphone dans la scène et coupait la barre d'état. */
  place-content: start;
}

.tel--carte {
  --l: min(80%, 320px);
  margin-inline: auto;
}

@media (max-width: 720px) {
  .fonc__scene--capture {
    aspect-ratio: 10 / 9;
  }
}

.tel--carte .tel__cadre {
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.22),
    inset 0 0 0 2.5px rgba(0, 0, 0, 0.45),
    0 30px 60px rgba(0, 0, 0, 0.6);
}

/* ═══════════════════════════════════════════════════════ 09 · PALIERS ═══ */

/* Le rail déborde de l'enveloppe : il traverse l'écran de bord à bord et les
   cartes des extrémités sont volontairement coupées. */
.rail {
  position: relative;
  overflow: hidden;
  -webkit-mask: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}

/* La piste porte deux séries identiques et glisse d'une demi-largeur : pour
   que la boucle soit invisible, chaque carte doit être suivie du même
   intervalle, la dernière comprise. D'où la marge de fin égale au gap, et
   aucune marge de début (le fondu du masque habille les bords). */
.rail__piste {
  display: flex;
  gap: 1.5rem;
  width: max-content;
  padding-inline-end: 1.5rem;
  animation: defile-rail 46s linear infinite;
}

/* La pause au survol ne vaut qu'avec une souris : au doigt, :hover reste
   collé après un simple toucher et figeait les planètes sur mobile. */
@media (hover: hover) {
  .rail:hover .rail__piste {
    animation-play-state: paused;
  }
}

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

.orbe-carte {
  flex: none;
  width: 230px;
  margin: 0;
  padding: 2.5rem 1rem;
  border-radius: var(--r-carte-l);
  background: var(--grad-section);
  border: 1px solid var(--trait);
  display: grid;
  gap: 1.5rem;
  justify-items: center;
}

.orbe-carte figcaption {
  display: grid;
  gap: 0.15rem;
  text-align: center;
}

.orbe-carte figcaption b {
  font-family: var(--police-titre);
  font-size: 1.1rem;
  color: var(--texte);
}

.orbe-carte figcaption span {
  font-size: var(--t-petit);
  color: var(--texte-faible);
}

/* ═════════════════════════════════════════════════════ 10 · BÉNÉFICES ═══ */

.benefices {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: center;
  gap: clamp(2rem, 1rem + 4vw, 4rem);
  padding: clamp(2.5rem, 1rem + 5vw, 5rem);
  border-radius: var(--r-bloc);
  position: relative;
  background-color: var(--verre-fond);
  background-image: var(--verre-spec),
    linear-gradient(var(--verre-teinte), var(--verre-teinte));
  -webkit-backdrop-filter: blur(var(--verre-flou));
  backdrop-filter: blur(var(--verre-flou));
  border: 1px solid var(--verre-rim);
  overflow: hidden;
}

.benefices__texte {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.25rem;
}

.benefices__texte h2 {
  max-width: 14ch;
}

.benefices__texte .chapeau {
  color: var(--texte-doux);
  max-width: 40ch;
}

/* La liste défile en boucle ; le masque haut/bas fait disparaître les items
   aux extrémités pour suggérer une liste sans fin. */
.benefices__liste {
  height: 320px;
  overflow: hidden;
  -webkit-mask: linear-gradient(180deg, transparent, #000 26%, #000 74%, transparent);
  mask: linear-gradient(180deg, transparent, #000 26%, #000 74%, transparent);
}

.benefices__piste {
  display: grid;
  gap: 0.75rem;
  animation: defile-benefices 22s linear infinite;
}

@media (hover: hover) {
  .benefices__liste:hover .benefices__piste {
    animation-play-state: paused;
  }
}

@keyframes defile-benefices {
  from { transform: translateY(0); }
  to { transform: translateY(-50%); }
}

.benefices__piste span {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 1.05rem 1.5rem;
  border-radius: var(--r-petit);
  background: var(--fond-carte);
  border: 1px solid var(--trait);
  font-size: 1.05rem;
}

@media (max-width: 820px) {
  .benefices {
    grid-template-columns: 1fr;
  }
}

/* ══════════════════════════════════════════════════ 11 · COMMUNAUTÉ ═══ */

/* Une grande carte lumineuse, le texte à gauche ; à droite, des morceaux
   réels de la communauté qui flottent en verre sur un ciel coloré : ceux qui
   sont là ce soir (leur avatar est leur planète du moment, cohérente avec
   les paliers), un post et son bouton Encourager, un palier atteint que l'on
   fête. Tout dit la même chose : ici, il se passe de bonnes choses. La scène
   est un conteneur, tout y est en cqi. */
.commu {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  align-items: center;
  gap: clamp(2.5rem, 1.5rem + 4vw, 5rem);
  padding: clamp(2.25rem, 1rem + 4.5vw, 4.5rem);
  border-radius: var(--r-bloc);
  position: relative;
  overflow: hidden;
  /* Trois nappes de lumière sur une nuit verte : accent en bas à droite,
     or près du palier fêté, émeraude en haut à gauche. */
  background:
    radial-gradient(55% 65% at 100% 100%, rgba(198, 255, 61, 0.55) 0%, rgba(198, 255, 61, 0.2) 34%, transparent 66%),
    radial-gradient(40% 50% at 80% 18%, rgba(255, 217, 122, 0.2), transparent 62%),
    radial-gradient(55% 60% at 0% 0%, rgba(46, 150, 110, 0.5), transparent 62%),
    linear-gradient(135deg, #10221b 0%, #0a0d12 52%, #0f1c13 100%);
  border: 1px solid rgba(255, 255, 255, 0.1);
}

/* Quelques étoiles, comme partout sur le site. */
.commu::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    radial-gradient(1px 1px at 8% 30%, #fff, transparent),
    radial-gradient(1.5px 1.5px at 30% 12%, #fff, transparent),
    radial-gradient(1px 1px at 46% 78%, #fff, transparent),
    radial-gradient(1px 1px at 62% 8%, #fff, transparent),
    radial-gradient(1.5px 1.5px at 88% 40%, #fff, transparent),
    radial-gradient(1px 1px at 72% 92%, #fff, transparent),
    radial-gradient(1px 1px at 18% 88%, #fff, transparent);
  opacity: 0.5;
}

.commu__texte {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.35rem;
}

.commu__texte h2 {
  max-width: 14ch;
}

.commu__texte p {
  color: var(--texte-doux);
  max-width: 40ch;
}

/* La promesse, en note sous le bouton. */
.commu__note {
  display: inline-flex;
  align-items: flex-start;
  gap: 0.5rem;
  font-size: var(--t-petit);
  color: var(--texte-faible);
}

.commu__note svg {
  flex: none;
  width: 1em;
  margin-top: 0.2em;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* La vitrine : l'étiquette d'abord, la scène dessous. L'étiquette est
   visible et lisible, elle dit que ce qui suit est un aperçu de l'interface
   et non des personnes réelles, avant même qu'on regarde la scène. */
.commu__vitrine {
  display: grid;
  gap: 0.75rem;
  align-content: start;
}

.commu__etiquette {
  margin: 0;
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  font-size: 0.86rem;
  font-weight: 500;
  line-height: 1.45;
  color: var(--texte-doux);
}

.commu__etiquette::before {
  content: "i";
  flex: none;
  width: 1.05rem;
  height: 1.05rem;
  margin-top: 0.1rem;
  border-radius: 50%;
  border: 1px solid currentColor;
  font-family: var(--police-titre);
  font-size: 0.72rem;
  line-height: 1rem;
  text-align: center;
}

/* La liste est dans le flux et donne sa hauteur à la scène ; le post et le
   palier flottent par-dessus. Rien ne peut déborder. */
.commu__scene {
  position: relative;
  container-type: inline-size;
  padding: 6% 0 12%;
}

/* Les panneaux : du verre sombre sur le ciel, un fil de lumière en haut. */
.commu__liste,
.commu__post,
.commu__palier {
  position: absolute;
  background: rgba(17, 20, 25, 0.86);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 4.5cqi;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    0 30px 60px -20px rgba(0, 0, 0, 0.8);
  font-size: clamp(0.72rem, 3.6cqi, 1.02rem);
  line-height: 1.3;
}

.commu__liste {
  position: relative;
  width: 62%;
  margin-bottom: 15cqi;
  padding: 4cqi 4.2cqi;
}

.commu__liste header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 3.2cqi;
  font-weight: 600;
  color: var(--texte);
}

.commu__liste header b {
  font-weight: 600;
  color: var(--texte-faible);
}

.commu__liste ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 3.2cqi;
}

.commu__membre,
.commu__post header,
.commu__palier {
  display: flex;
  align-items: center;
  gap: 3cqi;
}

.commu__membre span,
.commu__post header span,
.commu__palier > span {
  display: grid;
  gap: 0.35cqi;
  min-width: 0;
}

.commu__membre b,
.commu__post header b,
.commu__palier b {
  font-weight: 600;
}

.commu__membre small,
.commu__post header small,
.commu__palier small {
  font-size: 0.88em;
  color: var(--texte-doux);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* La couleur dit la nouvelle : accent pour celui qui est en forme, or pour
   un palier. */
.commu__membre--actif small {
  color: var(--accent);
}

.commu__membre--palier small,
.commu__palier small {
  color: #ffd97a;
}

/* L'avatar, c'est la planète du moment : la recette des paliers en petit,
   avec un anneau et une lueur de sa propre atmosphère. */
.commu__astre {
  flex: none;
  width: 8.5cqi;
  margin: 0;
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--a) 45%, transparent),
    0 0 16px color-mix(in srgb, var(--a) 55%, transparent),
    inset -3px -4px 8px rgba(0, 0, 0, 0.55),
    inset 1px 1px 3px color-mix(in srgb, var(--a) 50%, transparent);
}

.commu__astre::before {
  background-size: 60px;
  opacity: 0.6;
}

.commu__astre::after {
  inset: -1px;
  border-width: 1px;
  filter: blur(0.6px);
}

.commu__astre--grand {
  width: 12cqi;
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--a) 50%, transparent),
    0 0 26px color-mix(in srgb, var(--a) 65%, transparent),
    inset -4px -6px 12px rgba(0, 0, 0, 0.55),
    inset 2px 2px 5px color-mix(in srgb, var(--a) 50%, transparent);
}

.commu__post {
  right: 0;
  top: 16%;
  width: 54%;
  padding: 3.8cqi 4.2cqi;
  z-index: 1;
}

.commu__post header {
  margin-bottom: 3cqi;
}

.commu__post p {
  font-weight: 600;
  font-size: 1.1em;
  line-height: 1.4;
  margin-bottom: 3.2cqi;
}

.commu__post footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2cqi;
}

.commu__coeur {
  display: inline-flex;
  align-items: center;
  gap: 1.4cqi;
  font-weight: 600;
  color: var(--texte-doux);
}

.commu__coeur svg {
  width: 1.15em;
  fill: var(--accent);
}

.commu__encourager {
  padding: 1.8cqi 3.4cqi;
  border-radius: 999px;
  background: var(--accent);
  color: var(--sur-accent);
  font-weight: 700;
  font-size: 0.92em;
  box-shadow: 0 6px 18px -6px color-mix(in srgb, var(--accent) 70%, transparent);
}

/* Le palier fêté : la planète en grand, l'étincelle, l'or. Sa ligne peut se
   replier : on ne tronque pas une bonne nouvelle. */
.commu__palier small {
  white-space: normal;
}

.commu__palier {
  right: 3%;
  bottom: 0;
  width: 66%;
  padding: 3.4cqi 4cqi;
  z-index: 2;
  border-color: rgba(255, 217, 122, 0.28);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    0 30px 60px -20px rgba(0, 0, 0, 0.8),
    0 0 40px -10px rgba(255, 217, 122, 0.35);
}

.commu__fete {
  flex: none;
  margin-left: auto;
  width: 6cqi;
  color: #ffd97a;
  filter: drop-shadow(0 0 6px rgba(255, 217, 122, 0.7));
}

.commu__fete svg {
  width: 100%;
  fill: currentColor;
}

/* Sur une scène étroite (téléphone), tout se pose en colonne : liste, post,
   palier, chacun un peu décalé, plus rien ne se recouvre. */
@container (max-width: 460px) {
  .commu__scene {
    padding: 4% 0 2%;
  }

  .commu__liste {
    width: 100%;
    margin-bottom: 0;
  }

  .commu__post,
  .commu__palier {
    position: relative;
    top: auto;
    right: auto;
    bottom: auto;
  }

  .commu__post {
    width: 88%;
    margin: -3cqi 0 0 auto;
  }

  .commu__palier {
    width: 92%;
    margin: 3cqi 0 0 0;
  }
}

@media (max-width: 820px) {
  .commu {
    grid-template-columns: 1fr;
  }
}

/* ═══════════════════════════════════════════════════════ 12 · GUIDE ═══ */

/* L'arche : cinq écrans de l'app posés en éventail, les pieds sur une même
   ligne, la taille qui décroît vers l'extérieur. Aucune rotation - c'est la
   décroissance et le retrait du bas qui font l'arc. Les marges négatives
   règlent le recouvrement, les z-index l'ordre des plans. */
.arche {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  margin-bottom: clamp(2.5rem, 1.5rem + 3vw, 4rem);
  perspective: 1600px;
}

/* L'entrée : l'arche monte et se redresse, un peu plus lentement que le
   reste - c'est la pièce maîtresse de la section. */
.js .arche[data-reveal] {
  transition-duration: 1.2s;
}

.js .arche[data-reveal]:not(.est-visible) {
  transform: translateY(40px) rotateX(7deg) scale(0.97);
}

.arche .tel:nth-child(3) {
  --l: min(23%, 268px);
  z-index: 3;
  /* L'écran central déborde des deux côtés : il monte plus haut et descend
     plus bas que ses voisins. */
  translate: 0 4%;
}

.arche .tel:nth-child(2),
.arche .tel:nth-child(4) {
  --l: min(20.5%, 238px);
  z-index: 2;
}

.arche .tel:nth-child(1),
.arche .tel:nth-child(5) {
  --l: min(18%, 210px);
  z-index: 1;
}

.arche .tel:nth-child(2) { margin-inline-end: -3.2%; }
.arche .tel:nth-child(4) { margin-inline-start: -3.2%; }
.arche .tel:nth-child(1) { margin-inline-end: -2.6%; }
.arche .tel:nth-child(5) { margin-inline-start: -2.6%; }

/* Elles respirent, chacune à son rythme, comme le trio du hero. */
.arche .tel__cadre {
  animation: flotte 8s ease-in-out infinite;
}

.arche .tel:nth-child(1) .tel__cadre { animation-duration: 11s; animation-delay: -6s; }
.arche .tel:nth-child(2) .tel__cadre { animation-duration: 9.5s; animation-delay: -2s; }
.arche .tel:nth-child(4) .tel__cadre { animation-duration: 10s; animation-delay: -4s; }
.arche .tel:nth-child(5) .tel__cadre { animation-duration: 12s; animation-delay: -1s; }

/* ─────────────────────────────────────────────── les écrans du guide ───
   Les cinq écrans de l'arche ne sont pas des captures : ce sont les écrans
   « Apprendre » de l'app, reconstruits avec ses vrais textes
   (src/learn/catalog.ts) et ses vrais tokens (src/design/tokens.ts). Tout est
   dimensionné en points de l'app convertis en cqw - un iPhone fait 393 pt de
   large, donc 1 pt = 100/393 cqw - et l'écran se redessine à l'identique dans
   un cadre de 200 px comme de 260. */
.ecran--guide {
  padding: 0;
  container-type: size;
  font-family: -apple-system, "SF Pro Text", system-ui, sans-serif;
  color: #f7f8fa;
}

.app {
  --pt: 0.2545cqw;
  --lime: #c6ff3d;
  --texte: #f7f8fa;
  --texte-2: #a8afbc;
  --texte-3: #6b7280;
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: inherit;
  /* La GlassStage : quasi noir, deux nappes, quelques étoiles. */
  background:
    radial-gradient(1px 1px at 18% 31%, rgba(255, 255, 255, 0.5), transparent),
    radial-gradient(1px 1px at 72% 18%, rgba(255, 255, 255, 0.4), transparent),
    radial-gradient(1px 1px at 84% 57%, rgba(255, 255, 255, 0.45), transparent),
    radial-gradient(1px 1px at 33% 78%, rgba(255, 255, 255, 0.35), transparent),
    radial-gradient(1px 1px at 58% 92%, rgba(255, 255, 255, 0.4), transparent),
    radial-gradient(70% 45% at 20% 0%, rgba(255, 255, 255, 0.05), transparent 70%),
    radial-gradient(60% 40% at 90% 100%, rgba(198, 255, 61, 0.05), transparent 70%),
    #08090b;
  font-size: calc(16 * var(--pt));
  line-height: 1.45;
  letter-spacing: 0;
  display: flex;
  flex-direction: column;
}

/* La barre d'état : l'heure à gauche, réseau et batterie à droite, de part
   et d'autre de l'île. */
.app-statut {
  flex: none;
  height: calc(54 * var(--pt));
  padding: calc(16 * var(--pt)) calc(30 * var(--pt)) 0;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  font-size: calc(15 * var(--pt));
  font-weight: 600;
  letter-spacing: -0.01em;
}

.app-statut span {
  display: inline-flex;
  align-items: center;
  gap: calc(5 * var(--pt));
}

.app-statut svg {
  height: calc(11 * var(--pt));
  width: auto;
  fill: currentColor;
}

/* L'en-tête flottant : retour à gauche, titre compact centré. */
.app-entete {
  flex: none;
  height: calc(52 * var(--pt));
  padding-inline: calc(8 * var(--pt));
  display: grid;
  grid-template-columns: calc(44 * var(--pt)) 1fr calc(44 * var(--pt));
  align-items: center;
}

.app-entete svg {
  width: calc(22 * var(--pt));
  height: auto;
  margin-inline: auto;
  fill: none;
  stroke: var(--texte);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.app-entete b {
  text-align: center;
  font-size: calc(14 * var(--pt));
  font-weight: 600;
}

/* L'en-tête d'un module : le titre du module en sur-titre. */
.app-entete i {
  text-align: center;
  font-style: normal;
  font-size: calc(12 * var(--pt));
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--texte-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.app-contenu {
  flex: 1;
  min-height: 0;
  padding: calc(12 * var(--pt)) calc(20 * var(--pt)) 0;
  overflow: hidden;
}

/* LiquidCard : le verre de l'app. */
.app-carte {
  padding: calc(16 * var(--pt));
  border-radius: calc(20 * var(--pt));
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.075), rgba(255, 255, 255, 0.035));
  border: 1px solid rgba(255, 255, 255, 0.09);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
}

.app-carte--accent {
  background: linear-gradient(180deg, rgba(198, 255, 61, 0.14), rgba(198, 255, 61, 0.05));
  border-color: rgba(198, 255, 61, 0.28);
}

/* La tête de la bibliothèque : le compteur de leçons lues. */
.app-compteur {
  text-align: center;
}

.app-compteur b {
  display: block;
  font-size: calc(64 * var(--pt));
  line-height: 1.05;
  font-weight: 800;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
}

.app-compteur b small {
  font-size: calc(24 * var(--pt));
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--texte-3);
}

.app-eyebrow {
  display: block;
  font-size: calc(10 * var(--pt));
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--texte-2);
}

.app-compteur p {
  margin-top: calc(12 * var(--pt));
  font-size: calc(12 * var(--pt));
  line-height: 1.42;
  color: var(--texte-2);
}

.app-section {
  margin: calc(24 * var(--pt)) 0 calc(12 * var(--pt));
  font-size: calc(20 * var(--pt));
  font-weight: 700;
  letter-spacing: -0.015em;
}

.app-liste {
  display: grid;
  gap: calc(12 * var(--pt));
}

/* Une rangée de module : icône teintée, titre, résumé, méta, chevron, puis la
   piste de progression. */
.app-module {
  display: grid;
  grid-template-columns: calc(42 * var(--pt)) 1fr calc(17 * var(--pt));
  gap: calc(12 * var(--pt));
  align-items: center;
}

.app-module__icone {
  width: calc(42 * var(--pt));
  height: calc(42 * var(--pt));
  border-radius: calc(12 * var(--pt));
  display: grid;
  place-items: center;
  background: color-mix(in srgb, currentColor 12%, transparent);
}

.app-module__icone svg {
  width: calc(20 * var(--pt));
  height: auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.app-module b {
  display: block;
  font-size: calc(16 * var(--pt));
  font-weight: 600;
  line-height: 1.3;
  color: var(--texte);
}

.app-module p {
  margin-top: calc(2 * var(--pt));
  font-size: calc(12 * var(--pt));
  line-height: 1.4;
  color: var(--texte-2);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.app-module small {
  display: block;
  margin-top: calc(3 * var(--pt));
  font-size: calc(10 * var(--pt));
  color: var(--texte-3);
}

.app-chevron {
  width: calc(17 * var(--pt));
  height: auto;
  fill: none;
  stroke: var(--texte-3);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.app-piste {
  grid-column: 1 / -1;
  height: calc(4 * var(--pt));
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.07);
  overflow: hidden;
}

.app-piste i {
  display: block;
  height: 100%;
  width: var(--fait, 0%);
  border-radius: inherit;
  background: currentColor;
}

/* Un module ouvert : le résumé, puis les leçons numérotées. */
.app-resume {
  font-size: calc(14 * var(--pt));
  line-height: 1.5;
  color: var(--texte-2);
}

.app-lecons {
  display: grid;
  gap: calc(8 * var(--pt));
  margin-top: calc(24 * var(--pt));
}

.app-lecon {
  display: grid;
  grid-template-columns: calc(26 * var(--pt)) 1fr calc(17 * var(--pt));
  gap: calc(12 * var(--pt));
  align-items: center;
}

.app-lecon__puce {
  width: calc(26 * var(--pt));
  height: calc(26 * var(--pt));
  border-radius: 50%;
  border: calc(1.5 * var(--pt)) solid rgba(255, 255, 255, 0.14);
  display: grid;
  place-items: center;
  font-size: calc(11 * var(--pt));
  font-weight: 700;
  color: var(--texte-2);
}

.app-lecon__puce svg {
  width: calc(13 * var(--pt));
  height: auto;
  fill: none;
  stroke: #08090b;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.app-lecon--lue .app-lecon__puce {
  background: var(--lime);
  border-color: var(--lime);
}

.app-lecon b {
  display: block;
  font-size: calc(14 * var(--pt));
  font-weight: 600;
  line-height: 1.3;
}

.app-lecon--lue b {
  color: var(--texte-2);
}

.app-lecon small {
  display: block;
  margin-top: calc(1 * var(--pt));
  font-size: calc(10 * var(--pt));
  color: var(--texte-3);
}

/* La lecture d'une leçon. */
.app-lecture-eyebrow {
  display: block;
  margin-top: calc(8 * var(--pt));
  font-size: calc(10 * var(--pt));
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--lime);
}

.app-lecture-titre {
  margin-top: calc(8 * var(--pt));
  font-size: calc(32 * var(--pt));
  line-height: 1.15;
  font-weight: 800;
  letter-spacing: -0.03em;
}

.app-contenu p.app-para {
  margin-top: calc(16 * var(--pt));
  font-size: calc(16 * var(--pt));
  line-height: 1.62;
  color: var(--texte-2);
}

.app-action {
  margin-top: calc(24 * var(--pt));
}

.app-action b {
  display: block;
  margin-top: calc(8 * var(--pt));
  font-size: calc(16 * var(--pt));
  font-weight: 600;
  line-height: 1.5;
}

/* Le pied : le bouton principal, posé sur un voile qui fond le contenu. */
.app-pied {
  flex: none;
  padding: calc(8 * var(--pt)) calc(20 * var(--pt)) calc(34 * var(--pt));
  background: linear-gradient(180deg, transparent, #08090b 35%);
}

.app-bouton {
  height: calc(56 * var(--pt));
  border-radius: calc(16 * var(--pt));
  background: var(--lime);
  color: #08090b;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(8 * var(--pt));
  font-size: calc(16 * var(--pt));
  font-weight: 700;
  box-shadow: 0 calc(6 * var(--pt)) calc(20 * var(--pt)) rgba(198, 255, 61, 0.34);
}

.app-bouton svg {
  width: calc(18 * var(--pt));
  height: auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Une lecture qu'on a fait défiler : le début est passé sous l'en-tête. */
.app-contenu--defile {
  padding-top: 0;
}

.app-contenu--defile > :first-child {
  margin-top: calc(-40 * var(--pt));
}

/* ─────────────────────────────────────────────────── les quatre volets ───
   Un titre, une flèche ; derrière, l'argument : une accroche, le mécanisme
   en quelques lignes, trois points concrets, et le bouton. Le volet s'ouvre
   en hauteur par ::details-content (Chrome 131+, Safari 26) ; ailleurs il
   s'ouvre d'un coup, ce qui reste juste. Un seul volet ouvert à la fois,
   c'est app.js. */
.guide__liste {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
  gap: 1rem;
  align-items: start;
}

.article {
  padding: 0;
  interpolate-size: allow-keywords;
  transition: transform var(--d-moyen) var(--courbe), border-color var(--d-moyen);
}

.article:hover {
  transform: translateY(-4px);
}

.article:hover,
.article[open] {
  border-color: var(--trait-accent);
}

.article__titre {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.5rem 1.75rem;
  cursor: pointer;
  list-style: none;
}

.article__titre::-webkit-details-marker {
  display: none;
}

.article h3 {
  font-size: 1.2rem;
  text-wrap: balance;
}

.article__fleche {
  flex: none;
  width: 1.35rem;
  height: auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--texte-faible);
  transition: transform var(--d-moyen) var(--courbe-sortie), color var(--d-moyen);
}

.article:hover .article__fleche {
  transform: translateX(4px);
  color: var(--accent);
}

.article[open] .article__fleche,
.article[open]:hover .article__fleche {
  transform: rotate(90deg);
  color: var(--accent);
}

.article::details-content {
  block-size: 0;
  overflow: hidden;
  transition:
    block-size 0.55s var(--courbe-sortie),
    content-visibility 0.55s allow-discrete;
}

.article[open]::details-content {
  block-size: auto;
}

.article__corps {
  display: grid;
  gap: 1rem;
  margin: 0 1.75rem 1.75rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--trait);
}

.article__corps p {
  color: var(--texte-doux);
  max-width: 62ch;
}

.article__accroche {
  color: var(--texte);
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1.45;
}

.article__corps .article__accroche {
  color: var(--texte);
}

.article__eyebrow {
  margin-top: 0.25rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texte-faible);
}

.article__points {
  display: grid;
  gap: 0.6rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.article__points li {
  position: relative;
  padding-left: 1.35rem;
  font-size: 0.98rem;
}

.article__points li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 60%, transparent);
}

.article__cta {
  justify-self: start;
  margin-top: 0.5rem;
}

/* Sous 900 px l'arche se réduit à trois écrans, sinon les extrêmes ne sont
   plus que des timbres. */
@media (max-width: 900px) {
  .arche .tel:nth-child(1),
  .arche .tel:nth-child(5) {
    display: none;
  }

  .arche .tel:nth-child(3) { --l: min(34%, 250px); }

  .arche .tel:nth-child(2),
  .arche .tel:nth-child(4) {
    --l: min(30%, 220px);
  }

  .arche .tel:nth-child(2) { margin-inline-end: -5%; }
  .arche .tel:nth-child(4) { margin-inline-start: -5%; }
}

@media (max-width: 560px) {
  .arche .tel:nth-child(3) { --l: min(44%, 190px); }

  .arche .tel:nth-child(2),
  .arche .tel:nth-child(4) {
    --l: min(38%, 164px);
  }

  .arche .tel:nth-child(2) { margin-inline-end: -7%; }
  .arche .tel:nth-child(4) { margin-inline-start: -7%; }
}

/* ═════════════════════════════════════════════════════════ 13 · FAQ ═══ */

.enveloppe--etroite {
  max-width: var(--largeur-etroite);
}

.faq__liste {
  padding-inline: clamp(1.25rem, 0.5rem + 2vw, 2.25rem);
}

.faq__item {
  border-bottom: 1px solid var(--trait);
}

.faq__item:last-child {
  border-bottom: 0;
}

.faq__item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: 1.5rem;
  cursor: pointer;
  list-style: none;
  font-size: 1.05rem;
  transition: color var(--d-court);
}

.faq__item summary::-webkit-details-marker {
  display: none;
}

.faq__item summary:hover {
  color: var(--accent-vif);
}

/* Le « + » se transforme en « − » à l'ouverture, sans image ni police d'icône. */
.faq__icone {
  position: relative;
  flex: none;
  width: 18px;
  height: 18px;
}

.faq__icone::before,
.faq__icone::after {
  content: "";
  position: absolute;
  inset: 50% 0 auto;
  height: 1.5px;
  background: var(--texte-doux);
  translate: 0 -50%;
  transition: rotate var(--d-moyen) var(--courbe), opacity var(--d-moyen);
}

.faq__icone::after {
  rotate: 90deg;
}

.faq__item[open] .faq__icone::after {
  rotate: 0deg;
  opacity: 0;
}

/* La réponse s'ouvre en hauteur : grid-template-rows est la seule façon
   d'animer « auto » sans mesurer en JS. */
.faq__reponse {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--d-moyen) var(--courbe);
}

.faq__item[open] .faq__reponse {
  grid-template-rows: 1fr;
}

.faq__reponse > p {
  overflow: hidden;
  color: var(--texte-doux);
  padding-bottom: 1.5rem;
  max-width: 62ch;
}

/* ══════════════════════════════════════════════════ 14 · CTA FINAL ═══ */

/* Un bloc compact, centré : une carte de 760 px au plus, pas une dalle sur
   toute la largeur, avec un titre de section et non un titre de page. */
.cta-final {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  text-align: center;
  max-width: 760px;
  margin-inline: auto;
  padding: clamp(2.25rem, 1.25rem + 3vw, 3.5rem) clamp(1.5rem, 1rem + 2vw, 2.5rem);
  border-radius: var(--r-bloc);
  background-color: var(--verre-fond);
  background-image: var(--verre-spec), var(--verre-cast-accent),
    linear-gradient(var(--verre-teinte-haute), var(--verre-teinte-haute));
  -webkit-backdrop-filter: blur(var(--verre-flou));
  backdrop-filter: blur(var(--verre-flou));
  border: 1px solid var(--verre-rim-accent);
}

/* L'arête du héro s'allume dans l'accent (GlassHero). */
.cta-final::before {
  content: "";
  position: absolute;
  top: 0;
  left: 8%;
  right: 8%;
  height: 1px;
  background: var(--verre-arete-accent);
  z-index: 2;
  pointer-events: none;
}

.cta-final__halo {
  bottom: -40%;
  left: 50%;
  translate: -50% 0;
  width: min(80%, 700px);
  aspect-ratio: 2 / 1;
  background: radial-gradient(circle, rgba(198, 255, 61, 0.14) 0%, transparent 70%);
}

/* Le halo reste absolu : posé en relatif avec les autres enfants, il entrait
   dans le flux et ajoutait 300 px de vide au bloc. */
.cta-final > :not(.halo) {
  position: relative;
  z-index: 1;
}

.cta-final h2 {
  max-width: 16ch;
  font-size: clamp(1.6rem, 1.1rem + 2vw, 2.4rem);
}

.cta-final p {
  color: var(--texte-doux);
  max-width: 52ch;
}

.cta-final__signature {
  color: var(--texte-faible);
}

/* La signature se compose sur deux lignes : la phrase, puis l'équipe en
   petites capitales espacées. Le tiret qui finissait en bout de ligne a
   disparu avec la ligne unique. */
.cta-final__equipe {
  display: block;
  margin-top: 0.55rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--texte-faible);
}

.cta-final .btn {
  margin-top: 1rem;
}

/* ═══════════════════════════════════════════════════════ 15 · PIED ═══ */

.pied {
  padding-block: clamp(3rem, 2rem + 4vw, 5rem) 2.5rem;
  border-top: 1px solid var(--trait);
  background: var(--fond-noir);
}

.pied__haut {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 2fr);
  gap: clamp(2rem, 1rem + 4vw, 4rem);
  padding-bottom: 3rem;
}

.pied__marque p {
  margin-top: 0.85rem;
  color: var(--texte-doux);
  font-size: var(--t-petit);
  max-width: 34ch;
}

.pied__colonnes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 2rem;
}

.pied__colonnes h4 {
  margin: 0 0 1rem;
  font-family: var(--police-titre);
  font-size: 0.95rem;
  font-weight: 700;
}

.pied__colonnes a {
  display: block;
  /* 44 px de haut : une cible qu'un pouce ne rate pas. */
  padding-block: 0.7rem;
  margin-bottom: 0;
  color: var(--texte-doux);
  font-size: var(--t-petit);
  transition: color var(--d-court);
}

.pied__colonnes a:hover {
  color: var(--texte);
}

/* « Gérer les cookies » : un bouton habillé comme les liens voisins. */
.pied__cookies {
  display: block;
  padding-block: 0.7rem;
  background: none;
  border: 0;
  font: inherit;
  font-size: var(--t-petit);
  color: var(--texte-doux);
  text-align: left;
  cursor: pointer;
  transition: color var(--d-court);
}

.pied__cookies:hover {
  color: var(--texte);
}

/* ═══════════════════════════════════════════════════════ CONSENTEMENT ═══
   Le bandeau cookies : une carte de verre en bas, deux boutons de même
   poids (refuser vaut accepter, c'est la règle), un lien vers la politique.
   Affiché par app.js seulement quand il y a quelque chose à accepter. */
.consentement {
  position: fixed;
  left: 50%;
  bottom: max(1rem, env(safe-area-inset-bottom));
  translate: -50% 0;
  z-index: 60;
  width: min(calc(100% - 2rem), 640px);
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.8rem 1.25rem;
  align-items: center;
  padding: 1.25rem 1.5rem;
  border-radius: 22px;
  background:
    var(--verre-spec),
    linear-gradient(rgba(13, 15, 19, 0.94), rgba(13, 15, 19, 0.94));
  background-repeat: no-repeat;
  background-size: 100% 120px, 100% 100%;
  -webkit-backdrop-filter: blur(18px);
  backdrop-filter: blur(18px);
  border: 1px solid var(--verre-rim);
  box-shadow: var(--ombre-flottante);
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--texte-doux);
}

/* L'arête accent en haut, comme sur le bloc final : c'est la même famille. */
.consentement::before {
  content: "";
  position: absolute;
  top: 0;
  left: 10%;
  right: 10%;
  height: 1px;
  background: var(--verre-arete-accent);
  pointer-events: none;
}

/* Le bandeau a un display explicite : sans cette règle, l'attribut hidden
   posé par app.js ne le fermait pas, le grid l'emportait sur le navigateur. */
.consentement[hidden] {
  display: none;
}

/* Il arrive d'en bas, en fondu, quand il a quelque chose à demander. */
.consentement:not([hidden]) {
  animation: consentement-entre 0.55s var(--courbe-sortie) both;
}

@keyframes consentement-entre {
  from {
    opacity: 0;
    translate: -50% 16px;
  }
  to {
    opacity: 1;
    translate: -50% 0;
  }
}

.consentement p {
  margin: 0;
}

.consentement__actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

/* Le bouton d'accord : le bouton du site, taille normale, avec sa coche. */
.consentement__accord {
  padding: 0.95rem 1.7rem 0.95rem 1.4rem;
  gap: 0.5rem;
}

.consentement__accord svg {
  width: 1.1rem;
  height: 1.1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.consentement a {
  color: var(--texte);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* « Continuer sans accepter » : un texte, pas un bouton, mais à un clic et
   aussi haut qu'un bouton, c'est la règle. */
.consentement__refus {
  min-height: 44px;
  padding: 0 0.75rem;
  background: none;
  border: 0;
  font: inherit;
  font-size: 0.9rem;
  color: var(--texte-doux);
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.3);
  text-underline-offset: 4px;
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--d-court), text-decoration-color var(--d-court);
}

.consentement__refus:hover {
  color: var(--texte);
  text-decoration-color: currentColor;
}

@media (max-width: 700px) {
  .consentement {
    grid-template-columns: 1fr;
  }

  .consentement__actions {
    flex-direction: column-reverse;
    align-items: stretch;
  }
}

.pied__bas {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding-top: 2rem;
  border-top: 1px solid var(--trait);
  color: var(--texte-faible);
  font-size: 0.8rem;
}

.pied__avis {
  max-width: 56ch;
}

@media (max-width: 760px) {
  .pied__haut {
    grid-template-columns: 1fr;
  }
}

/* ══════════════════════════════════════════ RESPONSIVE - HERO & GLOBAL ═══ */

@media (max-width: 900px) {
  .hero__grille {
    grid-template-columns: 1fr;
    text-align: center;
  }
  .hero__texte {
    align-items: center;
  }
  .hero__actions {
    justify-content: center;
  }
  .hero__chapeau {
    margin-inline: auto;
  }
}

/* Sous 420 px, « Reprends le contrôle, » ne tient plus sur une ligne : le
   saut forcé donnait trois lignes bancales. On rend la coupe au navigateur,
   text-wrap: balance fait le reste. */
@media (max-width: 420px) {
  h1 br {
    display: none;
  }
}

@media (max-width: 520px) {
  .hero__visuel .tel--gauche,
  .hero__visuel .tel--droite {
    display: none;
  }
  .hero__visuel .tel--centre {
    --l: min(74%, 280px);
  }
  .btn {
    padding: 1rem 2rem;
  }
}

/* ══════════════════════════════════════════ OPTIMISATIONS MOBILES ═══
   En fin de feuille à dessein : ces règles doivent gagner la cascade sur
   les règles de base des sections, écrites plus haut avec la même
   spécificité. Moins de flou, moins d'air perdu, rendu différé hors écran. */
@media (max-width: 700px) {
  :root {
    --verre-flou: 14px;
    --verre-flou-leger: 10px;
    --sect-y: clamp(3.25rem, 2rem + 5vw, 4.5rem);
  }

  /* Les sections sous la ligne de flottaison ne se calculent qu'à l'approche :
     le premier écran arrive plus vite, le défilement reste fluide. */
  .section:not([data-section="benefices"]):not([data-section="paliers"]) {
    content-visibility: auto;
    contain-intrinsic-size: auto 800px;
  }

  .hero {
    padding-block: 6.5rem 3rem;
  }


  /* Boutons à taille de doigt : stores empilés, même largeur ; sélecteur
     de langue, burger et lignes de menu à 44 px. */
  .hero__actions {
    grid-auto-flow: row;
    /* Une seule colonne, pleine largeur du bloc : les deux stores font
       exactement la même largeur et remplissent leur ligne. */
    grid-template-columns: minmax(0, 1fr);
    /* Des badges, pas des barres : 232 px, la largeur d'un badge de store. */
    width: min(100%, 232px);
    gap: 0.7rem;
  }

  .store {
    width: 100%;
    justify-content: center;
    padding-block: 0.7rem;
  }

  .entete-site__burger {
    width: 44px;
    height: 44px;
  }

  .langues__bouton {
    padding: 0.7rem 0.9rem;
  }

  .langues__menu a {
    padding: 0.8rem 0.9rem;
  }
}

/* Sur /en/ et /es/, une ligne dit que les pages légales sont en français ;
   en français l'élément est vide et n'occupe aucune place. */
.pied__langue {
  margin: 0 0 0.6rem;
  font-size: var(--t-petit);
  line-height: 1.45;
  color: var(--texte-faible);
  max-width: 24ch;
  text-wrap: pretty;
}

.pied__langue:empty {
  display: none;
}

/* Les langues à mots longs (l'allemand surtout) : sur petit écran, un mot
   plus large que sa colonne élargissait tout le bloc et poussait le titre
   hors de l'écran. « anywhere » ne coupe que le mot qui ne tient pas, et
   entre dans le calcul de largeur minimale ; là où tout tient déjà, comme en
   français, rien ne change. La césure propre est réservée à l'allemand. */
@media (max-width: 520px) {
  h1,
  h2,
  h3,
  h4 {
    overflow-wrap: anywhere;
  }

  html[lang="de"] h1,
  html[lang="de"] h2,
  html[lang="de"] h3,
  html[lang="de"] h4,
  html[lang="de"] p,
  html[lang="de"] li {
    -webkit-hyphens: auto;
    hyphens: auto;
  }
}
