/* ==========================================================================
   Tunnel Licence Fondateur, Système 360D
   Tokens repris du Design System AutoHired, valeurs recopiées du prototype.
   Un seul point de rupture dans tout ce fichier : la barre CTA collante.
   ========================================================================== */

@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 100 1000;
  font-display: swap;
  src: url('assets/dmsans-latin-var.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;
}

:root {
  --bordeaux: #840032;
  --bordeaux-hover: #6B0028;
  --bordeaux-wash: rgba(132, 0, 50, 0.08);
  --ink: #111111;
  /* #6A7079, pas #6B7280 (valeur d'origine du design system) : la revue
     finale du lot 1 a mesuré ce dernier à 4,48:1 sur --bone, sous le seuil
     WCAG AA de 4,5:1 pour les 8 classes qui l'utilisent hors carte. Écart de
     0,4 %, sous la précision de l'arrondi du token lui-même, et imperceptible
     à l'œil ; referme les 4,48:1 → 4,62:1 d'un coup, sur toutes les
     occurrences. */
  --slate: #6A7079;
  --gray: #9CA3AF;
  --line: #E5E7EB;
  --line-strong: #D1D5DB;
  --white: #FFFFFF;
  --bone: #F7F6F4;
  /* #15803D, pas #16A34A (valeur d'origine) : 3,30:1 sur blanc mesuré à la
     revue finale, sous le seuil AA. */
  --green: #15803D;
  /* #B45309, pas #D97706 (valeur d'origine) : 3,19:1 sur blanc mesuré à la
     revue finale, sous le seuil AA. */
  --amber: #B45309;
  /* Fond du badge daté de l'élément 08 (section 7, envoi 2b) : le prototype
     écrit rgba(217,119,6,0.15) en clair sur ce badge, jamais nommé là-bas ;
     rgba() à opacité fixe plutôt qu'un token supplémentaire, pour un usage
     unique. */
  --amber-wash-15: rgba(217, 119, 6, 0.15);

  --radius-btn: 8px;
  --radius-card: 12px;
  --radius-pill: 20px;
  --radius-round: 999px;

  --shadow-card: 0 1px 3px rgba(0, 0, 0, 0.05);
  --shadow-float: 0 8px 24px rgba(0, 0, 0, 0.1);

  /* Overlays du lecteur vidéo (tâches 9 et 10). Le prototype les écrit en
     rgba() inline sur le composant lecteur ; jamais nommés comme tokens
     là-bas, mais la règle du projet veut toute couleur en variable hors
     :root. --ink-wash-25 est le voile de la variante démo (section 7). */
  --ink-wash-80: rgba(17, 17, 17, 0.8);
  --ink-wash-25: rgba(17, 17, 17, 0.25);
  --white-wash-25: rgba(255, 255, 255, 0.25);
  --white-wash-15: rgba(255, 255, 255, 0.15);

  scroll-behavior: smooth;
}

*, *::before, *::after { box-sizing: border-box; }

html, body { margin: 0; padding: 0; background: var(--white); }

body {
  font-family: 'DM Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 17px;
  line-height: 1.65;
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
}

a { color: var(--bordeaux); text-decoration: none; }
a:hover { color: var(--bordeaux-hover); text-decoration: underline; }

button { font-family: inherit; }

img { max-width: 100%; }

/* Le halo pulsant du bouton de son. Coupé pour qui a demandé moins de
   mouvement au niveau du système : le bouton reste bordeaux plein, seul le
   battement disparaît. */
@keyframes ah-sound-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(132, 0, 50, 0.55); }
  70%      { box-shadow: 0 0 0 16px rgba(132, 0, 50, 0); }
}

@media (prefers-reduced-motion: reduce) {
  :root { scroll-behavior: auto; }
  .player__sound--muted { animation: none !important; }
}

/* --- Rythme des sections --------------------------------------------------
   Fond alterné : sections impaires sur blanc, paires sur bone avec bordures.
   Padding vertical recopié du prototype, cqw devenu vw. */

.section {
  padding: clamp(56px, 7vw, 96px) 20px;
  scroll-margin-top: 72px;
}

.section--bone {
  background: var(--bone);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.section--hero { padding: clamp(28px, 4vw, 48px) 20px clamp(48px, 6vw, 72px); }

.container         { max-width: 1000px; margin: 0 auto; }
.container--hero   { max-width: 900px; margin: 0 auto; }
.container--narrow { max-width: 760px; margin: 0 auto; }
.container--text   { max-width: 680px; margin: 0 auto; }

.h2 {
  margin: 0 auto 32px;
  font-size: clamp(26px, 3.4vw, 38px);
  line-height: 1.15;
  letter-spacing: -0.02em;
  font-weight: 700;
  color: var(--ink);
  text-align: center;
}

/* Slate, pas bordeaux : les dix eyebrows en graisse 500 du prototype sont
   tous en #6B7280. Le seul eyebrow bordeaux est celui de la carte de prix
   (prototype ligne 530), en graisse 600, et la tâche 10 lui donne son
   propre modificateur. */
.eyebrow {
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--slate);
}

/* 1.45, valeur des cinq punchlines du prototype, qui portent toutes
   margin: 0 sans exception. La marge appartient donc au primitif, pas à une
   règle de voisinage qu'un changement de balisage briserait en silence. */
.punchline { margin: 0; font-size: 19px; font-weight: 600; line-height: 1.45; }

.rule { width: 28px; height: 2px; background: var(--bordeaux); border: 0; margin: 0; }

.tabular { font-variant-numeric: tabular-nums; }

/* --- Boutons --------------------------------------------------------------
   Le bordeaux est rare et signifiant : un seul bouton primaire par zone.
   Cible tactile de 52 px minimum, 56 px pour les boutons d'achat. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 52px;
  padding: 14px 20px;
  border-radius: var(--radius-btn);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}

.btn:hover { text-decoration: none; }

.btn--primary {
  background: var(--bordeaux);
  color: var(--white);
  border: 1px solid var(--bordeaux);
}
.btn--primary:hover { background: var(--bordeaux-hover); border-color: var(--bordeaux-hover); color: var(--white); }

.btn--secondary {
  background: var(--white);
  color: var(--ink);
  border: 1px solid var(--line-strong);
}
.btn--secondary:hover { background: var(--bone); border-color: var(--bordeaux); color: var(--bordeaux); }

/* gap: 10px est commun aux deux boutons d'achat de la page (prototype
   lignes 539 et 759, vérifié) ; leur padding horizontal diffère en revanche
   (24px ici contre 30px pour le second), donc pas posé ici : voir
   .price__card .btn--buy, section 8. */
.btn--buy { min-height: 56px; width: 100%; font-size: 17px; gap: 10px; }

/* Rendu des boutons d'achat quand CHECKOUT_URL n'est pas encore renseignée.
   Ils partent sans attribut href : un <a> sans href n'est ni cliquable ni
   atteignable au clavier, il n'y a donc rien à neutraliser. vente.js pose
   l'href dès que l'URL Stripe existe. */
.btn--buy:not([href]) {
  background: var(--line-strong);
  border-color: var(--line-strong);
  color: var(--white);
  cursor: not-allowed;
}

