/*
 * Primowise — feuille de style unique (primowise.com + /postule)
 * V5-CONTRAT.md (16/10/2026) : refonte épurée. Repartie d'une feuille propre (l'ancienne
 * version, 2686 lignes, patchait trop de variantes abandonnées). Conserve ce qui sert aux
 * AUTRES pages du site (accueil, mentions, confidentialité, désinscription, erreur) :
 * .skip-link, .sr-only, .nowrap, .site-header, .wordmark, .wm-primo, .wm-wise, .crumb*,
 * .container, .btn*, .site-footer, .footer-links, .annexe, .legal, .home*, .sticky-cta.
 * Aucune ressource externe. Compatible CSP style-src 'self' (pas de style="" dans le HTML ;
 * les ajustements dynamiques de la démo passent par element.style en JS, jamais par du CSS
 * injecté). Graisses 400 et 600 SEULEMENT (V5-CONTRAT §1).
 */

/* ---------- Polices auto-hébergées (OFL 1.1), V5.2 (lot B, V52-CONTRAT.md §1) ----------
 * Bricolage Grotesque (titres) : @fontsource-variable/bricolage-grotesque 5.3.0, fichier
 * variable latin (axes wght 200-800 + opsz). « woff2-variations » déclaré en premier pour les
 * navigateurs qui le reconnaissent, « woff2 » en repli (même fichier : un conteneur woff2
 * variable reste un woff2 valide). Nunito (texte courant + interface) : @fontsource-variable/nunito
 * 5.2.7, fichier variable latin (axe wght 200-1000). Figtree RETIRÉE (jamais 3 familles).
 * Licences : public/assets/fonts/LICENSE-OFL.txt. unicode-range latin reprise des CSS
 * fontsource (bg/package/opsz.css, nunito/wght.css). */
@font-face {
  font-family: "Bricolage Grotesque";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("/assets/fonts/bricolage-grotesque-latin-opsz-normal.woff2") format("woff2-variations"),
       url("/assets/fonts/bricolage-grotesque-latin-opsz-normal.woff2") format("woff2");
  font-optical-sizing: auto;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
    U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Nunito";
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url("/assets/fonts/nunito-latin-wght-normal.woff2") format("woff2-variations"),
       url("/assets/fonts/nunito-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
    U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- Tokens (V5-CONTRAT §1) ---------- */
:root {
  --ink: #14213D;
  --ink-rgb: 20 33 61;
  --paper: #FAFAF7;
  --white: #FFFFFF;
  --signal: #2660E0;        /* RÉSERVÉ : .btn-primary / .btn-cta / sticky + focus clavier */
  --signal-dark: #1B4BB4;
  --signal-rgb: 38 96 224;        /* V53B-CONTRAT.md §2 */
  --confirm: #257A4B;       /* RÉSERVÉ : coche/état « Envoyée » de la démo (.demo-sent*/.demo-done) */
  --confirm-rgb: 37 122 75;
  --alert: #C53030;         /* erreurs de formulaire uniquement */
  --line: #8A8A84;          /* bordures de champs (fonctionnelles, contraste >= 3:1) */
  --line-soft: #C7CAD0;     /* Ink 24 % sur blanc : contour des pastilles à libellé visible (W3C SC 1.4.11 « Boundaries », DA V5.4 l.35) */
  --offer-bg: #E9EFFC;      /* Signal 10 % sur blanc, en aplat : fond de l'encart d'offre (DA ★ V5.6 §3) */
  --mist: #E4E4DE;          /* séparateurs fins, jamais un fond décoratif */
  --ink-secondary: rgb(var(--ink-rgb) / 0.72); /* texte secondaire, contraste >= 4.5:1 sur Paper */
  --ink-text: rgb(var(--ink-rgb) / 0.80);      /* paragraphes de section, Nunito (V52-CONTRAT §1) */

  --ease: cubic-bezier(0.16, 1, 0.3, 1);

  --radius-field: 12px;
  --radius-window: 20px;
  --radius-pill: 999px;
  --shadow-demo: 0 1px 2px rgba(20, 33, 61, .06), 0 16px 40px rgba(20, 33, 61, .10);

  --container: 76rem;       /* 1216 px (V5.1 : scène du hero à taille réelle, même grille partout) */
  --side: 3rem;             /* 48 px — marge latérale ordinateur */
  --side-mobile: 1.5rem;    /* 24 px — marge latérale mobile */
  --section-y: 8rem;        /* 128 px — marge de section ordinateur */
  --curve: 32px;            /* courbe de transition entre sections, V53-CONTRAT.md §3 */

  --font: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-title: "Bricolage Grotesque", "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

@media (max-width: 47.99em) {
  :root {
    --section-y: 4.5rem;    /* 72 px — marge de section mobile */
    --curve: 20px;          /* courbe de transition entre sections, mobile */
  }
}

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

[hidden] {
  display: none !important;
}

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

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: 1.0625rem; /* 17 px mobile */
  font-weight: 400;
  line-height: 1.6;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  /* Filet de sécurité héritable (point 9) : à 200 % de zoom texte, un mot long (titres courts
     à police élevée, ex. « professionnelle ») peut dépasser son conteneur sans jamais casser
     normalement ; cette règle ne change rien en usage normal (elle ne s'applique qu'en dernier
     recours, quand il n'y a aucun autre endroit où couper la ligne). */
  overflow-wrap: break-word;
}

@media (min-width: 48em) {
  body {
    font-size: 1.125rem; /* 18 px ordinateur */
  }
}

main {
  flex: 1 0 auto;
}

h1, h2, h3 {
  color: var(--ink);
  font-family: var(--font-title);
  font-weight: 700;
  font-optical-sizing: auto;
  letter-spacing: -0.02em;
  text-wrap: balance; /* évite un dernier mot seul sur sa ligne (ex. « jours. ») */
  margin: 0 0 0.6em;
}

h1 {
  font-size: 2.375rem; /* 38 px mobile */
  line-height: 1.05;
}

h2 {
  font-size: 1.75rem; /* 28 px mobile */
  line-height: 1.1;
}

h3 {
  font-size: 1.1875rem;
  line-height: 1.3;
}

@media (min-width: 48em) {
  h1 {
    font-size: 4rem; /* 64 px */
  }
  h2 {
    font-size: 2.5rem; /* 40 px */
  }
}

p {
  margin: 0 0 1em;
}

a {
  color: var(--ink);
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}

a:hover {
  text-decoration-thickness: 2px;
}

:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

strong {
  font-weight: 600;
}

.small {
  font-size: 0.875rem; /* 14 px, les deux gabarits */
  line-height: 1.5;
}

.small,
small {
  color: var(--ink-secondary);
}

.nowrap {
  white-space: nowrap;
}

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

.skip-link {
  position: absolute;
  left: 1rem;
  top: -10rem;
  z-index: 100;
  background: var(--white);
  color: var(--ink);
  padding: 0.75rem 1rem;
  border-radius: var(--radius-field);
  font-weight: 600;
}

.skip-link:focus {
  top: 1rem;
}

/* ---------- Conteneur (1120 px max, marges 48 / 24 px) ---------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--side-mobile);
}

@media (min-width: 48em) {
  .container {
    padding: 0 var(--side);
  }
}

/* ---------- En-tête ---------- */
.site-header {
  padding: 1.5rem 0;
}

.site-header .container {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.5rem 1rem;
}

.wordmark {
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
  text-decoration: none;
  display: inline-block;
}

.wordmark:hover {
  text-decoration: none;
}

/* V5-CONTRAT §1 : wordmark entièrement Ink, plus de "wise" Signal */
.wm-primo,
.wm-wise {
  color: var(--ink);
}

.header-status {
  margin: 0;
  font-size: 0.875rem; /* 14 px */
  color: var(--ink-secondary);
}

/* Fil d'Ariane des pages annexes (mentions, confidentialité, désinscription, erreur) */
.crumb {
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink);
}

.crumb a,
.crumb-current {
  color: var(--ink);
}

.crumb-sep {
  color: var(--ink);
  margin-right: 0.25rem;
}

/* ---------- Boutons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 3rem;
  padding: 14px 24px;
  border-radius: var(--radius-pill);
  font-family: inherit;
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  border: 1.5px solid transparent;
}

.btn:hover {
  text-decoration: none;
}

.btn-primary {
  background: var(--signal);
  color: var(--white);
  border-color: var(--signal);
}

.btn-primary:hover {
  background: var(--signal-dark);
  border-color: var(--signal-dark);
  color: var(--white);
}

.btn-primary:disabled,
.btn-primary[aria-busy="true"] {
  cursor: progress;
}

.btn-ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--ink);
}

.btn-lg {
  min-height: 3.5rem;
  padding: 16px 32px;
  font-size: 1.125rem;
}

@media (max-width: 37.4375em) {
  .hero .btn {
    width: 100%;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .btn {
    transition: background-color 0.2s var(--ease), border-color 0.2s var(--ease);
  }
}

/* ---------- Sections (marges 128 px / 72 px, identiques partout, hero compris ;
   transitions en courbe + alternance de fonds, V53-CONTRAT.md §3) ---------- */
.section,
.hero {
  padding: var(--section-y) 0;
  background: var(--paper); /* fond explicite requis par le background: inherit de la courbe */
}

.tone-white {
  background: var(--white);
}

/* section précédée d'une section : on redonne à la courbe qui déborde dessus la place qu'elle prend */
.section + .section,
.hero + .section {
  padding-top: calc(var(--section-y) + var(--curve));
}

/* Courbe : le bas de chaque section de <main> déborde en arc large et bas dans la section
   suivante (y compris le CTA Signal -> pied de page Paper). Rien d'animé, rien lié au scroll,
   aucun dégradé ni ombre. ::after a un z-index explicite alors que la section reste en
   z-index: auto : la courbe « s'échappe » dans le contexte d'empilement commun des sections
   et se peint donc au-dessus de la section suivante plutôt que d'être recouverte par elle. */
main > section {
  position: relative;
}

main > section::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(-1 * var(--curve));
  height: var(--curve);
  background: inherit;
  border-radius: 0 0 50% 50% / 0 0 100% 100%;
  z-index: 1;
  pointer-events: none;
}

