/* ─── Touquand, site vitrine ─────────────────────────────────────────────────
   Direction issue de trois références fournies : Ronas IT (travel), Kites
   Design (e-commerce), Super Chill.

   Ce qu'elles ont en commun, et qu'on reprend :
     page claire et neutre, grands rayons, ombres FLOUES, grand rendu du
     téléphone comme visuel principal, pilule sombre pour l'action, petites
     pastilles flottant autour de l'appareil.

   Ce qu'on garde de la charte Touquand, sans fond beige :
     Anton en capitales pour les titres (Super Chill fait de même en lourd
     condensé), le surligneur JAUNE derrière un mot du titre, et des cartes
     en APLATS de corail, de jaune et d'encre posées sur du blanc.
     La couleur vient des blocs, jamais du papier : c'est ce qui remplace
     l'ancien fond crème.
   ───────────────────────────────────────────────────────────────────────── */

:root {
  color-scheme: light dark;

  /* Charte, invariante d'un thème à l'autre */
  --coral: #e54c5c;
  --yellow: #f7c61c;
  --ink: #141414;

  /* Rôles. Neutres FROIDS, jamais crème : c'est la contrainte de départ. */
  --bg: #ffffff;
  --surface: #ffffff;
  --surface-2: #f4f4f6;
  --tint-coral: #fdecee;
  --fg: #141414;
  --fg-soft: #5c5c64;
  --hairline: rgba(20, 20, 20, 0.1);
  --pill-bg: #141414;
  --pill-fg: #ffffff;
  --on-coral: #141414;
  --on-yellow: #141414;

  --r-lg: 30px;
  --r-md: 20px;

  /* Ombres floues, jamais pleines : premier écart, et le plus visible. */
  --lift: 0 1px 2px rgba(20, 20, 20, 0.04), 0 10px 28px rgba(20, 20, 20, 0.07);
  --lift-lg: 0 2px 4px rgba(20, 20, 20, 0.04), 0 30px 70px rgba(20, 20, 20, 0.12);

  --measure: 58ch;
  --gutter: clamp(1.25rem, 5vw, 3.5rem);
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f0f11;
    --surface: #18181b;
    --surface-2: #1e1e22;
    --tint-coral: #2a1a1d;
    --fg: #f5f5f7;
    --fg-soft: #a1a1aa;
    --hairline: rgba(245, 245, 247, 0.13);
    --pill-bg: #f5f5f7;
    --pill-fg: #141414;
    --lift: 0 1px 2px rgba(0, 0, 0, 0.5), 0 10px 28px rgba(0, 0, 0, 0.5);
    --lift-lg: 0 2px 4px rgba(0, 0, 0, 0.5), 0 30px 70px rgba(0, 0, 0, 0.6);
  }
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: Poppins, system-ui, -apple-system, sans-serif;
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  line-height: 1.62;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  margin: 0;
  font-family: Anton, Impact, sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.005em;
  line-height: 1.04;
}
/* Anton en capitales avance à ~0.46em par caractère : le plafond est calculé
   sur la largeur du bloc, pas choisi au jugé. Et 1.04 d'interligne minimum,
   sinon la cédille de « ÇA » se fait trancher par la ligne suivante. */
h1 { font-size: clamp(2.5rem, 1rem + 5vw, 4.75rem); padding-bottom: 0.06em; }
h2 { font-size: clamp(1.9rem, 1.2rem + 2.4vw, 3.1rem); padding-bottom: 0.06em; }
h3 { font-size: clamp(1.15rem, 1.02rem + 0.6vw, 1.45rem); line-height: 1.16; }