/* ==========================================================================
   Page de vente — sections 1 à 4
   Convention : bloc, __élément, --modificateur ; le bloc est préfixé par la
   section d'origine (hero, player, compare, direction, trace). player est un
   bloc à part : le lecteur vidéo se répète tel quel en section 7.
   ========================================================================== */

/* --- Section 1, hero ------------------------------------------------------ */

.hero__logo {
  height: clamp(32px, 4.5vw, 44px);
  width: auto;
  display: block;
  margin: 0 auto clamp(24px, 4vw, 40px);
}

.hero__title {
  margin: 0 auto;
  max-width: 820px;
  font-size: clamp(34px, 5.4vw, 60px);
  line-height: 1.06;
  letter-spacing: -0.025em;
  font-weight: 700;
  color: var(--ink);
  text-align: center;
}

.hero__subtitle {
  margin: 18px auto 0;
  font-size: clamp(18px, 2.2vw, 23px);
  line-height: 1.45;
  color: var(--slate);
  max-width: 640px;
  text-align: center;
}

/* Le prototype centre ce CTA via un conteneur flex englobant ; ici .btn est
   inline-flex, donc on bascule l'ancre elle-même en flex de largeur
   fit-content pour que la marge automatique la centre à sa place. */
.hero__cta {
  display: flex;
  width: fit-content;
  margin: 20px auto 0;
  padding-left: 26px;
  padding-right: 26px;
}

.hero__mechanism {
  margin-top: clamp(40px, 5vw, 56px);
  padding-top: clamp(28px, 4vw, 36px);
  border-top: 1px solid var(--line);
  text-align: center;
}
.hero__mechanism p { margin: 0; }
.hero__mechanism p + p { margin-top: 16px; font-weight: 600; }

/* Lecteur vidéo : bloc réutilisé trois fois (hero ici ; plugin et managers
   à la tâche 10). --hero ne porte que la marge qui le sépare du sous-titre,
   le reste est commun aux trois instances. */
.player {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--bone);
}
.player--hero { margin-top: clamp(28px, 4vw, 40px); }

.player__banner {
  margin: 0;
  background: var(--bordeaux);
  padding: 12px 16px;
  text-align: center;
  color: var(--white);
  font-size: clamp(16px, 2.1vw, 20px);
  font-weight: 600;
  line-height: 1.4;
}

/* 16 / 9, pas 16 / 10 : les trois vidéos sont en 1280x720 (16:9, ratio
   1,778). Un cadre 16:10 (1,600) est plus étroit que la source ; en
   object-fit: cover, ça rognait 5,5% de chaque côté (mesuré en prod). */
.player__stage {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--bone);
  cursor: pointer;
}

/* contain, pas cover : aujourd'hui les deux sont équivalents (le cadre est
   exactement 16:9, comme la source), mais contain est le choix défensif —
   une vidéo future qui ne serait pas pile 16:9 serait encadrée de bandes
   plutôt qu'amputée. Les posters (assets/poster-*.webp, 1280x720 vérifié)
   suivent : le navigateur rend l'image poster d'un <video> avec ce même
   object-fit, aucun changement séparé n'est nécessaire pour eux. */
.player__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.player__sound {
  position: absolute;
  top: 14px;
  right: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: var(--radius-round);
  border: 0;
  cursor: pointer;
  color: var(--white);
}
.player__sound--muted { background: var(--bordeaux); animation: ah-sound-pulse 2s ease-out infinite; }
.player__sound--unmuted { background: var(--ink-wash-80); }
.player__sound:hover { background: var(--bordeaux-hover); }

.player__bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
  background: var(--ink);
  color: var(--white);
}

/* color: un <button> ne suit pas le color: var(--white) hérité de
   .player__bar (les contrôles de formulaire ont leur propre color UA,
   buttontext = noir, non hérité) : sans cette ligne, les <svg
   fill/stroke="currentColor"> qu'il contient rendent en noir sur le fond
   sombre de la barre. .player__time (un <span>, pas un contrôle de
   formulaire) hérite bien, d'où le contraste observé en prod : le compteur
   était blanc, les boutons noirs sur noir. */
.player__ctrl {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 6px;
  background: transparent;
  border: 0;
  cursor: pointer;
  color: var(--white);
}
.player__ctrl:hover { background: var(--white-wash-15); }

.player__time { font-size: 12px; font-weight: 500; white-space: nowrap; }

/* Piste : le prototype superpose une zone de clic de 14px sur une piste
   visible de 4px. Le trait reste à 4px (couleur, rayon) ; la zone de clic
   élargie est ajoutée ci-dessous par ::before (tâche 12, fix round 1).
   overflow: hidden a été retiré : il ne clippait rien en usage normal (le
   fill partage le même border-radius, sa largeur ne dépasse jamais 100% de
   la piste — vérifié en mesurant fill.getBoundingClientRect() à 0/1/30/50/
   99/100% avec et sans le clip : rects strictement identiques dans tous les
   cas) et il aurait aussi clippé le pseudo-élément de la zone de clic. */
.player__track {
  position: relative;
  flex: 1;
  height: 4px;
  border-radius: 4px;
  background: var(--white-wash-25);
  cursor: pointer;
}

/* Zone de clic élargie, invisible, confinée à la largeur de la piste
   (left/right à 0 : aucune extension horizontale, donc aucun recouvrement
   possible des boutons voisins de la barre, qui sont en dehors de cette
   largeur). Elle ne déborde que verticalement (top/bottom négatifs), de
   5px de chaque côté : 4px + 5px + 5px = 14px, la valeur du prototype.
   Le calcul du déplacement (vente.js) n'utilise que rect.width de la piste,
   inchangé par cet ajout : cliquer n'importe où dans la zone élargie à une
   abscisse donnée déplace la lecture au même point qu'un clic sur le trait
   lui-même à cette abscisse. */
.player__track::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: -5px;
  bottom: -5px;
}

.player__fill { width: 0%; height: 100%; background: var(--white); border-radius: 4px; }

/* --- Lecteur vidéo, plein écran --------------------------------------------
   Fondateur, mesuré en prod : la scène gardait son aspect-ratio fixe même en
   plein écran, donc débordait dès que l'écran n'était pas pile 16:9 (mesuré
   sur 1920x1080 : scène 1918x1199, barre à 220px SOUS le bas de l'écran,
   invisible). En plein écran, .player devient une colonne : la scène
   abandonne son aspect-ratio pour occuper toute la hauteur restante
   (flex: 1 1 auto ; min-height: 0 pour qu'un flex item puisse réellement
   rétrécir sous sa taille intrinsèque), la barre reste ancrée en bas
   (flex: 0 0 auto, taille fixe à son contenu). Ainsi la colonne entière tient
   toujours exactement dans la hauteur de l'écran, 16:9 comme 16:10.
   Le bandeau d'accroche (.player__banner, hero seul) invite à lancer la
   vidéo : à ce stade c'est déjà fait, et il volerait de la hauteur à
   l'image en plein écran. Masqué ici, décision assumée. */
.player:fullscreen {
  display: flex;
  flex-direction: column;
  background: #000;
}
.player:fullscreen .player__banner { display: none; }
.player:fullscreen .player__stage {
  flex: 1 1 auto;
  aspect-ratio: auto;
  min-height: 0;
  background: #000;
}
.player:fullscreen .player__video { object-fit: contain; }
.player:fullscreen .player__bar {
  flex: 0 0 auto;
  transition: opacity 0.25s ease;
}