/* ---------- Hero ---------- */
.hero {
  overflow-x: clip; /* le halo flou ne crée jamais de défilement horizontal */
}

.hero-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 3rem;
}

.hero-grid > * {
  min-width: 0; /* zoom 200 % : aucune colonne du hero n'impose sa largeur minimale */
}

@media (min-width: 64em) {
  .hero {
    min-height: 45rem; /* ~720 px, ~1 écran */
    display: flex;
    align-items: center;
  }

  .hero-grid {
    width: 100%;
  }
}

/* V53B-CONTRAT.md §5a : vide legende -> bas du hero ramené à 80 px (padding 128 + reste du
   min-height) à ≥64em. */
@media (min-width: 64em) {
  .hero {
    padding-bottom: 5rem;
  }
}

/* Deux colonnes seulement quand la scène (38,5 rem = 616 px) tient à côté du titre :
   en dessous, titre puis appareils centrés (mesures réelles, V5.1). */
@media (min-width: 80em) {
  .hero-grid {
    grid-template-columns: minmax(0, 1fr) 40rem;
    align-items: center;
    column-gap: 4rem;
  }
}

.hero-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2.5rem;
}

.hero-text h1 {
  margin: 0;
  max-width: 11em;
}

/* V5.6 (DA ★ V5.6 §1) : bouton seul pleine largeur du bloc (descend au formulaire du bas) + encart d'offre
   dessous ; bloc max 384 px (garde l'air avec le socle de la démo). */
.hero-cta {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 1rem;
  width: 100%;
  max-width: 24rem;
}

.hero-cta .btn-cta {
  width: 100%;
  min-height: 3.25rem;
}

/* ---------- Démo (hero, décorative : aria-hidden) — V51-CONTRAT §2/§5bis ----------
 * Ordinateur portable (écran 16:10) + smartphone (9:19) dessinés en CSS (principe des device
 * mockups Flowbite, MIT, HTML/CSS réécrits). Le téléphone est posé devant le portable, en bas
 * à droite ; le formulaire de l'écran s'arrête 16 px avant lui (largeurs de texte mesurées en
 * Figtree, pas estimées) : il ne recouvre jamais un texte. */
.demo {
  position: relative;
  margin: 0;
}

@media (min-width: 48em) {
  .demo {
    width: 40rem; /* 640 px */
    max-width: 100%;
    margin: 0 auto;
  }
}

/* Halo d'accent (relecture marketing V5.1 n°6, recentré V52-CONTRAT §2) : Signal 18 %, flou 80 px,
   centré AU MILIEU entre le portable et le téléphone (mesuré : centre portable x≈17,5rem/y≈12,4rem,
   centre téléphone x≈32,9rem/y≈13,9rem dans le repère de .demo, milieu ≈ 63 % / 42,4 %). Taille réduite
   (30rem x 26rem) pour ne jamais être coupé par le bord droit de la fenêtre à 1440 et 1280 px (mesuré :
   bord droit du halo à ~1195 px sur 1280 et ~1276 px sur 1440, marge avant flou). Couleur unie, pas de dégradé. */
.demo-halo {
  position: absolute;
  top: 42.4%;
  left: 63%;
  width: 30rem;
  height: 26rem;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: rgb(38 96 224 / 0.18);
  filter: blur(80px);
  z-index: 0;
  pointer-events: none;
}

.demo-stage {
  position: relative;
  z-index: 1;
  padding-bottom: 5rem; /* le téléphone descend de ~80 px sous le socle du portable */
}

/* ---- Ordinateur portable ---- */
.device-laptop {
  position: relative;
  z-index: 1;
  width: 35rem; /* 560 px : écran 536 x 335 (16:10) */
  max-width: 100%;
  filter: drop-shadow(0 18px 22px rgb(var(--ink-rgb) / 0.14));
}

.laptop-lid {
  position: relative;
  background: var(--ink);
  border-radius: 20px 20px 4px 4px;
  padding: 14px 12px 12px;
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.08), 0 2px 4px rgb(var(--ink-rgb) / 0.10),
    0 24px 48px rgb(var(--ink-rgb) / 0.16);
}

/* caméra */
.laptop-lid::before {
  content: "";
  position: absolute;
  top: 4px;
  left: 50%;
  width: 6px;
  height: 6px;
  margin-left: -3px;
  border-radius: 50%;
  background: rgb(250 250 247 / 0.40);
}

.laptop-screen.demo-window {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--white);
  border-radius: 8px;
  padding: 1rem 1.25rem;
}

/* Charnière (relecture marketing V5.1 n°4) : bande Ink 4 px plus sombre sous l'écran. */
.laptop-lid::after {
  content: "";
  position: absolute;
  left: 6%;
  right: 6%;
  bottom: -4px;
  height: 4px;
  background: var(--ink);
  box-shadow: inset 0 0 0 4px rgb(0 0 0 / 0.35);
  border-radius: 0 0 3px 3px;
}

/* Base en trapèze (arrière étroit, avant plus large que l'écran) : 2 tons Ink 16 % / bord avant
   Ink 32 % pour l'épaisseur, encoche centrale. Le contrat V5 interdit les dégradés : pas de
   linear-gradient (la demande « dégradé Mist -> Line » est rendue par ces 2 tons). */
.laptop-base {
  position: relative;
  height: 20px;
  margin: 4px -3rem 0;
  background: rgb(var(--ink-rgb) / 0.16);
  border-bottom: 6px solid rgb(var(--ink-rgb) / 0.32);
  border-radius: 0 0 14px 14px;
  clip-path: polygon(7% 0, 93% 0, 100% 100%, 0 100%);
}

.laptop-base::after {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 4.5rem;
  height: 6px;
  margin-left: -2.25rem;
  background: rgb(var(--ink-rgb) / 0.28);
  border-radius: 0 0 6px 6px;
}

.demo-bar {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  margin: 0 0 0.875rem;
}

.demo-dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgb(var(--ink-rgb) / 0.22);
}

.demo-bar-text {
  margin-left: 0.5rem;
  font-size: 0.875rem;
  color: var(--ink-secondary);
  white-space: nowrap; /* 259 px mesurés : tient en entier, jamais d'ellipse */
}

.demo-job {
  width: fit-content; /* boîte = texte : jamais sous le téléphone (mesuré) */
  max-width: 22.75rem;
  margin: 0 0 0.875rem;
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.35;
}