p { margin: 0 0 1rem; max-width: var(--measure); color: var(--fg-soft); }
a { color: inherit; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img { display: block; max-width: 100%; }

.wrap { width: min(100% - (2 * var(--gutter)), 1180px); margin-inline: auto; }

/* Lien d'évitement : hors écran tant qu'il n'a pas le focus, puis posé
   par-dessus tout. « display: none » l'aurait rendu infocusable, donc inutile. */
.evitement {
  position: fixed; top: 0.75rem; left: 0.75rem; z-index: 100;
  padding: 0.7rem 1.1rem;
  border-radius: 999px;
  background: var(--pill-bg); color: var(--pill-fg);
  font-weight: 600; text-decoration: none;
  transform: translateY(-150%);
  transition: transform 160ms var(--ease);
}
.evitement:focus-visible { transform: translateY(0); }
main:focus { outline: none; }

/* Surligneur : le trait jaune de la charte passe DERRIÈRE le mot, comme au
   marqueur. Il est en pseudo-élément pour ne pas gêner la sélection du texte
   ni la lecture par un lecteur d'écran. */
/* Le surligneur est jaune dans les DEUX thèmes : le mot qu'il porte doit donc
   rester encre, même en sombre où le reste du titre passe en clair. Sans ça,
   « RIEN » s'affichait en blanc sur jaune, à 1.7:1. */
.mark { position: relative; display: inline-block; color: var(--ink); }
.mark::before {
  content: ""; position: absolute; z-index: -1;
  /* Le jaune couvre TOUTE la boîte du mot. Rentré de 0.12em, il laissait le
     haut et le bas des capitales en dehors : en thème sombre, ces parties
     tombaient sur le fond noir et le mot apparaissait tronqué. */
  inset: -0.02em -0.06em;
  background: var(--yellow);
  border-radius: 4px;
}

/* ── Navigation ──────────────────────────────────────────────────────────── */
.nav {
  position: sticky; top: 0; z-index: 20;
  padding: 0.85rem 0;
  background: color-mix(in srgb, var(--bg) 84%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color 200ms var(--ease);
}
.nav[data-stuck="true"] { border-bottom-color: var(--hairline); }
.nav__row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; height: 46px; }
.brand { display: flex; align-items: center; gap: 0.5rem; text-decoration: none; }
.brand img { width: 32px; height: 32px; }
.brand span { font-family: Anton, Impact, sans-serif; font-size: 1.3rem; letter-spacing: 0.02em; }
.nav__links { display: none; gap: 2.25rem; }
@media (min-width: 56rem) { .nav__links { display: flex; } }
.nav__links a { color: var(--fg-soft); text-decoration: none; font-size: 0.93rem; transition: color 160ms var(--ease); }
.nav__links a:hover { color: var(--fg); }
/* Repère de position sur une page de six écrans : sans lui, on ne sait jamais
   où l'on en est. Le trait, et non la couleur seule, pour que l'information ne
   dépende pas de la perception des teintes. */
.nav__links a[aria-current='true'] { color: var(--fg); }
.nav__links a[aria-current='true']::after {
  content: ""; display: block; height: 2px; margin-top: 3px;
  border-radius: 2px; background: var(--coral);
}
.nav__links a::after { content: ""; display: block; height: 2px; margin-top: 3px; }

/* ── Boutons ─────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0.85rem 1.7rem;
  border: 0; border-radius: 999px;
  background: var(--pill-bg); color: var(--pill-fg);
  font-family: inherit; font-size: 0.95rem; font-weight: 600; letter-spacing: -0.005em;
  text-decoration: none; white-space: nowrap; cursor: pointer;
  box-shadow: var(--lift);
  transition: transform 180ms var(--ease), box-shadow 180ms var(--ease);
}
.btn:hover, .btn:focus-visible { transform: translateY(-2px); box-shadow: var(--lift-lg); }
.btn:active { transform: translateY(0); }
.btn--sm { padding: 0.6rem 1.25rem; font-size: 0.88rem; }
.btn--yellow { background: var(--yellow); color: var(--on-yellow); }
.btn--ghost { background: transparent; color: var(--fg); border: 1px solid var(--hairline); box-shadow: none; }
.btn--ghost:hover, .btn--ghost:focus-visible { background: var(--surface-2); box-shadow: none; transform: translateY(-2px); }

:where(a, button):focus-visible { outline: 2px solid var(--coral); outline-offset: 3px; }

/* ── Héros ───────────────────────────────────────────────────────────────── */
.hero { position: relative; padding-block: clamp(2.5rem, 6vw, 4.5rem) 0; text-align: center; }
.hero__inner { max-width: 52rem; margin-inline: auto; }

/* Le logo est le premier porteur de la marque : grand et centré, pas une
   vignette. Il conserve son rapport de forme quelle que soit la largeur. */
.hero__logo {
  width: clamp(96px, 13vw, 168px);
  height: auto;
  /* Serré contre la baseline : les deux forment un verrou, pas deux éléments
     empilés. C'est cet écart réduit qui les fait lire ensemble. */
  margin: 0 auto 0.75rem;
}

/* La baseline. Estampille, pas phrase : capitales, corps petit, interlettrage
   ouvert. Anton l'aurait rendue trop présente juste au-dessus du titre, qui
   est déjà en Anton — deux blocs de la même police se seraient disputés. Le
   Poppins gras espacé la met à sa place, celle d'une mention de marque.
   Séparateurs dans la couleur du texte, et non en corail : mesurés à 3.8:1
   sur blanc, ils tombaient sous le seuil. Une ponctuation reste du texte, et
   la baseline se lit comme une marque par son traitement et sa place, pas
   parce qu'un point est rouge. */
.baseline {
  margin: 0 auto 1.6rem;
  font-size: 0.78rem; font-weight: 600;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--fg-soft);
}
.pill {
  display: inline-flex; align-items: center; gap: 0.5rem;
  /* Sous les boutons désormais, et non plus au-dessus du titre : « bêta
     fermée sur iOS » sert à décider une fois qu'on a envie, pas à identifier
     la marque. */
  padding: 0.4rem 1rem; margin: 1.25rem 0 0;
  border: 1px solid var(--hairline); border-radius: 999px;
  background: var(--surface); box-shadow: var(--lift);
  font-size: 0.82rem; font-weight: 500; color: var(--fg-soft);
}
.pill i { width: 6px; height: 6px; border-radius: 999px; background: var(--coral); }
.hero h1 { margin-bottom: 1.5rem; }
.hero__lede { margin-inline: auto; margin-bottom: 2.25rem; max-width: 33rem; font-size: clamp(1.02rem, 0.98rem + 0.3vw, 1.15rem); }
.hero__actions { display: flex; flex-wrap: wrap; gap: 0.75rem; justify-content: center; }
@media (max-width: 30rem) { .hero__actions { flex-direction: column; } }