/* Masquage à l'inactivité, plein écran seulement : classe posée par vente.js
   d'après lib/video-player.js::barHidden (fonction pure, TDD — la barre ne
   se masque jamais hors plein écran, quelle que soit la durée d'inactivité).
   opacity + pointer-events, jamais [hidden] ni display : la barre garde sa
   place dans la colonne flex, sinon la scène changerait de taille à chaque
   apparition/disparition. Le curseur suit : .player__stage porte son propre
   cursor: pointer (règle plus haut) qui gagnerait sur l'inherited cursor:
   none sans cette redéclaration explicite. Le rond de son (.player__sound)
   n'est pas concerné : ce n'est pas « la barre ». */
.player:fullscreen.player--idle,
.player:fullscreen.player--idle .player__stage {
  cursor: none;
}
.player:fullscreen.player--idle .player__bar {
  opacity: 0;
  pointer-events: none;
}

/* --- Aide partagée, sections 2 à 4 -----------------------------------------
   Motif identique à chaque section qui suit : l'eyebrow centré (le primitif
   .eyebrow ne l'est pas par défaut). La marge nulle des punchlines qui
   suivent un trait est désormais portée par le primitif .punchline lui-même
   (zone des primitifs, plus haut) : ce n'est pas une propriété du voisinage. */
.eyebrow--center { text-align: center; }

/* --- Section 2, ce qui change concrètement (compare) ---------------------- */

.compare__card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  overflow: hidden;
}

.compare__pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 18px 32px;
  padding: 20px;
  border-bottom: 1px solid var(--line);
}
.compare__pair:last-child { border-bottom: 0; }

.compare__label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: 6px;
}
.compare__label--before { color: var(--gray); }
.compare__label--after { color: var(--bordeaux); }

.compare__text { margin: 0; font-size: 17px; line-height: 1.5; color: var(--slate); }
.compare__text--after { color: var(--ink); }
.compare__text strong { font-weight: 700; color: var(--ink); }

.compare__closing { margin-top: 28px; text-align: center; }
.compare__closing .rule { margin: 0 auto 14px; }

.punchline--lg { font-size: clamp(18px, 2vw, 21px); line-height: 1.5; }

/* --- Section 3, les trois directions (direction) --------------------------- */

.direction__heading { max-width: 760px; margin-bottom: 20px; }

.direction__intro { margin-bottom: 44px; color: var(--slate); text-align: center; }

.direction__list { display: flex; flex-direction: column; gap: 20px; }

.direction__card {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--white);
  overflow: hidden;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}

.direction__body { padding: clamp(24px, 3vw, 34px); }
.direction__body .rule { margin: 22px 0 12px; }

.direction__badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--bordeaux);
  background: var(--bordeaux-wash);
  padding: 6px 10px;
  border-radius: var(--radius-pill);
}

.direction__title {
  margin: 16px 0 12px;
  font-size: clamp(21px, 2.4vw, 26px);
  line-height: 1.2;
  letter-spacing: -0.01em;
  font-weight: 700;
  color: var(--ink);
}

.direction__text { margin: 0; }

.direction__visual {
  border-left: 1px solid var(--line);
  background: var(--bone);
  display: flex;
  align-items: center;
  padding: clamp(16px, 2vw, 24px);
  min-height: 260px;
}

/* Trois cartes, trois ratios : chacun vient de la capture qu'il encadre. */
.direction__frame {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  background: var(--white);
  box-shadow: var(--shadow-card);
  cursor: zoom-in;
}
.direction__frame--scoring { aspect-ratio: 1200 / 557; }
.direction__frame--manager { aspect-ratio: 1556 / 940; }
.direction__frame--inbound { aspect-ratio: 2800 / 1424; background: var(--bone); }

.direction__image { width: 100%; height: 100%; object-fit: contain; display: block; }

/* --- Section 4, ce que l'Agent IA écrit en ton nom (trace) ----------------- */

.trace__heading { margin-bottom: 28px; }

.trace__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: clamp(24px, 4vw, 48px);
  align-items: start;
}

.trace__text { margin: 0 0 16px; }
.trace__text--last { margin-bottom: 24px; }
.trace__body .rule { margin-bottom: 12px; }

.trace__captures { display: flex; flex-direction: column; gap: 16px; }

.trace__card {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--white);
  overflow: hidden;
}

.trace__media { background: var(--white); cursor: zoom-in; }
.trace__media--validation { aspect-ratio: 1557 / 952; }
.trace__media--suivi { aspect-ratio: 1087 / 641; }

.trace__image { width: 100%; height: 100%; object-fit: contain; display: block; }

.trace__caption {
  margin: 0;
  padding: 10px 14px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  line-height: 1.5;
  color: var(--slate);
}

/* ==========================================================================
   Page de vente — sections 5 et 6
   Même convention qu'aux sections 1 à 4 : bloc préfixé par la section
   d'origine (massapply, privacy). Primitives réutilisées telles quelles :
   .section, .container, .container--narrow, .h2, .eyebrow, .eyebrow--center,
   .punchline, .rule, .tabular, .btn, .btn--primary.
   ========================================================================== */

/* --- Section 5, l'inverse du mass-apply (massapply) ------------------------ */

/* Même clamp que le primitif .h2 ; seule la marge basse diffère (24px, pas
   32px) : dans le prototype ce h2 précède un sous-titre optionnel (sc-if
   subInS5, hint-placeholder-val false = replié par défaut), absent de ce
   rendu statique. */
.massapply__heading { margin-bottom: 24px; }

.massapply__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: clamp(24px, 4vw, 48px);
  align-items: start;
}

.massapply__text { margin: 0 0 16px; }
.massapply__text--last { margin: 0; color: var(--slate); }

.massapply__card {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bone);
  padding: clamp(22px, 3vw, 30px);
}

.massapply__card-label {
  margin: 0 0 22px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--slate);
}

/* Pas de classe .massapply__stat de base : les deux lignes de statistique ne
   partagent qu'un nom d'élément, aucune propriété commune (24px et 22px de
   marge basse dans le prototype, rien d'autre) ; chaque modificateur est
   donc complet à lui seul plutôt que de laisser une règle vide derrière
   lui, ce qui aurait aussi produit une classe orpheline côté CSS. */
.massapply__stat--classic { margin-bottom: 24px; }
.massapply__stat--system { margin-bottom: 22px; }

.massapply__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}

.massapply__row-label { font-size: 14px; }
.massapply__row-label--classic { color: var(--slate); }
.massapply__row-label--system { color: var(--ink); font-weight: 600; }

/* white-space: nowrap sur les deux valeurs : ce sont les chiffres-clé de la
   comparaison, ils ne doivent jamais se couper en fin de ligne. */