/* Formulaire : une ligne par champ (libellé | champ), 24 rem de large = s'arrête 16 px avant
   le téléphone. */
.demo-form {
  width: 22.75rem; /* 364 px : s arrête 16 px avant le téléphone (mesuré) */
  max-width: 100%;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}

.demo-field {
  display: grid;
  grid-template-columns: 9.75rem minmax(0, 1fr); /* « Disponible rapidement ? » = 151 px mesurés */
  align-items: center;
  column-gap: 0.625rem;
  margin: 0;
}

.demo-label {
  font-size: 0.875rem;
  line-height: 1.3;
  color: var(--ink-secondary);
}

.demo-input {
  display: flex;
  align-items: center;
  min-height: 2.25rem;
  padding: 0 0.75rem;
  border: 1px solid rgb(var(--ink-rgb) / 0.22);
  border-radius: var(--radius-field);
  background: var(--white);
}

.demo-value {
  font-size: 0.875rem;
  font-weight: 600;
  white-space: nowrap;
}

.demo-send {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.25rem;
  padding: 0.4rem 1.25rem;
  margin-top: 0.25rem;
  border-radius: var(--radius-pill);
  background: var(--ink);
  color: var(--white);
  font-size: 0.9375rem;
  font-weight: 600;
  box-shadow: 0 2px 4px rgb(var(--ink-rgb) / 0.18);
}

/* Bouton « Envoyer » qui s'enfonce au clic (V52-CONTRAT §2, 150 ms, piloté par demo.js via classe
   posée/retirée selon t : déterministe pour data-demo-seek, pas de transition nécessaire). */
.demo-send.is-pressed {
  transform: scale(0.92) translateY(1px);
  background: rgb(var(--ink-rgb) / 0.68);
  box-shadow: 0 0 0 rgb(var(--ink-rgb) / 0);
}

/* Correction DA V5.7 (16/10) : le formulaire rempli reste visible (champs à 60 % d'opacité),
   seul le bouton « Envoyer » est remplacé par le message d'envoi, au même endroit. */
/* Relecture marketing V5.1 n°6 : les libellés restent en Ink 72 % pleins ; seul le champ rempli
   s'estompe après l'envoi. */
.demo-form.is-sent .demo-input {
  opacity: 0.6;
}

.demo-label {
  color: var(--ink-secondary);
}

.demo-sent {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.25rem;
}

.demo-sent[hidden] {
  display: none;
}

.demo-sent-check {
  flex: none;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--confirm);
  position: relative;
}

.demo-sent-check::after {
  content: "";
  position: absolute;
  left: 0.6rem;
  top: 0.62rem;
  width: 0.8rem;
  height: 0.42rem;
  border-left: 3px solid var(--white);
  border-bottom: 3px solid var(--white);
  transform: rotate(-45deg);
}

.demo-sent-text {
  font-weight: 600;
  color: var(--confirm);
  white-space: nowrap; /* « Candidature envoyée » sur une seule ligne (relecture marketing 16/10) */
}

/* Curseur réel (V52-CONTRAT §2) : position et échelle posées UNIQUEMENT via JS (CSSOM,
 * transform: translate(...) scale(...)), jamais top/left ni transition CSS — le mouvement est
 * recalculé à chaque image par demo.js (déterministe pour data-demo-seek). Trois SVG superposés
 * en haut à gauche du span ; seul celui qui correspond à [data-cursor] est affiché. */
.demo-cursor {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  pointer-events: none;
  z-index: 3;
}

.demo-cursor svg {
  position: absolute;
  top: 0;
  left: 0;
  display: none;
  overflow: visible;
  filter: drop-shadow(0 1px 1.5px rgb(var(--ink-rgb) / 0.35)); /* relief d'un vrai curseur système */
}

.demo-cursor[data-cursor="arrow"] svg.cursor-arrow,
.demo-cursor[data-cursor="text"] svg.cursor-text,
.demo-cursor[data-cursor="hand"] svg.cursor-hand {
  display: block;
}

/* Onde de clic (V52-CONTRAT §2) : cercle Signal 20 %, 0 -> 36 px, opacité 1 -> 0 en 450 ms, posé
 * au point chaud. Taille et opacité pilotées image par image par demo.js (transform + opacity),
 * déterministe pour data-demo-seek : pas d'animation/transition CSS ici. */
.demo-ripple {
  position: absolute;
  top: 0;
  left: 0;
  width: 44px;
  height: 44px;
  margin: -22px 0 0 -22px;
  border-radius: 50%;
  background: rgb(38 96 224 / 0.2);
  border: 2px solid rgb(38 96 224 / 0.55); /* anneau : l'onde reste visible sur le bouton Ink */
  pointer-events: none;
  opacity: 0;
  z-index: 2;
}

/* ---- Smartphone (9:19), posé devant le portable, en bas à droite ---- */
.device-phone.demo-phone {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 2;
  width: 14.25rem; /* 228 px : zone texte 184 px, postes sur 1 ligne (176 px mesurés max) */
  /* boutons latéraux (pseudo-éléments) : à gauche ils seraient posés sur l'écran du portable,
     on ne garde donc que le bouton de droite en ordinateur (revue d'image V5.1). */
  aspect-ratio: 9 / 17.5; /* 228 x 443 : silhouette smartphone, écran rempli par 4 offres (mesuré) */
  background: var(--ink);
  border-radius: 34px;
  padding: 8px;
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.10), 0 4px 8px rgb(var(--ink-rgb) / 0.14),
    0 28px 56px rgb(var(--ink-rgb) / 0.26);
}

/* boutons latéraux (volume à gauche, marche à droite) */
.device-phone.demo-phone::before,
.device-phone.demo-phone::after {
  content: "";
  position: absolute;
  width: 3px;
  background: var(--ink);
}

.device-phone.demo-phone::before {
  left: -3px;
  top: 20%;
  height: 7%;
  box-shadow: 0 2.25rem 0 var(--ink); /* 2 boutons de volume */
  border-radius: 2px 0 0 2px;
}

@media (min-width: 48em) {
  .device-phone.demo-phone::before {
    display: none; /* posé sur l'écran du portable : trait parasite (revue d'image V5.1) */
  }
}

.device-phone.demo-phone::after {
  right: -3px;
  top: 28%;
  height: 16%;
  border-radius: 0 2px 2px 0;
}

/* îlot (« dynamic island ») en haut de l'écran */
.phone-island {
  position: absolute;
  top: 16px;
  left: 50%;
  width: 3.5rem;
  height: 1rem;
  margin-left: -1.75rem;
  border-radius: 999px;
  background: var(--ink);
  z-index: 1;
}

.phone-screen {
  position: relative;
  height: 100%;
  background: var(--white);
  border-radius: 26px;
  overflow: hidden;
  padding: 2.25rem 0.875rem 1.5rem;
}

/* barre d'accueil */
.phone-screen::after {
  content: "";
  position: absolute;
  bottom: 8px;
  left: 50%;
  width: 4rem;
  height: 4px;
  margin-left: -2rem;
  border-radius: 999px;
  background: rgb(var(--ink-rgb) / 0.25);
}

.demo-phone-today {
  margin: 0 0 0.125rem;
  font-size: 0.875rem;
  color: var(--ink-secondary);
}

.demo-phone-title {
  margin: 0 0 0.875rem;
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.25;
}

.demo-phone-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.demo-phone-row {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--mist);
}

.demo-phone-row.is-off,
.demo-job.is-off {
  opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
  .demo-phone-row,
  .demo-job {
    transition: opacity 0.3s var(--ease);
  }
}

.demo-phone-job {
  min-width: 0;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.3;
  text-wrap: pretty;
  overflow-wrap: normal; /* relecture marketing 16/10 : jamais de mot coupé */
  hyphens: none;
}

.demo-phone-status {
  font-size: 0.875rem;
  line-height: 1.3;
  color: var(--ink-secondary);
}

/* Ligne 2 du téléphone = « Ville · état » : ville Ink 72 % 400, état dans sa couleur */
.demo-phone-city {
  font-weight: 400;
  color: var(--ink-secondary);
}

.demo-done {
  color: var(--confirm);
  font-weight: 600;
}