/* ── Le téléphone ────────────────────────────────────────────────────────── */
.showcase { position: relative; margin-top: clamp(2.5rem, 6vw, 4rem); display: grid; justify-items: center; }
/* Tache corail derrière l'appareil : c'est elle qui remplace l'ancien aplat
   crème. Rose franc, aucune dérive vers le beige. */
.showcase::before {
  content: ""; position: absolute; z-index: 0;
  width: min(92vw, 720px); aspect-ratio: 1 / 0.72;
  top: 8%; left: 50%; translate: -50% 0;
  background: radial-gradient(50% 50% at 50% 50%, var(--tint-coral), transparent 72%);
  pointer-events: none;
}
.device { position: relative; z-index: 1; width: min(100%, 292px); }
.device__frame { padding: 9px; border-radius: 44px; background: linear-gradient(160deg, #34333a, #121114); box-shadow: var(--lift-lg); }
/* La hauteur venait de l'image ; l'écran redessiné n'a pas de dimension
   intrinsèque, donc le cadre la porte lui-même. */
.device__screen { aspect-ratio: 9 / 18; border-radius: 36px; overflow: hidden; background: #f6dbc9; }
.device__screen img { width: 100%; height: auto; }

/* Pastilles flottantes : le motif commun aux trois références. Ici elles
   portent une information vraie, les champs que l'app tire d'une affiche. */
.chip {
  position: absolute; z-index: 2;
  padding: 0.6rem 0.95rem;
  border-radius: 999px;
  background: var(--surface); box-shadow: var(--lift-lg);
  text-align: left; white-space: nowrap;
}
.chip b { display: block; font-size: 0.9rem; font-weight: 600; line-height: 1.2; }
.chip small { display: block; font-size: 0.68rem; font-weight: 500; color: var(--fg-soft); }
.chip--a { top: 10%; left: -22%; }
.chip--b { top: 76%; left: 82%; }
.chip--c { bottom: 12%; left: -18%; background: var(--yellow); }
.chip--c b, .chip--c small { color: var(--on-yellow); }
.chip--c small { opacity: 0.72; }
@media (max-width: 56rem) {
  .chip--a { left: -4%; } .chip--b { top: 78%; left: 62%; } .chip--c { left: -2%; }
}
@media (max-width: 30rem) {
  .chip { padding: 0.45rem 0.7rem; }
  .chip b { font-size: 0.76rem; }
  .chip--a { left: 0; } .chip--b { top: 80%; left: 44%; } .chip--c { left: 0; }
}

@media (prefers-reduced-motion: no-preference) {
  .chip { animation: bob 6s ease-in-out infinite; }
  .chip--b { animation-delay: 1.4s; }
  .chip--c { animation-delay: 2.8s; }
  @keyframes bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-9px); } }
}

/* ── Sections ────────────────────────────────────────────────────────────── */
.section { padding-block: clamp(3.5rem, 8vw, 6.5rem); }
/* La barre reste collée en haut : sans cette marge, une ancre dépose la section
   sous la barre et son titre est masqué. 74px de barre, plus un peu d'air. */
[id] { scroll-margin-top: 5.5rem; }
.section__head { max-width: 42rem; margin-bottom: clamp(2rem, 4vw, 3rem); }
.section__head h2 { margin-bottom: 0.9rem; }

/* ── Ce que ça change : quatre paires en 2x2 ─────────────────────────────── */
/* Une grille plutôt qu'une rangée qui déborde : les quatre cartes sont du même
   rang, aucune n'est reléguée hors du cadre, et on les embrasse d'un coup
   d'œil. Le débordement avait un sens quand la section disait l'empilement ;
   elle dit maintenant un bénéfice, qui doit être lu en entier. */
.paires {
  display: grid;
  gap: clamp(0.9rem, 1.6vw, 1.25rem);
  grid-template-columns: 1fr;
}
@media (min-width: 48rem) { .paires { grid-template-columns: repeat(2, 1fr); } }

.paire {
  display: grid;
  align-content: start;
  padding: clamp(1.4rem, 2.4vw, 1.9rem);
  border-radius: var(--r-md);
  background: var(--surface-2);
}
.paire--jaune { background: var(--yellow); }
.paire--corail { background: var(--coral); }