.massapply__row-value {
  font-weight: 700;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.massapply__row-value--classic { font-size: clamp(22px, 3vw, 28px); color: var(--slate); }
.massapply__row-value--system { font-size: clamp(26px, 3.6vw, 34px); color: var(--bordeaux); }

.massapply__track {
  height: 10px;
  border-radius: var(--radius-pill);
  background: var(--line);
  overflow: hidden;
}

.massapply__fill { height: 100%; border-radius: var(--radius-pill); }
.massapply__fill--classic { width: 15%; background: var(--gray); }
.massapply__fill--system { width: 100%; background: var(--bordeaux); }

.massapply__note {
  margin: 0;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  font-size: 15px;
  line-height: 1.6;
}

.massapply__actions {
  margin-top: clamp(36px, 5vw, 52px);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}

/* Le CTA reprend .btn.btn--primary ; seuls le gap et le padding diffèrent
   du bouton générique (même logique que .hero__cta à la tâche 9). */
.massapply__cta { gap: 10px; padding: 15px 28px; }

.massapply__guarantee { font-size: 13px; color: var(--slate); }

/* --- Section 6, tes données (privacy) -------------------------------------- */

.privacy__wrap { text-align: center; }
.privacy__wrap .rule { margin: 0 auto 12px; }

.privacy__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-card);
  background: var(--bordeaux-wash);
  color: var(--bordeaux);
  margin-bottom: 20px;
}

/* Le seul h2 de la page à ne pas reprendre le clamp du primitif .h2 :
   valeurs plus petites dans le prototype (24/3/34 contre 26/3.4/38). */
.privacy__heading { margin-bottom: 20px; font-size: clamp(24px, 3vw, 34px); }

.privacy__text { margin: 0 0 16px; }
.privacy__text--last { margin-bottom: 24px; }

/* ==========================================================================
   Page de vente — section 7 (envoi 2a : ouverture + éléments 01 à 03)
   Bloc inventory, préfixé par la section, même convention qu'aux sections
   précédentes. Le bloc player (tâche 9) est réutilisé tel quel pour les
   deux lecteurs ; seules s'ajoutent les classes propres à la variante
   démo (voile, gros bouton play, petit haut-parleur, état d'attente) plus
   un jeu de tailles de barre plus dense propre à cette variante (recopié
   du prototype : boutons 28px / icônes 14px, contre 32px / 16px pour le
   hero — la barre du hero et celle des démos ne sont pas identiques).
   ========================================================================== */

/* --- Section 7, en-tête et grille (inventory) ------------------------------ */

.inventory__heading { margin-bottom: 20px; }

.inventory__intro { margin-bottom: 44px; color: var(--slate); text-align: center; }

.inventory__list {
  display: flex;
  flex-direction: column;
  gap: clamp(28px, 4vw, 44px);
}

.inventory__item {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: clamp(20px, 3vw, 40px);
  align-items: start;
  padding-bottom: clamp(28px, 4vw, 44px);
  border-bottom: 1px solid var(--line);
}

.inventory__number { font-size: 12px; font-weight: 700; letter-spacing: 0.08em; color: var(--bordeaux); }

.inventory__title {
  margin: 10px 0 14px;
  font-size: clamp(20px, 2.2vw, 25px);
  line-height: 1.2;
  letter-spacing: -0.01em;
  font-weight: 700;
  color: var(--ink);
}

.inventory__text { margin: 0 0 14px; }
.inventory__text--last { margin-bottom: 16px; }

.inventory__compat {
  margin: 0;
  padding: 10px 12px;
  background: var(--bone);
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--slate);
}

.inventory__media { display: flex; flex-direction: column; gap: 14px; }

/* Trois cartes de capture, trois ratios : chacun vient de la capture qu'il
   encadre, même motif que .direction__frame (tâche 9). */
.inventory__frame {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--white);
  cursor: zoom-in;
}
.inventory__frame--dashboard { aspect-ratio: 1200 / 557; }
.inventory__frame--suivi { aspect-ratio: 1444 / 498; }
.inventory__frame--manager { aspect-ratio: 1547 / 957; }

.inventory__image { width: 100%; height: 100%; object-fit: contain; display: block; }

/* --- Lecteur, variante démo (éléments 01 et 03) ----------------------------
   Gabarit .player de la tâche 9. Arrêt sur la première image, voile, gros
   bouton play, petit haut-parleur masqué au départ ([hidden] jusqu'à ce que
   la tâche 12 le révèle au lancement de la lecture). */

.player__veil {
  position: absolute;
  inset: 0;
  background: var(--ink-wash-25);
  display: none;
}

.player__bigplay {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 72px;
  height: 72px;
  border-radius: var(--radius-round);
  background: var(--bordeaux);
  border: 0;
  cursor: pointer;
  color: var(--white);
  box-shadow: var(--shadow-float);
  display: none;
  align-items: center;
  justify-content: center;
}

/* .player__stage--idle est la classe que la tâche 12 retire au lancement de
   la lecture : tant qu'elle est présente, le voile et le gros bouton play
   recouvrent la scène. */
.player__stage--idle .player__veil,
.player__stage--idle .player__bigplay {
  display: flex;
}

.player__sound--small {
  top: 12px;
  right: 12px;
  width: 44px;
  height: 44px;
  background: var(--ink-wash-80);
}
.player__sound--small:hover { background: var(--bordeaux); }

/* L'attribut natif [hidden] doit rester prioritaire sur le display: flex du
   primitif .player__sound (règle d'auteur), sans quoi le petit haut-parleur
   resterait visible malgré [hidden] au chargement de la page. */
.player__sound[hidden] { display: none; }

/* Piège cousin, cause différente : [hidden] ne fonctionne pas nativement sur
   un <svg>. Contrairement aux éléments HTML, la feuille de style de l'agent
   utilisateur pour le contenu SVG ne porte pas la règle [hidden] { display:
   none }. Vérifié en navigateur, hors de toute règle d'auteur : un <svg
   hidden> isolé calcule display: inline (jamais none), et une fois enfant
   d'un flex comme .player__ctrl / .player__sound ici, blockifie à block —
   donc reste visible. Les deux <svg data-icon> de chaque bouton play/son
   (vente.js, renderPlayer) ont donc besoin de cette règle explicite pour que
   celui qu'on masque disparaisse réellement. */
.player__ctrl svg[hidden],
.player__sound svg[hidden] { display: none; }

/* Barre plus dense que celle du hero (28px / 14px contre 32px / 16px),
   valeurs recopiées telles quelles du prototype (lignes 363-364, 368, et
   leur miroir exact 430-431, 435 pour le second lecteur). */
.player--demo .player__bar { gap: 10px; padding: 6px 10px; }
.player--demo .player__ctrl { width: 28px; height: 28px; }
.player--demo .player__time { font-size: 11px; }

/* ==========================================================================
   Page de vente — section 7 (envoi 2b : éléments 04 à 08 et CTA de section)
   Suite du bloc inventory (envoi 2a) : les primitifs .inventory__item,
   __number, __title, __text/--last, __compat, __frame, __image sont réutilisés
   tels quels. Ce bloc n'ajoute que les variantes propres aux cinq derniers
   éléments (paragraphe seul sans encadré, article texte sans grille, article
   sans filet de clôture, badge ambre daté) et le CTA de fin de section.
   ========================================================================== */

/* --- Éléments 05, 06 et 07 : paragraphe seul, sans encadré ni marge --------
   .inventory__text et --last supposent tous deux qu'un élément suit (un
   autre paragraphe ou l'encadré de compatibilité). Ici rien ne suit dans le
   texte : le prototype porte margin: 0 (les quatre côtés) sur les trois,
   sans exception (lignes 472, 483, 493). */