/* Flottement lent des 2 appareils (décalé), seulement en mouvement autorisé, arrêté quand la
   lecture unique est terminée (.is-ended) — V51-CONTRAT §2, arbitrage orchestrateur 16/10. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes device-float-laptop {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-3px); }
  }

  @keyframes device-float-phone {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-3px); }
  }

  .device-laptop {
    animation: device-float-laptop 7s ease-in-out infinite;
  }

  .device-phone.demo-phone {
    animation: device-float-phone 6s ease-in-out infinite;
    animation-delay: -2.5s; /* décalé par rapport au portable */
  }

  .demo.is-ended .device-laptop,
  .demo.is-ended .device-phone.demo-phone {
    animation-play-state: paused;
  }
}

@media (max-width: 47.99em) {
  /* Relecture marketing V5.1 n°5 : 48 px entre l'en-tête et le titre (au lieu de ~110),
     pour montrer plus de téléphone au 1er écran. Les autres sections gardent 72 px. */
  .hero {
    padding-top: 3rem; /* 48 px mesurés entre en-tête et titre */
  }

  .device-laptop {
    display: none;
  }

  .demo-stage {
    padding-bottom: 0;
  }

  .demo-halo {
    left: 50%;
    width: 90%;
    height: 80%;
    top: 50%;
  }

  .device-phone.demo-phone {
    position: relative;
    width: min(232px, 64vw);
    max-width: 100%;
    aspect-ratio: 9 / 16.5; /* écran rempli sans grand vide en bas (mesuré) */
    margin: 0 auto;
  }

  .phone-screen {
    padding-top: 2.5rem;
  }

  .demo-phone-list {
    gap: 0.875rem;
  }
}

.demo-caption {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem 0.75rem;
  margin: 1.5rem 0 0;
  text-align: center;
}

/* ---------- Comment ça marche — frise verticale (V53-CONTRAT.md §2) ----------
 * Verticale à TOUTES les largeurs : colonne gauche 56 px (pastille), ligne centrée sur les
 * pastilles (piste Mist = .steps::before, remplissage Signal = .steps::after, scaleY(--fill)).
 * >= 64em : 2 colonnes (titre + note centrés verticalement face à la frise, max 40rem, pas de
 * sticky). État par défaut (sans JS, reduced-motion) = ligne pleine ET pastilles allumées : le
 * CSS ne montre l'état « éteint » que sous html.anim (posé par anim.js seulement si no-preference). */
.steps-layout {
  display: grid;
  gap: 2rem;
}

.steps-head {
  margin: 0;
}

.steps-note {
  margin-top: 1.25rem;
}

@media (min-width: 64em) {
  .steps-layout {
    grid-template-columns: minmax(0, 20rem) minmax(0, 40rem);
    column-gap: 4rem;
    align-items: center; /* titre + note centrés verticalement face à la frise (V53-CONTRAT.md §2) */
  }
}

.steps {
  position: relative;
  list-style: none;
  margin: 3rem 0 0;
  padding: 0;
  max-width: 40rem;
}

@media (min-width: 64em) {
  .steps {
    margin-top: 0;
  }
}

/* piste (Mist) + remplissage (Signal) : centrés dans la colonne de 3.5rem des pastilles */
.steps::before,
.steps::after {
  content: "";
  position: absolute;
  left: 1.75rem;
  top: 1.75rem;
  bottom: 1.75rem;
  width: 2px;
  margin-left: -1px;
}

.steps::before {
  /* trait fin Mist (bordure, jamais un fond gris : DA v3.1) */
  width: 0;
  margin-left: -1px;
  border-left: 2px solid var(--mist);
}

.steps::after {
  background: var(--signal);
  transform: scaleY(var(--fill, 1));
  transform-origin: top;
}

.step {
  position: relative;
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr);
  column-gap: 1.25rem;
  padding-bottom: 2rem;
}

.step:last-child {
  padding-bottom: 0;
}

.step-icon {
  grid-row: 1 / span 3;
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 50%;
  background: var(--signal); /* par défaut (sans JS / reduced-motion) : pastille allumée */
  color: var(--white);
}

@media (prefers-reduced-motion: no-preference) {
  html.anim .step-icon {
    background: rgb(38 96 224 / 0.10);
    color: var(--signal);
    transition: background-color 0.3s var(--ease), color 0.3s var(--ease);
  }

  html.anim .step.is-lit .step-icon {
    background: var(--signal);
    color: var(--white);
  }
}

.step-icon svg,
.keep-icon svg,
.never-icon svg {
  display: block;
}

.step-num {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-secondary);
  margin: 0.125rem 0 0.25rem;
}

.step h3 {
  margin-bottom: 0.35em;
  text-wrap: balance;
}

.step p {
  margin: 0;
  color: var(--ink-text);
  text-wrap: pretty;
}

/* ---------- Ce que vous gardez en main — bento (DA V5.2, V52-CONTRAT.md §4) ----------
 * 1 grande carte (2 colonnes x 2 rangées) + 2 petites empilées à droite, >= 48em. Mobile :
 * empilées, la grande en premier (déjà l'ordre du HTML : auto-placement en grille). */
.keep {
  list-style: none;
  margin: 3rem 0 0;
  padding: 0;
  display: grid;
  gap: 1.5rem;
}

@media (min-width: 48em) {
  .keep.keep-bento {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: repeat(2, minmax(0, auto));
  }

  .keep-card-big {
    grid-column: 1 / span 2;
    grid-row: 1 / span 2;
  }
}

.keep-card {
  min-width: 0;
  width: 100%;
  box-sizing: border-box;
  background: var(--white);
  border: 1px solid var(--mist);
  border-radius: 16px;
  padding: 2rem;
}

@media (max-width: 47.99em) {
  .keep-card {
    padding: 1.5rem;
  }
}

.keep-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: 12px;
  background: rgb(38 96 224 / 0.10);
  color: var(--signal);
  margin-bottom: 1.25rem;
}

.keep-card h3 {
  margin-bottom: 0.35em;
  text-wrap: balance;
}

.keep-card p {
  margin: 0;
  color: var(--ink-text);
  text-wrap: pretty;
}

/* mini-liste fictive décorative (carte « Vue complète »), Nunito 14 px, Ink 72 % */
.keep-card-big {
  display: flex;
  flex-direction: column;
}

.keep-mini {
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

@media (min-width: 48em) {
  .keep-card-big .keep-mini {
    /* V53B-CONTRAT.md §5b : plus de margin-top:auto ; l'éventuel vide tombe sous la note */
    padding-top: 1.5rem;
  }
}

.keep-mini li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.375rem 0.75rem;
  padding: 0.875rem 0;
  border-top: 1px solid var(--mist);
  font-size: 0.9375rem;
  line-height: 1.4;
  color: var(--ink-text);
}

.keep-mini li:last-child {
  border-bottom: 1px solid var(--mist);
}

/* Liste fictive fixe : la 3e ligne est « Réponse reçue » -> pastille teintée (Signal 10 %, texte Ink) */
.keep-mini li:last-child span:last-child {
  background: rgb(38 96 224 / 0.10);
  border-color: transparent;
}

.keep-mini li span:first-child {
  min-width: 0;
}

.keep-mini li span:last-child {
  flex: none;
  padding: 0.125rem 0.625rem;
  border: 1px solid var(--mist);
  border-radius: var(--radius-pill);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}

.keep-mini-note {
  margin-top: 0.75rem;
}

@media (hover: hover) {
  .keep-card {
    transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
  }

  .keep-card:hover {
    border-color: var(--signal);
    box-shadow: 0 1px 2px rgb(var(--ink-rgb) / 0.06), 0 12px 28px rgb(var(--ink-rgb) / 0.10);
  }
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .keep-card {
    transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease), transform 0.2s var(--ease);
  }

  .keep-card:hover {
    transform: translateY(-2px);
  }
}

/* ---------- Section honnêteté — réécrite en POSITIF (V52-CONTRAT.md §5) ----------
 * Plus de croix ni d'Alert (ce ne sont plus des refus) : icônes Signal sur pastille Signal 10 %.
 * < 40em (640 px) : pastille 32 px AU-DESSUS du titre, texte pleine largeur (relecture V5.1 n°4).
 * >= 40em : pastille à gauche (grille 2,5rem + texte). */