/* Repères de temps. AUCUNE opacité : sur un aplat corail ou jaune, elle fait
   tomber le contraste sous le seuil AA. La hiérarchie passe par la graisse et
   la taille, jamais par la transparence. */
.paire__label {
  font-size: 0.7rem; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--fg-soft);
}
.paire__label--fort { margin-top: 1rem; color: var(--fg); }

.paire__avant {
  margin: 0.2rem 0 0; max-width: none;
  font-size: 1.02rem; font-weight: 400; line-height: 1.32;
  color: var(--fg-soft);
}
.paire__apres {
  margin: 0.2rem 0 0; max-width: none;
  font-size: 1.02rem; font-weight: 600; line-height: 1.32;
  color: var(--fg);
}

/* Les aplats gardent leur teinte dans les deux thèmes, donc leur texte reste
   encre dans les deux : c'est le seul couple qui tienne le 4.5:1 des deux
   côtés. Tout en opacité pleine. */
.paire--jaune :is(.paire__label, .paire__avant, .paire__apres),
.paire--corail :is(.paire__label, .paire__avant, .paire__apres) { color: var(--ink); }
.paire--jaune .paire__avant,
.paire--corail .paire__avant { font-weight: 500; }

/* ── Méthode : panneaux inégaux, couleur par aplats ──────────────────────── */
.panels { display: grid; gap: clamp(1rem, 1.8vw, 1.35rem); }
@media (min-width: 50rem) { .panels { grid-template-columns: 1.32fr 1fr; } }
.panel {
  display: flex; flex-direction: column; gap: 0.65rem;
  padding: clamp(1.6rem, 3vw, 2.35rem);
  border-radius: var(--r-lg);
  background: var(--surface-2);
}
.panel p { margin: 0; }
.panel--tall { grid-row: span 2; justify-content: space-between; }
.panel--coral { background: var(--coral); color: var(--on-coral); }
.panel--coral p { color: var(--on-coral); }
.panel--ink { background: var(--ink); color: #f5f5f7; }
.panel--ink p { color: rgba(245, 245, 247, 0.72); }
.panel__figure {
  margin-bottom: 1.5rem; border-radius: var(--r-md); overflow: hidden;
  background: var(--surface); box-shadow: var(--lift);
}
.panel__figure img { width: 100%; height: auto; }

/* ── Bénéfices : filets fins, deux colonnes ──────────────────────────────── */
.ledger__row { display: grid; gap: 0.5rem; padding-block: clamp(1.4rem, 3vw, 2.1rem); border-top: 1px solid var(--hairline); }
.ledger__row:last-child { border-bottom: 1px solid var(--hairline); }
@media (min-width: 50rem) { .ledger__row { grid-template-columns: 24rem 1fr; gap: 2.5rem; align-items: start; } }
.ledger__row p { margin: 0; }

/* ── Rejoindre : trois étapes puis une seule action ──────────────────────── */
.section__head--centre { margin-inline: auto; text-align: center; }
.section__head--centre h2 { margin-inline: auto; }
.section__head--centre p { margin-inline: auto; }

/* Une suite ordonnée, pas des cartes : trois étapes qui se lisent dans l'ordre
   n'ont pas besoin d'être encadrées pour être comprises. Le filet suffit. */
.etapes {
  display: grid; gap: 0;
  max-width: 44rem; margin: 0 auto;
  counter-reset: etape;
}
.etape {
  display: grid;
  grid-template-columns: 2.4rem 1fr;
  gap: 0 1rem;
  padding-block: clamp(1.1rem, 2.4vw, 1.5rem);
  border-top: 1px solid var(--hairline);
}
.etape:last-child { border-bottom: 1px solid var(--hairline); }
.etape__rang {
  grid-row: span 2;
  display: grid; place-items: center;
  width: 2.4rem; height: 2.4rem;
  border-radius: 999px;
  background: var(--yellow); color: var(--ink);
  font-family: Anton, Impact, sans-serif; font-size: 1.05rem;
}
.etape h3 { align-self: center; }
.etape p { margin: 0.2rem 0 0; }

.conversion { margin-top: clamp(2rem, 4vw, 2.75rem); text-align: center; }
.btn--large { padding: 1.05rem 2.2rem; font-size: 1.1rem; }
.conversion__note {
  margin: 1rem auto 0; max-width: 34rem;
  font-size: 0.9rem; color: var(--fg-soft);
}
.conversion__adresse { color: var(--fg); font-weight: 600; }

/* ── Révélation au défilement ────────────────────────────────────────────── */
.reveal { opacity: 0; transform: translateY(18px); transition: opacity 700ms var(--ease), transform 700ms var(--ease); }
.reveal.is-in { opacity: 1; transform: none; }
.panels .reveal:nth-child(2) { transition-delay: 80ms; }
.panels .reveal:nth-child(3) { transition-delay: 160ms; }

/* ── Pied de page ────────────────────────────────────────────────────────── */
.foot { border-top: 1px solid var(--hairline); padding-block: 2.5rem 3.5rem; }
.foot__row { display: flex; flex-wrap: wrap; gap: 1.25rem 2rem; align-items: center; justify-content: space-between; }
.foot p { margin: 0; font-size: 0.88rem; }
/* Les liens faisaient 23px de haut, sous le minimum de 24x24 du critère 2.5.8
   de WCAG 2.2. Le remplissage vertical les y amène sans changer la typographie. */
.foot nav { display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; }
.foot nav a {
  display: inline-flex; align-items: center; min-height: 28px;
  color: var(--fg-soft); text-decoration: none; font-size: 0.88rem;
}
.foot nav a:hover { color: var(--fg); }

/* ── Pages légales ───────────────────────────────────────────────────────── */
.legal { padding-block: clamp(2rem, 5vw, 3.5rem) clamp(3rem, 8vw, 5rem); }
.legal h1 { margin-bottom: 1.5rem; }
.legal h2 { font-size: clamp(1.3rem, 1.1rem + 0.9vw, 1.8rem); margin-block: 2.25rem 0.75rem; }
.legal p, .legal li { color: var(--fg-soft); }
.legal ul { max-width: var(--measure); padding-left: 1.2rem; list-style: disc; }
.legal li { margin-bottom: 0.5rem; }
.legal__updated { font-size: 0.88rem; }

/* ── Redirection deep link ───────────────────────────────────────────────── */
.redirect { min-height: 100dvh; display: grid; place-items: center; text-align: center; padding: var(--gutter); }
.redirect__card { background: var(--surface); border-radius: var(--r-lg); box-shadow: var(--lift-lg); padding: clamp(1.75rem, 5vw, 3rem); max-width: 30rem; }
.redirect code { display: inline-block; padding: 0.2rem 0.6rem; border-radius: 8px; background: var(--surface-2); font-size: 1.05rem; letter-spacing: 0.1em; }

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

/* ═══════════════════════════════════════════════════════════════════════════
   SCÈNES ILLUSTRÉES

   Choix assumé : ce ne sont PAS des imitations d'écran. La version précédente
   mimait l'interface dans un cadre de téléphone, et ce cadre promettait une
   capture ; assez proche pour qu'on attende du réel, trop loin pour y croire.
   Le faux chrome disparaît donc, ainsi que le texte d'interface à 9px.

   Ce qui reste est le langage Memphis de l'application, à grande échelle :
   contours ink de 3px, ombres pleines décalées, aplats de marque. C'est aussi
   la réponse à « il faut retrouver la charte » : elle vit ici, dans les
   illustrations, pendant que la page reste claire et neutre.

   La carte est SOMBRE, comme le style Mapbox par défaut de l'app. Elle est
   plus graphique sur une page blanche, et évite tout retour au beige.
   ═══════════════════════════════════════════════════════════════════════════ */

.scene {
  --s-ink: #141414;
  --s-coral: #e54c5c;
  --s-yellow: #f7c61c;
  position: relative;
  margin: 0;
}
.scene__inner {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-lg);
}