.inventory__text--solo { margin: 0; }

/* --- Élément 07 : pas de grille, pas de colonne média, largeur contrainte --
   Le prototype (ligne 490) ne pose ni display: grid ni grid-template-columns
   ni gap pour cet article ; padding-bottom et border-bottom restent ceux de
   .inventory__item (valeurs identiques, non redéclarées ici), seul
   max-width s'ajoute. */
.inventory__item--text {
  display: block;
  max-width: 680px;
}

/* --- Élément 08 : dernier de la liste, aucun filet ni espacement après ----
   Le prototype (ligne 496) garde la grille de .inventory__item mais omet
   padding-bottom et border-bottom : rien ne suit cet article dans la liste. */
.inventory__item--last {
  padding-bottom: 0;
  border-bottom: 0;
}

/* Quatre captures, quatre ratios propres, mesures issues de la tâche 2 et
   identiques au prototype. Deux d'entre elles (éléments 04 et 05) sont
   présentées sur fond bone dans le prototype plutôt que blanc : recopié tel
   quel, pas d'harmonisation avec le blanc des deux autres (déjà le fond par
   défaut de .inventory__frame, donc non redéclaré pour elles). */
.inventory__frame--emploi-ia { aspect-ratio: 2800 / 1424; background: var(--bone); }
.inventory__frame--coach { aspect-ratio: 2400 / 1042; background: var(--bone); }
.inventory__frame--communaute { aspect-ratio: 1542 / 727; }
.inventory__frame--app { aspect-ratio: 1265 / 972; }

/* --- Badge ambre de l'élément 08 : seul élément daté de toute la page ------ */
.inventory__badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 500;
  color: var(--amber);
  background: var(--amber-wash-15);
  padding: 6px 12px;
  border-radius: var(--radius-pill);
}

/* --- CTA de fin de section 7, ancre vers #s8 --------------------------------
   Même structure que .massapply__actions/__cta/__guarantee (section 5) mais
   valeurs et copy propres à cette section (margin-top 40/5/56 contre 36/5/52 ;
   tagline de clôture, pas une mention de garantie) : bloc distinct, .inventory
   ne partage aucune classe avec .massapply. */
.inventory__actions {
  margin-top: clamp(40px, 5vw, 56px);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}

/* Le CTA reprend .btn.btn--primary ; seuls le gap et le padding diffèrent
   du bouton générique (même logique que .massapply__cta et .hero__cta). */
.inventory__cta { gap: 10px; padding: 15px 28px; }

.inventory__tagline { font-size: 13px; color: var(--slate); }

/* ==========================================================================
   Page de vente — section 8 (prix et garantie)
   Bloc price, préfixé par la section comme les précédents. Carte de prix +
   colonne d'argumentaire + encadré de garantie. Primitives réutilisées
   telles quelles : .section, .section--bone, .container, .h2, .eyebrow,
   .tabular, .btn, .btn--primary, .btn--buy (gap complété dans la zone des
   primitives, padding scopé ci-dessous).
   ========================================================================== */

/* Même clamp que le primitif .h2 ; seule la marge basse diffère (36px, pas
   32px), recopiée du prototype (ligne 526). */
.price__heading { margin-bottom: 36px; }

.price__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: clamp(24px, 4vw, 44px);
  align-items: start;
}

.price__card {
  background: var(--white);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-card);
  padding: clamp(24px, 3vw, 34px);
  box-shadow: var(--shadow-card);
}

/* Le seul eyebrow bordeaux de toute la page (prototype ligne 530) : le cas
   général .eyebrow reste slate/graisse 500, ce modificateur ne surcharge
   que la couleur et la graisse — jamais la marge, propre à cet emplacement
   (voir .price__eyebrow ci-dessous). */
.eyebrow--brand { color: var(--bordeaux); font-weight: 600; }
.price__eyebrow { margin: 0 0 6px; }

.price__title {
  margin: 0 0 20px;
  font-size: clamp(21px, 2.4vw, 26px);
  line-height: 1.2;
  letter-spacing: -0.01em;
  font-weight: 700;
  color: var(--ink);
}

.price__amount {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}

.price__value {
  font-size: clamp(40px, 6vw, 56px);
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--ink);
  line-height: 1;
}

.price__equivalent { font-size: 15px; color: var(--slate); }

.price__unique { margin: 14px 0 0; font-size: 17px; line-height: 1.6; color: var(--ink); }
.price__founder { margin: 10px 0 24px; font-size: 15px; line-height: 1.6; color: var(--slate); }

/* Padding scopé à cette carte : les deux boutons d'achat de la page
   partagent gap et min-height (posés sur .btn--buy lui-même), mais pas le
   padding horizontal (24px ici, 30px pour le second bouton, hors de ce
   périmètre) — vérifié directement dans le prototype (lignes 539 et 759).
   Même mécanique que .player--demo .player__bar : un sélecteur scopé par
   ancêtre plutôt qu'une classe HTML supplémentaire, la tâche 10 imposant le
   balisage exact du bouton (trois classes, pas une de plus). */
.price__card .btn--buy { padding: 16px 24px; }

.price__reassurance {
  margin: 14px 0 0;
  font-size: 13px;
  line-height: 1.6;
  color: var(--slate);
  text-align: center;
}

.price__text { margin: 0 0 16px; }
.price__text--last { margin-bottom: 28px; }

.price__guarantee {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 20px;
}

.price__guarantee-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--green);
  margin-bottom: 10px;
}

.price__guarantee-text { margin: 0; font-size: 16px; line-height: 1.6; color: var(--ink); }

/* ==========================================================================
   Page de vente — section 9 (la preuve)
   Bloc proof, préfixé par la section comme les précédents. Primitives
   réutilisées telles quelles : .section, .container, .container--text, .h2,
   .eyebrow, .eyebrow--center.
   ========================================================================== */

/* Même clamp que le primitif .h2 ; seule la marge basse diffère (24px, pas
   32px), recopiée du prototype (ligne 567). */
.proof__heading { margin-bottom: 24px; }

/* .container--text fournit déjà max-width: 680px et margin: 0 auto (même
   réutilisation que .direction__intro/.inventory__intro) ; ce bloc ne
   redéclare que ce qui change réellement ici : la marge basse (36px) et le
   centrage du texte. Couleur non redéclarée : #111111 du prototype
   correspond au défaut du body (ink), déjà hérité. */
.proof__intro { margin-bottom: 36px; text-align: center; }

.proof__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 20px;
}

.proof__card {
  margin: 0;
  background: var(--bone);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.proof__quote { margin: 0; font-size: 16px; line-height: 1.65; color: var(--ink); flex: 1; }

.proof__footer { display: flex; align-items: center; gap: 12px; }

.proof__avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-round);
  background: var(--bordeaux-wash);
  color: var(--bordeaux);
  font-size: 14px;
  font-weight: 700;
  flex-shrink: 0;
}

.proof__name { display: block; font-size: 14px; font-weight: 700; color: var(--ink); }

/* Gris par défaut (poste visé) ; --obtained bascule au bordeaux pour la
   seule personne qui a déjà décroché le poste (Maïmouna, prototype ligne
   578). La couleur porte un sens (qui a déjà signé), pas seulement une
   variation visuelle : modificateur nommé en conséquence. */