.honest-intro {
  margin: 1.5rem 0 0;
  font-weight: 600;
  color: var(--ink);
}

.never {
  list-style: none;
  margin: 2rem 0 0;
  padding: 0;
  display: grid;
  gap: 1.5rem;
}

@media (min-width: 48em) {
  .never {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.never-card {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  min-width: 0;
  width: 100%;
  box-sizing: border-box;
  background: var(--white);
  border: 1px solid var(--mist);
  border-radius: 16px;
  padding: 1.75rem 1.5rem;
}

@media (min-width: 40em) {
  .never-card {
    display: grid;
    grid-template-columns: 2.5rem minmax(0, 1fr);
    column-gap: 1rem;
    align-items: start;
  }
}

@media (min-width: 48em) {
  .never-card {
    padding: 2rem;
  }
}

.never-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: rgb(38 96 224 / 0.10);
  color: var(--signal);
}

@media (min-width: 40em) {
  .never-icon {
    grid-row: 1 / span 2;
    width: 2.5rem;
    height: 2.5rem;
  }
}

.never-card h3 {
  font-size: 1.25rem; /* 20 px */
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink);
  margin: 0;
  text-wrap: balance;
}

@media (min-width: 40em) {
  .never-card h3 {
    margin: 0.25rem 0 0.4em;
  }
}

.never-card p {
  margin: 0;
  font-size: 1.125rem; /* 18 px */
  line-height: 1.55;
  color: var(--ink-text);
  text-wrap: pretty;
}

.honest-note {
  margin-top: 1.5rem;
}

/* La piste Embla fait 100vw : la section coupe tout débordement horizontal (barre de défilement
   classique sous Windows) sans couper l'axe vertical (courbe de bas de section). */
.section-moments {
  overflow-x: clip;
}

/* ---------- Profils « À chaque étape d'une vie professionnelle » — direction A (V53B-CONTRAT.md)
 * + rotation automatique 6 s, bouton Pause/Lecture (V54-CONTRAT.md, prime). Sélecteur en pastilles
 * (tablist APG) + carte à panneaux superposés dans la même cellule de grille (hauteur du plus
 * long, 0 saut de mise en page). Le minuteur de rotation EST le trait de progression CSS (aucun
 * setInterval). Patron marketing mesuré : projets/marketing/maquettes/v53-profils/profils.css. */
.moments-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

.moments-head {
  /* 4 px (au lieu de 12) : la ligne libellé+bouton passe à 44 px, écart visuel ~inchangé (§D) */
  margin-bottom: 0.25rem;
}

.profiles-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  min-height: 2.75rem; /* 44 px */
  margin-top: 1.5rem;
}

@media (min-width: 64em) {
  .profiles-bar {
    margin-top: 2rem;
  }
}

.profiles-label {
  margin: 0;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--ink-secondary);
}

.profile-card {
  margin-top: 1.5rem;
}

@media (min-width: 64em) {
  .moments-layout {
    grid-template-columns: 5fr 7fr;
    grid-template-rows: auto 1fr;
    column-gap: 5rem;
  }

  .moments-head {
    grid-column: 1;
    grid-row: 1;
    margin-bottom: 1rem;
  }

  .profiles-tabs {
    grid-column: 1;
    grid-row: 2;
    align-self: start;
  }

  .profile-card {
    grid-column: 2;
    grid-row: 1 / 3;
    margin-top: 0;
    align-self: stretch;
  }
}

/* ---------- Pastilles (tablist) ---------- */
.profiles-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
}

@media (min-width: 40em) and (max-width: 63.99em) {
  .profiles-tabs {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (min-width: 64em) {
  .profiles-tabs {
    grid-template-columns: 1fr;
    gap: 0.5rem;
  }
}

.profile-tab {
  position: relative; /* ancre le trait .tab-progress (V54-CONTRAT.md §D) */
  appearance: none;
  margin: 0;
  font: inherit;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.2;
  color: var(--ink);
  min-height: 3rem;
  padding: 0.25rem 0.5rem;
  border: 0;
  border-radius: 999px;
  background: var(--white);
  box-shadow: inset 0 0 0 1px var(--line-soft); /* V5.4 retouche : Ink 24 % (DA l.35) */
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  text-align: center;
  cursor: pointer;
  overflow-wrap: normal;
  hyphens: none;
  -webkit-tap-highlight-color: transparent;
}

.profile-tab .tab-icon,
.profile-tab .tab-chevron {
  display: none;
  flex: none;
}

@media (min-width: 30em) {
  .profile-tab {
    font-size: 0.9375rem;
  }
}

@media (hover: hover) {
  .profile-tab:hover {
    box-shadow: inset 0 0 0 1px var(--ink);
    background: var(--paper);
  }
}

.profile-tab[aria-selected="true"] {
  background: rgb(var(--signal-rgb) / 0.10);
  color: var(--signal);
  box-shadow: inset 0 0 0 2px var(--signal);
}

.profile-tab:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 3px;
}

@media (min-width: 64em) {
  .profile-tab {
    min-height: 3.25rem;
    justify-content: flex-start;
    text-align: left;
    padding: 0 1rem 0 1.25rem;
    font-size: 1.0625rem;
    border-radius: 16px;
  }

  .profile-tab .tab-icon {
    display: block;
    width: 20px;
    height: 20px;
    color: var(--ink-secondary);
  }

  .profile-tab[aria-selected="true"] .tab-icon {
    color: var(--signal);
  }

  .profile-tab .tab-chevron {
    display: block;
    width: 20px;
    height: 20px;
    margin-left: auto;
    visibility: hidden;
  }

  .profile-tab[aria-selected="true"] .tab-chevron {
    visibility: visible;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .profile-tab {
    transition: box-shadow 0.2s var(--ease), background-color 0.2s var(--ease), color 0.2s var(--ease);
  }
}

/* ---------- Minuteur de rotation = trait de progression (V54-CONTRAT.md §D), 0 setInterval ---------- */
.tab-progress {
  display: none;
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 6px;
  height: 2px;
  border-radius: 1px;
  background: var(--signal);
  transform: scaleX(0);
  transform-origin: left;
  pointer-events: none;
}

@keyframes profile-progress {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

@media (prefers-reduced-motion: no-preference) {
  .js .section-moments:not(.is-stopped) .profile-tab[aria-selected="true"] .tab-progress {
    display: block;
    animation: profile-progress 6s linear 1 both;
  }
}

/* Spécificité égale à la règle d'activation ci-dessus (même nombre de classes/attributs) et
   placée APRÈS dans la feuille : sans ce même poids, l'« animation » shorthand (qui remet
   implicitement animation-play-state à running) gagnerait malgré .is-paused. */
.js .section-moments.is-paused .profile-tab[aria-selected="true"] .tab-progress {
  animation-play-state: paused;
}

/* Forçage de redémarrage à 0 (Lecture, retour de reduced-motion) : coupe puis relâche
   l'animation ; profils.js intercale un reflow en lecture seule (void el.offsetWidth). */
.profile-tab[aria-selected="true"] .tab-progress.is-restart {
  animation: none;
}

/* ---------- Bouton Pause / Lecture — icône discrète, coin de section (V541-CONTRAT.md) ----------
 * Remplace la pastille visible V5.4/V5.4B (jugée trop voyante, décision du 17/10). Icône Lucide
 * 16 px trait 1,5 seule, Ink 55 % (gamme 50-60 % demandée), 0 fond, 0 bordure, 0 texte visible
 * (span.pause-text passe en .sr-only, texte accessible conservé pour les contrôles doc 02 et les
 * lecteurs d'écran qui ignoreraient l'aria-label). Zone tactile 44x44 INVISIBLE : c'est le bouton
 * lui-même qui fait 44x44 (plus besoin du ::before d'extension de la V5.4B). Positionnement : coin
 * (haut-droit) de la section, ancré sur .section-moments (position: relative ci-dessous), dans la
 * marge haute de la section (au-dessus du titre, hors de la zone où déborde la courbe de transition). */
.section-moments {
  position: relative;
}

.profiles-pause {
  position: absolute;
  top: 1.75rem;
  right: var(--side-mobile);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: none;
  box-shadow: none;
  color: rgb(var(--ink-rgb) / 0.55); /* Ink 55 % : icône discrète (décision du 17/10) */
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

@media (min-width: 48em) {
  .profiles-pause {
    top: 2.5rem;
    right: var(--side);
  }
}

.profiles-pause svg {
  width: 16px;
  height: 16px;
  flex: none;
}

.profiles-pause .play-icon {
  display: none;
}

.profiles-pause.is-play .play-icon {
  display: block;
}

.profiles-pause.is-play .pause-icon {
  display: none;
}

.profiles-pause[hidden] {
  display: none; /* OBLIGATOIRE : inline-flex écraserait hidden (V54-CONTRAT.md §D) */
}

@media (hover: hover) {
  .profiles-pause:hover {
    color: var(--ink); /* 0 fond/bordure même au survol : seule la teinte de l'icône s'assombrit */
  }
}

.profiles-pause:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 3px;
}

.no-js .profiles-pause {
  display: none;
}

@media (prefers-reduced-motion: no-preference) {
  .profiles-pause {
    transition: color 0.2s var(--ease);
  }
}

/* ---------- Carte : panneaux superposés dans la même cellule = hauteur du plus long, aucun saut ---------- */
.profile-card {
  display: grid;
  background: var(--white);
  border: 1px solid var(--mist);
  border-radius: 20px;
  box-shadow: var(--shadow-demo);
  padding: 1.5rem;
}

@media (min-width: 48em) {
  .profile-card {
    padding: 2rem;
  }
}

.profile-panel {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.js .profile-panel {
  opacity: 0;
  visibility: hidden;
}

.js .profile-panel.is-active {
  opacity: 1;
  visibility: visible;
}

@media (prefers-reduced-motion: no-preference) {
  .js .profile-panel {
    transition: opacity 0.2s var(--ease), visibility 0s linear 0.2s;
  }

  .js .profile-panel.is-active {
    transition: opacity 0.2s var(--ease), visibility 0s;
  }
}

.profile-panel:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 8px;
  border-radius: 12px;
}

.panel-tag {
  margin: 0 0 0.5rem;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--signal);
}

.profile-panel h3 {
  font-weight: 600;
  font-size: 1.375rem;
  line-height: 1.2;
  margin: 0 0 0.5rem;
  max-width: 26ch;
}

@media (min-width: 48em) {
  .profile-panel h3 {
    font-size: 1.75rem;
    max-width: 22ch;
  }
}

.panel-line {
  margin: 0;
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--ink-text);
  text-wrap: pretty;
  max-width: 40ch;
}

@media (min-width: 48em) {
  .panel-line {
    font-size: 1.125rem;
    max-width: none;
  }
}

.panel-example {
  margin-top: auto;
  padding-top: 1.5rem;
}

@media (min-width: 64em) {
  .panel-example {
    padding-top: 2rem;
  }

  .preview {
    padding: 1rem 1.25rem 0.375rem;
  }

  .preview-row {
    padding: 0.875rem 0;
  }

  .preview-row.is-compact {
    min-height: 3.5rem;
  }

  .profile-panel h3 {
    margin-bottom: 0.75rem;
  }

  .panel-tag {
    margin-bottom: 0.75rem;
  }
}

/* ---------- Mini-aperçu (même famille que le téléphone du hero) ---------- */
.preview {
  background: var(--paper);
  border: 1px solid var(--mist);
  border-radius: 12px;
  padding: 0.75rem 1rem 0.25rem;
}

.preview-head {
  margin: 0;
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--ink-secondary);
}