/* ── Scène carte ─────────────────────────────────────────────────────────── */
.scene--map { width: min(100%, 560px); margin-inline: auto; }
.scene--map .scene__inner {
  aspect-ratio: 4 / 3.4;
  /* Fond clair : la rue ressort en blanc, les îlots en gris, comme sur un
     fond de carte réel. Le sombre faisait de cette carte le seul objet foncé
     de la page, et les pins y perdaient : leur contour ink et leur disque
     blanc se battaient contre le fond au lieu de s'y détacher. */
  background: #ffffff;
  box-shadow: var(--lift-lg);
  outline: 1px solid var(--hairline);
  outline-offset: -1px;
}
/* Îlots urbains : quelques volumes irréguliers valent mieux qu'une grille
   régulière, qui lisait comme du papier millimétré. */
/* Palette reprise TELLE QUELLE du style Mapbox de l'application, une fois
   celui-ci passé au blanc : îlots gris, parcs vert punchy, eau cyan franc.
   L'illustration cesse d'être fade sans revenir au beige, et surtout elle
   devient reconnaissable : qui ouvre l'app retrouve la même carte. */
.blk {
  position: absolute;
  left: var(--x); top: var(--y); width: var(--w); height: var(--h);
  border-radius: 8px;
  background: #e7e7ee;
}
.blk--parc { background: #97cf5b; }
.blk--eau { background: #6fc6dc; border-radius: 40px; }

.pin {
  position: absolute;
  left: var(--x); top: var(--y);
  display: grid; place-items: center;
  width: 54px; height: 54px;
  border: 3px solid var(--s-ink);
  border-radius: 16px;
  background: var(--s-coral);
  box-shadow: 5px 5px 0 var(--s-ink);
  transform-origin: 50% 130%;
}
.pin::before { content: ""; position: absolute; inset: 6px; border-radius: 10px; background: #fff; }
.pin i { position: relative; z-index: 1; font-style: normal; font-size: 22px; line-height: 1; }
/* Une teinte par catégorie, reprises telles quelles de CATEGORIES dans
   src/theme/tokens.ts. Quatre profils différents plutôt qu'un seul public :
   quelqu'un qui va en concert, quelqu'un qui va au musée, quelqu'un qui
   sort dîner, quelqu'un qui visite. */
.pin--musique { --x: 12%; --y: 20%; background: #e54b5c; }
.pin--art     { --x: 74%; --y: 24%; background: #f5c842; }
.pin--resto   { --x: 44%; --y: 54%; background: #e84f2e; }
.pin--visite  { --x: 24%; --y: 68%; background: #6b8e7f; }

.here {
  position: absolute; left: 58%; top: 44%;
  width: 22px; height: 22px; border-radius: 999px;
  background: #2e8fe0; border: 4px solid #fff;
  box-shadow: 0 0 0 8px rgba(46, 143, 224, 0.22);
}

/* Réglette du temps : le motif du rail, agrandi et simplifié. */
.ruler { position: absolute; top: 7%; right: 0; bottom: 7%; width: 64px; }
.tk {
  position: absolute; right: 0; top: var(--y);
  width: var(--w); height: 5px; border-radius: 5px 0 0 5px;
  background: rgba(20, 20, 20, 0.28);
}
.tk--hot { background: var(--s-coral); }
.cursor {
  position: absolute; right: 0; top: 32%;
  display: grid; place-items: center;
  width: 44px; height: 44px;
  border: 3px solid var(--s-ink); border-right: 0;
  border-radius: 22px 0 0 22px;
  background: var(--s-yellow);
}
.cursor b {
  font-family: Anton, Impact, sans-serif; font-weight: 400; font-size: 20px;
  color: var(--s-ink);
}

/* ── Scène du héros : un écran qui se transforme ─────────────────────────── */
/*
 * Quatre états superposés au même endroit, dont un seul est visible. Pas
 * quatre vignettes alignées : Touquand ne fait pas quatre choses à la suite,
 * il en fait une seule, changer une affiche en sortie. Une transformation se
 * montre au même endroit, une succession se montre côte à côte.
 *
 * LE SENS EST DANS LA LISTE, pas dans le dessin. La scène est masquée aux
 * lecteurs d'écran et les quatre temps sont écrits en toutes lettres à côté,
 * donc la page se comprend entièrement sans une image d'animation.
 *
 * L'emphase de la ligne active passe par la GRAISSE et la COULEUR PLEINE,
 * jamais par l'opacité : atténuer les trois autres les ferait tomber sous le
 * seuil de contraste, et on ne rend pas trois lignes sur quatre illisibles
 * pour en souligner une.
 */
.scene--flux { width: min(100%, 880px); margin-inline: auto; }
.flux {
  display: grid;
  grid-template-columns: minmax(0, 296px) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: center;
  /* Le héros est centré, et la liste en héritait : lignes en drapeau des deux
     côtés, colonne de numéros alignée sur rien. Une énumération se lit à
     gauche, sans exception. */
  text-align: left;
}
.flux__stage { position: relative; aspect-ratio: 1 / 1.24; }

.flux__etat {
  position: absolute; inset: 0;
  opacity: 0; transform: scale(0.94);
  transition: opacity 420ms var(--ease), transform 420ms var(--ease);
}
/* AU REPOS, l'état final. Sans JavaScript, sans mouvement réduit, ou avant
   que la scène entre dans le champ : on voit la sortie enregistrée, c'est-à-
   dire la promesse tenue. Un état vide serait une page cassée. */
.flux__etat:last-child { opacity: 1; transform: none; }
/* Dès que le script pilote, il décide seul. */
.flux[data-pilote="1"] .flux__etat { opacity: 0; transform: scale(0.94); }
.flux[data-pilote="1"] .flux__etat[data-actif="1"] { opacity: 1; transform: none; }

/* L'écran : le langage Memphis de l'application, contour ink et ombre pleine
   décalée, à l'inverse des ombres floues du reste de la page. */
.ecran {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; gap: 9px;
  padding: 12px;
  border: 3px solid var(--s-ink);
  border-radius: 18px;
  background: #fff;
  box-shadow: 7px 7px 0 var(--s-ink);
}
.ecran__aplat { height: 42%; border-radius: 8px; background: var(--s-coral); }
.ecran__l { height: 8px; border-radius: 4px; background: rgba(20, 20, 20, 0.16); }
.ecran__l--titre { height: 12px; width: 76%; background: rgba(20, 20, 20, 0.34); }
.ecran__l--court { width: 54%; }

/* Le geste de partage, posé sur le coin de l'affiche et débordant du cadre :
   il n'appartient pas à l'affiche, il s'y applique. Aplat corail et encre
   par-dessus, comme partout ailleurs sur la marque. */
.geste {
  position: absolute; right: -16px; bottom: 30px;
  display: grid; place-items: center;
  width: 56px; height: 56px;
  border: 3px solid var(--s-ink); border-radius: 17px;
  background: var(--s-coral); color: var(--on-coral);
  box-shadow: 5px 5px 0 var(--s-ink);
}
.geste svg { width: 26px; height: 26px; display: block; }

/* L'affiche reste dessous, effacée mais présente : c'est la source, et c'est
   ce qui relie le temps 02 au temps 01. Un cadre blanc avec quatre pastilles
   flottantes ne disait pas d'où elles sortaient. */
.ecran--champs .ecran__aplat,
.ecran--champs .ecran__l { opacity: 0.22; }
.champs {
  position: absolute; inset: 12px;
  display: flex; flex-direction: column; justify-content: center;
  align-items: flex-start; gap: 10px;
}
.jeton {
  max-width: 100%;
  padding: 6px 13px;
  border: 2.5px solid var(--s-ink);
  border-radius: 999px;
  /* Blanc, pas crème : le beige est écarté de bout en bout sur ce site, y
     compris à la taille d'une pastille. Le contour ink suffit à la détacher
     de l'affiche estompée. */
  background: #fff;
  box-shadow: 3px 3px 0 var(--s-ink);
  font-size: 0.82rem; font-weight: 600; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.ecran--carte { padding: 9px; gap: 9px; }
.mini { position: relative; flex: 1; border-radius: 11px; background: #fff; overflow: hidden; }
.pin--flux {
  --x: 48%; --y: 26%;
  width: 34px; height: 34px; border-radius: 11px;
  background: var(--s-coral); box-shadow: 3px 3px 0 var(--s-ink);
}
.pin--flux::before { inset: 4px; border-radius: 6px; }
.ruler--mini { top: 6%; bottom: 6%; width: 34px; }
.cursor--mini { width: 26px; height: 26px; border-radius: 13px 0 0 13px; border-width: 2.5px; top: 30%; }
.cursor--mini b { font-size: 12px; }
.rappel {
  padding: 9px 11px;
  border: 3px solid var(--s-ink); border-radius: 11px;
  background: var(--s-yellow);
  font-size: 0.8rem; font-weight: 700; color: var(--ink);
  text-align: center;
}

/* Les quatre temps. Une liste ordonnée, parce que l'ordre porte une
   information : ils se suivent, ils ne se choisissent pas. */
.flux__temps { counter-reset: temps; display: flex; flex-direction: column; gap: 0.9rem; }
.temps {
  counter-increment: temps;
  position: relative; padding-left: 2.6rem;
  font-size: 1rem; line-height: 1.45; color: var(--fg-soft);
  transition: color 360ms var(--ease);
}
.temps::before {
  content: "0" counter(temps);
  position: absolute; left: 0; top: 0.02em;
  padding: 2px 6px; border-radius: 6px;
  font-family: Anton, Impact, sans-serif; font-size: 0.95rem;
  letter-spacing: 0.04em;
  color: var(--fg-soft);
  transition: color 360ms var(--ease), background-color 360ms var(--ease);
}
.temps b { font-weight: 600; color: var(--fg); }
/* Actif : ligne en couleur pleine, numéro en APLAT corail avec l'encre
   par-dessus. Le corail en texte sur du blanc ne donne que 3.8:1, mesuré —
   sous le seuil. En aplat, l'encre par-dessus donne 4.96:1, et c'est la règle
   de la charte : sur corail, le texte est toujours en encre pleine.
   Trois signaux, pas un seul : aplat, couleur du texte, graisse. Personne ne
   dépend de la perception d'une teinte. */
.flux[data-pilote="1"] .temps[data-actif="1"] { color: var(--fg); }
.flux[data-pilote="1"] .temps[data-actif="1"]::before {
  background: var(--coral); color: var(--on-coral);
}
.flux[data-pilote="1"] .temps[data-actif="1"] b { font-weight: 700; }

@media (max-width: 52rem) {
  .flux { grid-template-columns: 1fr; gap: 1.75rem; justify-items: center; }
  .flux__stage { width: min(100%, 260px); }
  .flux__temps { width: 100%; max-width: 30rem; }
}

/* ── Scène affiche : ce que Touquand en tire ─────────────────────────────── */
.panel__figure--stage {
  position: relative;
  display: grid; place-items: center;
  height: clamp(260px, 34vw, 360px);
  padding: 1.5rem;
  overflow: hidden;
  border-radius: var(--r-md);
  background: var(--surface-2);
  box-shadow: none;
}
.poster {
  position: relative;
  width: 132px; aspect-ratio: 3 / 4.2;
  padding: 12px;
  border: 3px solid var(--ink);
  border-radius: 10px;
  background: #fff;
  box-shadow: 6px 6px 0 var(--ink);
}
.poster__art { display: block; height: 46%; border-radius: 6px; background: #e54c5c; }
.poster__ln { display: block; height: 7px; margin-top: 10px; border-radius: 4px; background: var(--ink); }
.poster__ln--2 { width: 62%; }
.poster__tag {
  display: block; width: 42%; height: 14px; margin-top: 12px;
  border-radius: 4px; background: #f7c61c;
}

/* Les champs extraits sortent de l'affiche : c'est le geste du produit, dit
   par le mouvement plutôt que par une phrase. */
.out {
  position: absolute;
  padding: 0.5rem 0.85rem;
  border: 3px solid var(--ink); border-radius: 999px;
  background: #fff; color: var(--ink);
  box-shadow: 4px 4px 0 var(--ink);
  font-size: 0.82rem; font-weight: 600; white-space: nowrap;
}
.out--1 { top: 18%; right: 6%; }
.out--2 { top: 46%; left: 4%; }
.out--3 { bottom: 16%; right: 12%; background: var(--yellow); }

/* ── Scène rappel ────────────────────────────────────────────────────────── */
.scene--notif { width: min(100%, 340px); margin-inline: auto; }
.scene--notif .scene__inner {
  aspect-ratio: 1 / 1;
  background: #ffffff;
  box-shadow: var(--lift-lg);
  outline: 1px solid var(--hairline);
  outline-offset: -1px;
}
.scene--notif .pin--n1 { --x: 30%; --y: 30%; width: 46px; height: 46px; }
.scene--notif .pin--n1 i { font-size: 17px; }
.here--n { left: 56%; top: 58%; }

.alerte {
  position: absolute; left: -6%; right: -6%; top: 6%;
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px;
  border: 3px solid var(--ink); border-radius: 16px;
  background: #fff; color: var(--ink);
  box-shadow: 6px 6px 0 var(--ink);
  text-align: left;
}
.alerte img { flex: none; width: 30px; height: 30px; border-radius: 7px; }
.alerte b { display: block; font-size: 0.88rem; }
.alerte span { display: block; font-size: 0.8rem; line-height: 1.3; color: rgba(20, 20, 20, 0.7); }

/* ── Mouvement ───────────────────────────────────────────────────────────── */
/* Les animations ne s'appliquent QUE pendant que la scène joue : l'état au
   repos est l'état normal, donc rien ne disparaît si le JavaScript ne tourne
   pas. Le contenu ne doit jamais dépendre d'une animation. */
@media (prefers-reduced-motion: no-preference) {
  /* Les sorties se posent une à une : le geste que la page promet. */
  .is-playing .pin { animation: drop 720ms var(--ease) backwards; }
  .is-playing .pin--musique { animation-delay: 160ms; }
  .is-playing .pin--art     { animation-delay: 380ms; }
  .is-playing .pin--resto   { animation-delay: 600ms; }
  .is-playing .pin--visite  { animation-delay: 820ms; }
  @keyframes drop {
    from { opacity: 0; transform: translateY(-34px) scale(.5); }
    60%  { opacity: 1; transform: translateY(0) scale(1.14); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
  }

  /* La réglette parcourt le temps : sans ce mouvement, on ne comprend pas à
     quoi sert la colonne de droite. */
  .is-playing .cursor { animation: glisse 9s var(--ease) 1.2s infinite; }
  @keyframes glisse {
    0%, 14%  { top: 32%; }
    40%, 54% { top: 64%; }
    78%, 90% { top: 12%; }
    100%     { top: 32%; }
  }
  /* Les graduations denses respirent : elles disent « il y a des sorties ce
     jour-là », leur rôle exact dans l'application. */
  .is-playing .tk--hot { animation: souffle 9s ease-in-out 1.2s infinite; }
  @keyframes souffle { 0%, 100% { opacity: .5; } 45% { opacity: 1; } }

  /* Les champs sortent de l'affiche, l'un après l'autre. */
  .is-playing .out { animation: sortie 620ms var(--ease) backwards; }
  .is-playing .out--1 { animation-delay: 260ms; }
  .is-playing .out--2 { animation-delay: 460ms; }
  .is-playing .out--3 { animation-delay: 660ms; }
  @keyframes sortie {
    from { opacity: 0; transform: translate(-18px, 10px) scale(.86); }
    to   { opacity: 1; transform: none; }
  }

  /* Le rappel arrive, reste le temps d'être lu, repart. */
  .is-playing .alerte { animation: rappel 7s var(--ease) 500ms infinite; }
  @keyframes rappel {
    0%        { opacity: 0; transform: translateY(-34px); }
    9%, 62%   { opacity: 1; transform: translateY(0); }
    74%, 100% { opacity: 0; transform: translateY(-34px); }
  }
}

/* ── Mise en page des blocs qui portent une scène ────────────────────────── */
.remind { display: grid; gap: clamp(2rem, 5vw, 3.5rem); align-items: center; }
@media (min-width: 56rem) { .remind { grid-template-columns: 1fr 0.62fr; } }
.remind__device { display: grid; justify-items: center; }