.proof__role { display: block; font-size: 13px; color: var(--slate); }
.proof__role--obtained { color: var(--bordeaux); font-weight: 500; }

/* ==========================================================================
   Page de vente — section 10 (le mot du fondateur)
   Bloc founder, préfixé par la section comme les précédents. Primitives
   réutilisées telles quelles : .section, .section--bone, .container,
   .eyebrow (sans --center : cette instance reste alignée à gauche, aucun
   text-align dans le prototype à cet endroit, ligne 616).
   ========================================================================== */

.founder__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: clamp(24px, 4vw, 48px);
  align-items: start;
}

/* Le prototype porte ces styles sur un <div> enveloppant l'image-slot
   (overflow: hidden pour clipper au rayon ; aspect-ratio + max-width sur ce
   même <div>, sans largeur propre puisqu'un <div> de bloc remplit déjà sa
   colonne). Ici la structure cible est un <img> unique (donnée par le
   brief, pas de wrapper) : border-radius clippe déjà le contenu peint d'un
   élément remplacé, ce qui rend overflow: hidden sans effet sur un <img>
   sans enfants — non repris. width: 100% restitue le comportement du <div>
   de bloc que l'<img>, par défaut inline, n'a pas nativement. */
.founder__photo {
  display: block;
  width: 100%;
  max-width: 380px;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--white);
}

.founder__caption { margin: 12px 0 0; font-size: 13px; color: var(--slate); }

/* line-height 1.7, pas 1.65 (défaut du body) : seule valeur qui diffère
   des trois propriétés de police par défaut du body (17px/1.7/ink contre
   17px/1.65/ink), donc la seule redéclarée ici avec la marge — même
   mécanique que .massapply__text/.price__text pour les propriétés qui
   correspondent exactement au défaut du body. */
.founder__text { margin: 0 0 16px; line-height: 1.7; }
.founder__text--last { margin: 0; }

/* ==========================================================================
   Page de vente — section 11 (FAQ)
   Bloc faq : nommage fourni tel quel par le plan d'implémentation (pas de
   préfixe de section supplémentaire, contrairement aux blocs précédents).
   Accordéon exclusif câblé par la tâche 12 via lib/faq.js ; ce bloc ne pose
   que le balisage et les styles. Primitives réutilisées telles quelles :
   .section (sans --bone : section impaire, motif déjà établi pour s9),
   .container--narrow, .h2 — premier h2 de toute la page qui ne redéclare
   strictement rien (ni marge ni taille), le prototype (ligne 629) reproduit
   le primitif à l'identique.
   ========================================================================== */

.faq { border-top: 1px solid var(--line); }

.faq__item { border-bottom: 1px solid var(--line); }

.faq__question {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 60px;
  padding: 18px 4px;
  background: transparent;
  border: 0;
  cursor: pointer;
  text-align: left;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.45;
  color: var(--ink);
}
.faq__question:hover { color: var(--bordeaux); }

/* Le prototype permute deux <svg> distincts via sc-if (chevron bas gris à
   l'état fermé, chevron haut bordeaux à l'état ouvert). Le balisage cible ne
   porte qu'un seul <svg> : on garde le tracé « fermé » (celui dont
   hint-placeholder-val vaut true, donc celui déjà rendu par la convention
   établie tâches 9-11) et on le fait pivoter à 180° à l'ouverture. Une
   rotation de 180° de ce tracé reproduit exactement le second tracé du
   prototype point par point (m6 9 6 6 6-6, pivoté autour de son centre,
   redonne m18 15-6-6-6 6) : aucune perte visuelle par rapport aux deux
   icônes distinctes du prototype. flex-shrink: 0 est un ajout structurel
   (pas une valeur du prototype) : le bouton est en pleine largeur avec des
   titres de longueur très inégale, et rien ne doit réduire l'icône. */
.faq__chevron {
  flex-shrink: 0;
  color: var(--slate);
}
.faq__question[aria-expanded="true"] .faq__chevron {
  color: var(--bordeaux);
  transform: rotate(180deg);
}

.faq__answer { padding: 0 4px 22px; max-width: 660px; }

/* Le balisage cible laisse les <p> sans classe : la marge se pose donc par
   sélecteur descendant. margin-bottom 14px entre deux paragraphes (seule la
   question 1 en a deux, prototype lignes 640-641) ; le dernier paragraphe
   (et donc l'unique paragraphe des huit autres réponses, à la fois premier
   et dernier enfant) retombe à 0 via :last-child. font-size 16px redéclaré
   (diffère du corps à 17px) ; line-height 1.65 et color #111111 non
   redéclarés, déjà les valeurs par défaut du body héritées jusqu'ici. */
.faq__answer p { margin: 0 0 14px; font-size: 16px; }
.faq__answer p:last-child { margin-bottom: 0; }

/* Aucune règle ci-dessus ne pose de display sur .faq__answer : le <div>
   reste block par défaut (règle du navigateur), et [hidden] (règle du
   navigateur elle aussi, plus spécifique que le sélecteur de type) l'emporte
   sans intervention. Pas de règle .faq__answer[hidden] à ajouter ici — à la
   différence de .player__sound (tâche 10), qui posait display: flex en
   propriété d'auteur et devait donc neutraliser [hidden] explicitement.
   Vérifié en rendu réel (voir rapport), pas seulement déduit. */

/* ==========================================================================
   Page de vente — section 12 (le CTA final)
   Bloc final-cta, préfixé par la section comme les précédents. Primitives
   réutilisées telles quelles : .section, .section--bone (border-bottom
   annulé, voir ci-dessous), .container--narrow, .h2, .btn, .btn--primary,
   .btn--buy (gap/min-height/font-size déjà posés dans la zone des
   primitives ; le padding, différent du premier bouton d'achat, est scopé
   ci-dessous — même mécanique que .price__card .btn--buy, section 8).
   ========================================================================== */

/* .section--bone pose background + border-top + border-bottom ; le prototype
   de la section 12 (ligne 754) ne porte qu'un border-top — le pied de page
   qui suit immédiatement (ligne 767) porte déjà son propre border-top, donc
   pas de second filet ici pour éviter un double trait entre les deux. */
.final-cta { border-bottom: 0; }

.final-cta__wrap { text-align: center; }

/* Même clamp que le primitif .h2, mais réellement différent ici (prototype
   ligne 756) : 28/3.6/42 contre 26/3.4/38, line-height 1.12 (pas 1.15),
   letter-spacing -0.025em (pas -0.02em). font-weight/color/text-align
   restent ceux du primitif, non redéclarés. */
.final-cta__heading {
  margin-bottom: 20px;
  font-size: clamp(28px, 3.6vw, 42px);
  line-height: 1.12;
  letter-spacing: -0.025em;
}

/* 17px/1.65/#111111 non redéclarés : valeurs par défaut du body déjà héritées
   (même mécanique que .price__text/.massapply__text). Seule la marge basse
   diffère entre les deux paragraphes (10px puis 28px, prototype lignes
   757-758). */
.final-cta__text { margin: 0 0 10px; }
.final-cta__text--last { margin-bottom: 28px; }