.preview-list {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
}

.preview-row {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  padding: 0.625rem 0;
  border-top: 1px solid var(--mist);
}

.row-job {
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink);
  overflow-wrap: normal;
  hyphens: none;
}

.row-status {
  font-size: 0.875rem;
  line-height: 1.4;
  color: var(--ink-secondary);
}

.state {
  font-weight: 600;
  white-space: nowrap;
}

.state-sent {
  color: var(--confirm);
}

.state-sent::before {
  content: "";
  display: inline-block;
  width: 0.65em;
  height: 0.35em;
  margin: 0 0.4em 0.2em 0.05em;
  border-left: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
}

.state-spot {
  color: var(--ink-secondary);
}

.state-spot::before {
  content: "";
  display: inline-block;
  width: 0.5em;
  height: 0.5em;
  margin: 0 0.4em 0.05em 0.1em;
  border: 1.5px solid currentColor;
  border-radius: 50%;
}

.state-reply {
  color: var(--ink);
  background: rgb(var(--signal-rgb) / 0.10);
  border-radius: 999px;
  padding: 0.125rem 0.625rem;
}

.preview-row.is-compact {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  min-height: 2.75rem;
  padding: 0.5rem 0;
}

.preview-row.is-compact .state {
  font-size: 0.875rem;
  line-height: 1.4;
}

.preview-row.is-wide {
  display: none;
}

@media (min-width: 64em) {
  .preview-row.is-wide {
    display: flex;
  }
}

.example-note {
  margin: 0.75rem 0 0;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--ink-secondary);
}

/* Zoom 200 % sur mobile (viewport CSS ~188 px) : les marges carte + aperçu laissaient 56 px
   aux lignes de l'aperçu et les intitulés débordaient. On resserre et on autorise la coupure. */
@media (max-width: 15em) {
  /* V5.5 (banc V5.5, 188 px = zoom 200 % sur 375) : les colonnes 1fr gardaient la largeur min-content des
     libellés (« Demandeur d'emploi ») et les pastilles dépassaient de 57 px, rognées par l'overflow-x: clip
     de la section (invisible pour scrollWidth). Colonnes bornées + libellés qui passent à la ligne. */
  .profiles-tabs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .profile-tab {
    min-width: 0;
    height: auto;
    min-height: 3rem;
  }

  .profile-tab .tab-label {
    min-width: 0;
    white-space: normal;
    overflow-wrap: anywhere;
  }

  .profile-card {
    padding: 1rem 0.75rem;
  }

  .preview {
    padding-left: 0.5rem;
    padding-right: 0.5rem;
  }

  .row-job,
  .row-status {
    overflow-wrap: anywhere;
  }
}

/* ---------- Sans JavaScript : sélecteur + bouton masqués, les 6 panneaux empilés lisibles ---------- */
.no-js .profiles-bar,
.no-js .profiles-tabs {
  display: none;
}

.no-js .profile-card {
  display: block;
  background: none;
  border: 0;
  box-shadow: none;
  padding: 0;
}

.no-js .profile-panel {
  background: var(--white);
  border: 1px solid var(--mist);
  border-radius: 20px;
  padding: 1.5rem;
  margin-top: 1rem;
}

@media (min-width: 64em) {
  .no-js .moments-layout {
    display: block;
  }

  .no-js .profile-card {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.5rem;
  }

  .no-js .profile-panel {
    grid-area: auto;
    margin: 0;
  }
}

/* ---------- FAQ — accordéon (patron shadcn/ui « Accordion », MIT, sur <details> natif) ---------- */
.faq {
  max-width: 50rem;
}

.faq h2 {
  margin-bottom: 1.5rem;
}

.faq-q {
  text-wrap: balance;
}

.faq-item {
  border-bottom: 1px solid var(--mist);
}

.faq-item:first-of-type {
  border-top: 1px solid var(--mist);
}

.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 3rem;
  padding: 1.25rem 0;
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1.4;
  cursor: pointer;
  list-style: none;
}

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

@media (hover: hover) {
  .faq-item summary:hover .faq-q {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
  }
}

.faq-chevron {
  flex: none;
  color: var(--ink);
}

/* l'état ouvert est toujours indiqué par la rotation ; seule l'animation dépend du mouvement */
.faq-item[open] .faq-chevron {
  transform: rotate(180deg);
}

@media (prefers-reduced-motion: no-preference) {
  .faq-chevron {
    transition: transform 0.2s var(--ease);
  }
}

.faq-item p {
  margin: 0 0 1.25rem;
  color: var(--ink-secondary);
}

.faq .source {
  font-style: italic;
}

/* ---------- Inscription — formulaire V3.2b (inchangé : name/id/data-* conservés) ---------- */
/* CTA final (V5.1) : bloc pleine largeur fond Signal, titre blanc, formulaire dans une carte
   blanche surélevée (patron HyperUI « CTA », MIT). Bouton de la carte en Ink (pas de bleu sur bleu). */