/* Padding scopé à cette section : gap/min-height/font-size sont déjà
   partagés par les deux boutons d'achat de la page via .btn--buy lui-même
   (posé section 8) ; seul le padding horizontal diffère (30px ici contre
   24px pour le premier bouton) — vérifié dans le prototype (ligne 759,
   contre 539). */
.final-cta__wrap .btn--buy { padding: 16px 30px; }

.final-cta__note { margin: 14px 0 0; font-size: 13px; color: var(--slate); }

/* ==========================================================================
   Pied de page — identique sur les cinq pages du tunnel (à recopier tel
   quel aux tâches 13 et 14). Bloc footer. Le balisage cible ne porte aucune
   classe supplémentaire sur le <div class="container"> qui aligne logo et
   nav : la disposition flex du prototype (ligne 768) est donc scopée par
   sélecteur descendant .footer .container, même mécanique que
   .price__card .btn--buy plutôt qu'une classe HTML de plus.
   ========================================================================== */

.footer {
  padding: 36px 20px 48px;
  background: var(--white);
  border-top: 1px solid var(--line);
}

.footer .container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.footer__logo { height: 20px; width: auto; display: block; opacity: 0.9; }

.footer__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  font-size: 14px;
}
/* Slate, sans style-hover propre dans le prototype (lignes 771-774, à la
   différence des CTA qui en portent tous un) : le survol ne change rien. */
.footer__nav a { color: var(--slate); text-decoration: none; }
/* Fix round 1/5 : rendu explicite plutôt que confié à l'ordre de la
   cascade. Avant ce correctif, l'absence de changement au survol ne tenait
   qu'à un hasard de spécificité égale entre .footer__nav a et le a:hover
   global (bordeaux, tête de fichier) — cette règle-ci gagnait seulement
   parce qu'elle vient après lui dans le fichier. Un pied de page recopié
   tel quel sur cinq pages (tâches 13 et 14) finirait par casser ce hasard
   dans l'une d'elles sans que personne ne le voie. Zéro changement visuel
   (vérifié en rendu réel avant/après cette règle, voir rapport) ; le
   risque disparaît avant d'être multiplié par cinq. */
.footer__nav a:hover { color: var(--slate); text-decoration: none; }

.footer__legal {
  max-width: 1000px;
  margin: 20px auto 0;
  font-size: 12px;
  /* --slate, pas --gray : ce n'est pas un état atténué comme les étiquettes
     "Aujourd'hui" de la section 2, c'est la mention de l'éditeur. --gray sur
     blanc mesurait 2,54:1 à la revue finale, loin sous le seuil WCAG AA. */
  color: var(--slate);
}

/* ==========================================================================
   Barre CTA collante, mobile uniquement. Part masquée (attribut hidden posé
   dans le HTML) ; vente.js la démasque à la tâche 12 quand la section 2
   entre dans la fenêtre — le conteneur sticky du prototype (lignes 780-789)
   n'est délibérément pas reproduit, voir task-9-report.md pour le
   raisonnement complet (effet invisible à la lecture, cassé sans bruit par
   un réordonnancement du balisage). Jamais de lien Stripe ici : c'est ce qui
   préserve la règle « aucun CTA d'achat au-dessus de la ligne de
   flottaison » alors même que la barre suit le lecteur.
   ========================================================================== */

.sticky-cta { display: none; }

@media (max-width: 600px) {
  .sticky-cta {
    display: block;
    position: sticky;
    bottom: 0;
    z-index: 45;
    margin-top: -76px;
    padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
    /* Blanc à 97 %, prototype ligne 781 : aucun token existant pour cette
       opacité précise (--white-wash-25/-15 sont les deux seules réserves
       posées par la tâche 9) ; laissé en rgba() plutôt que d'en créer un
       troisième pour un usage unique, comme demandé pour cet envoi. */
    background: rgba(255, 255, 255, 0.97);
    border-top: 1px solid var(--line);
  }
  .sticky-cta__btn { display: flex; width: 100%; }

  /* Padding-bottom supplémentaire du pied de page, mobile uniquement : la
     barre collante ci-dessus (.sticky-cta, juste après .footer dans le DOM)
     se pose avec un margin-top de -76px, ce qui la fait recouvrir les 76
     derniers pixels de ce qui la précède dans le flux normal — ici, la fin
     du pied de page. Les 48px de padding-bottom habituels (règle .footer,
     plus haut) ne suffisent pas : la revue finale a mesuré .footer__legal
     entièrement recouverte par la barre en bas de page, à 390px, sans façon
     de défiler plus loin pour la révéler. 124px = 48px habituels + 76px pour
     absorber tout le recouvrement, en conservant les 48px de respiration
     d'origine sous la mention légale. */
  .footer { padding-bottom: 124px; }
}

/* L'attribut natif [hidden] doit rester prioritaire sur le display: block/
   flex ci-dessus (règles d'auteur), sans quoi la barre resterait visible au
   chargement malgré [hidden] — même piège que .player__sound[hidden]
   (tâche 10). Le sélecteur d'attribut ajoute une spécificité supérieure à la
   classe seule, donc ces deux règles l'emportent quelle que soit leur
   position dans le fichier par rapport à la media query. La seconde
   (.sticky-cta__btn[hidden]) n'est pas demandée littéralement par la
   consigne de cet envoi, mais partage exactement le même mécanisme que la
   première sur le bouton de phase 2 : sans elle, les deux boutons de phase
   s'afficheraient l'un sur l'autre dès que la tâche 12 démasque la barre. */
.sticky-cta[hidden] { display: none; }
.sticky-cta__btn[hidden] { display: none; }

/* ==========================================================================
   Overlay de lightbox, en fin de <body>. Part masqué (attribut hidden) ;
   vente.js l'ouvre à la tâche 12 au clic sur une vignette. Les vignettes
   elles-mêmes portent déjà cursor: zoom-in depuis les tâches 9 et 10
   (.direction__frame, .trace__media, .inventory__frame).
   ========================================================================== */

.lightbox {
  display: flex;
  position: fixed;
  inset: 0;
  z-index: 100;
  align-items: center;
  justify-content: center;
  padding: clamp(16px, 3vw, 48px);
  /* Overlay à 92 % d'opacité, prototype ligne 60 : aucun token existant pour
     cette valeur précise (--ink-wash-80/-25 sont les deux seules réserves,
     tâches 9 et 10) ; laissé en rgba(), même règle que le blanc à 97 % de la
     barre collante ci-dessus. */
  background: rgba(17, 17, 17, 0.92);
  cursor: zoom-out;
}
/* Règle jumelle de .sticky-cta[hidden] : display: flex ci-dessus est une
   propriété d'auteur qui bat [hidden] sans cette redéclaration, sans quoi
   l'overlay resterait visible au chargement. */
.lightbox[hidden] { display: none; }

.lightbox__img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 8px;
}

.lightbox__close {
  position: absolute;
  top: 16px;
  right: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-round);
  /* Blanc à 12 %, prototype ligne 62 : troisième et dernier rgba() sans
     token de cet envoi, même règle que les deux précédents. */
  background: rgba(255, 255, 255, 0.12);
  border: 0;
  cursor: pointer;
  color: var(--white);
}
.lightbox__close:hover { background: var(--bordeaux); }