.section-cta {
  background: var(--signal);
  color: var(--white);
}

.signup-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.section-cta h2 {
  color: var(--white);
  text-align: center;
  /* « Postule pour moi » est insécable (jamais coupé) : la taille suit la largeur pour tenir
     jusqu'à 188 px CSS (zoom 200 % sur 375), 36 px dès 400 px de large. */
  font-size: clamp(1.25rem, 9vw, 2.25rem);
  line-height: 1.08;
  margin: 0 0 2.5rem;
}

@media (min-width: 48em) {
  .section-cta h2 {
    font-size: 3.5rem; /* 56 px */
    margin-bottom: 3rem;
  }
}

/* Le nom du produit ne se coupe pas (relecture d'image V5.2) ; sous 352 px (zoom 200 % compris)
   il peut revenir à la ligne normalement, pour ne jamais déborder. */
.cta-name {
  white-space: nowrap;
}

@media (max-width: 22em) {
  .cta-name {
    white-space: normal;
  }
}

.section-cta :focus-visible {
  outline-color: var(--white);
}

.section-cta .signup-card :focus-visible {
  outline-color: var(--signal);
}

.signup-card {
  width: 100%;
  max-width: 34rem;
  background: var(--white);
  color: var(--ink);
  border-radius: 24px;
  padding: 2.5rem 1.5rem;
  box-shadow: 0 2px 6px rgb(var(--ink-rgb) / 0.14), 0 32px 64px rgb(var(--ink-rgb) / 0.30);
}

.btn-primary.btn-ink {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--white);
}

.btn-primary.btn-ink:hover {
  background: rgb(var(--ink-rgb) / 0.86);
  border-color: rgb(var(--ink-rgb) / 0.86);
  color: var(--white);
}

@media (min-width: 48em) {
  .signup-card {
    padding: 3rem;
  }
}


.field {
  margin: 0 0 1.25rem;
}

.field > label {
  display: block;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

input[type="email"],
input[type="text"] {
  display: block;
  width: 100%;
  min-height: 3rem;
  padding: 0.75rem;
  font-family: inherit;
  font-size: 1.0625rem; /* >= 16 px : pas de zoom auto iOS */
  color: var(--ink);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-field);
}

input[type="email"]:focus,
input[type="text"]:focus {
  border-color: var(--signal);
  outline: 2px solid var(--signal);
  outline-offset: 0;
}

input[aria-invalid="true"] {
  border-color: var(--alert);
  border-width: 2px;
}

.field-email input {
  min-height: 3.625rem;
  padding: 0.75rem 1rem;
  font-size: 1.125rem;
}

/* Ordre V52-CONTRAT.md §8 : champ (pleine largeur) -> case+lien -> note RGPD -> bouton (pleine
   largeur) -> réassurance. Le bouton reste pleine largeur à toutes les tailles. */
.btn-submit {
  min-height: 3.625rem;
  margin-top: 1.25rem;
  padding: 1rem 1.75rem;
  font-size: 1.0625rem;
  width: 100%;
}

/* Honeypot : hors écran, invisible pour tous, taille nulle (aucun débordement horizontal) */
.hp {
  position: absolute;
  left: -9999px;
  top: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.consent-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 1rem;
  margin: 0.75rem 0 0;
}

.consent {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  cursor: pointer;
  font-size: 0.9375rem;
  line-height: 1.35;
}

.consent-box {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 44px;
  height: 44px;
  margin-left: -10px;
}

.consent-box input {
  width: 1.375rem;
  height: 1.375rem;
  margin: 0;
  accent-color: var(--ink);
  cursor: pointer;
}

.consent input[aria-invalid="true"] {
  outline: 2px solid var(--alert);
  outline-offset: 2px;
}

.consent-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.9375rem;
}

/* V5.5 : .consent-note et .signup-reassure retirées (textes supprimés, doc 02 §0 ★ V5.5 §2). */

/* ---------- Lignes d'offre (hero) / RGPD (formulaire) — V5.5, hero V5.6 ---------- */
.signup-offer,
.signup-rgpd {
  margin: 0.75rem 0 0;
  font-size: 0.875rem; /* 14 px */
  line-height: 1.45;
  color: var(--ink-secondary); /* Ink 72 % */
}

.signup-offer + .signup-rgpd {
  margin-top: 0.5rem; /* revue d'image : 2 messages distincts, pas un seul bloc gris */
}

.signup-offer a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 0.15em;
  white-space: nowrap;
}

/* V5.6 : .signup-intro (phrase d'offre plate) et .signup-signed (« Vous êtes inscrit. ») retirés : un seul
   formulaire, l'offre passe dans l'encart .offer ci-dessous (DA ★ V5.6 §3, doc 02 §0 ★ V5.6 §3). */

/* ---------- V5.6 — encart d'offre (un composant, 2 places : .offer-hero sous le bouton, .offer-bas en tête
   de la carte). Patron : maquette marketing projets/marketing/maquettes/v56-offre (offre.css.ref). Aplat Signal
   10 % sur blanc, ni bordure ni ombre, aucun mouvement propre, seul le chiffre est en Signal. ---------- */
.offer {
  background: var(--offer-bg);
  border-radius: 16px;
  padding: 1rem 1.25rem 1.125rem;
  color: var(--ink);
}

.offer p {
  margin: 0;
}

.offer .offer-tag {
  display: inline-block;
  background: var(--white);
  color: var(--ink);
  font-weight: 600;
  font-size: 0.8125rem; /* 13 px */
  line-height: 1.25rem;
  padding: 0 0.625rem;
  border-radius: 999px;
}

.offer .offer-main {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  column-gap: 0.875rem;
  margin-top: 0.625rem;
}