/* ==========================================================================
   Page de remerciement (/merci) — tâche 13. Prototype lignes 795-824, écran
   isMerci : un seul bloc, sans section numérotée. Bloc .merci. Le pied de
   page qui suit (.footer, plus haut dans ce fichier) est recopié tel quel
   dans merci.html, sans règle CSS propre à ajouter ici.
   ========================================================================== */

.merci__wrap {
  max-width: 620px;
  margin: 0 auto;
  padding: clamp(28px, 4vw, 48px) 20px clamp(48px, 8vw, 96px);
  text-align: center;
}

.merci__logo {
  height: clamp(32px, 4.5vw, 44px);
  width: auto;
  display: block;
  margin: 0 auto clamp(32px, 5vw, 56px);
}

.merci__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: var(--radius-round);
  background: var(--bordeaux-wash);
  color: var(--bordeaux);
  margin-bottom: 28px;
}

.merci__title {
  margin: 0 0 24px;
  font-size: clamp(30px, 4.4vw, 44px);
  line-height: 1.12;
  letter-spacing: -0.025em;
  font-weight: 700;
  color: var(--ink);
}

/* font-size seul diffère du défaut du body (17px) ; line-height (1.65) et
   color (#111111 = --ink) sont déjà celui hérité, non redéclarés — même
   convention que .founder__text / .faq__answer p. */
.merci__text { margin: 0 0 18px; font-size: 18px; text-align: left; }
.merci__text--last { margin-bottom: 36px; }

.merci__note {
  background: var(--bone);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 20px;
  text-align: left;
}

/* Même label que les eyebrows du reste du site : taille, majuscules,
   traçage et couleur viennent du primitif .eyebrow. Seule différence du
   prototype (ligne 807) avec ce primitif : graisse 600 au lieu de 500. */
.merci__note-label { margin: 0 0 8px; font-weight: 600; }

/* Même règle d'omission que .merci__text ci-dessus : line-height et color
   égalent déjà le défaut du body. */
.merci__note-text { margin: 0; font-size: 16px; }

/* ==========================================================================
   Pages légales (/confidentialite, /conditions, /mentions-legales) — tâche
   14. Prototype lignes 826-901 : gabarit commun aux trois pages (logo,
   pills de navigation croisée, article, lien de retour), contenu propre à
   chaque page dans l'<article> (lignes 835-850, 851-866, 867-882). Bloc
   .legal. Le pied de page qui suit (.footer, plus haut dans ce fichier) est
   recopié tel quel dans les trois fichiers, sans règle CSS propre ici.
   ========================================================================== */

.legal__wrap {
  max-width: 760px;
  margin: 0 auto;
  padding: clamp(28px, 4vw, 48px) 20px clamp(48px, 7vw, 80px);
}

/* Logo de tête des pages légales, devenu un lien vers la page de vente
   (correctif du 8 août 2026) — jamais sur /merci (renvoyer un acheteur vers
   ce qu'il vient d'acheter n'a pas de sens), jamais le logo du pied de page
   ni celui du hero de la page de vente, restés de simples images. Libellé
   accessible identique au lien texte .legal__back plus bas : « Retour à la
   page de vente », porté par aria-label sur le lien lui-même plutôt que par
   l'alt de l'image (resté "AutoHired") — un aria-label sur l'ancêtre prime
   sur son contenu dans le calcul du nom accessible, donc un lecteur d'écran
   n'annonce que lui, jamais les deux à la suite.
   display: block + width: fit-content pour que la marge automatique centre
   le lien à la place de l'image (même technique que .hero__cta plus haut). */
.legal__logo {
  display: block;
  width: fit-content;
  margin: 0 auto clamp(24px, 4vw, 40px);
}
/* Neutralisé explicitement, même raison que .footer__nav a:hover et
   .legal__tab:hover : sans cette règle, le a:hover global (bordeaux-hover +
   soulignement, tête de fichier) s'applique quand même à ce lien, vérifié en
   rendu réel (voir le rapport du correctif) — text-decoration ne se serait
   pas vu (pas de texte dans ce lien), mais color s'appliquait bel et bien,
   simplement sans effet visible tant que ce lien ne contient qu'une image.
   Repris à --bordeaux (sa couleur de repos, pas --bordeaux-hover) pour ne pas
   laisser un futur contenu texte hériter d'un survol jamais voulu ici. */
.legal__logo:hover { color: var(--bordeaux); text-decoration: none; }
/* Anneau de focus clavier : ce logo est nouvellement interactif et n'en
   hérite aucun ailleurs sur la page. Couleur reprise de --bordeaux, déjà la
   couleur d'interaction du site (liens, pastille active des onglets). */
.legal__logo:focus-visible {
  outline: 2px solid var(--bordeaux);
  outline-offset: 4px;
  border-radius: 4px;
}

.legal__logo-img {
  height: clamp(32px, 4.5vw, 44px);
  width: auto;
  display: block;
}

.legal__tabs {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: center;
  margin-bottom: clamp(32px, 5vw, 48px);
}

/* Pills de navigation croisée entre les trois pages légales. Le prototype
   ne donne aucune valeur littérale pour ce composant : les trois boutons
   sont liés à une variable calculée par l'outil de prototypage ({{ tabConf
   }} etc.), jamais un style inline lisible — même situation que
   .lightbox__img (tâche 11). Valeurs ci-dessous choisies à ma discrétion,
   cohérentes avec le système existant (rayon --radius-pill déjà réservé à
   cet usage, jamais utilisé en stade plein avant cette tâche ; couleurs
   posées d'après la règle écrite de la consigne : pill active en bordure et
   texte bordeaux sur lavis 8 %, pills inactives neutres). Hover neutralisé
   explicitement pour les deux états, même raison que .footer__nav a:hover :
   sans ces règles, le a:hover global (bordeaux-hover + soulignement)
   gagnerait sur .legal__tab au survol, aucune des deux couleurs n'étant une
   valeur voulue ici. */
.legal__tab {
  display: inline-flex;
  align-items: center;
  padding: 8px 16px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line-strong);
  background: var(--white);
  font-size: 14px;
  font-weight: 500;
  line-height: 1.2;
  color: var(--ink);
  text-decoration: none;
}
.legal__tab:hover { color: var(--ink); text-decoration: none; }

.legal__tab--active {
  border-color: var(--bordeaux);
  background: var(--bordeaux-wash);
  color: var(--bordeaux);
}
.legal__tab--active:hover { color: var(--bordeaux); text-decoration: none; }

.legal__eyebrow { margin: 0 0 10px; }

.legal__title {
  margin: 0 0 8px;
  font-size: clamp(28px, 4vw, 40px);
  line-height: 1.14;
  letter-spacing: -0.025em;
  font-weight: 700;
  color: var(--ink);
}

.legal__updated { margin: 0 0 36px; font-size: 13px; color: var(--slate); }

.legal__h2 {
  margin: 0 0 12px;
  font-size: 20px;
  line-height: 1.3;
  font-weight: 700;
  color: var(--ink);
}

/* font-size (17px) et color (--ink) égalent déjà le défaut du body, non
   redéclarés — même convention que .founder__text / .merci__text. */
.legal__body { margin: 0 0 24px; line-height: 1.7; }
.legal__body--last { margin: 0; }

.legal__back { margin: 44px 0 0; font-size: 14px; }