.offer-pct {
  font-family: var(--font-title);
  font-weight: 700;
  color: var(--signal);
  font-size: 2.5rem; /* 40 px */
  line-height: 1;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.offer-what {
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.3;
  color: var(--ink);
}

.offer .offer-date {
  margin-top: 0.75rem;
  font-size: 0.875rem;
  line-height: 1.45;
  color: var(--ink-secondary);
}

.offer-link {
  display: inline-block;
  padding: 0.25rem 0;
  margin: -0.25rem 0;
  color: var(--ink);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.15em;
  white-space: nowrap;
}

.offer-link:hover {
  text-decoration-thickness: 2px;
}

.offer-bas {
  margin-bottom: 1.75rem; /* 28 px avant le libellé « Votre email » */
}

@media (min-width: 48em) {
  .offer {
    padding: 1.25rem 1.5rem;
  }
  .offer-pct {
    font-size: 3rem; /* 48 px */
  }
  .offer-what {
    font-size: 1.0625rem;
  }
}

/* <= 352 px (320 et zoom 200 %) : chiffre au-dessus du bénéfice, date libre de se couper. */
@media (max-width: 22em) {
  .offer .offer-main {
    grid-template-columns: 1fr;
    row-gap: 0.25rem;
  }
  .offer-date .nowrap {
    white-space: normal;
  }
}

/* Écarts mesurés V56-CONTRAT §3 (encart du BAS, plus étroit que celui du haut : carte + son padding de 24 px).
   « −50 % » (114 px) + écart 14 + « 3 premiers mois » insécable (118 px) = 246 px ; place = largeur écran − 136 px
   => en dessous de 382 px la ligne débordait dans le padding (7 px à 375, 22 px = hors de l'encart à 360).
   <= 26em (416 px) : padding latéral 16 px + écart 12 px (244 px pour 239..280 de place : tient dès 372 px).
   <= 23em (368 px, ex. 360) : chiffre au-dessus du bénéfice, comme à <= 22em pour l'encart du haut. */
@media (max-width: 26em) {
  .offer-bas {
    padding-left: 1rem;
    padding-right: 1rem;
  }
  .offer-bas .offer-main {
    column-gap: 0.75rem;
  }
}

@media (max-width: 23em) {
  .offer-bas .offer-main {
    grid-template-columns: 1fr;
    row-gap: 0.25rem;
  }
}

/* <= 240 px (zoom 200 % sur 375 = 188 px CSS) : à 40 px le « −50 % » (118 px) sortait de l'encart (100 px de
   place en haut, 52 en bas), rogné par l'overflow clip de la section (invisible pour scrollWidth), et les mots de
   la date se coupaient au milieu. Chiffre 28 px (83 px), « 3 premiers mois » peut passer à la ligne, encart et
   carte moins rembourrés : tout tient dans la boîte, aucun mot coupé. */
@media (max-width: 15em) {
  .offer,
  .offer-bas {
    padding: 0.75rem 0.5rem;
  }
  .offer-pct {
    font-size: 1.75rem;
  }
  .offer-what .nowrap {
    white-space: normal;
  }
  .offer-bas {
    margin-bottom: 1.25rem;
  }
  .signup-card {
    padding-inline: 0.75rem;
  }
}

/* Conditions de l'offre : accordéon imbriqué dans la question FAQ (le style des questions ne s'y
   applique pas : sélecteurs plus précis ci-dessous). */
.faq-item .faq-conditions {
  margin: 0 0 1.25rem;
}

.faq-item .faq-conditions > summary {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem; /* cible 44 px */
  padding: 0;
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  cursor: pointer;
  list-style: revert;
}

.faq-item .faq-conditions > summary::-webkit-details-marker {
  display: revert;
}

.conditions {
  margin: 0.5rem 0 0;
  padding-left: 1.5rem;
  color: var(--ink-secondary);
  line-height: 1.55;
}

.conditions li + li {
  margin-top: 0.5rem;
}

@media (max-width: 47.99em) {
  /* 375 x 667 : h1 + bouton visibles sans défiler. */
  .hero-text {
    gap: 1.5rem;
  }
}

.form-error {
  color: var(--alert);
  background: var(--white);
  border-left: 4px solid var(--alert);
  font-weight: 600;
  padding: 0.5rem 1rem;
  margin: 0 0 1.25rem;
}

.form-error:empty {
  display: none;
}

.success {
  padding: 1rem 0;
}

.success-title {
  margin: 0;
  font-size: 1.1875rem;
  color: var(--ink);
}

.success-title:focus {
  outline: none;
}

.success-title:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

.step2 {
  margin-top: 1.5rem;
}

.step2-title {
  font-size: 1.0625rem;
  margin: 0 0 1rem;
}

.chip-group {
  margin: 0 0 1rem;
}

.chip-legend {
  margin: 0 0 0.5rem;
  font-weight: 600;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.chip-choice {
  min-height: 44px;
  padding: 0.5rem 1.25rem;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--paper);
  color: var(--ink);
  font-family: inherit;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
}

.chip-choice:hover {
  border-color: var(--ink);
}

.chip-choice[aria-pressed="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--white);
}

.step2[aria-busy="true"] .chip-choice {
  cursor: progress;
}

.btn-skip {
  margin-top: 0.25rem;
  min-height: 44px;
  padding: 0.5rem 1.5rem;
}

.step2-thanks {
  margin: 0;
  font-weight: 600;
}

.step2-thanks:focus {
  outline: none;
}

@media (prefers-reduced-motion: no-preference) {
  .chip-choice {
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
  }
}

/* ---------- Pied de page ---------- */
.site-footer {
  padding: calc(2rem + var(--curve)) 0 2.5rem; /* place pour la courbe du CTA qui déborde dessus */
  margin-top: 0;
  font-size: 0.9375rem;
  color: var(--ink-secondary);
}

.site-footer p {
  margin: 0 0 0.75rem;
}

.footer-links {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.5rem;
}

.footer-links a {
  display: inline-block;
  padding: 0.5rem 0;
  color: var(--ink);
}

/* ---------- CTA collant mobile ---------- */
.sticky-cta {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  background: var(--paper);
  border-top: 1px solid var(--mist);
  padding: 0.75rem 1.5rem calc(0.75rem + env(safe-area-inset-bottom, 0px));
}

.sticky-cta .btn {
  width: 100%;
}

body.has-sticky {
  padding-bottom: calc(5.5rem + env(safe-area-inset-bottom, 0px));
}

@media (min-width: 48em) {
  .sticky-cta {
    display: none !important;
  }

  body.has-sticky {
    padding-bottom: 0;
  }
}

/* ---------- Pages annexes (désinscription, erreur, mentions, confidentialité) ---------- */
.annexe {
  padding-top: 2.5rem;
  padding-bottom: 3rem;
}

.annexe > h1,
.annexe > p,
.annexe > form,
.legal > * {
  max-width: 37rem;
}

@media (min-width: 48em) {
  .annexe {
    padding-top: 4rem;
    padding-bottom: 5rem;
  }
}

.annexe h1 {
  font-size: clamp(1.875rem, 1.4rem + 2vw, 2.5rem);
}

.annexe form {
  margin-top: 1.75rem;
}

.legal h1 {
  font-size: clamp(1.875rem, 1.4rem + 2vw, 2.5rem);
}

.legal ul {
  padding-left: 1.25rem;
}

.legal li {
  margin-bottom: 0.75rem;
}

/* ---------- Racine primowise.com ---------- */
.home {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-top: 4rem;
  padding-bottom: 4rem;
}

.home h1 {
  font-size: clamp(2.5rem, 1.8rem + 4vw, 4rem);
  margin-bottom: 1.25rem;
}

.home-line {
  font-size: 1.25rem;
  max-width: 36rem;
  color: var(--ink-secondary);
}

@media (min-width: 48em) {
  .home-line {
    font-size: 1.5rem;
  }
}

/* ---------- Mouvement — .reveal (700 ms), uniquement sous html.anim + prefers-reduced-motion: no-preference.
   Rien n'est jamais caché sans JS ni en reduced-motion : [hidden] déjà géré ci-dessus, et le CSS
   ci-dessous ne masque le départ de l'animation que quand html.anim est posée par anim.js
   (lui-même conditionné par la media query). ---------- */
@media (prefers-reduced-motion: no-preference) {
  html.anim .reveal {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
  }

  html.anim .reveal.is-visible {
    opacity: 1;
    transform: translateY(0);
  }

  /* cascade 80 ms sur les cartes des listes qui apparaissent ensemble (V52-CONTRAT.md §7) */
  html.anim .keep.reveal .keep-card,
  html.anim .never.reveal .never-card {
    transition-delay: var(--reveal-delay, 0s);
  }

  html.anim .keep.reveal .keep-card:nth-child(1) { --reveal-delay: 0s; }
  html.anim .keep.reveal .keep-card:nth-child(2) { --reveal-delay: 0.08s; }
  html.anim .keep.reveal .keep-card:nth-child(3) { --reveal-delay: 0.16s; }

  html.anim .never.reveal .never-card:nth-child(1) { --reveal-delay: 0s; }
  html.anim .never.reveal .never-card:nth-child(2) { --reveal-delay: 0.08s; }
  html.anim .never.reveal .never-card:nth-child(3) { --reveal-delay: 0.16s; }
  html.anim .never.reveal .never-card:nth-child(4) { --reveal-delay: 0.24s; }

  /* Section profils (V53B/V54-CONTRAT.md) : pas de classe .reveal, rien ne bouge sans action ;
     les règles carrousel/moment/scene de V5.2/V5.3 sont retirées. */
}

/* ---------- Icônes Lucide qui se tracent (V52-CONTRAT.md §7) ----------
 * Chaque forme (path/circle/line/rect/polyline) des icônes .step-icon/.keep-icon/.never-icon
 * reçoit pathLength="1" dans le HTML : sous html.anim + no-preference, le trait est
 * masqué (dasharray/dashoffset 1) puis se dessine en 900 ms une seule fois (icône <- .reveal
 * devenu .is-visible ; frise <- li.step devenu .is-lit). Reduced-motion / sans JS : trait plein. */
@media (prefers-reduced-motion: no-preference) {
  html.anim .step-icon svg :is(path, circle, line, rect, polyline),
  html.anim .keep-icon svg :is(path, circle, line, rect, polyline),
  html.anim .never-icon svg :is(path, circle, line, rect, polyline) {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    transition: stroke-dashoffset 0.9s var(--ease);
  }

  html.anim .reveal.is-visible .keep-icon svg :is(path, circle, line, rect, polyline),
  html.anim .reveal.is-visible .never-icon svg :is(path, circle, line, rect, polyline),
  html.anim .step.is-lit .step-icon svg :is(path, circle, line, rect, polyline) {
    stroke-dashoffset: 0;
  }
}
