/* =========================================================================
   READY RELEASE — main.css
   AI music finishing studio. Design system: editorial, dark, signal-driven.
   Palette meaning: "before" is desaturated grey; the --signal accent IS the
   sound once it has been treated. Used with extreme restraint.
   ========================================================================= */

/* ----- Fonts: Helvetica system stack (reference charter). No webfont — uses
   the visitor's installed Helvetica Neue / Helvetica, falling back to Arial.
   This is the licence-safe way to get the reference's Helvetica look. ----- */

/* ----- Design tokens ----- */
:root {
  /* color */
  --void: #0A0B0D;
  --void-2: #0E0F12;
  --surface: #121316;
  --surface-2: #17191D;
  --bone: #F2F0EB;
  --ash: #8A8F98;
  --ash-dim: #5A5F68;
  /* v86 — STUDIO 54 YELLOW / v93 — LA VALEUR EXACTE DU BRIEF.
     Le bleu de marque (#5b8bff / #3f6fe6 / #1d4ed8) est remplace par l'or,
     exactement, partout ou il servait d'accent.

     v93 : l'or est #E8C547, la valeur ecrite NEUF FOIS dans le document du
     26/08 avec la mention « Color lock (mandatory) ». La v92 lui avait
     substitue #F5C400 en invoquant un arbitrage ; le client a tranche le
     26/08 : c'est le document qui fait foi.

     Le changement est GLOBAL et non local. Le document decrit #E8C547 comme
     « the same yellow already used on the badge MOST CHOSEN » : ne le poser
     que sur les neuf textes nommes aurait mis deux jaunes cote a cote dans
     la meme carte, ce que le brief v86 interdisait deja explicitement.

     Pour revenir en arriere : #E8C547 -> #F5C400, rgba(232, 197, 71 ->
     rgba(245, 196, 0, #BCA047 -> #C99F00, #F2D56D -> #FFD426. Rien d'autre.

     Les deux variantes d'ETAT conservent l'ecart exact qu'elles avaient :
     --signal-dim est #BCA047 (soit #E8C547 moins 44/37/0, comme #C99F00
     l'etait de #F5C400) et le survol est #F2D56D (soit plus 10/16/38, comme
     #FFD426 l'etait). Ce ne sont pas d'autres jaunes, ce sont des etats.

     Le brief interdit de choisir « un jaune different selon les composants ».
     Les trois tokens ne sont pourtant pas trois nuances decoratives : ce sont
     trois ROLES (accent, remplissage, etat au repos). --signal et
     --signal-fill portent donc la meme valeur exacte, #E8C547 ; --signal-dim
     reste une variante d'ETAT du meme ton, pas un autre jaune. Sans elle, le
     survol et le repos deviennent indiscernables.

     Le nom des tokens n'est PAS renomme en --yellow : 230 usages `var()` et
     71 rgba() en dur en dependent, et un renommage massif pour un gain
     cosmetique est exactement le genre de diff qui cache une regression. */
  --signal: #E8C547;
  --signal-dim: #BCA047;
  --signal-fill: #E8C547;
  --line: rgba(242, 240, 235, 0.10);
  --line-strong: rgba(242, 240, 235, 0.18);

  /* type — v57, typographie Softriver. Trois voix, une par role :
     Inter Tight porte les titres (grotesque serree, dessinee pour les
     grandes tailles), Manrope le corps / la navigation / l'UI, Plus Jakarta
     Sans les phrases en capitales a tracking large. Montserrat n'intervient
     qu'en renfort sur les numeraux tres gras. */
  --display: 'Inter Tight Variable', 'Inter Tight', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --body: 'Manrope Variable', Manrope, 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --caps: 'Plus Jakarta Sans Variable', 'Plus Jakarta Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --heavy: 'Montserrat Variable', Montserrat, 'Inter Tight Variable', Helvetica, Arial, sans-serif;

  /* fluid type scale (clamp) */
  --fs-mega:   clamp(3rem, 8.5vw, 7.5rem);
  --fs-h1:     clamp(2.6rem, 7.5vw, 6.5rem);
  --fs-h2:     clamp(2rem, 5vw, 4.25rem);
  --fs-h3:     clamp(1.35rem, 2.6vw, 2.1rem);
  --fs-lead:   clamp(1.05rem, 1.6vw, 1.35rem);
  --fs-body:   clamp(1rem, 1.15vw, 1.125rem);
  --fs-micro:  0.8125rem;

  /* spacing / layout */
  --container: 1320px;
  --container-narrow: 940px;
  --gutter: clamp(1.25rem, 4vw, 3.5rem);
  --section-y: clamp(5rem, 12vw, 11rem);
  --radius-s: 4px;
  --radius-m: 10px;

  /* motion */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --dur: 0.7s;
}

/* ----- Reset ----- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--void);
  color: var(--bone);
  font-family: var(--body);
  font-size: var(--fs-body);
  line-height: 1.6;
  font-feature-settings: 'kern' 1, 'liga' 1;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* v106 — un mot insecable plus large que sa colonne ne doit jamais
     pousser la page. `break-word` ne coupe QUE dans ce cas : tant que le
     mot tient, rien ne change. Sans cette regle, l'adresse
     hello@readyrelease.net (un seul token de 202px) faisait deborder
     account.html de 52px et monetize-my-song.html de 54px en 375. */
  overflow-wrap: break-word;
  overflow-x: hidden;
}
img, svg, canvas, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; background: none; border: none; }
h1, h2, h3, h4 { margin: 0; font-family: var(--display); font-weight: 600; line-height: 1.02; letter-spacing: -0.02em; }
p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }

::selection { background: var(--signal-fill); color: var(--void); }

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

/* ----- Layout helpers ----- */
.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }
.container--narrow { max-width: var(--container-narrow); }
.section { padding-block: var(--section-y); position: relative; }
.eyebrow {
  font-family: var(--display);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ash);
  display: inline-flex;
  align-items: center;
  gap: 0.65em;
}
.eyebrow::before {
  content: '';
  width: 1.75rem; height: 1px;
  background: var(--signal);
  display: inline-block;
}
.lead { font-size: var(--fs-lead); color: var(--ash); max-width: 46ch; line-height: 1.55; }
.text-signal { color: var(--signal); }
.text-ash { color: var(--ash); }
.mono-label {
  font-family: var(--display);
  font-size: var(--fs-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash);
}

/* =========================================================================
   HEADER
   ========================================================================= */
.site-head {
  position: fixed; inset: 0 0 auto 0; z-index: 100;
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.15rem var(--gutter);
  transition: padding 0.4s var(--ease), background 0.4s var(--ease), border-color 0.4s var(--ease);
  border-bottom: 1px solid transparent;
}
.site-head.is-scrolled {
  padding-block: 0.7rem;
  background: rgba(10, 11, 13, 0.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom-color: var(--line);
}
.brand {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.02rem;
  letter-spacing: -0.01em;
  display: inline-flex; align-items: center; gap: 0.55rem;
}
.brand__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--signal); flex: none; }
.nav { display: flex; align-items: center; gap: clamp(1.25rem, 2.6vw, 2.4rem); }
.nav__link {
  font-size: 0.9rem; color: var(--ash);
  position: relative; padding-block: 0.25rem;
  transition: color 0.3s var(--ease);
}
.nav__link::after {
  content: ''; position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: left; transition: transform 0.35s var(--ease);
}
.nav__link:hover { color: var(--bone); }
.nav__link:hover::after { transform: scaleX(1); }

.nav-toggle { display: none; }

/* =========================================================================
   BUTTONS
   ========================================================================= */
.btn {
  --pad-y: 0.9rem; --pad-x: 1.5rem;
  display: inline-flex; align-items: center; gap: 0.6rem;
  font-family: var(--display); font-weight: 500; font-size: 0.92rem;
  letter-spacing: 0.02em;
  padding: var(--pad-y) var(--pad-x);
  border-radius: var(--radius-s);
  transition: transform 0.3s var(--ease), background 0.3s var(--ease), color 0.3s var(--ease), border-color 0.3s var(--ease);
  white-space: nowrap;
}
.btn__arrow { transition: transform 0.35s var(--ease); }
.btn:hover .btn__arrow { transform: translateX(4px); }
.btn--primary { background: var(--signal-fill); color: var(--void); }
.btn--primary:hover { background: #F2D56D; transform: translateY(-2px); }
.btn--ghost { color: var(--bone); border: 1px solid var(--line-strong); }
.btn--ghost:hover { border-color: var(--bone); transform: translateY(-2px); }
.btn--small { --pad-y: 0.6rem; --pad-x: 1rem; font-size: 0.82rem; }
.btn--block { width: 100%; justify-content: center; }

/* =========================================================================
   HERO
   ========================================================================= */
.hero {
  min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  padding-top: 7rem; padding-bottom: 3rem;
  position: relative; overflow: hidden;
}
.hero__wave {
  position: absolute;
  left: 0; right: 0;
  top: 50%; height: 42%;
  transform: translateY(-50%);
  z-index: 0;
  opacity: 0.22;
  mask-image: linear-gradient(90deg, transparent, #000 20%, #000 80%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 20%, #000 80%, transparent);
  pointer-events: none;
}
.hero__inner { position: relative; z-index: 1; }
.hero__title {
  font-size: var(--fs-mega);
  font-weight: 700;
  letter-spacing: -0.035em;
  margin-top: 1.25rem;
  text-wrap: balance;
}
.hero__title .line { display: block; overflow: hidden; }
.hero__title .line > span { display: block; }
.hero__sub {
  margin-top: 1.75rem;
  font-size: var(--fs-lead);
  color: #b9bdc4;
  max-width: 40ch;
  line-height: 1.5;
}
.hero__actions { display: flex; flex-wrap: wrap; gap: 0.85rem; margin-top: 2.25rem; }
/* v53 — la place des deux boutons retires. 3.0625rem = 0.9rem de padding en
   haut et en bas + la ligne de 0.92rem, soit exactement la hauteur d'un .btn.
   Le compteur et l'invite de defilement gardent donc leur position au pixel
   pres, et le hero ne se recompose pas. */
/* v62 — la reserve tombe a zero : le bandeau occupe desormais l'espace
   qu'elle tenait vide depuis la v53. */
.hero__actions--reserved { min-height: 0; pointer-events: none; }
.hero__reassure {
  margin-top: 2.5rem;
  display: flex; flex-wrap: wrap; gap: 0.75rem 1.5rem;
  font-family: var(--display); font-size: var(--fs-micro);
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--ash);
}
.hero__reassure span { display: inline-flex; align-items: center; gap: 0.5rem; }
.hero__reassure span::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--signal-dim); }

/* =========================================================================
   PROBLEM / EDITORIAL STATEMENT
   ========================================================================= */
.statement {
  font-size: var(--fs-h1);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.0;
  max-width: 18ch;
  text-wrap: balance;
}
.statement .muted { color: var(--ash-dim); }
.statement-block { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: clamp(2rem, 6vw, 5rem); align-items: end; }
.statement-block__aside { padding-bottom: 0.5rem; }
.statement-block__aside p + p { margin-top: 1.1rem; }

/* transformation strip */
.transform-strip {
  margin-top: clamp(3rem, 7vw, 5.5rem);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: clamp(1rem,4vw,3rem);
  padding-block: clamp(1.5rem, 4vw, 2.75rem);
}
.transform-strip__state { display: flex; flex-direction: column; gap: 0.35rem; }
.transform-strip__state .k { font-family: var(--display); font-size: var(--fs-micro); letter-spacing: 0.18em; text-transform: uppercase; color: var(--ash); }
.transform-strip__state .v { font-family: var(--display); font-size: clamp(1.4rem, 3vw, 2.4rem); font-weight: 600; letter-spacing: -0.02em; }
.transform-strip__state.is-after .v { color: var(--signal); }
.transform-strip__arrow { color: var(--ash); font-size: 1.5rem; }

/* =========================================================================
   A/B AUDIO COMPARISON
   ========================================================================= */
.ab {
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  background: linear-gradient(180deg, var(--surface), var(--void-2));
  padding: clamp(1.5rem, 4vw, 2.75rem);
  margin-top: clamp(2.5rem, 6vw, 4rem);
}
.ab__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 1rem; margin-bottom: 1.75rem; }
.ab__switch { display: inline-flex; border: 1px solid var(--line-strong); border-radius: var(--radius-s); overflow: hidden; }
.ab__switch button {
  font-family: var(--display); font-size: 0.82rem; letter-spacing: 0.08em; text-transform: uppercase;
  padding: 0.55rem 1.1rem; color: var(--ash); transition: color 0.3s var(--ease), background 0.3s var(--ease);
}
.ab__switch button[aria-pressed="true"] { background: var(--signal-fill); color: var(--void); }
.ab__switch button:not([aria-pressed="true"]):hover { color: var(--bone); }
.ab__stage { display: flex; align-items: center; gap: clamp(1rem,3vw,1.75rem); }
.ab__play {
  flex: none; width: 64px; height: 64px; border-radius: 50%;
  border: 1px solid var(--line-strong); display: grid; place-items: center;
  transition: border-color 0.3s var(--ease), transform 0.3s var(--ease), background 0.3s var(--ease);
}
.ab__play:hover { border-color: var(--signal); transform: scale(1.04); }
.ab__play svg { width: 22px; height: 22px; fill: var(--bone); transition: fill 0.3s var(--ease); }
.ab__play:hover svg { fill: var(--signal); }
.ab__wave { flex: 1; height: 88px; }
.ab__meta { display: flex; justify-content: space-between; margin-top: 1.1rem; font-family: var(--display); font-size: var(--fs-micro); letter-spacing: 0.1em; text-transform: uppercase; color: var(--ash); }
.ab__note { margin-top: 1.5rem; font-size: 0.85rem; color: var(--ash-dim); max-width: 60ch; }

/* =========================================================================
   PROCESS 01 → 05 (sticky visual + scrolling content)
   ========================================================================= */
.process { position: relative; }
.process__layout { display: grid; grid-template-columns: 0.85fr 1.15fr; gap: clamp(2rem, 6vw, 5rem); }
.process__sticky { position: sticky; top: 0; height: 100svh; display: flex; flex-direction: column; justify-content: center; }
.process__index { font-family: var(--display); font-weight: 700; letter-spacing: -0.03em; line-height: 0.9; }
.process__index .cur { font-size: clamp(5rem, 16vw, 13rem); color: var(--bone); transition: color 0.5s var(--ease); }
.process__index .cur.is-live { color: var(--signal); }
.process__index .total { font-size: clamp(1.5rem, 3vw, 2.25rem); color: var(--ash-dim); }
.process__visual { margin-top: 2rem; height: 120px; }
.process__steps { padding-block: clamp(3rem, 10vw, 8rem); }
.process__step {
  min-height: 78svh; display: flex; flex-direction: column; justify-content: center;
  border-top: 1px solid var(--line);
  padding-block: 2rem;
  opacity: 0.35; transition: opacity 0.5s var(--ease);
}
.process__step.is-active { opacity: 1; }
.process__step .num { font-family: var(--display); font-size: var(--fs-micro); letter-spacing: 0.18em; color: var(--signal); }
.process__step h3 { font-size: var(--fs-h3); margin-top: 0.75rem; }
.process__step p { margin-top: 1rem; color: var(--ash); max-width: 44ch; }
.process__step ul { margin-top: 1.25rem; display: flex; flex-wrap: wrap; gap: 0.5rem; }
.process__step li { font-family: var(--display); font-size: var(--fs-micro); letter-spacing: 0.05em; text-transform: uppercase; color: var(--ash); border: 1px solid var(--line); border-radius: 999px; padding: 0.35rem 0.85rem; }

/* =========================================================================
   COMPARISON — three approaches
   ========================================================================= */
.compare { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius-m); overflow: hidden; margin-top: clamp(2.5rem,6vw,4rem); }
.compare__col { background: var(--void); padding: clamp(1.5rem, 3vw, 2.5rem); display: flex; flex-direction: column; gap: 1.25rem; }
.compare__col.is-hero { background: var(--surface); }
.compare__col h3 { font-family: var(--display); font-size: 0.95rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ash); font-weight: 500; }
.compare__col.is-hero h3 { color: var(--signal); }
.compare__col ul { display: flex; flex-direction: column; gap: 0.85rem; }
.compare__col li { font-size: 1.05rem; color: var(--ash); display: flex; align-items: baseline; gap: 0.6rem; }
.compare__col.is-hero li { color: var(--bone); }
.compare__col li::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--ash-dim); flex: none; transform: translateY(-2px); }
.compare__col.is-hero li::before { background: var(--signal); }
.compare__tag { margin-top: auto; font-family: var(--display); font-size: var(--fs-micro); letter-spacing: 0.1em; text-transform: uppercase; color: var(--ash-dim); }
.compare__col.is-hero .compare__tag { color: var(--signal); }

/* =========================================================================
   PRICING
   ========================================================================= */
.pricing-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; margin-top: clamp(2.5rem,6vw,4rem); }
.price-card {
  border: 1px solid var(--line); border-radius: var(--radius-m);
  background: var(--void-2); padding: clamp(1.75rem, 3vw, 2.5rem);
  display: flex; flex-direction: column;
  transition: transform 0.4s var(--ease), border-color 0.4s var(--ease), background 0.4s var(--ease);
}
.price-card:hover { transform: translateY(-6px); border-color: var(--line-strong); }
.price-card.is-popular { border-color: var(--signal); background: var(--surface); }
.price-card__badge { font-family: var(--display); font-size: var(--fs-micro); letter-spacing: 0.16em; text-transform: uppercase; color: var(--signal); margin-bottom: 1rem; height: 1rem; }
.price-card__name { font-family: var(--display); font-size: 1.1rem; letter-spacing: 0.02em; color: var(--ash); font-weight: 500; }
.price-card__price { font-family: var(--display); font-size: clamp(2.75rem, 6vw, 3.75rem); font-weight: 700; letter-spacing: -0.03em; margin: 0.5rem 0 0.25rem; }
.price-card__price span { font-size: 1.25rem; color: var(--ash); font-weight: 400; }
.price-card__tagline { color: var(--ash); font-size: 0.95rem; min-height: 2.6em; }
.price-card__list { display: flex; flex-direction: column; gap: 0.7rem; margin: 1.75rem 0; padding-top: 1.75rem; border-top: 1px solid var(--line); }
.price-card__list li { font-size: 0.95rem; color: var(--bone); display: flex; align-items: baseline; gap: 0.6rem; }
.price-card__list li::before { content: '+'; color: var(--signal); font-family: var(--display); flex: none; }
.price-card .btn { margin-top: auto; }

/* =========================================================================
   DESTINATIONS
   ========================================================================= */
.dest-list { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 2.5rem; }
.dest-list li { font-family: var(--display); font-size: clamp(1.1rem,2.4vw,1.6rem); font-weight: 500; letter-spacing: -0.01em; color: var(--ash); border: 1px solid var(--line); border-radius: 999px; padding: 0.6rem 1.4rem; transition: color 0.3s var(--ease), border-color 0.3s var(--ease); }
.dest-list li:hover { color: var(--bone); border-color: var(--line-strong); }
.dest-note { margin-top: 1.75rem; font-size: 0.85rem; color: var(--ash-dim); max-width: 60ch; }

/* =========================================================================
   STATS
   ========================================================================= */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--line); border-block: 1px solid var(--line); }
.stat { background: var(--void); padding: clamp(1.75rem,4vw,3rem) clamp(1rem,2vw,1.5rem); }
.stat__value { font-family: var(--display); font-size: clamp(2.5rem,6vw,4.5rem); font-weight: 700; letter-spacing: -0.03em; line-height: 1; }
.stat__value .u { color: var(--signal); }
.stat__label { margin-top: 0.75rem; font-family: var(--display); font-size: var(--fs-micro); letter-spacing: 0.12em; text-transform: uppercase; color: var(--ash); }
.stat__note { margin-top: 0.4rem; font-size: 0.78rem; color: var(--ash-dim); }

/* =========================================================================
   TESTIMONIALS (placeholders — clearly marked, never faked)
   ========================================================================= */
.testi-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 1.25rem; margin-top: clamp(2.5rem,6vw,4rem); }
.testi {
  border: 1px dashed var(--line-strong); border-radius: var(--radius-m);
  padding: clamp(1.5rem,3vw,2.25rem); background: var(--void-2);
  display: flex; flex-direction: column; gap: 1.5rem;
}
.testi__mark { font-family: var(--display); font-size: var(--fs-micro); letter-spacing: 0.14em; text-transform: uppercase; color: var(--ash-dim); }
.testi__quote { font-size: 1.1rem; color: var(--ash); line-height: 1.5; flex: 1; }
.testi__who { display: flex; align-items: center; gap: 0.85rem; }
.testi__avatar { width: 40px; height: 40px; border-radius: 50%; background: var(--surface-2); border: 1px solid var(--line); flex: none; }
.testi__name { font-family: var(--display); font-size: 0.9rem; color: var(--ash); }
.testi__role { font-size: 0.8rem; color: var(--ash-dim); }

/* =========================================================================
   FAQ
   ========================================================================= */
.faq { border-top: 1px solid var(--line); margin-top: clamp(2rem,5vw,3.5rem); }
.faq__item { border-bottom: 1px solid var(--line); }
.faq__q {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
  padding: clamp(1.25rem,2.5vw,1.75rem) 0; text-align: left;
  font-family: var(--display); font-size: clamp(1.05rem,2vw,1.35rem); font-weight: 500; letter-spacing: -0.01em;
  transition: color 0.3s var(--ease);
}
.faq__q:hover { color: var(--signal); }
.faq__icon { flex: none; width: 22px; height: 22px; position: relative; transition: transform 0.4s var(--ease); }
.faq__icon::before, .faq__icon::after { content: ''; position: absolute; background: currentColor; }
.faq__icon::before { left: 0; top: 50%; width: 100%; height: 1.5px; transform: translateY(-50%); }
.faq__icon::after { top: 0; left: 50%; height: 100%; width: 1.5px; transform: translateX(-50%); transition: transform 0.4s var(--ease); }
.faq__item[aria-expanded="true"] .faq__icon { transform: rotate(180deg); }
.faq__item[aria-expanded="true"] .faq__icon::after { transform: translateX(-50%) scaleY(0); }
.faq__a { overflow: hidden; height: 0; transition: height 0.45s var(--ease); }
.faq__a-inner { padding-bottom: clamp(1.25rem,2.5vw,1.75rem); color: var(--ash); max-width: 68ch; line-height: 1.6; }
.faq__a-inner strong { color: var(--bone); font-weight: 600; }

/* =========================================================================
   FINAL CTA
   ========================================================================= */
.final { text-align: center; padding-block: clamp(6rem, 16vw, 13rem); }
.final__title { font-size: var(--fs-h1); font-weight: 700; letter-spacing: -0.035em; text-wrap: balance; }
.final__title .muted { color: var(--ash-dim); }
.final__sub { margin: 1.75rem auto 2.5rem; color: var(--ash); font-size: var(--fs-lead); max-width: 42ch; }

/* =========================================================================
   FOOTER
   ========================================================================= */
.site-foot { border-top: 1px solid var(--line); padding-block: clamp(3rem,7vw,5rem) 2.5rem; }
.foot-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: clamp(2rem,5vw,4rem); }
.foot__brand { font-family: var(--display); font-weight: 700; font-size: 1.3rem; letter-spacing: -0.01em; }
.foot__desc { margin-top: 1rem; color: var(--ash); font-size: 0.92rem; max-width: 32ch; }
.foot__col h4 { font-family: var(--display); font-size: var(--fs-micro); letter-spacing: 0.14em; text-transform: uppercase; color: var(--ash-dim); font-weight: 500; margin-bottom: 1.1rem; }
.foot__col ul { display: flex; flex-direction: column; gap: 0.7rem; }
.foot__col a { color: var(--ash); font-size: 0.92rem; transition: color 0.3s var(--ease); }
.foot__col a:hover { color: var(--bone); }
.foot-bottom { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem; margin-top: clamp(3rem,6vw,4.5rem); padding-top: 2rem; border-top: 1px solid var(--line); }
.foot-bottom p { font-size: 0.82rem; color: var(--ash-dim); }
/* v95 — la classe s'appelait .placeholder-note. Le mot "placeholder" ne
   doit plus exister dans le source livre au client (brief §1), pas meme
   dans un nom de classe : il se lit dans l'inspecteur. */
.foot-bottom .foot-legal { color: var(--ash-dim); font-size: 0.78rem; }
.foot-bottom .foot-legal--ask { margin-top: 0.35rem; }
.foot-bottom .foot-legal--ask a { color: var(--ash); text-decoration: none; border-bottom: 1px solid var(--line-strong); }
.foot-bottom .foot-legal--ask a:hover { color: var(--signal); border-bottom-color: var(--signal); }

/* =========================================================================
   PAGE HEADER (interior SEO pages)
   ========================================================================= */
.page-hero { padding-top: clamp(8rem, 16vw, 12rem); padding-bottom: clamp(3rem,7vw,5rem); border-bottom: 1px solid var(--line); }
.page-hero h1 { font-size: var(--fs-h1); font-weight: 700; letter-spacing: -0.035em; max-width: 18ch; text-wrap: balance; margin-top: 1.25rem; }
.page-hero .lead { margin-top: 1.75rem; max-width: 54ch; }
.breadcrumb { font-family: var(--display); font-size: var(--fs-micro); letter-spacing: 0.08em; text-transform: uppercase; color: var(--ash-dim); }
.breadcrumb a { color: var(--ash); }
.breadcrumb a:hover { color: var(--bone); }
.breadcrumb span { margin-inline: 0.5rem; }

/* answer-first block for SEO/GEO pages */
.answer-block {
  border-left: 2px solid var(--signal);
  padding-left: clamp(1.25rem, 3vw, 2rem);
  margin-block: clamp(2rem,5vw,3rem);
}
.answer-block h2 { font-size: var(--fs-h3); margin-bottom: 1rem; }
.answer-block .answer-lead { font-size: var(--fs-lead); color: var(--bone); line-height: 1.5; }
.answer-block .answer-lead strong { color: var(--signal); font-weight: 600; }

.prose h2 { font-size: var(--fs-h2); margin-top: clamp(3rem,6vw,4.5rem); margin-bottom: 1.25rem; letter-spacing: -0.025em; }
.prose h3 { font-size: var(--fs-h3); margin-top: 2.5rem; margin-bottom: 0.75rem; }
.prose p { color: var(--ash); margin-top: 1rem; max-width: 68ch; }
.prose p strong { color: var(--bone); }
.prose ul.bullets { margin-top: 1.25rem; display: flex; flex-direction: column; gap: 0.7rem; }
/* v106 — LES PUCES NE SONT PLUS DES CONTENEURS FLEX.

   `display: flex` sur un <li> transforme CHAQUE fragment du contenu en
   element flex distinct : le <strong>, le texte qui suit, le <a>, le texte
   d'apres. Quatre boites cote a cote sur une seule ligne, qui ne peuvent
   pas se renvoyer de mots. La puce ne se coupait donc jamais, quelle que
   soit la largeur : 407px de contenu dans une colonne de 335px sur
   account.html en 375, 409px sur monetize-my-song.html.

   Ce n'etait pas qu'un debordement. Le texte des puces ne s'enroulait pas
   du tout sur petit ecran : il sortait du cadre, purement et simplement.

   Le « + » redevient un marqueur absolu et le <li> un bloc normal. Le
   rendu est identique a partir du moment ou le texte tient sur une ligne,
   et correct quand il n'y tient pas. padding-left reprend la somme de
   l'ancien couple (largeur du « + » ~10px + gap 0.7rem). */
.prose ul.bullets li {
  color: var(--ash);
  display: block;
  position: relative;
  padding-left: 1.35rem;
  max-width: 66ch;
}
.prose ul.bullets li::before {
  content: '+';
  position: absolute;
  left: 0;
  top: 0;
  color: var(--signal);
  font-family: var(--display);
}
.prose a.inline-link { color: var(--bone); border-bottom: 1px solid var(--signal-dim); transition: color 0.3s var(--ease); }
.prose a.inline-link:hover { color: var(--signal); }

.related-links { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px,1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius-m); overflow: hidden; margin-top: clamp(2rem,5vw,3rem); }
.related-links a { background: var(--void); padding: 1.5rem; display: flex; flex-direction: column; gap: 0.4rem; transition: background 0.3s var(--ease); }
.related-links a:hover { background: var(--surface); }
.related-links a .rl-k { font-family: var(--display); font-size: var(--fs-micro); letter-spacing: 0.12em; text-transform: uppercase; color: var(--signal); }
.related-links a .rl-t { font-family: var(--display); font-size: 1.05rem; color: var(--bone); }

/* =========================================================================
   REVEAL animations
   ========================================================================= */
.reveal { opacity: 0; transform: translateY(28px); transition: opacity 0.8s var(--ease), transform 0.8s var(--ease); }
.reveal.is-in { opacity: 1; transform: none; }
.reveal[data-delay="1"] { transition-delay: 0.08s; }
.reveal[data-delay="2"] { transition-delay: 0.16s; }
.reveal[data-delay="3"] { transition-delay: 0.24s; }

/* =========================================================================
   RESPONSIVE
   ========================================================================= */
@media (max-width: 1024px) {
  .statement-block { grid-template-columns: 1fr; align-items: start; gap: 2.5rem; }
  .process__layout { grid-template-columns: 1fr; }
  .process__sticky { position: relative; height: auto; padding-block: 2rem 0; }
  .process__visual { display: none; }
  .process__step { min-height: auto; opacity: 1; }
  .foot-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 760px) {
  .nav { position: fixed; inset: 0; flex-direction: column; justify-content: center; gap: 1.75rem;
         background: var(--void); transform: translateX(100%); transition: transform 0.5s var(--ease); z-index: 90; }
  .nav.is-open { transform: none; }
  .nav__link { font-size: 1.5rem; color: var(--bone); }
  .nav .btn { font-size: 1rem; }
  .nav-toggle { display: flex; flex-direction: column; gap: 5px; z-index: 95; width: 28px; }
  .nav-toggle span { height: 2px; width: 100%; background: var(--bone); transition: transform 0.4s var(--ease), opacity 0.3s var(--ease); }
  .nav-toggle.is-open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .nav-toggle.is-open span:nth-child(2) { opacity: 0; }
  .nav-toggle.is-open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

  .compare, .pricing-grid, .testi-grid { grid-template-columns: 1fr; }
  .stats { grid-template-columns: 1fr 1fr; }
  .transform-strip { grid-template-columns: 1fr; text-align: center; gap: 1rem; }
  .transform-strip__arrow { transform: rotate(90deg); }
  .foot-grid { grid-template-columns: 1fr; gap: 2.5rem; }
  .ab__stage { flex-direction: column; align-items: stretch; gap: 1.25rem; }
  .ab__play { align-self: center; }
}

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

/* =========================================================================
   VIDEO HERO (reference charter)
   Full-bleed looping video background with a dark scrim for legibility, and
   a poster image that carries the look until the video plays (or if it can't
   load). Blue accent, Helvetica type, liquid glass, fade-up.
   ========================================================================= */

.hero__video-bg {
  position: absolute; inset: 0; z-index: 0;
  overflow: hidden;
  transform: scale(1.08); transform-origin: center;
  pointer-events: none;
}
.hero__video-bg video {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.hero.has-video .hero__wave { opacity: 0; }
.hero__video-scrim {
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(180deg, rgba(10,11,13,0.55) 0%, rgba(10,11,13,0.30) 42%, rgba(10,11,13,0.80) 100%),
    linear-gradient(90deg, rgba(10,11,13,0.82) 0%, rgba(10,11,13,0.30) 55%, rgba(10,11,13,0.05) 100%);
}

/* --- Liquid glass (adapted; signal-tinted, no blue) --- */
.liquid-glass {
  background: rgba(255, 255, 255, 0.02);
  background-blend-mode: luminosity;
  backdrop-filter: blur(6px) saturate(120%);
  -webkit-backdrop-filter: blur(6px) saturate(120%);
  border: none;
  box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.12);
  position: relative;
  overflow: hidden;
}
.liquid-glass::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  padding: 1.4px;
  background: linear-gradient(180deg,
    rgba(255,255,255,0.45) 0%, rgba(255,255,255,0.15) 20%,
    rgba(255,255,255,0) 40%, rgba(255,255,255,0) 60%,
    rgba(255,255,255,0.15) 80%, rgba(255,255,255,0.45) 100%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
          mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  pointer-events: none;
}

/* glass pill variant for the hero eyebrow */
.eyebrow--glass {
  padding: 0.5rem 1rem 0.5rem 0.85rem;
  border-radius: 999px;
  color: var(--bone);
}
.eyebrow--glass::before { background: var(--signal); }

/* secondary CTA as glass */
.btn--glass { color: var(--bone); border-radius: var(--radius-s); }
.btn--glass:hover { transform: translateY(-2px); }

/* --- Fade-up entrance --- */
/* IMPORTANT: fill-mode `backwards`, not `both`/`forwards`. `both`/`forwards`
   leave a residual transform on the element, which breaks backdrop-filter on
   any .liquid-glass child. `backwards` applies the start state before the run
   and releases every property on completion, so the glass blur keeps working. */
@keyframes fade-up {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: none; }
}
.animate-fade-up { animation: fade-up 0.7s var(--ease) backwards; }
.animate-fade-up.d1 { animation-delay: 0.10s; }
.animate-fade-up.d2 { animation-delay: 0.25s; }
.animate-fade-up.d3 { animation-delay: 0.40s; }
.animate-fade-up.d4 { animation-delay: 0.55s; }
.animate-fade-up.d5 { animation-delay: 0.75s; }
@media (prefers-reduced-motion: reduce) {
  .animate-fade-up { animation: none; }
  /* v51 - CHOIX CLIENT (reponse 19B) : comportement conserve tel quel.
     Sous prefers-reduced-motion, tout le fond du hero est masque, donc ni la
     video NI le poster ne s'affichent : le hero devient un aplat sombre.
     A noter, parce que la decision se relit mieux ecrite : le document de
     specification demande l'inverse ("utiliser le poster / fallback"), et
     un poster est une image fixe qui ne declenche aucun mouvement. Pour
     revenir au comportement specifie, remplacer la regle ci-dessous par :
        .hero__video-bg video { display: none; }
        .hero__video-bg { background: url(/assets/img/hero-poster.jpg) center/cover; }
     Une seule ligne a changer, aucun impact ailleurs. */
  .hero__video-bg { display: none; }
}

/* =========================================================================
   HERO FLOATING A/B CARD  (adapted from the reference "now playing" widget)
   White card so the blue accent pops against the dark hero, matching the
   reference. Not real audio — a labelled visual A/B preview.
   ========================================================================= */
.np-card {
  position: absolute; z-index: 20;
  bottom: clamp(1rem, 4vw, 2rem); right: clamp(1rem, 4vw, 2.5rem);
  width: 288px; max-width: calc(100vw - 2rem);
  display: flex; flex-direction: column; gap: 0.6rem;
}
.np-track {
  background: #fff; color: #0d0f13;
  border-radius: 16px; padding: 0.65rem 1rem 0.65rem 0.65rem;
  display: flex; align-items: center; gap: 0.75rem;
  box-shadow: 0 18px 40px -12px rgba(0,0,0,0.55);
}
.np-ico {
  flex: none; width: 44px; height: 44px; border-radius: 12px;
  background: var(--signal-fill); display: grid; place-items: center;
}
.np-ico svg { width: 20px; height: 20px; stroke: #fff; }
.np-meta { min-width: 0; flex: 1; }
.np-title { font-family: var(--display); font-weight: 600; font-size: 0.9rem; letter-spacing: -0.01em; color: #0d0f13; }
.np-sub { font-size: 0.72rem; color: #5a6270; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 1px; }
.np-bar { height: 4px; border-radius: 999px; background: #e6e8ec; margin-top: 0.55rem; overflow: hidden; }
.np-fill { display: block; height: 100%; width: 30%; border-radius: 999px; background: var(--signal-fill); }
.np-card.is-playing .np-fill { animation: np-progress 6s linear infinite; }
@keyframes np-progress { from { width: 4%; } to { width: 100%; } }
.np-times { display: flex; justify-content: space-between; margin-top: 0.35rem; font-size: 0.62rem; color: #8a909c; font-family: var(--display); letter-spacing: 0.02em; }

.np-controls { display: flex; align-items: center; gap: 0.5rem; }
.np-btn {
  flex: 1; background: #fff; color: #0d0f13; border-radius: 14px; padding: 0.5rem 0;
  font-family: var(--display); font-size: 0.78rem; font-weight: 500; letter-spacing: 0.03em;
  box-shadow: 0 10px 26px -14px rgba(0,0,0,0.55);
  transition: transform 0.2s var(--ease), color 0.2s var(--ease), background 0.2s var(--ease);
}
.np-btn:hover { transform: scale(1.04); }
.np-btn[aria-pressed="true"] { background: var(--signal-fill); color: var(--void); }
.np-play {
  flex: none; width: 40px; height: 40px; border-radius: 50%; background: #fff;
  display: grid; place-items: center; box-shadow: 0 10px 26px -12px rgba(0,0,0,0.55);
  transition: transform 0.2s var(--ease);
}
.np-play:hover { transform: scale(1.1); }
.np-play svg { width: 16px; height: 16px; fill: var(--signal-fill); }

@media (max-width: 820px) { .np-card { display: none; } }  /* keep the hero uncluttered on small screens */
@media (prefers-reduced-motion: reduce) { .np-card.is-playing .np-fill { animation: none; } }

/* =========================================================================
   MODULAR PRICING BUILDER
   ========================================================================= */
.builder { display: grid; grid-template-columns: 1.35fr 0.85fr; gap: clamp(1.25rem, 3vw, 2rem); margin-top: clamp(2rem, 5vw, 3rem); align-items: start; }
.builder__options { display: flex; flex-direction: column; gap: 0.9rem; }
.opt-card {
  display: flex; align-items: center; gap: 1rem; text-align: left; width: 100%;
  border: 1px solid var(--line); border-radius: var(--radius-m); background: var(--void-2);
  padding: clamp(1.1rem, 2.4vw, 1.6rem);
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease), transform 0.2s var(--ease);
}
.opt-card:hover { border-color: var(--line-strong); transform: translateY(-2px); }
.opt-card[aria-pressed="true"] { border-color: var(--signal); background: var(--surface); }
.opt-card__check {
  flex: none; width: 26px; height: 26px; border-radius: 7px; border: 1px solid var(--line-strong);
  display: grid; place-items: center; transition: background 0.25s var(--ease), border-color 0.25s var(--ease);
}
.opt-card[aria-pressed="true"] .opt-card__check { background: var(--signal-fill); border-color: var(--signal-fill); }
.opt-card__check::after { content: ''; width: 6px; height: 11px; border: solid var(--void); border-width: 0 2px 2px 0; transform: rotate(45deg) scale(0); transition: transform 0.25s var(--ease); margin-top: -2px; }
.opt-card[aria-pressed="true"] .opt-card__check::after { transform: rotate(45deg) scale(1); }
.opt-card__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.25rem; }
.opt-card__name { font-family: var(--display); font-weight: 600; font-size: 1.02rem; letter-spacing: -0.01em; color: var(--bone); }
.opt-card__desc { font-size: 0.85rem; color: var(--ash); line-height: 1.45; }
.opt-card__price { flex: none; font-family: var(--display); font-weight: 700; font-size: 1.3rem; letter-spacing: -0.02em; color: var(--bone); }
.builder__bonus { margin-top: 0.35rem; font-size: 0.85rem; color: var(--ash); }

.builder__summary {
  position: sticky; top: 5.5rem;
  border: 1px solid var(--line-strong); border-radius: var(--radius-m);
  background: var(--surface); padding: clamp(1.4rem, 3vw, 1.9rem);
  display: flex; flex-direction: column; gap: 0.85rem;
}
.bsum__badge { font-family: var(--display); font-size: var(--fs-micro); letter-spacing: 0.12em; text-transform: uppercase; color: var(--signal); }
.bsum__row { display: flex; justify-content: space-between; align-items: baseline; font-size: 0.95rem; color: var(--ash); }
.bsum__row span:last-child { color: var(--bone); font-family: var(--display); }
.bsum__row--save span { color: var(--signal) !important; }
.bsum__total { display: flex; justify-content: space-between; align-items: baseline; padding-top: 0.85rem; margin-top: 0.25rem; border-top: 1px solid var(--line); }
.bsum__total span:first-child { font-family: var(--display); font-size: 0.95rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ash); }
.bsum__total span:last-child { font-family: var(--display); font-weight: 700; font-size: clamp(2rem, 5vw, 2.75rem); letter-spacing: -0.03em; color: var(--bone); }
.builder__summary .btn { margin-top: 0.5rem; }
.bsum__note { font-size: 0.75rem; color: var(--ash-dim); line-height: 1.4; }

@media (max-width: 860px) {
  .builder { grid-template-columns: 1fr; }
  .builder__summary { position: static; }
}

/* =========================================================================
   RELEASE-EXPERIENCE SECTIONS (music + visuals + content positioning)
   ========================================================================= */
.hero__stat { margin-top: 1.4rem; font-family: var(--display); font-size: var(--fs-micro); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ash); }
.hero__stat b { color: var(--bone); font-weight: 700; }

.feature-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius-m); overflow: hidden; margin-top: clamp(2rem, 5vw, 3.5rem); }
.feature { background: var(--void); padding: clamp(1.5rem, 3vw, 2.25rem); display: flex; flex-direction: column; gap: 0.6rem; }
.feature .k { font-family: var(--display); font-size: var(--fs-micro); letter-spacing: 0.14em; text-transform: uppercase; color: var(--signal); }
.feature h3 { font-size: var(--fs-h3); letter-spacing: -0.02em; }
.feature p { color: var(--ash); font-size: 0.95rem; line-height: 1.55; }
.feature .price { font-family: var(--display); font-weight: 700; font-size: 1.6rem; letter-spacing: -0.02em; color: var(--bone); margin-top: 0.15rem; }
.feature ul { margin-top: 0.4rem; display: flex; flex-direction: column; gap: 0.45rem; }
.feature li { font-size: 0.9rem; color: var(--ash); display: flex; gap: 0.55rem; align-items: baseline; }
.feature li::before { content: '+'; color: var(--signal); font-family: var(--display); flex: none; }

.bignum { font-family: var(--display); font-weight: 700; font-size: clamp(3.5rem, 12vw, 8.5rem); letter-spacing: -0.04em; line-height: 0.95; }
.bignum .u { color: var(--signal); }

.pkg-band { text-align: center; border: 1px solid var(--signal); border-radius: var(--radius-m); background: var(--surface); padding: clamp(2rem, 5vw, 3.25rem); margin-top: 1.25rem; }
.pkg-band .name { font-family: var(--display); font-size: var(--fs-micro); letter-spacing: 0.16em; text-transform: uppercase; color: var(--signal); }
.pkg-band .amt { font-family: var(--display); font-weight: 700; font-size: clamp(2.75rem, 7vw, 4.25rem); letter-spacing: -0.03em; margin: 0.4rem 0 0.75rem; }
.pkg-band .sub { color: var(--ash); margin-bottom: 1.5rem; }

.problem-list { margin-top: 2rem; display: flex; flex-direction: column; gap: 0.75rem; }
.problem-list li { font-size: var(--fs-lead); color: var(--ash); }
.problem-list li b { color: var(--bone); font-weight: 500; }

.viral { text-align: center; }
.viral .dest-note { margin-inline: auto; }
.ig-band { text-align: center; border-top: 1px solid var(--line); padding-top: clamp(3rem,7vw,4.5rem); }

/* =========================================================================
   INTRO OVERLAY (full-screen animation, plays once per session)
   Hold 0-3s, fade 3s->6s, then reveal the site. Fill screen (cover).
   ========================================================================= */
/* v51 — CSS de l'ecran d'introduction retire avec le bloc HTML et
   initIntro() dans main.js. Plus aucun overlay, plus de body.intro-lock. */

/* =========================================================================
   V2 — RELEASE PRODUCTION SITE
   Master prompt §4: Inter, blue accents, restraint. Everything below is
   additive; earlier rules stay untouched so the SEO pages keep rendering.
   ========================================================================= */

:root {
  /* v57 — ce second :root ecrasait le premier depuis la v2 : c'est LUI qui
     decide. Switzer n'a jamais ete livre (dossier /assets/fonts vide), la
     page tournait donc en Helvetica systeme. Remplace par la charte
     Softriver, cette fois avec les fichiers presents. */
  --display: 'Inter Tight Variable', 'Inter Tight', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --body: 'Manrope Variable', Manrope, 'Helvetica Neue', Helvetica, Arial, sans-serif;
  /* v57 — .mono n'est plus une monospace mais la voix "capitales" de la
     charte Softriver. Le chiffre reste aligne grace a 'tnum' declare sur
     .mono ; sur les compteurs et les prix, verifier l'alignement colonne. */
  --mono: var(--caps);
  --rbar-h: 64px;
}

/* ---------- utilities ---------- */
/* class-level display rules outrank the UA [hidden] rule — this puts it back */
[hidden] { display: none !important; }
.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: -9999px; top: 0; z-index: 200;
  background: var(--signal-fill); color: var(--void); padding: 0.75rem 1.25rem;
}
.skip-link:focus { left: 1rem; top: 1rem; }
:where(a, button, select, [tabindex]):focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 3px;
  border-radius: 3px;
}
.ph-tag {
  display: inline-block; font-size: 0.68rem; letter-spacing: 0.14em;
  text-transform: uppercase; border: 1px solid var(--line-strong);
  color: var(--ash-dim); padding: 0.15em 0.5em; border-radius: 3px;
  margin-right: 0.5rem;
}
.ph-note { margin-top: 1.5rem; color: var(--ash-dim); font-size: 0.88rem; }
code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.9em; color: var(--ash); }

/* ---------- header ---------- */
.nav__link.is-active { color: var(--bone); }
.nav__link.is-active::after { transform: scaleX(1); background: var(--signal); }
.nav__space {
  font-size: 0.82rem; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--bone); border: 1px solid var(--line-strong);
  padding: 0.5rem 0.9rem; border-radius: var(--radius-s);
  transition: border-color 0.3s var(--ease);
}
.nav__space:hover { border-color: var(--bone); }

/* ---------- hero ---------- */
.hero__title { font-weight: 800; letter-spacing: -0.035em; }
.hero__claim {
  margin-top: 1.5rem; font-family: var(--display); font-weight: 700;
  font-size: clamp(1.1rem, 2.2vw, 1.6rem); letter-spacing: -0.01em;
}
.hero__sub { margin-top: 0.85rem; max-width: 52ch; }
.hero__cats {
  margin-top: 1rem; font-size: var(--fs-micro); letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--ash-dim);
}
.hero__stat--todo { color: var(--ash-dim); font-size: 0.85rem; }
.hero__hint {
  margin-top: 2.25rem; color: var(--ash); font-size: 0.9rem;
  animation: rr-bob 2.8s var(--ease) infinite;
}
@keyframes rr-bob { 0%,100% { transform: translateY(0); opacity: 0.7; } 50% { transform: translateY(5px); opacity: 1; } }

/* ---------- release map ---------- */
.section--map { padding-block: clamp(3.5rem, 8vw, 6rem); }
.map-head { display: flex; flex-direction: column; gap: 1rem; margin-bottom: clamp(2rem, 4vw, 3rem); }
.map-title { font-size: var(--fs-h3); font-weight: 700; letter-spacing: -0.02em; }
.map-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); }
.map-card {
  background: var(--void); padding: clamp(1.4rem, 2.4vw, 2rem);
  display: flex; flex-direction: column; gap: 0.55rem; min-height: 15rem;
  transition: background 0.35s var(--ease);
}
.map-card:hover { background: var(--surface); }
.map-card__num { font-family: var(--display); font-size: 0.75rem; letter-spacing: 0.2em; color: var(--signal); }
.map-card__kicker { font-size: var(--fs-micro); letter-spacing: 0.16em; text-transform: uppercase; color: var(--ash-dim); }
.map-card__title { font-family: var(--display); font-weight: 700; font-size: 1.15rem; letter-spacing: -0.01em; }
.map-card__desc { color: var(--ash); font-size: 0.92rem; line-height: 1.5; }
.map-card__go { margin-top: auto; color: var(--signal); transition: transform 0.35s var(--ease); }
.map-card:hover .map-card__go { transform: translateY(4px); }

/* ---------- diagnosis ---------- */
.diag { margin-top: clamp(2.5rem, 6vw, 4rem); }
.diag__title { font-size: var(--fs-h3); font-weight: 700; letter-spacing: -0.02em; max-width: 22ch; }
.diag__cols { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line); border: 1px solid var(--line); margin-top: 2rem; }
.diag__col { background: var(--void); padding: clamp(1.5rem, 2.5vw, 2.25rem); }
.diag__col h4 {
  font-size: var(--fs-micro); letter-spacing: 0.16em; text-transform: uppercase;
  margin-bottom: 1.25rem;
}
.diag__col--bad { color: var(--ash-dim); }
.diag__col--bad h4 { color: var(--ash-dim); }
.diag__col--good h4 { color: var(--signal); }
.diag__col ul { display: flex; flex-direction: column; gap: 0.8rem; }
.diag__col li { font-size: 0.95rem; line-height: 1.45; padding-left: 1.25rem; position: relative; }
.diag__col li::before { content: ''; position: absolute; left: 0; top: 0.6em; width: 8px; height: 1px; background: currentColor; opacity: 0.5; }
.diag__col--good li { color: var(--bone); }
.diag__col--good li::before { background: var(--signal); opacity: 1; }

/* ---------- 13-step process ---------- */
.proc { margin-top: clamp(3rem, 7vw, 5rem); }
.proc__title { font-size: var(--fs-h3); font-weight: 700; letter-spacing: -0.02em; margin-bottom: 2rem; }
.proc__table { width: 100%; border-collapse: collapse; text-align: left; }
.proc__table thead th {
  font-size: var(--fs-micro); letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ash-dim); font-weight: 500; padding-bottom: 1rem; border-bottom: 1px solid var(--line-strong);
}
.proc__table tbody tr { border-bottom: 1px solid var(--line); }
.proc__table th, .proc__table td { padding: 1.35rem 1.25rem 1.35rem 0; vertical-align: top; }
.proc__table th[scope="row"] { width: 15rem; }
.step-n { display: block; font-family: var(--display); font-size: 0.75rem; letter-spacing: 0.2em; color: var(--signal); }
.step-name { display: block; margin-top: 0.35rem; font-weight: 600; font-size: 1rem; letter-spacing: -0.01em; }
.step-do { color: var(--ash); font-size: 0.92rem; line-height: 1.55; width: 32%; }
.step-why { color: var(--bone); font-size: 1.02rem; line-height: 1.55; font-weight: 500; }
.proc__cards { display: none; }
.proc [data-steps-toggle] { margin-top: 2rem; }

/* ---------- summary ---------- */
.sum { margin-top: clamp(2.5rem, 5vw, 3.5rem); max-width: 62ch; }
.sum__punch {
  margin-top: 1.5rem; font-family: var(--display); font-weight: 700;
  font-size: clamp(1.2rem, 2.6vw, 1.9rem); letter-spacing: -0.02em; color: var(--bone);
  border-left: 2px solid var(--signal); padding-left: 1.25rem;
}

/* ---------- feel the difference ---------- */
.feel { margin-top: clamp(3rem, 7vw, 5rem); }
.feel__title { font-size: var(--fs-h3); font-weight: 700; letter-spacing: -0.02em; }
.feel__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; margin-top: 2rem; }
.abu { border: 1px solid var(--line); border-radius: var(--radius-s); padding: 1.5rem; background: var(--surface); }
.abu--todo { opacity: 0.7; }
.abu__head { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; }
.abu__style { font-size: 0.85rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ash); }
.abu__specs { font-size: 0.78rem; color: var(--ash-dim); }
.abu__stage { height: 3px; background: var(--line-strong); margin: 1.5rem 0; position: relative; overflow: hidden; }
.abu__fill { position: absolute; inset: 0 auto 0 0; width: 0; background: var(--ash); transition: background 0.06s linear; }
.abu.is-after .abu__fill { background: var(--signal); }
.abu__controls { display: flex; align-items: center; justify-content: center; gap: 0.75rem; }
.abu__switch {
  font-size: 0.82rem; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ash-dim); border: 1px solid var(--line-strong); border-radius: 999px;
  padding: 0.45rem 0.9rem; transition: all 0.25s var(--ease);
}
.abu__switch.is-on { color: var(--bone); border-color: var(--bone); }
.abu__switch[data-ab-side="after"].is-on { color: var(--signal); border-color: var(--signal); }
.abu__play {
  width: 44px; height: 44px; border-radius: 50%; background: var(--signal-fill);
  display: grid; place-items: center; flex: none;
}
.abu__play svg { width: 18px; height: 18px; fill: #fff; }
.abu__play:disabled { background: var(--surface-2); }
.abu__todo { margin-top: 1rem; font-size: 0.85rem; color: var(--ash-dim); }

/* ---------- section CTA ---------- */
.sec-cta { margin-top: clamp(2rem, 4vw, 3rem); display: flex; flex-direction: column; gap: 0.6rem; align-items: flex-start; }
.sec-cta--inline { margin-top: 1.75rem; }
.add-btn {
  font-family: var(--display); font-weight: 600; font-size: 0.95rem; letter-spacing: 0.02em;
  background: var(--signal-fill); color: var(--void); padding: 1rem 1.75rem; border-radius: var(--radius-s);
  transition: background 0.3s var(--ease), transform 0.3s var(--ease), color 0.3s var(--ease);
}
.add-btn:hover:not(:disabled) { background: #F2D56D; transform: translateY(-2px); }
.add-btn.is-on { background: transparent; color: var(--signal); border: 1px solid var(--signal); }
.add-btn:disabled { background: var(--surface-2); color: var(--ash-dim); cursor: not-allowed; }
.sec-cta__note, .sec-cta__bundle { font-size: 0.85rem; color: var(--ash-dim); }
.sec-cta__bundle { color: var(--signal); }

/* ---------- product blocks ---------- */
.mantra {
  margin-top: 1.75rem; font-family: var(--display); font-weight: 600;
  font-size: clamp(1.05rem, 2.2vw, 1.5rem); letter-spacing: -0.015em;
  color: var(--ash); max-width: 40ch;
}
.prod { margin-top: clamp(3rem, 6vw, 4.5rem); }
.prod__title { font-size: var(--fs-h3); font-weight: 700; letter-spacing: -0.02em; display: flex; align-items: baseline; gap: 0.9rem; flex-wrap: wrap; }
.prod__ratio { font-size: var(--fs-micro); letter-spacing: 0.16em; text-transform: uppercase; color: var(--signal); }
.prod__pair { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.5rem, 4vw, 3rem); margin-top: 1.5rem; }
.prod__pair h4 { font-size: var(--fs-micro); letter-spacing: 0.16em; text-transform: uppercase; color: var(--ash-dim); margin-bottom: 0.75rem; }
.prod__pair p { line-height: 1.6; }
.prod__pair > div:first-child p { color: var(--ash); font-size: 0.95rem; }
.prod__pair > div:last-child p { color: var(--bone); font-size: 1.02rem; }
.prod__note { margin-top: 1.5rem; padding-left: 1rem; border-left: 2px solid var(--signal); color: var(--bone); font-weight: 500; }
.getlist { margin-top: 1.75rem; }
.getlist h4 { font-size: var(--fs-micro); letter-spacing: 0.16em; text-transform: uppercase; color: var(--ash-dim); margin-bottom: 0.9rem; }
.getlist ul { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.getlist li { font-size: 0.85rem; color: var(--ash); border: 1px solid var(--line); border-radius: 999px; padding: 0.35rem 0.85rem; }

/* ---------- carousels ---------- */
.rail { margin-top: 2rem; position: relative; }
.rail__track {
  display: flex; gap: 1rem; overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; padding-bottom: 0.5rem;
}
.rail__track::-webkit-scrollbar { display: none; }
.rail__item { flex: 0 0 clamp(240px, 28vw, 360px); scroll-snap-align: start; }
.rail__meta { margin-top: 0.6rem; font-size: 0.82rem; color: var(--ash-dim); letter-spacing: 0.04em; }
.rail__nav { display: flex; gap: 0.5rem; margin-top: 1rem; }
.rail__btn {
  width: 40px; height: 40px; border: 1px solid var(--line-strong); border-radius: 50%;
  color: var(--bone); transition: border-color 0.3s var(--ease);
}
.rail__btn:hover:not(:disabled) { border-color: var(--bone); }
.rail__btn:disabled { color: var(--ash-dim); border-color: var(--line); }
.rail__note { margin-top: 0.9rem; font-size: 0.82rem; color: var(--ash-dim); }
.rail__sound {
  position: absolute; right: 0.6rem; bottom: 0.6rem; z-index: 2;
  font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase;
  background: rgba(10,11,13,0.72); color: var(--bone);
  border: 1px solid var(--line-strong); border-radius: 999px; padding: 0.3rem 0.7rem;
}
.ph {
  position: relative; overflow: hidden; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius-s);
  display: grid; place-items: center; text-align: center;
}
.ph > span { font-size: 0.78rem; color: var(--ash-dim); padding: 1rem; }
.ph--sq { aspect-ratio: 1 / 1; }
.ph--wide { aspect-ratio: 16 / 9; }
.ph--tall { aspect-ratio: 9 / 16; }
.ph--film { border-radius: 0; border-inline: 0; }
.rail__media { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---------- shorts anatomy ---------- */
.anat { margin-top: clamp(2.5rem, 5vw, 3.5rem); }
.anat__title { font-size: var(--fs-h3); font-weight: 700; letter-spacing: -0.02em; margin-bottom: 2rem; }
.anat__track { display: grid; grid-template-columns: repeat(5, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); }
.stage { background: var(--void); padding: 1.5rem 1.25rem; display: flex; flex-direction: column; gap: 0.6rem; }
.stage__t { font-family: var(--display); font-size: 0.75rem; letter-spacing: 0.16em; color: var(--signal); }
.stage__name { font-size: 1.05rem; font-weight: 700; letter-spacing: -0.01em; }
.stage__do { font-size: 0.88rem; color: var(--ash); line-height: 1.5; }
.stage__why { font-size: 0.98rem; color: var(--bone); line-height: 1.5; font-weight: 500; margin-top: auto; }

/* ---------- pickers ---------- */
.picker {
  margin-top: clamp(2.5rem, 5vw, 3.5rem); border: 1px solid var(--line);
  border-radius: var(--radius-s); padding: clamp(1.5rem, 3vw, 2.25rem); background: var(--surface);
}
.picker__row { display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.picker__label { font-size: var(--fs-micro); letter-spacing: 0.16em; text-transform: uppercase; color: var(--ash-dim); min-width: 7rem; }
.picker__opts { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.chip {
  font-size: 0.9rem; color: var(--ash); border: 1px solid var(--line-strong);
  border-radius: 999px; padding: 0.55rem 1.1rem; transition: all 0.25s var(--ease);
}
.chip:hover { color: var(--bone); border-color: var(--bone); }
.chip.is-on { color: var(--void); background: var(--signal-fill); border-color: var(--signal-fill); }

/* ---------- clip section ---------- */
.section--clip { padding-block: 0 var(--section-y); }
.clip-open { margin-bottom: clamp(3rem, 7vw, 5rem); }

/* ---------- v55 : bande d'ouverture du chapitre 04 ----------
   Meme geometrie que le placeholder qu'elle remplace (16:9, pleine largeur,
   pas de rayon, pas de bordure laterale), pour que le chapitre s'ouvre
   exactement la ou il s'ouvrait avant. */
.copen {
  position: relative; overflow: hidden;
  aspect-ratio: 16 / 9; background: var(--void-2);
  border-block: 1px solid var(--line);
}
.copen__v { width: 100%; height: 100%; object-fit: cover; display: block; }

/* le bouton reprend .rail__sound tel quel ; seul l'ecart au bord change,
   parce que la bande est pleine largeur et non une tuile de carrousel */
.copen__sound { right: clamp(0.9rem, 2.5vw, 2rem); bottom: clamp(0.9rem, 2.5vw, 2rem); }

/* La ligne. Blanc pur et non rose : la source est deja integralement
   magenta et violet, un rose pose dessus se noierait dedans.
   Elle est en bas a gauche, tres espacee, graisse legere — une signature,
   pas un sous-titre. Le degrade est confine au coin : un voile sur toute
   l'image assombrirait un plan que le visiteur est cense regarder. */
.copen__line {
  position: absolute; left: clamp(1rem, 3vw, 2.75rem); bottom: clamp(1.4rem, 3.5vw, 2.75rem);
  z-index: 2; margin: 0; max-width: min(88%, 46ch);
  /* sans cela la phrase casse en laissant "FOR." seul sur la seconde ligne ;
     une veuve d'un mot sur une signature de trois mots se voit */
  text-wrap: balance;
  font-family: var(--display); font-weight: 300;
  font-size: clamp(0.95rem, 1.5vw, 1.35rem);
  letter-spacing: 0.26em; text-transform: uppercase;
  color: #fff; text-shadow: 0 1px 18px rgba(10, 11, 13, 0.65);
  opacity: 0; transform: translateY(8px);
  transition: opacity 1.1s var(--ease), transform 1.1s var(--ease);
  pointer-events: none;
}
.copen__line.is-on { opacity: 1; transform: none; }

.copen::after {
  content: ''; position: absolute; inset: auto 0 0 0; height: 42%;
  background: linear-gradient(to top, rgba(10,11,13,0.55), transparent 78%);
  opacity: 0; transition: opacity 1.1s var(--ease); pointer-events: none; z-index: 1;
}
.copen.is-lined::after { opacity: 1; }

/* Chemin de repli. Si le navigateur refuse la lecture (mode economie de
   donnees, politique stricte), on rend les controles natifs — mais leur
   barre occupe le bas du cadre, exactement ou vivent la ligne et le bouton
   Sound. Les deux se chevaucheraient. Le bouton disparait (les controles
   portent deja le son) et la ligne remonte au-dessus de la barre. */
.copen.is-fallback .copen__sound { display: none; }
.copen.is-fallback .copen__line { bottom: clamp(3.6rem, 6vw, 4.6rem); }

@media (max-width: 640px) {
  .copen { aspect-ratio: 4 / 3; }
  .copen__line { letter-spacing: 0.18em; max-width: min(92%, 26ch); font-size: 0.9rem; }
}
.statement--big { font-size: var(--fs-mega); font-weight: 800; letter-spacing: -0.04em; }
.clip-pos {
  margin-top: 2rem; font-family: var(--display); font-weight: 600;
  font-size: clamp(1.15rem, 2.8vw, 1.85rem); letter-spacing: -0.02em;
  max-width: 34ch; color: var(--bone);
}
.cproc { margin-top: clamp(3rem, 6vw, 4.5rem); }
.cproc__title { font-size: var(--fs-h3); font-weight: 700; letter-spacing: -0.02em; margin-bottom: 2rem; }
.cproc__list { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); }
.cstep { background: var(--void); padding: clamp(1.4rem, 2.4vw, 2rem); display: flex; flex-direction: column; gap: 0.6rem; }
.cstep__n { font-family: var(--display); font-size: 0.75rem; letter-spacing: 0.2em; color: var(--signal); }
.cstep__name { font-size: 1.1rem; font-weight: 700; letter-spacing: -0.01em; }
.cstep__do { font-size: 0.88rem; color: var(--ash); line-height: 1.5; }
.cstep__why { font-size: 1rem; color: var(--bone); line-height: 1.5; font-weight: 500; margin-top: auto; }

/* ---------- team ---------- */
.lead--wide { max-width: 60ch; margin-top: 1.5rem; }
/* v53 — un bloc de declarations orphelin vivait ici : un selecteur avait ete
   supprime en laissant ses proprietes et son accolade fermante. Le parseur
   CSS cherchait alors une accolade OUVRANTE, la trouvait sur la regle
   suivante, et jetait cette regle avec le fatras : .logos__title n'etait
   simplement jamais appliquee. Un defaut invisible en lecture du fichier,
   silencieux dans le navigateur, et anterieur a la v52. */

/* ---------- client logos ---------- */
.logos__title { font-size: var(--fs-h3); font-weight: 700; letter-spacing: -0.02em; text-align: center; }
.logos { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: clamp(2rem,5vw,4rem); margin-top: 2.5rem; }
.logos img { max-height: 34px; width: auto; opacity: 0.65; filter: grayscale(1); }

/* ---------- order ---------- */
.order { border: 1px solid var(--line-strong); border-radius: var(--radius-s); padding: clamp(1.5rem, 3.5vw, 2.75rem); background: var(--surface); }
.order__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; }
.order__title { font-size: var(--fs-h3); font-weight: 700; letter-spacing: -0.025em; margin-top: 1rem; max-width: 20ch; }
.cur select {
  background: var(--void); color: var(--bone); border: 1px solid var(--line-strong);
  border-radius: var(--radius-s); padding: 0.55rem 0.9rem; font: inherit; font-size: 0.9rem;
}
.order__list { margin-top: 2rem; border-top: 1px solid var(--line); }
.oline { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; padding: 1.1rem 0; border-bottom: 1px solid var(--line); }
.oline.is-off { opacity: 0.55; }
.oline__label { display: block; font-weight: 600; letter-spacing: -0.01em; }
.oline__sub { display: block; font-size: 0.8rem; color: var(--ash-dim); letter-spacing: 0.06em; text-transform: uppercase; margin-top: 0.25rem; }
.oline__right { display: flex; align-items: center; gap: 1rem; flex: none; }
.oline__price { font-family: var(--display); font-weight: 600; }
.oline__rm { font-size: 0.8rem; color: var(--ash-dim); text-decoration: underline; }
.oline__rm:hover { color: var(--bone); }
.oline__add { font-size: 0.85rem; color: var(--signal); border: 1px solid var(--line-strong); border-radius: 999px; padding: 0.45rem 0.9rem; white-space: nowrap; }
.oline__add:hover { border-color: var(--signal); }
.oline__add s { color: var(--ash-dim); margin-left: 0.35rem; }
.order__totals { margin-top: 1.75rem; }
.order__row { display: flex; justify-content: space-between; gap: 1rem; padding: 0.5rem 0; color: var(--ash); }
.order__row--disc { color: var(--signal); }
.order__row--total { color: var(--bone); font-family: var(--display); font-weight: 800; font-size: clamp(1.2rem, 2.4vw, 1.6rem); border-top: 1px solid var(--line-strong); margin-top: 0.75rem; padding-top: 1rem; }
.order__tax { font-size: 0.8rem; color: var(--ash-dim); margin-top: 0.5rem; }
.order__save { font-size: 0.9rem; color: var(--signal); margin-top: 0.5rem; }
.order [data-order-cta] { margin-top: 1.75rem; --pad-y: 1.1rem; }
.order [data-order-cta]:disabled { background: var(--surface-2); color: var(--ash-dim); transform: none; }
.order__error { margin-top: 0.9rem; font-size: 0.85rem; color: var(--ash); }
.rea { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1rem; margin-top: 1.75rem; }
.rea li { font-size: 0.85rem; color: var(--ash); }
.rea__k { display: block; font-size: 0.7rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ash-dim); margin-bottom: 0.3rem; }
.aft { margin-top: clamp(2.5rem, 5vw, 3.5rem); }
.aft__title { font-size: var(--fs-h3); font-weight: 700; letter-spacing: -0.02em; }
.aft__list { display: grid; grid-template-columns: repeat(6, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); margin-top: 1.75rem; }
.aft__list li { background: var(--void); padding: 1.25rem 1rem; display: flex; flex-direction: column; gap: 0.5rem; font-size: 0.92rem; }
.aft__n { font-family: var(--display); font-size: 0.72rem; letter-spacing: 0.2em; color: var(--signal); }

/* ---------- persistent release bar ---------- */
.rbar {
  position: fixed; inset: auto 0 0 0; z-index: 90; max-height: var(--rbar-h);
  background: rgba(10, 11, 13, 0.86); backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px); border-top: 1px solid var(--line-strong);
}
.rbar__inner {
  max-width: var(--container); margin-inline: auto; height: var(--rbar-h);
  padding-inline: var(--gutter); display: flex; align-items: center; gap: 1.5rem;
}
.rbar__slots { display: flex; gap: 1.1rem; }
.rbar__slot { display: inline-flex; align-items: center; gap: 0.45rem; font-size: 0.78rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ash-dim); }
.rbar__dot { width: 7px; height: 7px; border-radius: 50%; border: 1px solid var(--ash-dim); }
.rbar__slot.is-on { color: var(--bone); }
.rbar__slot.is-on .rbar__dot { background: var(--signal); border-color: var(--signal); }
.rbar__status { font-size: 0.82rem; color: var(--ash); margin-left: auto; }
.rbar__cta { background: var(--signal-fill); color: var(--void); padding: 0.7rem 1.25rem; border-radius: var(--radius-s); font-weight: 600; font-size: 0.9rem; white-space: nowrap; }
.rbar__cta-short { display: none; }
body.has-rbar { padding-bottom: var(--rbar-h); }
.foot__cur { margin-top: 1.25rem; }

/* =========================================================================
   RESPONSIVE
   ========================================================================= */
@media (max-width: 1080px) {
  .map-grid { grid-template-columns: repeat(2, 1fr); }
  .feel__grid { grid-template-columns: 1fr; }
  .anat__track { grid-template-columns: repeat(2, 1fr); }
  .cproc__list { grid-template-columns: repeat(2, 1fr); }
    .aft__list { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 860px) {
  .nav {
    position: fixed; inset: 0; z-index: 99;
    flex-direction: column; align-items: flex-start; justify-content: center;
    gap: 1.25rem; padding: 6rem var(--gutter) 3rem;
    background: var(--void); transform: translateX(100%);
    transition: transform 0.45s var(--ease); overflow-y: auto;
  }
  .nav.is-open { transform: none; }
  .nav__link { font-size: 1.6rem; font-weight: 600; letter-spacing: -0.02em; color: var(--bone); }
  .nav-toggle { display: block; position: relative; z-index: 100; width: 30px; height: 22px; }
  .nav-toggle span { display: block; height: 1.5px; background: var(--bone); margin-bottom: 8px; transition: transform 0.35s var(--ease), opacity 0.2s; }
  .nav-toggle span:last-child { margin-bottom: 0; }
  .nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(9.5px) rotate(45deg); }
  .nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-9.5px) rotate(-45deg); }

  .prod__pair { grid-template-columns: 1fr; }
  .diag__cols { grid-template-columns: 1fr; }
  .order__head { align-items: flex-start; }

  /* the 13 steps become cards */
  .proc__table { display: none; }
  .proc__cards { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }
  .step-card { background: var(--void); padding: 1.4rem 1.25rem; display: flex; flex-direction: column; gap: 0.5rem; }
  .step-card .step-do { width: auto; }

  .rbar__status { display: none; }
  .rbar__cta-full { display: none; }
  .rbar__cta-short { display: inline; }
  .rbar__slots { gap: 0.75rem; }
  .rbar__cta { margin-left: auto; }
}

@media (max-width: 600px) {
  .map-grid { grid-template-columns: 1fr; }
  .anat__track { grid-template-columns: 1fr; }
  .cproc__list { grid-template-columns: 1fr; }
  .aft__list { grid-template-columns: 1fr; }
  .foot-grid { grid-template-columns: 1fr; }
  .oline { flex-direction: column; align-items: flex-start; gap: 0.75rem; }
  .oline__right { width: 100%; justify-content: space-between; }
  .rbar__label { display: none; }
  .rbar__inner { gap: 0.75rem; padding-inline: 1rem; }
  .rbar__slots { gap: 0.6rem; }
  .rbar__cta { padding: 0.65rem 1rem; font-size: 0.85rem; }
  .picker__row { flex-direction: column; align-items: flex-start; gap: 0.6rem; }
}

@media (prefers-reduced-motion: reduce) {
  .hero__hint { animation: none; }
  .rail__track { scroll-behavior: auto; }
}

/* the glass eyebrow is a pill; the accent rule would float outside it */
.eyebrow--glass::before { display: none; }

/* ---------- complete release ---------- */
.cmp { margin-top: clamp(1.75rem, 3.5vw, 2.5rem); padding-bottom: 0.5rem; }
.cmp__line { font-family: var(--display); font-weight: 700; font-size: clamp(1.05rem, 2.2vw, 1.4rem); letter-spacing: -0.02em; }
.cmp__sub { color: var(--ash); margin-top: 0.4rem; font-size: 0.95rem; }
.cmp__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 1.5rem; }
.cmp-card {
  text-align: left; display: flex; flex-direction: column; gap: 0.5rem;
  border: 1px solid var(--line-strong); border-radius: var(--radius-s);
  padding: 1.35rem; background: var(--void);
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.cmp-card:hover { border-color: var(--bone); }
.cmp-card.is-on { border-color: var(--signal); background: rgba(232, 197, 71, 0.08); }
.cmp-card__title { font-family: var(--display); font-weight: 700; font-size: 1.05rem; letter-spacing: -0.01em; }
.cmp-card__desc { color: var(--ash); font-size: 0.9rem; line-height: 1.5; }
.cmp-card__price { font-family: var(--display); font-weight: 800; font-size: clamp(1.3rem, 2.6vw, 1.75rem); margin-top: 0.4rem; }
.cmp-card__go { font-size: 0.85rem; color: var(--signal); letter-spacing: 0.04em; }
.cmp-extras { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1.25rem; }
.cmp-extras li { font-size: 0.82rem; color: var(--signal); border: 1px solid var(--line); border-radius: 999px; padding: 0.3rem 0.8rem; }
.cmp__note { margin-top: 1rem; font-size: 0.85rem; color: var(--ash-dim); }
@media (max-width: 700px) { .cmp__grid { grid-template-columns: 1fr; } }

/* ---------- hero: supplied line, revealed word by word ---------- */
.hero__sub--type .w { opacity: 0; transform: translateY(6px); display: inline-block; transition: opacity 0.5s var(--ease), transform 0.5s var(--ease); }
.hero__sub--type .w.in { opacity: 1; transform: none; }
.hero__stat { margin-top: 1.5rem; font-size: 0.95rem; color: var(--ash); text-transform: none; letter-spacing: 0; }
.hero__stat b { color: var(--bone); font-weight: 700; }
.hero__stat-sep { color: var(--ash-dim); margin-inline: 0.35rem; }

/* ---------- take all five ---------- */
.add-btn--lg { --pad: 1.15rem 2.25rem; padding: 1.15rem 2.25rem; font-size: 1rem; }

/* ---------- section 01 reveal block ---------- */
.sec-cta__bundle.is-revealing { animation: rr-reveal 0.6s var(--ease) both; }
@keyframes rr-reveal { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.sec-cta__formats { font-size: 0.8rem; color: var(--ash-dim); margin-top: 0.6rem; }
.picker__hint { font-size: 0.85rem; color: var(--ash-dim); margin: -0.5rem 0 1.25rem; }

/* ---------- order additions ---------- */
.order__lead { color: var(--ash); margin-top: 0.75rem; max-width: 46ch; }
.order__nudge { margin-top: 1.25rem; color: var(--signal); font-size: 0.92rem; }
.order__all { margin-top: 1rem; width: 100%; text-align: left; padding: 0.9rem 1.1rem; border: 1px dashed var(--line-strong); border-radius: var(--radius-s); color: var(--bone); font-weight: 600; transition: border-color 0.3s var(--ease); }
.order__all:hover { border-color: var(--signal); color: var(--signal); }
.oline__eta { display: block; font-size: 0.78rem; color: var(--ash-dim); margin-top: 0.3rem; }

/* ---------- carousel: drag + peek ---------- */
.rail__track { cursor: grab; }
.rail__track.is-dragging { cursor: grabbing; scroll-snap-type: none; user-select: none; }
.rail__track:focus-visible { outline: 2px solid var(--signal); outline-offset: 4px; }
.rail__nav { opacity: 0; transition: opacity 0.3s var(--ease); }
.rail:hover .rail__nav, .rail__track:focus-visible ~ .rail__nav, .rail__nav:focus-within { opacity: 1; }
@media (hover: none) { .rail__nav { display: none; } }
@media (max-width: 600px) { .rail__item { flex-basis: 80%; } }

/* ---------- client logo ticker ---------- */
.logos--ticker { display: flex; flex-wrap: nowrap; overflow: hidden; gap: 0; -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); }
.logos--ticker .logos__row { display: flex; align-items: center; gap: clamp(2.5rem, 6vw, 5rem); padding-right: clamp(2.5rem, 6vw, 5rem); animation: rr-ticker 46s linear infinite; }
.logos--ticker:hover .logos__row, .logos--ticker:focus-within .logos__row { animation-play-state: paused; }
@keyframes rr-ticker { from { transform: translateX(0); } to { transform: translateX(-100%); } }
@media (prefers-reduced-motion: reduce) {
  .logos--ticker { overflow: visible; -webkit-mask-image: none; mask-image: none; flex-wrap: wrap; justify-content: center; }
  .logos--ticker .logos__row { animation: none; flex-wrap: wrap; justify-content: center; }
  .logos--ticker .logos__row[aria-hidden="true"] { display: none; }
}

/* ============================================================
   v4 — guided CTA, price rationale, overflow diagnostics
   ============================================================ */

/* A CTA whose variant is not chosen yet: visibly secondary, still clickable.
   It collects the intent and takes the visitor to the missing choice. */
.add-btn.is-waiting {
  background: transparent;
  color: var(--bone);
  border: 1px solid var(--line);
}
.add-btn.is-waiting:hover { background: rgba(242, 240, 235, 0.06); border-color: var(--bone); }

/* The picker the visitor was sent to. */
.picker.needs-choice { animation: rr-needs 1.6s var(--ease); }
@keyframes rr-needs {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  15%, 55% { box-shadow: 0 0 0 2px var(--signal); }
}
.picker.needs-choice [data-picker-note] { color: var(--signal); }

/* Why the live-action price is what it is. */
.why-price {
  margin-top: 1.75rem; padding: 1.25rem 1.5rem;
  border: 1px solid var(--line); border-radius: var(--radius-m);
  background: var(--surface-2);
}
.why-price h4 {
  margin: 0 0 0.75rem; font-family: var(--display); font-size: var(--fs-micro);
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--ash-dim);
}
.why-price ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 0.7rem; }
.why-price li { font-size: 0.95rem; line-height: 1.5; max-width: 62ch; }
.why-price b { color: var(--bone); }
.prod__todo {
  margin-top: 1.75rem; font-size: 0.85rem; color: var(--ash-dim);
  border-left: 2px solid var(--line); padding-left: 0.9rem; max-width: 62ch;
}

/* Horizontal overflow was hidden on the body, so a real overflow could never
   be seen in a test. It stays hidden in production; ?debug=overflow releases
   it and outlines whatever is too wide. */
html[data-debug-overflow] body { overflow-x: visible; }
html[data-debug-overflow] * { outline: 1px solid rgba(255, 0, 0, 0.35); }

/* ============================================================
   v5 — self-hosted type, circular logo, hero manifesto
   ============================================================ */

/* v57 — Switzer et Geist Mono etaient declares mais jamais livres. */
/* v57 — les quatre familles Softriver, auto-hebergees, sous-jeu latin,
   axe de graisse variable (une seule requete par famille au lieu de six).
   Toutes en SIL OFL 1.1 : libres pour un usage commercial, redistribuables.
   Fichiers dans /assets/fonts, ~134 Ko au total. */
@font-face {
  font-family: 'Inter Tight Variable'; font-style: normal; font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/inter-tight-latin-wght-normal.woff2') format('woff2-variations');
  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: 'Manrope Variable'; font-style: normal; font-weight: 200 800;
  font-display: swap;
  src: url('/assets/fonts/manrope-latin-wght-normal.woff2') format('woff2-variations');
  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: 'Plus Jakarta Sans Variable'; font-style: normal; font-weight: 200 800;
  font-display: swap;
  src: url('/assets/fonts/plus-jakarta-sans-latin-wght-normal.woff2') format('woff2-variations');
  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: 'Montserrat Variable'; font-style: normal; font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/montserrat-latin-wght-normal.woff2') format('woff2-variations');
  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;
}

/* One typographic voice, not three. --editorial used to be a serif; a second
   voice on a page that already has display + mono reads as a template. It now
   resolves to the grotesque, differentiated by weight and tracking instead. */
:root { --editorial: var(--display); }

/* ---------- mono label: the single repeated micro-primitive ----------
   Every kicker, tag, counter and button label on the page uses this and
   nothing else. Consistency is what reads as expensive, not variety. */
.mono {
  font-family: var(--mono);
  font-size: 0.75rem;
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ash);
  font-feature-settings: 'tnum' 1;
}
.mono--bracket::before { content: '[ '; opacity: 0.55; }
.mono--bracket::after  { content: ' ]'; opacity: 0.55; }

/* ---------- text reveal: the single repeated motion primitive ----------
   A masked line that rises into place. Applied to headings, labels and CTAs.
   Nothing else on the page is allowed to animate its own way. */
.rv { display: block; overflow: hidden; }
.rv > * {
  display: block;
  transform: translateY(105%);
  transition: transform 0.9s var(--ease);
  transition-delay: calc(var(--rv-i, 0) * 60ms);
  will-change: transform;
}
.is-in .rv > *, .rv.is-in > * { transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
  .rv > * { transform: none; transition: none; }
}

/* ---------- circular logo, header + footer ---------- */
.brand__badge {
  width: 38px; height: 38px; border-radius: 50%; flex: none; display: block;
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease);
}
.brand:hover .brand__badge { transform: rotate(-6deg) scale(1.04); }
.brand__word { font-family: var(--display); font-weight: 700; letter-spacing: -0.01em; }
.site-head.is-scrolled .brand__badge { width: 32px; height: 32px; }
.foot__badge { width: 84px; height: 84px; border-radius: 50%; display: block; }
@media (max-width: 600px) {
  .brand__badge { width: 34px; height: 34px; }
  .brand__word { font-size: 0.95rem; }
}

/* ---------- hero manifesto: the line the visitor must keep ---------- */
.hero__sub--type {
  font-family: var(--editorial);
  font-weight: 400;
  font-size: clamp(1.45rem, 3.1vw, 2.5rem);
  line-height: 1.32;
  letter-spacing: -0.005em;
  color: var(--bone);
  max-width: 22ch;
  margin-top: 1.6rem;
  text-wrap: balance;
}
.hero__sub--type .w {
  transition: opacity 0.55s var(--ease), transform 0.55s var(--ease), filter 0.55s var(--ease);
  filter: blur(4px);
}
.hero__sub--type .w.in { filter: blur(0); }
@media (max-width: 700px) { .hero__sub--type { max-width: 18ch; } }

/* ---------- hero hint: the line that sends you down the page ---------- */
.hero__hint {
  font-family: var(--editorial);
  font-size: clamp(1.15rem, 2.4vw, 1.75rem);
  letter-spacing: 0;
  text-transform: none;
  color: var(--bone);
  text-align: center;
  margin-inline: auto;
  margin-top: clamp(2rem, 4vw, 3rem);
  opacity: 0.95;
}
.hero__hint-n {
  font-size: 1.35em;
  line-height: 1;
  display: inline-block;
  color: var(--signal);
  animation: rr-blink 1.6s steps(1, end) infinite;
}
@keyframes rr-blink { 0%, 62% { opacity: 1; } 63%, 100% { opacity: 0.28; } }
/* keeps the downward bob, drops the dimming that made it unreadable */
.hero__hint { animation: rr-bob-strong 2.8s var(--ease) infinite; }
@keyframes rr-bob-strong { 0%,100% { transform: translateY(0); } 50% { transform: translateY(6px); } }
@media (prefers-reduced-motion: reduce) {
  .hero__hint, .hero__hint-n { animation: none; opacity: 1; }
}

/* The black bands beside the hero clip were not baked into the video: the
   <section> carried .container, so the video — inset:0 inside it — stopped at
   1320px while the page kept going. The container now sits on .hero__inner,
   the section is full-bleed, and the video covers the whole viewport width.
   --hero-crop is the original 1.08 zoom that hides the clip's own edges. */
:root { --hero-crop: 1.08; }
.hero { padding-inline: 0; max-width: none; }
.hero__video-bg { transform: scale(var(--hero-crop)); }

/* The logo speaks for itself — no wordmark beside it. */
.brand { gap: 0; }
.brand__badge { width: 46px; height: 46px; }
.site-head.is-scrolled .brand__badge { width: 38px; height: 38px; }
@media (max-width: 600px) { .brand__badge { width: 40px; height: 40px; } }

/* ============================================================
   v8 — bigger logo, serif chrome, the 50M+ statement
   ============================================================ */

/* ---------- header: the logo has to be readable ----------
   The name is inside the disc, so the disc has to be big enough to read it.
   80px means a taller bar; the hero's top padding follows.

   v89 — TAILLE +10 % ET ROTATION CONTINUE (brief Word du 26/08).
   80 -> 88px au repos, et les trois autres paliers suivent la meme hausse
   (58->64, 62->68, 54->60, 48->52, 44->48). La barre ne grandit pas pour
   autant : .site-head garde son padding, le disque prend dans la reserve
   qui existait deja. */
.brand__badge { width: 88px; height: 88px; }
.site-head { padding-block: 1rem; }
.site-head.is-scrolled .brand__badge { width: 64px; height: 64px; }
.hero { padding-top: 9.5rem; }
@media (max-width: 900px) {
  .brand__badge { width: 68px; height: 68px; }
  .site-head.is-scrolled .brand__badge { width: 52px; height: 52px; }
  .hero { padding-top: 8rem; }
}
@media (max-width: 600px) {
  .brand__badge { width: 60px; height: 60px; }
  .site-head.is-scrolled .brand__badge { width: 48px; height: 48px; }
}

/* =========================================================================
   v89 — LE DISQUE TOURNE, EN PERMANENCE

   6 secondes par tour, `linear`, `infinite`. Ce n'est PAS la vitesse d'un
   33 tours : un 33 tours fait un tour en 1,8 s, ce qui, sur un element
   present en permanence dans un en-tete fixe, se lit comme une agitation et
   fatigue au bout de quelques secondes. 6 s garde la lecture de disque qui
   tourne sans capter l'attention. Arbitrage valide le 26/08.

   TROIS PIEGES CONTOURNES ICI, dans l'ordre ou ils se seraient produits :

   1. .brand__badge portait deja `transition: transform` et le survol pose
      `transform: rotate(-6deg) scale(1.04)`. Une animation et une transition
      sur la MEME propriete du MEME element : l'animation gagne toujours, le
      survol serait devenu inerte. La rotation est donc portee par un
      pseudo-parent — non, plus simple et sans toucher au HTML : elle est
      posee sur .brand__badge et le survol est reporte sur .brand, qui agit
      sur l'echelle via une variable. Voir ci-dessous.

   2. `animation` sur une image en rotation permanente maintient une couche
      de compositing active en continu. `will-change: transform` l'y place
      explicitement, ce qui evite un repeint du texte voisin a chaque image.

   3. Le disque est un PNG carre a coins arrondis en 50 % : il tourne donc
      rond. Si le fichier venait a etre remplace par un visuel non centre,
      la rotation deviendrait un balancement — le centre de rotation est le
      centre de la boite, pas celui du dessin.
   ========================================================================= */
@keyframes brand-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
.brand__badge {
  animation: brand-spin 6s linear infinite;
  will-change: transform;
}
/* Le survol ne touche plus a `transform` (il serait ignore) : il agit sur
   l'echelle du CONTENEUR, qui n'est pas anime. Le disque continue de
   tourner pendant qu'il grossit. */
.brand:hover .brand__badge { transform: none; }
.brand {
  transition: transform 0.4s var(--ease);
  transform-origin: center;
}
.brand:hover { transform: scale(1.04); }

/* Mouvement permanent = premiere chose a couper sous prefers-reduced-motion.
   Une rotation infinie est exactement le type de mouvement vise par ce
   reglage (vertiges, troubles vestibulaires). */
@media (prefers-reduced-motion: reduce) {
  .brand__badge { animation: none; will-change: auto; }
  .brand { transition: none; }
  .brand:hover { transform: none; }
}

/* ---------- the chrome takes the editorial serif ---------- */
.nav__link,
.site-head .btn,
.foot a,
.foot__col-title,
.foot__nav a {
  font-family: var(--editorial);
  letter-spacing: 0;
  text-transform: none;
}
.nav__link { font-size: 1.05rem; }
.site-head .btn { font-size: 0.98rem; letter-spacing: 0.02em; }
.foot a { font-size: 1rem; }
@media (max-width: 900px) { .nav__link { font-size: 1.6rem; } }

/* ---------- 50M+ : the loudest thing on the page ---------- */
.hero__stat--big {
  margin-top: clamp(2rem, 4vw, 3rem);
  display: flex; flex-direction: column; align-items: center; gap: 0.35rem;
  text-align: center;
  margin-inline: auto;
  text-transform: none; letter-spacing: 0;
}
.hero__stat-num {
  font-family: var(--display);
  font-weight: 900;
  font-size: clamp(3.6rem, 10vw, 7.5rem);
  line-height: 0.9;
  letter-spacing: -0.045em;
  color: var(--bone);
  display: block;
}
.hero__stat-line {
  font-family: var(--editorial);
  font-size: clamp(1rem, 1.6vw, 1.35rem);
  color: var(--ash);
  max-width: 46ch;
}
.hero__stat--big .hero__stat-sep { color: var(--ash-dim); }

/* ---------- the 4 carries the line ---------- */
.hero__hint-n {
  font-size: 2.4em;
  font-family: var(--display);
  font-weight: 900;
  vertical-align: -0.18em;
  margin-inline: 0.08em;
}

/* Between the mobile breakpoint and comfortable desktop the bigger logo plus
   the serif nav gets tight — the nav shrinks before it wraps. */
@media (min-width: 901px) and (max-width: 1200px) {
  .nav { gap: 1.1rem; }
  .nav__link { font-size: 0.95rem; }
  .brand__badge { width: 64px; height: 64px; }
}

/* ============================================================
   v10 — card 01: studio at full intensity, then the text lands
   ============================================================ */

.map-card--live { position: relative; isolation: isolate; overflow: hidden; }
.map-card__media { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.map-card__v {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;                 /* cropped and fitted inside the cube */
  opacity: 0;
  transition: opacity 0.45s var(--ease), filter 0.5s var(--ease);
  filter: none;                      /* full intensity for the first 1.8s */
}
.map-card__v.is-on { opacity: 1; }

/* The scrim is transparent while the studio plays clean, then comes up just
   enough to carry the text. Stronger at the bottom, where the copy sits. */
.map-card__scrim {
  position: absolute; inset: 0;
  opacity: 0;
  transition: opacity 0.5s var(--ease);
  background: linear-gradient(180deg,
    rgba(10, 11, 13, 0.30) 0%,
    rgba(10, 11, 13, 0.45) 45%,
    rgba(10, 11, 13, 0.72) 100%);
}

/* --- phase 2: the moment the text lands, the video steps back --- */
.map-card--live.is-revealed .map-card__v.is-on { opacity: 0.82; }
.map-card--live.is-revealed .map-card__v { filter: brightness(0.8) saturate(0.92); }
.map-card--live.is-revealed .map-card__scrim { opacity: 1; }
.map-card--live.is-revealed:hover .map-card__v.is-on { opacity: 0.9; }

/* --- the text: hidden during phase 1, then instant, no fade --- */
.map-card--live.is-intro > :not(.map-card__media) { opacity: 0; }
.map-card--vis.is-intro > :not(.map-card__media) { opacity: 0; }
.map-card--vis.is-revealed .vis__stage { opacity: 0.86; filter: brightness(0.86) saturate(0.95); }
.vis__stage { transition: opacity 0.5s var(--ease), filter 0.5s var(--ease); }
.map-card--live > :not(.map-card__media) { transition: none; }

.map-card--live .map-card__title {
  font-size: 1.22rem;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);
}
.map-card--live .map-card__desc {
  color: var(--bone);
  font-weight: 600;
  font-size: 0.95rem;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);
}
.map-card--live .map-card__kicker,
.map-card--live .map-card__num { text-shadow: 0 1px 3px rgba(0, 0, 0, 0.7); }
.map-card--live .map-card__kicker { color: var(--bone); opacity: 0.75; }

@media (prefers-reduced-motion: reduce) {
  .map-card__v { transition: none; }
  /* no hold, no reveal choreography: text is there from the start */
  .map-card--live.is-intro > :not(.map-card__media) { opacity: 1; }
}

/* ============================================================
   v11 — card 02: the format tells you what it is
   Squares live in a record sleeve with the disc sliding out.
   16:9 lives in a player frame with a red progress bar and a duration
   chip. No label needed: nobody mistakes one for the other.
   ============================================================ */

.map-card--vis { position: relative; isolation: isolate; overflow: hidden; }
.map-card__media--vis { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.vis__stage { position: absolute; inset: 0; display: grid; place-items: center; }

.vis__frame {
  position: absolute;
  opacity: 0;
  transform: translateX(28px) scale(0.96);
  transition: opacity 0.32s var(--ease), transform 0.42s var(--ease);
}
.vis__frame.is-live { opacity: 1; transform: none; }
.vis__frame.is-out { opacity: 0; transform: translateX(-28px) scale(0.96); }

/* ---------- 1:1 — the sleeve ---------- */
.vis__frame--sleeve { width: min(58%, 190px); aspect-ratio: 1 / 1; }
.vis__sleeve-body {
  position: absolute; inset: 0;
  border-radius: 2px;
  overflow: hidden;
  background: var(--surface);
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.55), inset 0 0 0 1px rgba(242, 240, 235, 0.14);
}
/* the record slides out of the sleeve, so the square reads as a sleeve */
.vis__disc {
  position: absolute; top: 6%; bottom: 6%; right: 0;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%, #d8cdb4 0 8%, #17181c 8.5% 12%, #101114 12% 100%);
  box-shadow: inset 0 0 0 1px rgba(242, 240, 235, 0.12);
  transform: translateX(34%);
  animation: vis-spin 4.5s linear infinite;
}
@keyframes vis-spin { to { transform: translateX(34%) rotate(360deg); } }
.vis__spine {
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 15px;
  display: grid; place-items: center;
  background: rgba(10, 11, 13, 0.72);
  color: var(--bone);
  font-family: var(--display);
  font-size: 6.5px; letter-spacing: 0.14em; text-transform: uppercase;
  writing-mode: vertical-rl; transform: rotate(180deg);
  white-space: nowrap;
}

/* ---------- 16:9 — the player ---------- */
.vis__frame--player { width: min(88%, 268px); }
.vis__screen {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: 4px 4px 0 0;
  overflow: hidden;
  background: var(--surface);
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.55), inset 0 0 0 1px rgba(242, 240, 235, 0.14);
}
.vis__bar { display: block; height: 3px; background: rgba(242, 240, 235, 0.18); border-radius: 0 0 4px 4px; overflow: hidden; }
.vis__bar-fill { display: block; height: 100%; width: 0; background: #ff0033; }

/* the images stack; one is shown at a time */
.vis__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.18s linear;
}
.vis__img.is-on { opacity: 1; }

.vis__todo {
  position: absolute; left: 0; right: 0; bottom: 0;
  font-size: 0.62rem; color: var(--ash-dim);
  padding: 0.3rem 0.5rem; background: rgba(10, 11, 13, 0.8);
}

@media (prefers-reduced-motion: reduce) {
  .vis__disc { animation: none; }
  .vis__frame { transition: none; }
}

/* Card 03 plays 9:16 shorts inside a 4:3 card. `cover` would crop the frame to
   a strip of torso; the clip is scaled to sit in the card as a vertical panel
   with the card's own surface behind it. */
.map-card--vertical .map-card__v { object-fit: cover; object-position: center 35%; }
.map-card--vertical .map-card__scrim {
  background: linear-gradient(180deg,
    rgba(10, 11, 13, 0.34) 0%,
    rgba(10, 11, 13, 0.48) 45%,
    rgba(10, 11, 13, 0.74) 100%);
}
.map-title__claim { display: block; color: var(--ash); font-weight: 400; margin-top: 0.35rem; }

/* ============================================================
   v17 — release map: the four are a closed set, not a list
   ============================================================ */

.section--map { position: relative; }

/* v106 — LE DEBORDEMENT HORIZONTAL DU SITE, CORRIGE ICI.
   MISSING-CONTENT §0.10, ouverte depuis la v57, tentative echouee en v91.

   La cause est le `left: -6% / right: -6%` du .map-head::before ci-dessous :
   un halo radial decoratif qui deborde de 42px de chaque cote d'un bloc de
   707px. Le cote droit sort de la fenetre et etend le scrollWidth du
   document. C'est le SEUL element du site a le faire — verifie par
   masquage, a 390, 430, 768, 1024 et 1280 : masquer #release-map ramene
   scrollWidth a la largeur exacte de la fenetre a chaque fois.

   Pourquoi la v91 ne l'a pas trouve : un pseudo-element n'apparait pas
   dans querySelectorAll et n'a pas de getBoundingClientRect. Les mesures
   de la v91 pointaient .hero__video-bg et .bnd__track, tous deux DEJA
   coupes par un `overflow: hidden` d'ancetre (.hero et .bnd__rail) : ils
   ne contribuaient a rien. Poser `overflow-x: clip` sur eux ne pouvait
   donc rien changer, ce que la mesure d'alors a effectivement constate.

   `clip` et non `hidden` : `hidden` ferait de la section un conteneur de
   defilement, ce qui casserait tout `position: sticky` place a
   l'interieur. `clip` coupe sans creer ce contexte. `overflow-y: visible`
   est explicite pour que le halo garde son debordement VERTICAL, qui est
   voulu (top/bottom: -40%). */
.section--map { overflow-x: clip; overflow-y: visible; }

/* a soft radial behind the text block gives the copy something to sit on */
.map-head { position: relative; }
.map-head::before {
  content: ""; position: absolute; z-index: -1;
  left: -6%; right: -6%; top: -40%; bottom: -40%;
  background: radial-gradient(60% 70% at 30% 50%, rgba(242, 240, 235, 0.045), transparent 70%);
  pointer-events: none;
}

/* the spine: grows as the section is scrolled through */
.map-spine {
  position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--line);
}
.map-spine i {
  position: absolute; inset: 0 0 auto 0;
  height: var(--map-progress, 0%);
  background: linear-gradient(180deg, var(--signal), rgba(232, 197, 71, 0.35));
  transition: height 0.15s linear;
}
@media (max-width: 900px) { .map-spine { display: none; } }

/* ---------- the four words read as a checklist ---------- */
.map-title {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 0 0.55em;
  font-size: clamp(1.9rem, 4.4vw, 3.2rem);
  letter-spacing: -0.005em;
}
.mt-w {
  color: var(--bone);
  font-weight: 900;
  letter-spacing: 0.01em;
  display: inline-block;
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease),
              text-shadow 0.3s var(--ease), scale 0.3s var(--ease);
  transition-delay: calc(var(--i) * 90ms);
}
/* armed by JS; without JS the words are simply there */
.section--map.is-armed .mt-w { opacity: 0; transform: translateY(12px); }
.section--map.is-armed.is-in .mt-w { opacity: 1; transform: none; }
.mt-dot {
  font-style: normal;
  color: var(--signal);
  font-size: 1.25em;
  line-height: 0;
  margin-left: 0.04em;
}
@media (hover: hover) {
  .mt-w:hover { scale: 1.03; text-shadow: 0 0 18px rgba(242, 240, 235, 0.45); }
}

/* ---------- the money line ---------- */
.map-title__claim {
  flex: 1 0 100%;
  display: block;
  margin-top: 0.7rem;              /* +10px of air under the four words */
  font-family: var(--editorial);
  font-weight: 400;
  font-size: clamp(1.05rem, 1.9vw, 1.5rem);
  letter-spacing: 0;
  color: #EDEAE3;                  /* off-white, not the old grey */
}
.map-title__claim b { font-weight: 400; color: var(--bone); font-style: italic; }
.mt-rev {
  position: relative;
  background: linear-gradient(90deg, #ffffff 0%, #EDEAE3 55%, #A8AEB8 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
.mt-rule {
  position: absolute; left: 0; right: 0; bottom: -0.12em; height: 1px;
  background: rgba(237, 234, 227, 0.75);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1) 0.45s;
}
.section--map.is-in .mt-rule,
.section--map:not(.is-armed) .mt-rule { transform: scaleX(1); }

/* ---------- 4/4, shown once when the set is on screen ---------- */
.map-count {
  position: absolute; right: 0; top: 0;
  font-family: var(--display); font-size: 0.8rem; font-weight: 700;
  letter-spacing: 0.18em; color: var(--signal);
  border: 1px solid rgba(232, 197, 71, 0.4); border-radius: 999px;
  padding: 0.25rem 0.7rem;
  opacity: 0; transform: translateY(-4px);
  transition: opacity 0.45s var(--ease), transform 0.45s var(--ease);
}
.map-count.is-on { opacity: 1; transform: none; }

/* ---------- the cards ---------- */
.map-card {
  position: relative;
  border: 1px solid rgba(242, 240, 235, 0.09);
  transition: background 0.35s var(--ease), border-color 0.35s var(--ease);
}
.section--map.is-armed .map-card { opacity: 0; transform: translateY(18px); }
.section--map.is-armed.is-in .map-card {
  opacity: 1; transform: none;
  transition: opacity 0.55s var(--ease) calc(var(--card-i) * 100ms),
              transform 0.55s var(--ease) calc(var(--card-i) * 100ms),
              background 0.35s var(--ease), border-color 0.35s var(--ease);
}
.map-card:hover { border-color: rgba(242, 240, 235, 0.28); }

/* the validation bar down the left edge */
.map-card__bar {
  position: absolute; left: 0; top: 0; width: 2px;
  height: 0; background: var(--signal);
  transition: height 0.7s var(--ease) calc(var(--card-i) * 120ms + 200ms);
}
.section--map.is-in .map-card__bar { height: 100%; }
.section--map:not(.is-armed) .map-card__bar { height: 100%; }

.map-card__num {
  font-size: 1.35rem; font-weight: 900; letter-spacing: 0.02em;
  color: var(--bone);
  text-shadow: 0 0 14px rgba(232, 197, 71, 0.55);
  line-height: 1;
}
.map-card__kicker {
  color: rgba(242, 240, 235, 0.78);
  font-weight: 600; letter-spacing: 0.2em;
  margin-top: 0.9rem; margin-bottom: -0.15rem;   /* label sticks to its title */
}
.map-card__title {
  color: var(--bone); font-weight: 900;
  font-size: clamp(1.15rem, 1.5vw, 1.4rem);
  text-shadow: 0 2px 3px rgba(0, 0, 0, 0.75);
  transition: scale 0.3s var(--ease), text-shadow 0.3s var(--ease);
}
@media (hover: hover) {
  .map-card:hover .map-card__title {
    scale: 1.04; transform-origin: left;
    text-shadow: 0 2px 3px rgba(0,0,0,0.75), 0 0 20px rgba(242,240,235,0.35);
  }
}
.map-card__desc { line-height: 1.65; opacity: 0.82; }
.map-card__go { margin-top: auto; }
/* the text block lifts off the bottom edge, and the floor darkens under it */
.map-card--live { padding-bottom: 1.9rem; }
.map-card--live .map-card__scrim {
  background: linear-gradient(180deg,
    rgba(10, 11, 13, 0.26) 0%,
    rgba(10, 11, 13, 0.44) 40%,
    rgba(10, 11, 13, 0.88) 100%);
}

/* ---------- the hero 4: the number is the rule ---------- */
.hero__hint-n {
  font-size: 3.6em;
  color: #FFFFFF;
  -webkit-text-stroke: 0.6px rgba(255, 255, 255, 0.55);
  text-shadow: 0 0 26px rgba(255, 255, 255, 0.45), 0 0 60px rgba(232, 197, 71, 0.35);
  animation: rr-4-in 0.72s cubic-bezier(0.34, 1.56, 0.64, 1) both,
             rr-4-pulse 4.5s var(--ease) 1.2s infinite;
  vertical-align: -0.22em;
  margin-inline: 0.06em;
}
@keyframes rr-4-in {
  from { transform: scale(0.8); opacity: 0; }
  70%  { transform: scale(1.05); opacity: 1; }
  to   { transform: scale(1); opacity: 1; }
}
@keyframes rr-4-pulse {
  0%, 88%, 100% { text-shadow: 0 0 26px rgba(255,255,255,0.45), 0 0 60px rgba(232, 197, 71,0.35); }
  94% { text-shadow: 0 0 34px rgba(255,255,255,0.75), 0 0 90px rgba(232, 197, 71,0.6); }
}

@media (prefers-reduced-motion: reduce) {
  .hero__hint-n { animation: none; }
  .mt-w, .map-card { opacity: 1; transform: none; }
  .mt-rule { transform: scaleX(1); }
  .map-card__bar { height: 100%; transition: none; }
  .map-spine i { transition: none; }
}

/* mobile: the four words stack as a numbered checklist */
@media (max-width: 640px) {
  .map-title { flex-direction: column; gap: 0.15rem; align-items: flex-start; }
  .mt-w { counter-increment: mtw; display: flex; align-items: baseline; gap: 0.5rem; }
  .mt-w::before {
    content: "0" counter(mtw);
    font-family: var(--display); font-size: 0.5em; font-weight: 700;
    letter-spacing: 0.14em; color: var(--ash-dim);
  }
  .map-title { counter-reset: mtw; }
  .map-count { position: static; display: inline-block; margin-bottom: 0.8rem; }
}

/* =========================================================================
   CHAPTERS — the four service sections as one continuous scroll
   -------------------------------------------------------------------------
   No pinning, no scroll hijacking, no library. Each chapter has a sticky
   full-viewport stage; the next chapter's body scrolls up over it. The JS
   only writes a 0..1 progress into --p; every visual consequence is here.
   ========================================================================= */

.chapters { position: relative; }

.chapter {
  position: relative;
  z-index: calc(var(--ch-i) + 1);   /* later chapters cover earlier ones */
  --p: 0;
}

/* ---- sticky visual stage ---- */
.chapter__stage {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  display: grid;
  place-items: center;
  background: var(--void);
}
.chapter__frame {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  /* opens from a letterbox slit to full bleed as the chapter is entered */
  clip-path: inset(calc((1 - var(--p)) * 18%) calc((1 - var(--p)) * 6%));
  transition: clip-path 0.1s linear;
}
.chapter__media {
  width: 100%; height: 100%;
  object-fit: cover;
  transform: scale(calc(1.12 - var(--p) * 0.12));
  transform-origin: 50% 50%;
  will-change: transform;
}
.chapter__media--tall { width: auto; height: 100%; max-width: none; }
.chapter__media--sq   { width: auto; height: 62%; object-fit: contain; }
.chapter__media--off  { display: none; }
.chapter__veil {
  position: absolute; inset: 0;
  background: linear-gradient(to bottom,
    rgba(10, 11, 13, 0.55) 0%, rgba(10, 11, 13, 0.15) 38%, var(--void) 100%);
}

/* ---- chapter title, sitting on the stage ---- */
.chapter__head {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 100svh;
  z-index: 2;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 0.9rem;
  padding: 0 var(--gutter) clamp(3.5rem, 9vh, 7rem);
  pointer-events: none;
  /* the title leaves before the body arrives, instead of colliding with it */
  opacity: clamp(0, calc(1 - (var(--p) - 0.62) * 4), 1);
  transform: translateY(calc(var(--p) * -3vh));
}
.chapter__num {
  font-family: var(--mono);
  font-size: clamp(4rem, 13vw, 11rem);
  font-weight: 300;
  line-height: 0.8;
  letter-spacing: -0.04em;
  /* Semi-transparent fill + a brighter, thicker stroke. The old 1px stroke in
     --line-strong vanished on the darker stages (02, 03, 04) — 01 only read
     because its video is warm and bright behind it. Identical on all four. */
  color: rgba(242, 240, 235, 0.07);
  -webkit-text-stroke: 1.5px rgba(242, 240, 235, 0.34);
  text-shadow: 0 0 40px rgba(10, 11, 13, 0.55);
  margin-bottom: -0.15em;
}
.chapter__title {
  font-size: var(--fs-h1);
  font-weight: 700;
  letter-spacing: -0.035em;
  max-width: 16ch;
}
.chapter__tags { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.chapter__tag {
  border: 1px solid var(--line-strong);
  padding: 0.28rem 0.6rem;
  color: var(--bone);
}

/* ---- the V17 content, riding up over its own stage ---- */
.chapter__body {
  position: relative;
  z-index: 3;
  margin-top: -100svh;      /* body starts at the stage, scrolls over it */
  padding-top: 100svh;
  background: linear-gradient(to bottom, transparent 0, var(--void) 100svh);
}
.chapter__body > .section { background: var(--void); }

/* the inner heading stays for screen readers; the chapter shell is what shows */
.chapter-dup {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---- editorial progress indicator ---- */
.chprog {
  position: fixed;
  left: var(--gutter);
  bottom: calc(var(--rbar-h) + 1.25rem);
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  opacity: 0;
  transform: translateY(0.5rem);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
  pointer-events: none;
}
.chprog.is-on { opacity: 1; transform: none; pointer-events: auto; }
.chprog__count b { color: var(--bone); font-weight: 400; }
.chprog__dots { display: flex; gap: 0.3rem; }
.chprog__dot {
  width: 1.6rem; height: 2px;
  background: var(--line-strong);
  transition: background 0.35s var(--ease);
}
.chprog__dot.is-on { background: var(--signal); }

/* ---- mobile: same chapters, less simultaneous movement ---- */
@media (max-width: 860px) {
  .chapter__stage { height: 72svh; }
  .chapter__head  { height: 72svh; padding-bottom: 2rem; }
  .chapter__body  { margin-top: -72svh; padding-top: 72svh; }
  .chapter__frame { clip-path: none; }
  .chapter__media { transform: scale(calc(1.06 - var(--p) * 0.06)); }
  .chprog__dot { width: 1.1rem; }
}

/* ---- reduced motion: the layout survives, the movement does not ---- */
@media (prefers-reduced-motion: reduce) {
  .chapter__stage { position: relative; height: 56svh; }
  .chapter__head  { position: relative; height: auto; padding: 2rem var(--gutter);
                    opacity: 1; transform: none; }
  .chapter__body  { margin-top: 0; padding-top: 0; background: none; }
  .chapter__frame { clip-path: none; transition: none; }
  .chapter__media { transform: none; }
  .chprog { transition: none; }
}

/* =========================================================================
   V18.1 — OVERVIEW FIRST, THEN CHOSEN WORLD
   The four chapters stay in document order (deep links, no-JS and crawlers
   all depend on that). What changes is control: the overview is the entry
   point, every card opens its world directly, and each chapter ends with a
   chooser instead of spilling into the next one.
   ========================================================================= */

/* ---- overview: hovering one component makes the other three recede ---- */
.map-sub { display: block; margin-top: 0.9rem; color: var(--ash); }
.map-sub__hint { color: var(--ash-dim); }

.map-grid .map-card { transition: opacity 0.45s var(--ease), transform 0.45s var(--ease); }
@media (hover: hover) {
  .map-grid:hover .map-card { opacity: 0.38; }
  .map-grid:hover .map-card:hover { opacity: 1; }
  .map-grid:hover .map-card:hover .map-card__media { transform: scale(1.04); }
}
.map-card__media { transition: transform 0.6s var(--ease); }

.map-card__go {
  display: inline-flex; align-items: center; gap: 0.4rem;
  color: var(--ash-dim);
  transition: color 0.35s var(--ease);
}
.map-card__go i { font-style: normal; transition: transform 0.35s var(--ease); }
.map-card:hover .map-card__go { color: var(--signal); }
.map-card:hover .map-card__go i { transform: translateX(4px); }

/* ---- entering a world: the card's visual grows into the viewport ---- */
.enter-veil {
  position: fixed; inset: 0; z-index: 90;
  pointer-events: none;
  background: var(--void);
  opacity: 0;
  transition: opacity 0.35s linear;
}
.enter-veil.is-on { opacity: 1; }
.enter-flier {
  position: fixed; z-index: 91;
  pointer-events: none;
  overflow: hidden;
  background: var(--void);
  will-change: transform, width, height, top, left;
  transition: top 0.62s var(--ease), left 0.62s var(--ease),
              width 0.62s var(--ease), height 0.62s var(--ease),
              opacity 0.25s linear 0.5s;
}
.enter-flier img, .enter-flier video { width: 100%; height: 100%; object-fit: cover; }

/* ---- the indicator is now navigation, not just a scroll readout ---- */
.chprog__count { display: inline-flex; align-items: center; gap: 0.35rem; }
.chprog__count i { font-style: normal; opacity: 0; transition: opacity 0.3s var(--ease); }
.chprog:hover .chprog__count i { opacity: 0.7; }
.chprog__dot { cursor: pointer; }
.chprog__dot:hover { background: var(--bone); }

@media (prefers-reduced-motion: reduce) {
  .enter-flier, .enter-veil { display: none !important; }
  .map-grid .map-card, .map-card__media { transition: none; }
}

/* =========================================================================
   SECTION 01 — conversion rebuild
   Every motion here is IntersectionObserver + transform/opacity. The easing
   and stagger are the ones specified; no animation library is involved.
   ========================================================================= */

:root { --ease-out-expo: cubic-bezier(0.22, 1, 0.36, 1); }

/* ---- 1. section hero ---- */
.shero { max-width: 24ch; margin-bottom: clamp(3rem, 7vw, 5.5rem); }
.shero__t { max-width: 18ch; }
.shero__sub { margin-top: 1.4rem; max-width: 46ch; }
.shero__micro { margin-top: 1rem; color: var(--ash-dim); letter-spacing: 0.1em; }

/* ---- 2. contrast ---- */
.diag__cols { position: relative; }
.diag__h { display: block; margin-bottom: 1.4rem; }
.diag__col--good .diag__h { color: var(--signal); }

.diag__i {
  display: flex; align-items: baseline; gap: 0.75rem;
  padding: 0.42rem 0;
  transition: color 0.3s linear;
}

.diag__mark { width: 0.7rem; height: 1px; flex: none; background: currentColor; opacity: 0.5; }
.diag__col--bad  .diag__i { color: var(--ash-dim); }
.diag__col--good .diag__i { color: var(--bone); }
.diag__col--good .diag__mark { background: var(--signal); opacity: 1; }

/* hovering one side dims its counterpart on the other: the pair is the point */
.diag__i.is-paired { color: var(--ash-dim); opacity: 0.45; }
.diag__i.is-lit { color: var(--bone); }

/* the line drawn between the two columns as the block enters */
.diag__rule {
  position: absolute; top: 0; bottom: 0; left: 50%;
  width: 1px; overflow: hidden;
}
.diag__rule i {
  display: block; width: 100%; height: 100%;
  background: var(--line-strong);
  transform: scaleY(0); transform-origin: top;
  transition: transform 1.1s var(--ease-out-expo) 0.15s;
}
.is-in .diag__rule i { transform: scaleY(1); }

/* ---- 3. listening examples ---- */
.lstblk { margin-top: clamp(3.5rem, 8vw, 6rem); }
.lstblk__grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 1px; background: var(--line); border: 1px solid var(--line);
  margin-top: 2rem;
}
.lst { background: var(--void); padding: 1.6rem 1.4rem; }
.lst__head { display: flex; justify-content: space-between; gap: 1rem; min-height: 1.2em; }
.lst__specs { color: var(--ash-dim); }
.lst__wave { position: relative; height: 2px; background: var(--line-strong); margin: 1.6rem 0 1.3rem; }
.lst__fill {
  position: absolute; inset: 0 auto 0 0; width: 0%;
  background: var(--signal);
  transition: width 0.12s linear;
}
.lst__row { display: flex; align-items: center; gap: 1rem; }
.lst__play {
  position: relative;
  width: 48px; height: 48px; border-radius: 50%;
  border: 1px solid var(--line-strong);
  display: grid; place-items: center;
  transition: transform 0.3s var(--ease-out-expo), border-color 0.3s var(--ease-out-expo);
}
.lst__play:hover { transform: scale(1.06); border-color: var(--signal); }
.lst__ico { width: 18px; height: 18px; fill: var(--bone); grid-area: 1 / 1; }
.lst__ico--pause { display: none; }
.lst__play[aria-pressed="true"] .lst__ico--play { display: none; }
.lst__play[aria-pressed="true"] .lst__ico--pause { display: block; }
.lst__ripple {
  position: absolute; inset: -1px; border-radius: 50%;
  border: 1px solid var(--signal);
  opacity: 0; transform: scale(1);
}
.lst__play:active .lst__ripple { animation: lstRipple 0.55s var(--ease-out-expo); }
@keyframes lstRipple {
  from { opacity: 0.7; transform: scale(1); }
  to   { opacity: 0;   transform: scale(1.45); }
}
.lst__time { color: var(--ash-dim); }
.lst__note { margin-top: 1.2rem; color: var(--ash-dim); }
.lstblk__cta { margin-top: 2rem; }

/* ---- 4. thirteen steps ---- */
.proc__list { position: relative; margin-top: 2.5rem; padding-left: 0; }
.proc__spine {
  position: absolute; top: 0.4rem; bottom: 0.4rem; left: 0;
  width: 1px; background: var(--line);
}
.proc__spine i {
  display: block; width: 100%; height: 0;
  background: var(--signal);
  transition: height 0.25s linear;
}
.pstep {
  display: flex; gap: clamp(1rem, 3vw, 2.5rem);
  padding: 1.5rem 0 1.5rem clamp(1.25rem, 3vw, 2.5rem);
  border-bottom: 1px solid var(--line);
  opacity: 0; transform: translateY(16px);
  transition: opacity 0.55s var(--ease-out-expo), transform 0.55s var(--ease-out-expo);
  transition-delay: calc(var(--s) * 120ms);
}
.pstep.is-in { opacity: 1; transform: none; }
.pstep__n { flex: none; width: 3ch; color: var(--ash-dim); transition: color 0.4s var(--ease-out-expo); }
.pstep.is-in .pstep__n { color: var(--signal); }
.pstep__name { font-size: var(--fs-h3); font-weight: 600; letter-spacing: -0.02em; }
.pstep__why { margin-top: 0.5rem; color: var(--bone); max-width: 60ch; }
.pstep__do { margin-top: 0.6rem; color: var(--ash-dim); max-width: 60ch; display: none; }
[data-steps].is-open .pstep__do { display: block; }

/* ---- 5. against automatic services ---- */
.vsblk {
  margin-top: clamp(3.5rem, 8vw, 6rem);
  border: 1px solid var(--line-strong);
  background: var(--surface);
  padding: clamp(2rem, 5vw, 3.5rem);
}
.vsblk__t { font-size: var(--fs-h3); font-weight: 600; letter-spacing: -0.02em; max-width: 42ch; }
.vsblk__cols { display: grid; grid-template-columns: 0.84fr 1.16fr; gap: clamp(1.5rem, 4vw, 3rem); margin-top: 2rem; }
.vsblk__h { display: block; margin-bottom: 0.7rem; }
.vsblk__c p { color: var(--ash); max-width: 42ch; }
.vsblk__c--us .vsblk__h { color: var(--signal); }
.vsblk__c--us p { color: var(--bone); }
.vsblk__foot { margin-top: 2rem; color: var(--ash-dim); }

/* ---- 6. final CTA: see the .conv block further down. .sec-cta--big was
   retired when section 01's CTA became the conversion block. ---- */
.btn--xl {
  display: inline-block;
  padding: 1.15rem 2.6rem;
  font-size: var(--fs-lead);
  font-weight: 600;
  transition: transform 0.35s var(--ease-out-expo), box-shadow 0.35s var(--ease-out-expo);
}
.btn--xl:hover {
  transform: scale(1.025);
  box-shadow: 0 0 0 1px var(--signal), 0 12px 40px -12px var(--signal);
}

@media (max-width: 860px) {
  .lstblk__grid { grid-template-columns: 1fr; }
  .vsblk__cols  { grid-template-columns: 1fr; }
  .diag__rule   { display: none; }
  .shero        { max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
  .diag__i, .pstep { opacity: 1; transform: none; transition: opacity 0.3s linear; }
  .diag__rule i { transform: scaleY(1); transition: none; }
  .proc__spine i, .lst__fill { transition: none; }
  .btn--xl, .lst__play { transition: none; }
  .lst__play:hover, .btn--xl:hover { transform: none; }
  .lst__play:active .lst__ripple { animation: none; }
}

/* =========================================================================
   SECTION 01 — v2: tightened rhythm, slot-machine contrast, heavier CTA
   ========================================================================= */

/* ---- 1. vertical rhythm: the blocks now follow each other on a beat ---- */
.shero        { margin-bottom: clamp(2rem, 4.5vw, 3.5rem); }
.diag         { margin-top: clamp(1.75rem, 4vw, 3rem); }
.lstblk       { margin-top: clamp(2.5rem, 5.5vw, 4rem); }
.proc         { margin-top: clamp(2.5rem, 5.5vw, 4rem); }
.vsblk        { margin-top: clamp(2.5rem, 5.5vw, 4rem); }
.conv         { margin-top: clamp(2.75rem, 6vw, 4.5rem); }

/* ---- 2. slot machine ----
   The reel is a column of lines inside a one-line window. It starts showing
   a decoy and settles on the real phrase. One transform, one transition:
   the expo-out easing is what makes it read as "spinning fast, then landing"
   without any per-frame JavaScript. */
.diag__roller {
  display: block;
  overflow: hidden;
  height: 1.6em;                 /* exactly one line of body text */
  flex: 1;
}
.diag__roll-track {
  display: block;
  transform: translateY(0);      /* parked on the first decoy */
  will-change: transform;
}
.diag__roll-item {
  display: block;
  height: 1.6em;
  line-height: 1.6em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* the decoys are dimmed and slightly blurred: motion blur without a filter
   running during the animation, which would cost a repaint every frame */
.diag__roll-item:not(.diag__roll-item--real) { opacity: 0.4; }

/* JS sets --dur and --delay per line, then adds this class */
.diag__i.is-rolling .diag__roll-track, .pain.is-rolling .diag__roll-track {
  transform: translateY(calc(var(--n) * -1.6em));
  transition: transform var(--dur, 1.1s) var(--ease-out-expo) var(--delay, 0s);
}
/* the click: a very short squash as the reel lands */
.diag__i.is-landed .diag__roller,
.pain.is-landed .diag__roller { animation: diagLand 0.22s var(--ease-out-expo); }
@keyframes diagLand {
  0%   { transform: scaleY(1.04); }
  100% { transform: scaleY(1); }
}
.diag__i.is-landed .diag__mark { opacity: 1; }

/* until a line has rolled, its marker stays quiet */
.diag__mark { transition: opacity 0.3s linear; }
.diag__i:not(.is-landed) .diag__mark { opacity: 0.25; }

/* ---- 3. Feel the difference ---- */
.lstblk__head { max-width: 52ch; }
.lstblk__title { font-size: var(--fs-h3); font-weight: 600; letter-spacing: -0.02em; }
.lstblk__sub { margin-top: 0.7rem; }
.lstblk__cta { margin-top: 1.75rem; }
.lstblk .lst {
  opacity: 0; transform: translateY(16px);
  transition: opacity 0.55s var(--ease-out-expo), transform 0.55s var(--ease-out-expo);
}
.lstblk .lst:nth-child(2) { transition-delay: 110ms; }
.lstblk .lst:nth-child(3) { transition-delay: 220ms; }
.lstblk.is-in .lst { opacity: 1; transform: none; }

/* ---- the arrow from the benefits title down to the rolling line ----
   Anchored in the right margin of .diag. The title and the rolling line are
   both capped at 22ch, so that margin is empty by construction and the arrow
   cannot land on either. Drawn once on entry, like the hero one. */
.diag { position: relative; }
.diag__arrow {
  position: absolute;
  z-index: 2;
  top: 0.35rem;
  right: clamp(1rem, 7vw, 7rem);
  width: clamp(88px, 11vw, 138px);
  height: auto;
  color: var(--bone);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s var(--ease-out-expo) 0.15s;
}
.diag__arrow-line, .diag__arrow-head {
  stroke-dasharray: var(--len, 520);
  stroke-dashoffset: var(--len, 520);
}
.diag.is-in .diag__arrow { opacity: 0.6; }
.diag.is-in .diag__arrow-line {
  animation: arrowDraw 1.25s var(--ease-out-expo) 0.3s forwards;
}
.diag.is-in .diag__arrow-head {
  animation: arrowDraw 0.4s var(--ease-out-expo) 1.4s forwards,
             arrowPulseDown 2.6s var(--ease) 1.95s infinite;
}
@keyframes arrowPulseDown {
  0%, 100% { opacity: 1; transform: translate(0, 0); }
  50%      { opacity: 0.45; transform: translate(0, 4px); }
}
@media (max-width: 1023px) {
  .diag__arrow { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .diag.is-in .diag__arrow { opacity: 0.6; }
  .diag__arrow-line, .diag__arrow-head { stroke-dashoffset: 0; animation: none; }
}

/* =========================================================================
   SECTION 01 — the conversion block
   Compact and horizontal by requirement: it has to read without scrolling on a
   laptop. Two columns from 860px up — what you get on the left, the action and
   the price on the right — then two full-width lines under them. Nothing here
   is allowed to grow tall: the whole block targets roughly 300px.
   ========================================================================= */
.conv {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  border: 1px solid var(--signal-dim);
  background:
    radial-gradient(120% 140% at 50% 0%, rgba(232, 197, 71, 0.10), transparent 70%),
    var(--surface);
  padding: clamp(1.5rem, 3vw, 2.25rem) clamp(1.25rem, 3vw, 2.5rem);
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: clamp(1.5rem, 4vw, 3.5rem);
  row-gap: clamp(1rem, 2.5vw, 1.5rem);
  align-items: center;
}

/* ---- the studio photograph ----
   It is not dimmed into a ghost: it keeps its own contrast and is masked out
   instead, so it is fully present where it lands and simply absent where the
   copy is. Anchored right, dissolving before it reaches the text column. */
.conv__photo {
  position: absolute;
  inset: 0 0 0 auto;
  width: 66%;
  z-index: -2;
  pointer-events: none;
}
.conv__photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 62% center;   /* keeps the hands on the desk in frame */
  display: block;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,0.45) 26%, #000 64%);
          mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,0.45) 26%, #000 64%);
}
/* A single veil doing two jobs: killing the last of the photo under the text
   column, and keeping the bottom two lines on solid ground. */
.conv__veil {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    linear-gradient(100deg,
      var(--surface) 0%,
      rgba(15, 17, 21, 0.95) 32%,
      rgba(15, 17, 21, 0.52) 54%,
      rgba(15, 17, 21, 0.16) 100%),
    linear-gradient(to top, rgba(15, 17, 21, 0.90) 0%, transparent 28%);
}

/* header: title then promise, stacked and left — every small line stays on the
   clean side of the block, never on the photograph */
.conv__head {
  grid-column: 1 / -1;
  max-width: 58ch;
  padding-bottom: clamp(0.85rem, 2vw, 1.15rem);
  border-bottom: 1px solid var(--line);
}
.conv__t {
  font-size: clamp(1.35rem, 2.4vw, 2rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.14;
  color: var(--bone);
  max-width: 24ch;
}
.conv__sub {
  margin-top: 0.6rem;
  font-size: var(--fs-micro);
  letter-spacing: 0.05em;
  line-height: 1.6;
  color: var(--ash);
}

/* the money words carry weight wherever they appear in this block */
.conv .kw {
  color: var(--bone);
  font-weight: 700;
  /* a hairline under the word rather than a highlighter block: at this size a
     filled highlight turns the line into a warning banner */
  box-shadow: inset 0 -0.34em 0 rgba(232, 197, 71, 0.22);
}

/* what you get — three lines, no bullets running down a column of air */
.conv__t .kw { box-shadow: inset 0 -0.2em 0 rgba(232, 197, 71, 0.28); }
/* left column: what you get, then what it costs — both on clean surface, so
   neither ever competes with the photograph for legibility */
.conv__offer { display: grid; gap: clamp(1.1rem, 2.5vw, 1.6rem); align-content: center; }
.conv__inc { display: grid; gap: 0.5rem; }
.conv__inc li {
  position: relative;
  padding-left: 1.35rem;
  font-size: 0.95rem;
  line-height: 1.35;
  color: var(--ash);
}
/* a tick, not a chevron: equal arms rotated 45 degrees read as "v" */
.conv__inc li::before {
  content: "";
  position: absolute;
  left: 0.15rem; top: 0.34em;
  width: 0.3rem; height: 0.58rem;
  border-right: 1.6px solid var(--signal);
  border-bottom: 1.6px solid var(--signal);
  transform: rotate(42deg);
}

/* right column: the upload alone, floating on the studio photograph */
.conv__act { display: grid; align-content: center; }

.conv__dropbox {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.15rem;
  min-height: 5.5rem;               /* short on purpose — it is a control */
  padding: 0.9rem 1rem;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-s);
  /* it sits on the photograph, so it needs its own ground to stay crisp */
  background: rgba(12, 14, 18, 0.82);
  -webkit-backdrop-filter: blur(10px);
          backdrop-filter: blur(10px);
  cursor: pointer;
  text-align: center;
  transition: border-color 0.25s var(--ease), background-color 0.25s var(--ease),
              box-shadow 0.35s var(--ease-out-expo), transform 0.35s var(--ease-out-expo);
}
.conv__dropbox:hover,
.conv__drop.is-over .conv__dropbox {
  border-color: var(--signal);
  background: rgba(18, 26, 46, 0.88);
  box-shadow: 0 0 0 1px var(--signal-dim), 0 18px 44px -20px var(--signal);
  transform: translateY(-2px);
}
.conv__drop.is-loaded .conv__dropbox {
  border-style: solid;
  border-color: var(--signal);
  background: rgba(232, 197, 71, 0.12);
}
/* the input is visually hidden but must still show focus from the keyboard */
.conv__drop input:focus-visible + .conv__dropbox { outline: 2px solid var(--signal); outline-offset: 3px; }
.conv__droptitle {
  font-family: var(--display);
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--bone);
}
.conv__drop.is-loaded .conv__droptitle::before {
  content: "\2713\00a0";
  color: var(--signal);
}
/* --ash, not --ash-dim: this line sits on a panel floating over a photograph,
   and dim grey on that ground measured 2.2:1 */
.conv__dropsub { font-size: 0.8rem; color: var(--ash); }
.conv__dropstate {
  min-height: 1.1em;
  margin-top: 0.4rem;
  font-size: 0.78rem;
  color: var(--signal);
  text-align: center;
  word-break: break-all;
}
.conv__dropstate.is-err { color: #ff8a8a; }

/* price: the reference, the badge and the real figure on one line */
.conv__price {
  display: flex;
  align-items: baseline;
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: 0.3rem 0.7rem;
}
.conv__was {
  font-family: var(--display);
  font-size: 1.35rem;
  color: var(--ash-dim);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}
.conv__badge {
  font-size: 0.6875rem;
  background: rgba(232, 197, 71, 0.14);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--signal);
  border: 1px solid var(--signal-dim);
  border-radius: 999px;
  padding: 0.2rem 0.55rem;
  align-self: center;
}
.conv__now {
  font-family: var(--display);
  font-size: clamp(2.3rem, 4.4vw, 3.2rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--bone);
}

/* two closing lines, full width, small */
.conv__trust, .conv__disc { grid-column: 1 / -1; font-size: 0.82rem; max-width: 64ch; }
.conv__trust {
  margin-top: -0.25rem;
  padding-top: clamp(0.75rem, 2vw, 1rem);
  border-top: 1px solid var(--line);
  color: var(--ash);
}
.conv__disc { margin-top: -0.6rem; }
.conv__discin {
  display: inline-flex;
  align-items: baseline;
  gap: 0.15rem;
  padding: 0.42rem 0.85rem;
  border: 1px solid var(--signal-dim);
  border-radius: 999px;
  background: rgba(232, 197, 71, 0.09);
  color: var(--ash);
}
.conv__discin .kw { box-shadow: none; color: var(--signal); }

/* micro-reveal: the pieces arrive in reading order, once, on entry */
.conv__head, .conv__offer, .conv__act, .conv__trust, .conv__disc,
.conv--slim .conv__inc {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.55s var(--ease-out-expo), transform 0.55s var(--ease-out-expo);
}
.conv.is-in .conv__head,
.conv.is-in .conv__offer,
.conv.is-in .conv__act,
.conv.is-in .conv__trust,
.conv.is-in .conv__disc,
.conv--slim.is-in .conv__inc { opacity: 1; transform: none; }
.conv--slim.is-in .conv__inc { transition-delay: 0.09s; }
.conv.is-in .conv__offer { transition-delay: 0.09s; }
.conv.is-in .conv__act  { transition-delay: 0.18s; }
.conv.is-in .conv__trust { transition-delay: 0.27s; }
.conv.is-in .conv__disc { transition-delay: 0.34s; }

@media (max-width: 859px) {
  .conv { grid-template-columns: 1fr; }
  .conv__t { max-width: none; }
  .conv__trust, .conv__disc { margin-top: 0; }
  /* one column means text crosses the whole width, so the photograph moves
     behind it entirely and the veil takes over: texture, no interference */
  .conv__photo { width: 100%; }
  .conv__photo img {
    object-position: 70% center;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 55%);
            mask-image: linear-gradient(to bottom, transparent 0%, #000 55%);
  }
  .conv__veil {
    background:
      linear-gradient(to bottom, var(--surface) 0%, rgba(15, 17, 21, 0.90) 38%, rgba(15, 17, 21, 0.80) 100%);
  }
  .conv__offer { gap: 1.1rem; }
}
@media (prefers-reduced-motion: reduce) {
  .conv__head, .conv__offer, .conv__act, .conv__trust, .conv__disc,
  .conv--slim .conv__inc {
    opacity: 1; transform: none; transition: none;
  }
}

/* v53 — .chprog__cart (le badge "✓ PACK +2 MORE") est retire du rail : le
   panneau de commande de droite dit deja, ligne par ligne, ce qu'il y a dans
   la release. Il etait le seul utilisateur de @keyframes cartPop, qui part
   avec lui. */

@media (max-width: 860px) {
  /* the reel is slower and the window taller: two lines fit on a phone */
  .diag__roller { height: 3.2em; }
  .diag__roll-item { height: 3.2em; line-height: 1.6em; white-space: normal; }
  .diag__i.is-rolling .diag__roll-track { transform: translateY(calc(var(--n) * -3.2em)); }
}

@media (prefers-reduced-motion: reduce) {
  /* no reel at all: the real phrase is simply there, faded in */
  .diag__roll-track { transform: translateY(calc(var(--n) * -1.6em)) !important; transition: none !important; }
  .diag__i.is-landed .diag__roller { animation: none; }
  .diag__mark, .diag__i:not(.is-landed) .diag__mark { opacity: 1; }
  .lstblk .lst { opacity: 1; transform: none; transition: none; }
}
@media (prefers-reduced-motion: reduce) and (max-width: 860px) {
  .diag__roll-track { transform: translateY(calc(var(--n) * -3.2em)) !important; }
}

/* =========================================================================
   SECTION 01 — v4: hero paragraph, and the seven benefits one at a time
   ========================================================================= */

/* ---- hero subtitle: a real measure, not a 20-character gutter ---- */
.shero { max-width: none; }
.shero__t { max-width: 20ch; }
.shero__sub {
  max-width: 46ch;            /* the 42-48ch the brief asks for */
  margin-top: 1.25rem;
  font-size: var(--fs-lead);
  line-height: 1.62;
  color: var(--ash);
  text-wrap: pretty;          /* kills the orphan words on supporting browsers */
}
.shero__sub + .shero__sub { margin-top: 1rem; }
.shero__micro { margin-top: 1.35rem; }

/* ---- the line the whole section turns on ----
   Two steps up the type scale from --fs-lead, set in white instead of ash so
   it separates from the paragraph above it, with "paid" underlined. It stays
   below --fs-h2 on purpose: it is the answer to the headline, not a second
   headline competing with it. */
.shero__sub--key {
  font-size: var(--fs-h3);
  line-height: 1.32;
  color: var(--bone);
  max-width: 22ch;            /* the measure has to shrink as the size grows */
  margin-top: 1.5rem;
  letter-spacing: -0.01em;
}
.shero__sub--key .kw {
  text-decoration: underline;
  text-decoration-thickness: from-font;
  text-underline-offset: 0.16em;
}

/* ---- block 4: the transformation, the punchline of section 01 ----
   This block carried no styling at all: an unstyled h3 and a body paragraph
   sitting under a full-width benefits list. */
.tform {
  margin-top: clamp(2.5rem, 6vw, 4.5rem);
  padding-left: clamp(1rem, 2.5vw, 1.75rem);
  border-left: 2px solid var(--signal);
  max-width: 52ch;
}
.tform__t {
  font-size: var(--fs-h3);
  line-height: 1.2;
  color: var(--bone);
  letter-spacing: -0.01em;
}
.tform__p {
  margin-top: 0.85rem;
  font-size: var(--fs-lead);
  line-height: 1.6;
  color: var(--ash);
}
.tform__earn {
  font-weight: 700;
  color: var(--bone);
  text-decoration: underline;
  text-decoration-thickness: from-font;
  text-underline-offset: 0.16em;
}

/* ---- the seven benefits ----
   One line on stage at a time, sized to dominate the section. The stage is a
   fixed-height window; the items are stacked in it and slide through. Only
   transform and opacity move, so a rotation costs nothing. */
.ben {
  margin-top: clamp(1.75rem, 4vw, 3rem);
  border-block: 1px solid var(--line);
  padding: clamp(2rem, 5vw, 3.5rem) 0;
}
.ben__stage {
  position: relative;
  min-height: clamp(7rem, 15vw, 10.5rem);
  display: grid;
  align-items: center;
  overflow: hidden;
}
.ben__item {
  grid-area: 1 / 1;
  display: flex;
  align-items: baseline;
  gap: clamp(0.75rem, 2vw, 1.5rem);
  opacity: 0;
  transform: translateY(46%);
  transition: opacity 0.5s var(--ease-out-expo), transform 0.5s var(--ease-out-expo);
  pointer-events: none;
}
.ben__item.is-on  { opacity: 1; transform: none; pointer-events: auto; }
.ben__item.is-out { opacity: 0; transform: translateY(-46%); }

.ben__n { flex: none; color: var(--ash-dim); }
.ben__txt {
  font-size: clamp(1.5rem, 4.2vw, 3.1rem);
  font-weight: 600;
  line-height: 1.14;
  letter-spacing: -0.03em;
  color: var(--bone);
  max-width: 22ch;
}
.ben__txt .kw { color: var(--signal); font-weight: 700; }

.ben__prog { display: flex; gap: 0.4rem; margin-top: clamp(1.25rem, 3vw, 2rem); }
.ben__dot {
  width: 2.25rem; height: 2px;
  background: var(--line-strong);
  transition: background 0.35s var(--ease-out-expo);
}
.ben__dot.is-on { background: var(--signal); }
.ben__dot:hover { background: var(--bone); }

.ben__close { margin-top: 1.5rem; color: var(--ash-dim); font-size: var(--fs-micro); }

@media (max-width: 720px) {
  .ben__stage { min-height: 11rem; }
  .ben__txt { max-width: none; font-size: clamp(1.35rem, 6.4vw, 2rem); }
  .ben__dot { width: 1.5rem; }
  .shero__sub { max-width: none; }
}

/* ---- reduced motion: no rotation at all, the seven are simply listed ---- */
@media (prefers-reduced-motion: reduce) {
  .ben__stage {
    display: block;
    min-height: 0;
    overflow: visible;
  }
  .ben__item {
    opacity: 1; transform: none; transition: none; pointer-events: auto;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--line);
  }
  .ben__item:last-child { border-bottom: 0; }
  .ben__txt { font-size: var(--fs-h3); max-width: none; }
  .ben__prog { display: none; }
}

/* =========================================================================
   FIXED INDICATOR — where am I, what do I get, roughly what does it cost
   ========================================================================= */
.chprog { align-items: flex-end; gap: 0.9rem; }
.chprog__card {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;                     /* deliberately tight: three lines, one block */
  line-height: 1.25;
  padding: 0.35rem 0.6rem 0.35rem 0;
}
/* v53 — .chprog__ben, .chprog__price et .chprog__cart n'existent plus dans le
   markup : la ligne benefice imposait la largeur du rail, le prix doublonnait
   le panneau de commande, le badge panier le doublonnait une troisieme fois.
   Leurs regles sont retirees avec eux plutot que laissees a trainer. */
.chprog__ttl { color: var(--ash); letter-spacing: 0.06em; }
/* un simple fondu au changement de section, rien de plus */
.chprog__ttl { transition: opacity 0.3s var(--ease); }

/* ---- the left-edge label ----
   Horizontal text, no rotation of any kind. It is the only orientation a
   visitor reads without tilting their head, which was the stated priority, and
   it costs width: the panel is 138px, so it can only appear once the page has
   that much empty margin to the left of the text column.

   The panel is flush with the viewport edge but the TEXT is not: 1rem of
   padding on the left, 0.75rem on the right, so nothing ever touches either
   border. Vertically centred on the viewport.

   Threshold. Section text starts at (viewport - 1320) / 2 + gutter:
     1440px -> 116px  panel would overlap by 22px
     1500px -> 146px  8px clear
     1512px -> 152px  14px clear
     1920px -> 356px  218px clear
   So 1500px. Below it the indicator stays exactly as it is today: the same
   markup, the same three lines, anchored at the bottom left instead. Nothing
   is hidden and nothing changes shape — it only moves. */
/* ---- v53 : le rail ne recouvre plus rien ----------------------------------
   Le defaut corrige. En v52 le rail etait pose SUR la page : `left: 0`, 138px
   de large, aucune place reservee. Tant qu'il n'y avait rien a droite, la
   marge naturelle de la page suffisait a l'absorber. La v52 a ajoute le
   panneau de commande, qui reserve `--rpan-w` a droite sur `main > *` : le
   bloc de contenu s'est donc recentre vers la gauche, et est passe sous le
   rail. Mesure du recouvrement, avant correction :

     1500px  le texte demarrait a 56px   ->  82px sous le rail
     1600px  le texte demarrait a 84px   ->  54px sous le rail
     1920px  le texte demarrait a 240px  ->  aucun

   D'ou l'effet decrit : illisible sur un ecran de 1500-1600px, parfait sur un
   27 pouces. Un defaut qu'on ne voit pas si on ne teste que sur son propre
   ecran.

   La correction n'est pas un ajustement de largeur — ce serait le meme bug,
   plus tard. Le rail reserve sa place, exactement comme le panneau de droite
   reserve la sienne, avec le meme selecteur et la meme mecanique. Le contenu
   ne peut alors plus passer dessous, quelle que soit la largeur de fenetre.

   Consequence agreable : le rail n'a plus d'image derriere lui. Le degrade
   opaque et le flou de 8px, qui existaient uniquement pour rester lisible
   par-dessus les scenes des chapitres 02 a 04, disparaissent. Il reste un
   filet vertical. C'est ce qui le fait cesser de se lire comme une pop-up.

   Largeurs apres correction, zone de contenu = viewport - rail - panneau :
     1500px   rail 105px  panneau 210px  ->  1185px de contenu
     1600px   rail 112px  panneau 224px  ->  1264px de contenu
     1920px   rail 112px  panneau 232px  ->  1576px de contenu
   --------------------------------------------------------------------------- */
@media (min-width: 1500px) {
  :root { --lrail-w: clamp(6rem, 7vw, 7rem); }

  /* Meme selecteur que la reserve de droite, pour la meme raison : le hero
     est une video plein cadre, une bande noire sur son bord se lit comme un
     defaut d'affichage. Le rail n'est de toute facon jamais allume dessus.

     v60 — meme correction que pour la reserve de droite : le rail de
     chapitres n'existe que sur release.html, mais sa reserve etait servie a
     toutes les pages. Au-dessus de 1500px elle poussait le contenu de 112px
     vers la droite ; en dessous de 1280px la reserve de droite le poussait
     de 224px vers la gauche. Selon la largeur de fenetre, un texte annonce
     comme centre etait donc decale d'un cote ou de l'autre. Les deux
     reserves sont desormais conditionnees a .page--panel.

     v87 — .page--rail rejoint la reserve de GAUCHE, et elle seule.
     blueprint.html porte le rail (.wrail) sans porter le panneau de
     commande : lui donner .page--panel aurait reserve les 14vw de droite
     pour un panneau absent, donc recentre toute la page vers la gauche —
     le defaut v60 decrit juste au-dessus, reintroduit. Deux classes pour
     deux gouttieres : .page--panel = les deux, .page--rail = la gauche. */
  .page--panel main > *:not(.hero),
  .page--panel .site-foot,
  .page--rail main > *:not(.hero),
  .page--rail .site-foot { padding-left: var(--lrail-w); }

  .chprog {
    left: 0;
    bottom: auto;
    top: 50%;
    transform: translateY(-50%);
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
    width: var(--lrail-w);
    padding: 1rem 0.6rem 1rem 1rem;        /* le texte ne touche aucun bord */
    z-index: 60;                           /* au-dessus des scenes, sous la nav */
    border-right: 1px solid var(--line);
    background: none;                      /* plus rien derriere : plus de fond */
    -webkit-backdrop-filter: none;
            backdrop-filter: none;
  }
  /* la regle de base annule transform sur .is-on ; sans ceci le rail
     descendrait de la moitie de sa hauteur a l'instant ou il apparait */
  .chprog.is-on { transform: translateY(-50%); }
  .chprog { transition: opacity 0.5s var(--ease); }

  .chprog__card { display: block; padding: 0; width: 100%; }
  .chprog__ttl  { font-size: 0.625rem; letter-spacing: 0.09em; color: var(--bone); }

  .chprog__dots { gap: 0.3rem; }
  .chprog__dot  { width: 1.2rem; height: 2px; }
}
@media (min-width: 1500px) and (prefers-reduced-motion: reduce) {
  .chprog { transition: none; }
}

/* ---- v53 : sous 1500px, le rail devient un bandeau de pied ---------------
   Meme exigence qu'au-dessus de 1500px — ne recouvrir ni texte ni image —
   mais la contrainte est inverse : il n'y a AUCUNE marge laterale libre a
   cette largeur. Un bloc flottant en bas a gauche etait donc pose sur le
   contenu par construction. Mesure a 1280px, chapitre 02 : le bloc tombait
   en plein sur la bande de pochettes.

   Il devient une bande pleine largeur ancree au bas de la fenetre, et la
   page reserve sa hauteur. Le contenu s'arrete au-dessus, definitivement.

   C'est le meme arbitrage que la reserve de droite : la place est prise en
   permanence alors que la bande ne s'allume qu'a partir du premier chapitre.
   La reserver a l'apparition ferait sauter toute la page d'un cran sous les
   yeux du visiteur, ce qui est bien pire qu'une bande de 32px inoccupee sur
   le hero.

   Empilement en bas de fenetre : la barre de release (--rbar-h) existe sous
   1280px et n'existe plus au-dessus. La bande se cale donc sur elle quand
   elle est la, sur le bord de la fenetre sinon. */
@media (max-width: 1499px) {
  :root { --lrail-h: 2rem; }

  .chprog {
    left: 0; right: 0;
    bottom: 0;
    height: var(--lrail-h);
    flex-direction: row;
    align-items: center;
    gap: 0.9rem;
    padding-inline: var(--gutter);
    /* opaque, pas translucide : la bande passe au-dessus de pochettes tres
       claires, et un fond a 70% laissait le libelle a 2:1 de contraste */
    background: var(--void);
    border-top: 1px solid var(--line);
    z-index: 60;
  }
  .chprog.is-on { transform: none; }
  .chprog__card { padding: 0; }
  .chprog__ttl  { font-size: 0.625rem; letter-spacing: 0.1em; color: var(--bone); }
  .chprog__pos  { margin-left: auto; }

  /* La reserve est portee par le PIED DE PAGE, pas par <body>.
     Deux raisons. D'abord `body.has-rbar { padding-bottom: 0 }` existe deja
     dans le bloc du panneau de commande, plus loin dans ce fichier : a
     specificite egale c'est lui qui gagnerait, et le pied repasserait sous la
     bande des qu'un article entre dans la release. Ensuite le pied est le
     dernier element de la page — c'est le seul dont la fin doit etre
     garantie visible. */
  .site-foot { padding-bottom: calc(2.5rem + var(--lrail-h)); }
}
/* Entre 1280 et 1499px les deux existent en meme temps : la bande en bas, le
   panneau de commande a droite. Sans cette borne, la bande passe SOUS le
   panneau — meme z-index, et c'est le panneau qui gagne parce qu'il vient
   apres dans le DOM. En rendu a 1280px, l'index "02 / 04" et les quatre
   tirets disparaissaient derriere lui. La bande s'arrete donc sur la lisiere
   du panneau, exactement comme le contenu de la page. */
@media (min-width: 1280px) and (max-width: 1499px) {
  .chprog { right: var(--rpan-w); }
}

/* sous 1280px la barre de release reprend le bas de la fenetre : la bande se
   pose dessus, et les deux hauteurs s'additionnent dans la reserve */
@media (max-width: 1279px) {
  /* `.rbar` n'est peinte QUE lorsqu'il y a quelque chose dans la release :
     `body.has-rbar` est posee par release.js. Caler la bande sur --rbar-h en
     permanence laissait donc un vide de 64px sous elle sur une page vierge,
     et le pied de page passait dedans. Mesure a 768px avant correction : le
     pied depassait de 56px sous la bande. La bande suit l'etat reel. */
  body.has-rbar .chprog { bottom: var(--rbar-h); }
  body.has-rbar .site-foot {
    padding-bottom: calc(2.5rem + var(--lrail-h) + var(--rbar-h));
  }
}

@media (max-width: 720px) {
  .chprog { gap: 0.6rem; }
  .chprog__ttl { font-size: 0.625rem; }
}
@media (prefers-reduced-motion: reduce) {
  .chprog__ttl { transition: none; }
}

/* =========================================================================
   SECTION 01 HERO — text, hand-drawn arrow, record player
   The hero becomes two columns: the argument on the left, the proof on the
   right. The arrow is the only piece of ornament allowed here, and it exists
   for one reason — to move the eye from the word "paid" to the play button.
   ========================================================================= */
.shero__grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 0.98fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;              /* the disc sits level with the second
                                      paragraph -- the line the arrow leaves
                                      from -- not floated against the middle
                                      of a column the pills make far taller */
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
}
.shero__text { max-width: 46ch; }
.shero__grid .shero__sub { max-width: none; }
/* ...except the key line, whose measure has to tighten as its size grows */
.shero__grid .shero__sub--key { max-width: 24ch; }
.shero__player {
  justify-self: end;
  width: 100%;
  max-width: 30rem;
  /* Set in JS: the offset that brings the centre of the disc onto the line the
     arrow leaves from ("...actually gets paid."). A margin, not a transform, so
     the row grows with it and the pills can never sit over the next block. */
  margin-top: var(--vnl-shift, 0px);
}

/* ---- the arrow ----
   Sits in the gap between the two columns, anchored to the last line of the
   text. Drawn once, when the hero enters the viewport, then a slow pulse at
   the tip. Purely decorative, so it never appears to assistive tech and it
   leaves the layout entirely below 1024px. */
.shero__arrow {
  position: absolute;
  z-index: 2;
  left: var(--arw-l, 27%);
  top: var(--arw-t, 9.5rem);       /* JS pins the tail to the "paid" line */
  width: var(--arw-w, 42%);
  height: auto;
  /* White, not signal blue: at this size the blue read as a UI element
     pointing at nothing rather than as a mark on the page. */
  color: var(--bone);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s var(--ease-out-expo) 0.15s;
}
.shero__arrow-line, .shero__arrow-head {
  stroke-dasharray: var(--len, 320);
  stroke-dashoffset: var(--len, 320);
}
.shero.is-in .shero__arrow { opacity: 0.72; }
.shero.is-in .shero__arrow-line {
  animation: arrowDraw 1.15s var(--ease-out-expo) 0.35s forwards;
}
.shero.is-in .shero__arrow-head {
  animation: arrowDraw 0.4s var(--ease-out-expo) 1.35s forwards,
             arrowPulse 2.6s var(--ease) 1.9s infinite;
}
@keyframes arrowDraw { to { stroke-dashoffset: 0; } }
@keyframes arrowPulse {
  0%, 100% { opacity: 1; transform: translate(0, 0); }
  50%      { opacity: 0.45; transform: translate(3px, -3px); }
}

/* =========================================================================
   THE RECORD PLAYER
   A disc, not a rectangle. Grooves are one repeating gradient, the progress
   is one stroked circle, the tonearm is two elements. Nothing animates while
   the player is idle.
   ========================================================================= */
.vnl { --disc: clamp(13rem, 22vw, 17.5rem); position: relative; }

.vnl__deck {
  position: relative;
  display: flex;
  justify-content: center;
  padding-block: 0.5rem;
}
.vnl__disc {
  position: relative;
  width: var(--disc);
  height: var(--disc);
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%, #17181c 0 22%, #0d0e11 22.5% 100%);
  box-shadow:
    0 0 0 1px var(--line-strong),
    0 24px 60px -20px rgba(0, 0, 0, 0.9),
    inset 0 0 60px rgba(0, 0, 0, 0.7);
  display: grid;
  place-items: center;
  isolation: isolate;
}
/* grooves: concentric hairlines, deliberately near-invisible */
.vnl__grooves {
  position: absolute;
  inset: 6%;
  border-radius: 50%;
  background: repeating-radial-gradient(
    circle at 50% 50%,
    rgba(242, 240, 235, 0.045) 0 1px,
    rgba(242, 240, 235, 0) 1px 5px);
  mask-image: radial-gradient(circle at 50% 50%, transparent 0 26%, #000 27% 100%);
  -webkit-mask-image: radial-gradient(circle at 50% 50%, transparent 0 26%, #000 27% 100%);
  transform-origin: 50% 50%;
}
/* the light that sweeps a real record under a studio lamp */
.vnl__sheen {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 210deg,
    rgba(242, 240, 235, 0) 0deg,
    rgba(242, 240, 235, 0.055) 42deg,
    rgba(242, 240, 235, 0) 96deg,
    rgba(242, 240, 235, 0) 240deg,
    rgba(232, 197, 71, 0.07) 288deg,
    rgba(242, 240, 235, 0) 340deg);
  pointer-events: none;
}
.vnl.is-playing .vnl__grooves,
.vnl.is-playing .vnl__sheen { animation: discSpin 4.2s linear infinite; }

@keyframes discSpin { to { transform: rotate(360deg); } }

/* progress: an arc traced around the rim */
.vnl__ring { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.vnl__ring circle { fill: none; stroke-width: 2; }
.vnl__ring-bed { stroke: rgba(242, 240, 235, 0.09); }
.vnl__ring-arc {
  stroke: var(--signal);
  stroke-linecap: round;
  stroke-dasharray: 578;
  stroke-dashoffset: 578;
  transition: stroke-dashoffset 0.2s linear;
}

/* centre label carries the control */
.vnl__label {
  position: absolute;
  width: 44%;
  height: 44%;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 35%, #1d1f24 0%, #131418 70%);
  box-shadow: 0 0 0 1px var(--line-strong), inset 0 1px 0 rgba(242, 240, 235, 0.05);
}
.vnl__play {
  position: relative;
  z-index: 2;
  width: 32%;
  aspect-ratio: 1;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--bone);
  transition: transform 0.3s var(--ease-out-expo), background-color 0.3s var(--ease-out-expo);
}
.vnl__play:hover { transform: scale(1.06); background: #fff; }
.vnl__ico { width: 34%; height: 34%; fill: var(--void); grid-area: 1 / 1; }
.vnl__ico--pause { display: none; }
.vnl__play[aria-pressed="true"] .vnl__ico--play { display: none; }
.vnl__play[aria-pressed="true"] .vnl__ico--pause { display: block; }
.vnl__ripple {
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 1px solid var(--signal);
  opacity: 0;
}
.vnl.is-playing .vnl__ripple { animation: vnlRipple 2.4s var(--ease) infinite; }
@keyframes vnlRipple {
  0%   { opacity: 0.55; transform: scale(1); }
  100% { opacity: 0;    transform: scale(1.55); }
}

/* tonearm: down when playing, parked when not */
.vnl__arm {
  position: absolute;
  top: 4%;
  right: calc(50% - (var(--disc) / 2) - 1.6rem);
  width: 1.6rem;
  height: 62%;
  transform-origin: 50% 8%;
  transform: rotate(24deg);
  transition: transform 0.9s var(--ease-out-expo);
  pointer-events: none;
}
.vnl__arm i {
  position: absolute;
  left: 50%;
  top: 6%;
  width: 2px;
  height: 94%;
  background: linear-gradient(180deg, var(--ash-dim), rgba(90, 95, 104, 0.35));
  transform: translateX(-50%);
}
.vnl__arm b {
  position: absolute;
  left: 50%;
  top: 0;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 50%;
  background: var(--surface-2);
  box-shadow: 0 0 0 1px var(--line-strong);
  transform: translateX(-50%);
}
.vnl.is-playing .vnl__arm { transform: rotate(-9deg); }

/* meta line */
.vnl__meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-top: clamp(1.1rem, 2.5vw, 1.6rem);
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--line);
}
.vnl__now {
  font-family: var(--display);
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--bone);
}
.vnl__time { color: var(--ash-dim); font-size: 0.6875rem; }

.vnl__hint { margin-top: 1rem; color: var(--ash-dim); font-size: 0.625rem; }

/* style selector */
.vnl__pills {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.7rem;
}
.vnl__pill {
  padding: 0.34rem 0.62rem;
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  color: var(--ash);
  border: 1px solid var(--line);
  border-radius: 999px;
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease),
              background-color 0.25s var(--ease);
}
.vnl__pill:hover { color: var(--bone); border-color: var(--line-strong); }
.vnl__pill[aria-selected="true"] {
  color: var(--void);
  background: var(--bone);
  border-color: var(--bone);
}
.vnl__pill.is-na { opacity: 0.45; }

.vnl__note { margin-top: 1rem; color: var(--ash-dim); font-size: 0.625rem; }
.vnl__status {
  min-height: 1.2em;
  margin-top: 0.4rem;
  color: var(--signal);
  font-size: 0.625rem;
}

@media (max-width: 1023px) {
  .shero__grid { grid-template-columns: 1fr; gap: clamp(2rem, 6vw, 3rem); }
  .shero__arrow { display: none; }              /* asked for: no arrow on mobile */
  .shero__player { justify-self: center; max-width: 26rem; }
  .vnl { --disc: clamp(12rem, 52vw, 16rem); }
  .vnl__meta { justify-content: center; gap: 1.4rem; }
  .vnl__pills { justify-content: center; }
  .vnl__hint, .vnl__note, .vnl__status { text-align: center; }
}

@media (prefers-reduced-motion: reduce) {
  .shero__arrow { opacity: 0.72; }
  .shero__arrow-line, .shero__arrow-head { stroke-dashoffset: 0; animation: none; }
  .vnl.is-playing .vnl__grooves,
  .vnl.is-playing .vnl__sheen,
  .vnl.is-playing .vnl__ripple { animation: none; }
  .vnl__arm, .vnl__play, .vnl__ring-arc { transition: none; }
}

/* =========================================================================
   COMPARISON BLOCK — two background images, one per claim
   Left: the automatic route. Right: the studio. They are atmosphere, nothing
   more: 18% opacity, under a dark overlay that is strongest exactly where the
   copy sits. If a visitor has to work to read the text, the images have failed.
   ========================================================================= */
.vsblk { position: relative; overflow: hidden; isolation: isolate; }

.vsblk__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  pointer-events: none;
}
.vsblk__half { position: relative; overflow: hidden; }
.vsblk__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.18;
}
/* v40 : l'asymetrie commence dans le fond. Gauche desaturee et effacee,
   droite plus lisible : la photo de studio doit se voir, celle d'en face non. */
.vsblk__half--them .vsblk__img { filter: grayscale(1) contrast(1.02) brightness(0.85); opacity: 0.09; }
.vsblk__half--us   .vsblk__img { filter: saturate(1.02); opacity: 0.30; }
/* the seam: a hairline plus a short fade, so the two never butt together */
.vsblk__half--them::after,
.vsblk__half--us::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  width: 14%;
  pointer-events: none;
}
.vsblk__half--them::after { right: 0; background: linear-gradient(90deg, transparent, var(--surface)); }
.vsblk__half--us::after   { left: 0;  background: linear-gradient(270deg, transparent, var(--surface)); }

/* the readability layer: darkest at the bottom, where the columns are */
.vsblk::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(180deg, rgba(10, 11, 13, 0.40) 0%, rgba(10, 11, 13, 0.62) 52%, rgba(10, 11, 13, 0.80) 100%);
  pointer-events: none;
}
.vsblk > *:not(.vsblk__bg) { position: relative; z-index: 2; }

/* per-column titles: the mono label names the side, the title states the claim */
.vsblk__cols { margin-top: 0; }
.vsblk__c .vsblk__t {
  margin-top: 0.55rem;
  font-size: clamp(1.25rem, 2.2vw, 1.75rem);
  font-weight: 600;
  line-height: 1.14;
  letter-spacing: -0.02em;
  max-width: 24ch;
  color: var(--bone);
}
.vsblk__c--us .vsblk__t { color: var(--bone); }
.vsblk__c p { margin-top: 0.9rem; }
.vsblk__foot { margin-top: 2.25rem; }

@media (max-width: 860px) {
  .vsblk__bg { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
  .vsblk__half--them::after { right: auto; left: 0; top: auto; bottom: 0; width: 100%; height: 16%;
    background: linear-gradient(180deg, transparent, var(--surface)); }
  .vsblk__half--us::after { left: 0; top: 0; bottom: auto; width: 100%; height: 16%;
    background: linear-gradient(0deg, transparent, var(--surface)); }
}

/* ============================================================
   v32 — section 02 cover band: an infinite marquee, not a row
   ------------------------------------------------------------
   Replaces the five-tile .rail under Cover Art. Same dark treatment,
   same genre caption under each cover, same order — only the movement
   and the height change.

   Two things are load-bearing:
   - the track holds the set TWICE and the keyframe travels exactly -50%,
     so the loop restarts on an identical tile and the seam is invisible.
     Add or remove a cover in content.py and this still holds, because both
     passes come from the same list.
   - .cmq__viewport clips horizontally but is padded vertically, so a tile
     scaled to 1.06 on hover is not sliced off at the top and bottom.
   ============================================================ */

.cmq { margin-top: clamp(1.75rem, 3.5vw, 2.75rem); }

/* full-bleed: the band runs edge to edge even inside a .container section */
.cmq__viewport {
  position: relative;
  width: 100vw;
  margin-inline: calc(50% - 50vw);
  overflow: hidden;
  padding-block: 0.75rem;          /* headroom for the hover scale */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}

.cmq__track {
  --cmq-dur: 60s;
  display: flex;
  gap: clamp(0.6rem, 1.2vw, 1rem);
  margin: 0;
  padding: 0;
  list-style: none;
  width: max-content;
  animation: cmq-scroll var(--cmq-dur) linear infinite;
  will-change: transform;
}
@keyframes cmq-scroll {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

.cmq__item { flex: none; }

.cmq__tile {
  width: clamp(112px, 11vw, 168px);   /* compact: roughly half the old rail */
  aspect-ratio: 1 / 1;
  border-radius: var(--radius-m);
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  transition: transform 0.32s var(--ease);
  will-change: transform;
}
.cmq__media { width: 100%; height: 100%; object-fit: cover; display: block; }

/* the only hover effect: the cover grows a little. The band keeps moving. */
.cmq__item:hover .cmq__tile { transform: scale(1.06); }

.cmq__meta {
  margin-top: 0.5rem;
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  color: var(--ash-dim);
  text-align: center;
}
.cmq__item[aria-hidden="true"] .cmq__meta { }   /* duplicate pass keeps the label */

@media (max-width: 600px) { .cmq__track { --cmq-dur: 42s; } }

/* Reduced motion: no self-scrolling band. It becomes a normal swipeable row. */
@media (prefers-reduced-motion: reduce) {
  .cmq__viewport { overflow-x: auto; -webkit-overflow-scrolling: touch; scroll-snap-type: x mandatory; }
  .cmq__track { animation: none; }
  .cmq__item { scroll-snap-align: center; }
  .cmq__tile { transition: none; }
  .cmq__item:hover .cmq__tile { transform: none; }
}

/* ---- emphasis inside the What we do / What it's for pair ----
   Bold + underline + signal colour. The underline is drawn with a box-shadow
   rather than text-decoration so it sits clear of the descenders. */
.prod__pair .kw { font-weight: 700; color: var(--bone); }
.prod__pair .kw--u {
  box-shadow: inset 0 -0.16em 0 rgba(232, 197, 71, 0.55);
  padding-bottom: 0.02em;
}

/* =========================================================================
   PLATFORM RAIL — the right margin of .diag, under the arrow
   Answers the one question the benefits list raises but never names: paid by
   whom. It sits in the margin the arrow already occupies, so it costs the
   section no vertical space on desktop.
   ========================================================================= */

/* Marker hand for the rail title — the third and last voice on the page, and
   deliberately confined to this one block. Self-hosted like the other two:
   drop PermanentMarker-Regular.woff2 in /assets/fonts (Apache 2.0, Google
   Fonts — free for commercial use). Falls back to the system handwriting
   faces if the file is missing, so the block never renders in the grotesque. */
@font-face {
  font-family: 'Permanent Marker';
  font-style: normal; font-weight: 400; font-display: swap;
  src: url('/assets/fonts/PermanentMarker-Regular.woff2') format('woff2');
}

/* =========================================================================
   v88 — CAVEAT PASSE EN AUTO-HEBERGEMENT (correctif RGPD)

   index.html appelait fonts.googleapis.com pour cette seule famille, servant
   exactement UN paragraphe : la citation signee du fondateur (.fsig__q). Un
   appel a Google Fonts transmet l'adresse IP du visiteur a un tiers hors UE
   avant tout consentement — c'est le motif de sanction retenu par la CNIL et
   par plusieurs juridictions allemandes. Trois requetes reseau bloquantes et
   une exposition juridique, pour quatre lignes de texte.

   Les deux <link rel="preconnect"> et le <link rel="stylesheet"> ont ete
   retires d'index.html. Caveat est sous licence SIL OFL : la redistribution
   est autorisee, l'auto-hebergement est donc pleinement legal.

   /!\ LE FICHIER N'EST PAS ENCORE LA. Il n'a pas pu etre telecharge
   (environnement sans reseau). Tant que /assets/fonts/caveat-latin-wght-
   normal.woff2 est absent, la citation se rend avec la premiere manuscrite
   du systeme (Segoe Script sur Windows, Bradley Hand sur macOS) — lisible,
   mais variable d'une machine a l'autre. Deposer le .woff2 au chemin
   ci-dessous suffit a retrouver le rendu exact, sans autre modification.
   Source : github.com/fontsource/font-files (dossier caveat).
   ========================================================================= */
@font-face {
  font-family: 'Caveat';
  font-style: normal; font-weight: 400 700; font-display: swap;
  src: url('/assets/fonts/caveat-latin-wght-normal.woff2') format('woff2-variations');
}

.plat {
  position: absolute;
  z-index: 2;
  /* clears the arrow head: the arrow is 170x262 at width clamp(88px,11vw,138px),
     so its foot sits at roughly 1.54x that width from the top of .diag */
  top: clamp(15rem, 20vw, 17.5rem);
  right: clamp(0.5rem, 3.5vw, 3rem);
  width: clamp(14rem, 18vw, 17rem);
  color: var(--bone);
}

.plat__t {
  font-family: 'Permanent Marker', 'Bradley Hand', 'Segoe Script',
               'Brush Script MT', cursive;
  font-weight: 400;
  font-size: clamp(1.15rem, 1.55vw, 1.5rem);
  line-height: 1.18;
  letter-spacing: 0.01em;
  text-align: center;
  color: var(--bone);
  transform: rotate(-2.4deg);
  text-shadow: 0 0 22px rgba(242, 240, 235, 0.14);
}
/* hand-drawn stroke under the title — same marker language as the arrow */
.plat__ul {
  display: block;
  width: 82%;
  height: auto;
  margin: 0.5rem auto clamp(1.1rem, 2vw, 1.75rem);
  color: var(--bone);
  opacity: 0.55;
  transform: rotate(-1.2deg);
}

.plat__list { display: flex; flex-direction: column; gap: clamp(0.6rem, 1.1vw, 0.95rem); }

.plat__row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  min-height: 1.5rem;
}
/* Fixed-width cell, sized by HEIGHT, so a square symbol (Spotify, Deezer) and
   a wide wordmark (Amazon Music, Qobuz) sit on the same baseline and the names
   still line up in one clean column. object-fit keeps both undistorted. */
.plat__logo {
  flex: none;
  width: clamp(52px, 4.6vw, 68px);
  height: clamp(17px, 1.5vw, 21px);
  object-fit: contain;
  object-position: center;
  opacity: 0.9;
}
.plat__name {
  font-size: clamp(0.8rem, 0.92vw, 0.95rem);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: -0.005em;
  color: var(--bone);
  white-space: nowrap;
}

/* Enters with the rest of .diag, staggered one row at a time, after the arrow
   has finished drawing (~1.8s) so the two hand-drawn elements do not compete. */
.plat__t, .plat__ul, .plat__row {
  opacity: 0;
  transform: translateY(10px) rotate(var(--pr, 0deg));
  transition: opacity 0.55s var(--ease-out-expo), transform 0.55s var(--ease-out-expo);
  transition-delay: calc(1.75s + var(--pi, 0) * 0.06s);
}
.plat__t  { --pr: -2.4deg; }
.plat__ul { --pr: -1.2deg; --pi: 0.5; }
.diag.is-in .plat__t,
.diag.is-in .plat__ul,
.diag.is-in .plat__row { opacity: 1; transform: translateY(0) rotate(var(--pr, 0deg)); }

/* Below 1200px the right margin is gone (and the arrow is hidden), so the rail
   drops into normal flow under the benefits. Same block, same order. */
@media (max-width: 1200px) {
  .plat {
    position: static;
    width: auto;
    max-width: 22rem;
    margin-top: clamp(2.25rem, 5vw, 3.25rem);
  }
  .plat__t { text-align: left; }
  .plat__ul { margin-left: 0; width: 11rem; }
  .plat__t, .plat__ul, .plat__row { transition-delay: calc(var(--pi, 0) * 0.05s); }
}

@media (prefers-reduced-motion: reduce) {
  .plat__t, .plat__ul, .plat__row {
    opacity: 1;
    transform: rotate(var(--pr, 0deg));
    transition: none;
  }
}

/* =========================================================================
   THUMBNAIL BAND + KEYWORD REVEAL — section 02, YouTube Thumbnail only
   ========================================================================= */

/* ---- 16:9 variant of the cover marquee ----
   Same engine as .cmq (track holds the set twice, keyframe travels -50%),
   only the tile geometry changes. Compact on purpose: a thumbnail reads as a
   thumbnail at small size, which is the whole argument of the block. */
.cmq--wide .cmq__tile {
  width: clamp(168px, 17vw, 252px);
  aspect-ratio: 16 / 9;
}
.cmq--wide .cmq__track { --cmq-dur: 52s; }
.cmq--wide .cmq__item:hover .cmq__tile { transform: scale(1.07); }
@media (max-width: 600px) { .cmq--wide .cmq__track { --cmq-dur: 38s; } }

/* ---- keyword highlight that draws itself in ----
   box-shadow cannot animate its width, so the rule is a background gradient
   sized from 0% to 100%. Scoped to .prod--thumb so the cover block above is
   untouched and keeps its static underline. */
.prod--thumb .prod__pair .kw--u {
  box-shadow: none;
  background-image: linear-gradient(rgba(232, 197, 71, 0.55), rgba(232, 197, 71, 0.55));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 0.16em;
  padding-bottom: 0.02em;
  transition: background-size 0.62s var(--ease-out-expo),
              color 0.5s var(--ease-out-expo);
  transition-delay: calc(0.18s + var(--k, 0) * 0.085s);
}
.prod--thumb [data-kw-reveal].is-in .prod__pair .kw--u { background-size: 100% 0.16em; }

@media (prefers-reduced-motion: reduce) {
  .prod--thumb .prod__pair .kw--u {
    background-size: 100% 0.16em;
    transition: none;
  }
}

/* =========================================================================
   V38 — signature du bloc comparatif, triptyque de transition
   ========================================================================= */

/* ---- v39 : le badge quitte le coin du bloc et rentre dans la colonne ----
   En absolu il flottait au-dessus des deux colonnes : personne ne savait a
   quel cote il appartenait, et il tombait sur l'image. Dans le flux, juste
   au-dessus du titre de droite, l'attribution ne se discute plus. */
.vsblk__logo {
  width: 132px;
  height: 132px;
  border-radius: 50%;
  display: block;
  pointer-events: none;
  opacity: 0;
  transform: translateY(10px) scale(0.94);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
.vsblk.is-in .vsblk__logo { opacity: 1; transform: none; }
@media (max-width: 900px) { .vsblk__logo { width: 104px; height: 104px; } }

/* L'intitule bleu a disparu a droite mais reste a gauche : sans ce fantome,
   les deux titres h3 ne demarrent plus a la meme hauteur. subgrid aligne les
   trois rangees exactement ; le min-height couvre les moteurs sans subgrid. */
.vsblk__h--ghost { min-height: 1lh; }
@supports (grid-template-rows: subgrid) {
  .vsblk__cols { grid-template-rows: auto auto auto; }
  .vsblk__c { display: grid; grid-row: span 3; grid-template-rows: subgrid; }
}

/* ---- triptyque de transition, stage du chapitre 03 ----
   Le zoom d'entree porte sur le conteneur, pas sur chaque video : trois boites
   a taille fixe qui grandissent individuellement finiraient par se chevaucher. */
.chapter__trio {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(0.6rem, 1.4vw, 1.4rem);
  width: 100%;
  transform: scale(calc(1.06 - var(--p, 0) * 0.06));
  transform-origin: 50% 50%;
  will-change: transform;
}
.chapter__media--trio {
  flex: none;
  width: clamp(132px, 15vw, 232px);   /* volontairement reduit : c'est un raccord */
  height: auto;
  aspect-ratio: 9 / 16;
  max-height: 62svh;
  object-fit: cover;
  border-radius: var(--radius-m);
  transform: none;                     /* neutralise le scale de .chapter__media */
}

/* Sous 860px : le duo central seul, un peu plus grand. Les deux autres sortent
   du DOM rendu et le JS ne les demarre pas (voir initChapters). */
@media (max-width: 860px) {
  .chapter__media--trio:not(:nth-child(2)) { display: none; }
  .chapter__media--trio { width: min(58vw, 300px); max-height: 68svh; }
}

/* =========================================================================
   V39 — bloc comparatif : signature de colonne + mots-cles animes
   Gauche : un groupe d'outils, pas une marque. Le meme glyphe repete cinq
   fois — trois barres strictement egales, soit une dynamique ecrasee — dit
   "meme algorithme sur tous les fichiers" sans citer personne en image.
   Aucun logo concurrent n'est reproduit : les noms restent du texte.
   ========================================================================= */
.vsblk__mark {
  display: flex;
  align-items: flex-end;
  gap: 0.5rem;
  min-height: 132px;          /* aligne le bas du cluster sur le bas du badge */
  margin-bottom: 0.9rem;
}
@media (max-width: 900px) { .vsblk__mark { min-height: 104px; } }

.vsblk__tool {
  width: 52px;
  height: 52px;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: rgba(242, 240, 235, 0.03);
  color: var(--ash-dim);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.55s var(--ease), transform 0.55s var(--ease);
}
.vsblk__tool svg { width: 22px; height: 22px; display: block; }
.vsblk__tool--more { color: var(--ash-dim); font-size: 0.9rem; }
/* aucun decalage entre les tuiles : elles arrivent ensemble, a l'identique.
   C'est le propos — un seul traitement pour tout le monde. */
.vsblk.is-in .vsblk__tool { opacity: 0.62; transform: none; }
.vsblk.is-in .vsblk__tool { animation: vs-tool-tick 3.4s var(--ease) 0.9s infinite; }
@keyframes vs-tool-tick {
  0%, 82%, 100% { border-color: var(--line); background: rgba(242, 240, 235, 0.03); }
  88%           { border-color: var(--line-strong); background: rgba(242, 240, 235, 0.07); }
}
@media (max-width: 900px) { .vsblk__tool { width: 44px; height: 44px; } }
@media (max-width: 400px) { .vsblk__mark { gap: 0.35rem; } .vsblk__tool { width: 38px; height: 38px; } }

/* ---- mots-cles : le trait se dessine sous le mot quand le bloc entre ----
   Un souligne qui se remplit, pas un surlignage plein : a cette taille un
   bloc de couleur transforme la phrase en bandeau d'alerte. */
.vsblk__kw {
  font-weight: 700;
  color: var(--bone);
  background-image: linear-gradient(var(--kwc, rgba(232, 197, 71, 0.34)), var(--kwc, rgba(232, 197, 71, 0.34)));
  background-repeat: no-repeat;
  background-position: 0 92%;
  background-size: 0 0.16em;
  /* un mot-cle peut passer a la ligne : sans clone, le trait ne se dessine que
     sous le premier fragment et la seconde ligne reste nue */
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  transition: background-size 0.85s var(--ease) var(--d, 0ms);
}
.vsblk.is-in .vsblk__kw { background-size: 100% 0.16em; }
/* cote gauche : le meme mecanisme, mais gris. Le bleu est reserve a l'offre. */
.vsblk__kw--neg { --kwc: rgba(138, 143, 152, 0.42); color: var(--bone); }

@media (prefers-reduced-motion: reduce) {
  .vsblk__logo { opacity: 1; transform: none; transition: none; }
  .vsblk__tool { opacity: 0.62; transform: none; transition: none; animation: none; }
  .vsblk.is-in .vsblk__tool { animation: none; }
  .vsblk__kw { background-size: 100% 0.16em; transition: none; }
}

/* =========================================================================
   V40 — le bloc comparatif cesse d'etre un match nul
   Le probleme du v39 n'etait pas le texte, c'etait la symetrie : deux colonnes
   de meme largeur, meme corps, meme couleur, donc deux options credibles. Ici
   la gauche est traitee comme une impasse (gris, corps reduit, image lavee) et
   la droite comme la sortie (plus large, plus claire, filet signal, badge).
   ========================================================================= */

/* ---- gauche : l'impasse ---- */
.vsblk__c--them .vsblk__t {
  font-size: clamp(1.1rem, 1.85vw, 1.45rem);
  color: var(--ash);
  max-width: 22ch;
}
.vsblk__c--them .vsblk__body p { color: var(--ash-dim); }
.vsblk__body .vsblk__names { color: var(--ash-dim); margin-bottom: 0.55rem; }
/* les tuiles s'eteignent : elles arrivent, elles restent grises, c'est tout */
.vsblk__c--them .vsblk__tool { border-radius: 8px; }
.vsblk.is-in .vsblk__c--them .vsblk__tool { opacity: 0.4; }

/* ---- droite : la sortie ---- */
.vsblk__c--us {
  border-left: 2px solid rgba(232, 197, 71, 0.55);
  padding-left: clamp(1.25rem, 2.4vw, 2.25rem);
  background: linear-gradient(180deg, rgba(232, 197, 71, 0.055), transparent 62%);
}
.vsblk__c--us .vsblk__t {
  font-size: clamp(1.45rem, 2.9vw, 2.2rem);
  color: var(--bone);
  max-width: 20ch;
}
.vsblk__c--us .vsblk__body p { color: var(--bone); }
.vsblk__c--us em { font-style: italic; color: var(--signal); }

/* le badge : centre au-dessus du titre, pas colle dans un coin. Centre sur la
   colonne alors que le texte reste ferre a gauche : c'est un sceau, pas un
   element de mise en page. */
.vsblk__mark--rr { justify-content: center; align-items: center; }
.vsblk__logo {
  box-shadow: 0 0 0 1px rgba(242, 240, 235, 0.10), 0 18px 60px -18px rgba(232, 197, 71, 0.55);
}

/* ---- corps en lignes courtes : chaque phrase frappe seule ---- */
.vsblk__body { margin-top: 0.9rem; }
.vsblk__body p { margin: 0 0 0.3rem; max-width: 40ch; line-height: 1.45; }
.vsblk__body p:last-child { margin-bottom: 0; }

/* ---- mots-cles : le trait se dessine, puis le mot flashe une fois ---- */
.vsblk.is-in .vsblk__kw {
  background-size: 100% 0.18em;
  animation: vs-kw-flash 1.05s var(--ease) var(--d, 0ms) 1 both;
}
@keyframes vs-kw-flash {
  0%   { text-shadow: none; }
  38%  { text-shadow: 0 0 20px var(--kwglow, rgba(232, 197, 71, 0.75)); }
  100% { text-shadow: none; }
}
/* le rouge n'existe nulle part ailleurs sur le site : il est reserve a ce que
   le visiteur perd. Un seul usage, donc il se lit comme une alarme. */
.vsblk__kw--neg {
  --kwc: rgba(224, 91, 84, 0.55);
  --kwglow: rgba(224, 91, 84, 0.65);
  color: #E8837D;
}
.vsblk__c--them .vsblk__t .vsblk__kw--neg { color: #EC948F; }

@media (max-width: 860px) {
  .vsblk__cols { grid-template-columns: 1fr; }
  .vsblk__c--us {
    border-left: 0;
    border-top: 2px solid rgba(232, 197, 71, 0.55);
    padding-left: 0;
    padding-top: clamp(1.25rem, 5vw, 2rem);
  }
  .vsblk__mark--rr { justify-content: flex-start; }
}

@media (prefers-reduced-motion: reduce) {
  .vsblk.is-in .vsblk__kw { animation: none; }
}

/* =========================================================================
   V41 — 03 / Anatomy of a 15-second short
   Le tableau devient une pellicule : cinq plans carres, un timing, deux
   lignes. Les vignettes sont du decor sous licence (aria-hidden, sans
   legende) : elles illustrent un moment de short, elles ne documentent pas
   une de nos productions.
   ========================================================================= */
.anat__title { margin-bottom: 1rem; }

/* ---- tete de lecture : une seule ligne qui traverse les cinq plans ----
   Elle part avec le premier panneau et arrive avec le dernier. C'est ce qui
   transforme cinq cartes en une timeline. */
.anat__bar {
  display: block;
  height: 2px;
  background: var(--line);
  margin-bottom: 1.25rem;
  overflow: hidden;
}
.anat__bar i {
  display: block;
  height: 100%;
  width: 100%;
  background: linear-gradient(90deg, var(--signal-dim), var(--signal));
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 2.2s linear;
}
.anat.is-in .anat__bar i { transform: scaleX(1); }

.anat__track {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}

/* ---- un plan ---- */
.stage {
  background: var(--void);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.65s var(--ease) var(--d, 0ms),
              transform 0.65s var(--ease) var(--d, 0ms);
}
.anat.is-in .stage { opacity: 1; transform: none; }

.stage__shot {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--surface);
}
.stage__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* le plan s'ouvre legerement : le mouvement vient de l'image, pas du cadre */
  transform: scale(1.07);
  transition: transform 1.1s var(--ease) var(--d, 0ms);
}
.anat.is-in .stage__img { transform: scale(1); }
/* le bas de l'image se fond dans le fond du panneau, sinon la photo coupe net
   au-dessus du texte et les deux se disputent la meme ligne */
.stage__shot::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 38%;
  background: linear-gradient(180deg, transparent, rgba(10, 11, 13, 0.85) 78%, var(--void));
  pointer-events: none;
}

.stage__body { padding: 1.15rem 1.15rem 1.35rem; display: flex; flex-direction: column; gap: 0.4rem; flex: 1; }
.stage__t {
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  color: var(--signal);
  font-weight: 500;
}
.stage__name { font-size: 1.15rem; font-weight: 700; letter-spacing: -0.015em; }
.stage__do { font-size: 0.88rem; color: var(--ash); line-height: 1.45; }
.stage__why {
  font-size: 0.95rem;
  color: var(--bone);
  line-height: 1.45;
  font-weight: 500;
  margin-top: auto;
  padding-top: 0.5rem;
}

@media (max-width: 1080px) {
  .anat__track { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
  .anat__track { grid-template-columns: 1fr; }
  .stage__shot { aspect-ratio: 16 / 10; }
  .stage__img { object-position: 50% 32%; }
}

@media (prefers-reduced-motion: reduce) {
  .stage { opacity: 1; transform: none; transition: none; }
  .stage__img { transform: none; transition: none; }
  .anat__bar i { transform: scaleX(1); transition: none; }
}

/* =========================================================================
   V42 — le rail de gauche devient la seule navigation
   Avant : chaque chapitre se terminait sur un panneau "Explore another part
   of your release" qui rejouait l'index. Quatre fois le meme menu, ~700px
   chacun, et une lecture qui repartait de zero a chaque fin de section. Le
   panneau est supprime. L'index vit ici, en peripherie, en permanence.
   ========================================================================= */

/* le rail existe pour le clavier meme quand il est encore invisible, mais il
   ne doit pas etre focusable a ce moment-la : visibility, pas seulement
   opacity, sinon on tabule dans un panneau qu'on ne voit pas */
.chprog { visibility: hidden; }
.chprog.is-on { visibility: visible; }

.chprog__idx { display: flex; gap: 0.3rem; list-style: none; margin: 0; padding: 0; }
.chprog__step { display: block; }

/* ---- forme compacte (sous 1500px) : quatre tirets, comme avant ----
   Les intitules restent dans le DOM pour le clavier et les lecteurs d'ecran,
   ils ne sont simplement pas peints. */
.chprog__dot {
  display: block;
  width: 1.6rem;
  height: 2px;
  background: var(--line-strong);
  cursor: pointer;
  transition: background 0.35s var(--ease);
}
.chprog__dot.is-on { background: var(--signal); }
.chprog__dot:hover { background: var(--bone); }
.chprog__n, .chprog__lbl {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.chprog__pos { color: var(--ash-dim); font-size: 0.625rem; letter-spacing: 0.12em; }
.chprog__dot:focus-visible { outline: 1px solid var(--signal); outline-offset: 3px; }

/* ---- forme index (1500px et plus) : la timeline editoriale ----
   Meme seuil et meme largeur de panneau que la version precedente : le calcul
   de marge qui la justifie est documente plus haut, il n'a pas change. */
@media (min-width: 1500px) {
  .chprog__pos { display: none; }          /* l'index dit deja ou on en est */

  .chprog__idx {
    position: relative;
    flex-direction: column;
    gap: 0;
    width: 100%;
    padding-left: 0.75rem;
  }
  /* le guide vertical, et par-dessus le segment parcouru */
  .chprog__idx::before,
  .chprog__idx::after {
    content: '';
    position: absolute;
    left: 0;
    top: 0.5rem;
    width: 1px;
  }
  .chprog__idx::before { bottom: 0.5rem; background: var(--line-strong); }
  .chprog__idx::after {
    height: calc(var(--chp, 0) * (100% - 1rem));
    background: var(--signal);
    transition: height 0.5s var(--ease);
  }

  .chprog__dot {
    position: relative;
    display: block;
    width: 100%;
    height: auto;
    background: none;
    padding: 0.42rem 0 0.42rem 0.55rem;
    transition: none;
  }
  .chprog__dot:hover, .chprog__dot.is-on { background: none; }
  /* le marqueur sur le guide : discret, il grossit a peine a l'actif */
  .chprog__dot::before {
    content: '';
    position: absolute;
    left: -1px;
    top: 0.72rem;
    width: 3px;
    height: 3px;
    background: var(--line-strong);
    transition: background 0.3s var(--ease), height 0.3s var(--ease), top 0.3s var(--ease);
  }
  .chprog__dot.is-on::before {
    background: var(--signal);
    height: 1rem;
    top: 0.32rem;
    left: -1px;
    width: 2px;
  }

  .chprog__n, .chprog__lbl {
    position: static;
    width: auto; height: auto;
    overflow: visible;
    clip-path: none;
    white-space: normal;
    display: block;
  }
  .chprog__n {
    font-size: 0.5625rem;
    letter-spacing: 0.14em;
    color: var(--ash-dim);
    transition: color 0.3s var(--ease);
  }
  .chprog__lbl {
    font-size: 0.625rem;
    letter-spacing: 0.06em;
    line-height: 1.35;
    color: var(--ash-dim);
    transition: color 0.3s var(--ease);
  }
  .chprog__dot:hover .chprog__n,
  .chprog__dot:hover .chprog__lbl { color: var(--ash); }
  .chprog__dot.is-on .chprog__n { color: var(--signal); }
  .chprog__dot.is-on .chprog__lbl { color: var(--bone); font-weight: 500; }
}

@media (prefers-reduced-motion: reduce) {
  .chprog__idx::after, .chprog__dot::before, .chprog__n, .chprog__lbl { transition: none; }
}

/* =========================================================================
   V43 — REAL PERFORMERS : la copy a gauche, la preuve a droite
   Le bandeau pleine largeur qui vivait sous les deux produits est supprime.
   Il occupait toute la page, servait les deux blocs a la fois et ne prouvait
   donc precisement rien. Les dix shorts deviennent un deck local a ce bloc :
   une carte au premier plan, la precedente et la suivante en retrait.
   ========================================================================= */
.prod--real,
.prod--ai {
  display: grid;
  grid-template-columns: minmax(0, 1.27fr) minmax(0, 1fr);   /* ~56 / 44 */
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: center;
}

/* ---- colonne gauche ---- */
.rp__copy { min-width: 0; }
.rp__head {
  font-family: var(--display);
  font-size: clamp(1.5rem, 2.6vw, 2.05rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.12;
  color: var(--bone);
  max-width: 18ch;                 /* le headline doit tenir en deux lignes */
  margin-top: 1.1rem;
}
.rp__lead {
  color: var(--ash);
  font-size: 0.98rem;
  line-height: 1.6;
  max-width: 50ch;                 /* jamais toute la largeur de la colonne */
  margin-top: 0.9rem;
}
.rp__proofs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--line);
  border-block: 1px solid var(--line);
  margin-top: 1.6rem;
}
.rp__proof { background: var(--void); padding: 0.95rem 0.9rem 1.05rem 0; }
.rp__proof:not(:first-child) { padding-left: 0.9rem; }
.rp__plabel {
  font-size: var(--fs-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bone);
  font-weight: 500;
  margin-bottom: 0.4rem;
}
.rp__ptext { color: var(--ash-dim); font-size: 0.8125rem; line-height: 1.45; }
.rp__genres { margin-top: 1rem; font-size: 0.875rem; color: var(--ash); }
.rp__pills { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 1.35rem; list-style: none; padding: 0; }
.rp__pill {
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.32rem 0.72rem;
  font-size: 0.75rem;
  color: var(--ash-dim);
}

/* ---- colonne droite : le deck ---- */
.rp__deck { min-width: 0; }
.deck__stage {
  position: relative;
  height: 400px;
  display: grid;
  place-items: center;
  overflow: hidden;                /* rien ne sort de la colonne */
}
.deck__list { list-style: none; margin: 0; padding: 0; }
.deck__card {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 220px;
  aspect-ratio: 9 / 16;
  max-height: 100%;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  /* etat par defaut = carte hors champ. Sans JS, seule la premiere est
     ramenee au premier plan par la regle :first-child plus bas. */
  transform: translate(-50%, -50%) scale(0.7);
  opacity: 0;
  z-index: 0;
  pointer-events: none;
  transition: transform 0.55s cubic-bezier(0.22, 1, 0.36, 1),
              opacity 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}
.deck__video { width: 100%; height: 100%; object-fit: cover; display: block; }

.deck__card[data-pos="current"] {
  transform: translate(-50%, -50%) scale(1);
  opacity: 1;
  z-index: 3;
  pointer-events: auto;
  border-color: var(--line-strong);
}
.deck__card[data-pos="prev"] {
  transform: translate(calc(-50% - 148px), -50%) scale(0.78);
  opacity: 0.42;
  z-index: 2;
}
.deck__card[data-pos="next"] {
  transform: translate(calc(-50% + 148px), -50%) scale(0.78);
  opacity: 0.42;
  z-index: 2;
}
/* sans JS : la premiere carte tient le premier plan, sur son poster */
.deck__list > .deck__card:first-child:not([data-pos]) {
  transform: translate(-50%, -50%) scale(1);
  opacity: 1;
  z-index: 3;
}

/* ---- le son : sur la carte de devant, au survol ----
   Le bouton reste dans le DOM et cliquable : au doigt il n'y a pas de survol,
   et un son qui n'existe qu'au pointeur n'existe pas sur mobile. */
.deck__sound {
  position: absolute;
  z-index: 4;
  bottom: 0.75rem;
  left: 50%;
  transform: translateX(-50%);
  width: 2rem; height: 2rem;
  display: grid; place-items: center;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: rgba(10, 11, 13, 0.72);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  color: var(--bone);
  font-size: 0.9rem;
  opacity: 0.35;
  cursor: pointer;
  transition: opacity 0.3s var(--ease), background 0.3s var(--ease);
}
.deck__stage:hover .deck__sound,
.deck__sound:focus-visible { opacity: 1; }
.deck__sound[aria-pressed="true"] { background: var(--signal-fill); border-color: transparent; opacity: 1; }
.deck__note { margin-top: 0.9rem; font-size: 0.8125rem; color: var(--ash-dim); text-align: center; }

/* ---- responsive : une colonne, le deck avant les pills ---- */
@media (max-width: 980px) {
  .prod--real, .prod--ai { grid-template-columns: 1fr; gap: 1.75rem; }
  .rp__copy { display: contents; }
  .prod--real .prod__title, .prod--ai .prod__title { order: 1; }
  .rp__head   { order: 2; max-width: 22ch; }
  .rp__lead   { order: 3; }
  .rp__proofs { order: 4; }
  .rp__genres { order: 5; }
  .rp__deck   { order: 6; }
  .rp__pills  { order: 7; }
}
@media (max-width: 640px) {
  .rp__proofs { grid-template-columns: 1fr; }
  .rp__proof:not(:first-child) { padding-left: 0; }
  .deck__stage { height: 340px; }
  .deck__card { width: 178px; }
  .deck__card[data-pos="prev"] { transform: translate(calc(-50% - 112px), -50%) scale(0.76); }
  .deck__card[data-pos="next"] { transform: translate(calc(-50% + 112px), -50%) scale(0.76); }
}

/* ---- mouvement reduit : une seule carte, rien ne tourne ---- */
@media (prefers-reduced-motion: reduce) {
  .deck__card { transition: none; }
  .deck__card[data-pos="prev"], .deck__card[data-pos="next"] { opacity: 0; }
}

/* ---- palier intermediaire : entre 981 et 1279px la colonne de droite est
   trop etroite pour un jeu de cartes a 220px. Les cartes laterales seraient
   rognees par l'overflow du stage. On reduit l'ensemble plutot que de laisser
   couper. */
@media (min-width: 981px) and (max-width: 1279px) {
  .deck__stage { height: 344px; }
  .deck__card { width: 184px; }
  .deck__card[data-pos="prev"] { transform: translate(calc(-50% - 120px), -50%) scale(0.78); }
  .deck__card[data-pos="next"] { transform: translate(calc(-50% + 120px), -50%) scale(0.78); }
}

/* ---- v44 : bloc AI. Meme grille, meme rythme, meme deck que Real
   performers : deux modes de production d'un meme produit. La difference vient
   des videos et de l'argument, jamais de la forme.

   Le badge de divulgation, lui, n'existe que de ce cote. Il est discret pour
   ne pas ecraser la video, mais il est pose sur le stage et non sous le bloc :
   ces videos partent sur des reseaux sociaux, et un visiteur qui regarde la
   pile doit savoir ce qu'il regarde sans avoir a lire la legende. */
.deck__badge {
  position: absolute;
  z-index: 4;
  top: 0.7rem;
  left: 50%;
  transform: translateX(-50%);
  padding: 0.22rem 0.6rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: rgba(10, 11, 13, 0.72);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  font-size: 0.5625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--bone);
  pointer-events: none;
}

/* =========================================================================
   V47 — OFFRE SHORTS
   La v46 posait un configurateur sur une grande photo : hauteur subie, moitie
   gauche vide, et huit prix cachés derriere deux clics. Ici le conteneur fixe
   la hauteur, la photo passe en absolu derriere, et les deux colonnes de prix
   sont lisibles sans toucher a rien.
   ========================================================================= */
.offer {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  margin-top: clamp(2.5rem, 6vw, 4rem);
  border: 1px solid var(--signal-dim);
  background:
    radial-gradient(110% 130% at 12% 0%, rgba(232, 197, 71, 0.10), transparent 68%),
    var(--surface);
  padding: clamp(1.6rem, 3vw, 2.4rem) clamp(1.4rem, 3vw, 2.6rem);
  display: grid;
  grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
  column-gap: clamp(1.75rem, 4vw, 3.25rem);
  align-items: center;
}

/* La photo ne dicte plus la hauteur : elle remplit ce que le conteneur decide.
   Masquee a gauche, ou vit la copy — le voile seul ne suffisait pas a garder
   un titre lisible sur un ecran d'ordinateur allume. */
.offer__photo { position: absolute; inset: 0; z-index: -2; display: block; }
.offer__photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 65% center;
  opacity: 0.5;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 58%);
          mask-image: linear-gradient(90deg, transparent 0%, #000 58%);
}
.offer__veil {
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg, var(--surface) 26%, rgba(18, 19, 22, 0.72) 62%, rgba(18, 19, 22, 0.58));
}

/* ---- colonne gauche : ce qu'on achete et pourquoi ---- */
.offer__left { display: grid; gap: 0.85rem; align-content: center; }
.offer__t {
  font-family: var(--display);
  font-size: clamp(1.75rem, 3.1vw, 2.75rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.08;
  color: var(--bone);
  max-width: 15ch;
}
.offer__sub { color: var(--ash); font-size: 1.0625rem; line-height: 1.5; max-width: 34ch; }
/* Trois lignes, pas un paragraphe : c'est un rythme, il doit se lire d'un
   coup d'oeil. C'est l'argument du pack, pas un descriptif. */
.offer__val { list-style: none; margin: 0.15rem 0 0; padding: 0; display: grid; gap: 0.1rem; }
.offer__val li {
  font-family: var(--display);
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--bone);
  line-height: 1.35;
}
.offer__val li:last-child { color: var(--signal); }
.offer__specs { font-size: 0.6875rem; letter-spacing: 0.1em; color: var(--ash-dim); }
.offer__act { margin-top: 0.5rem; display: grid; gap: 0.4rem; justify-items: start; }
.offer__note { font-size: 0.8125rem; color: var(--signal); }
.offer__trust { font-size: 0.8125rem; color: var(--ash-dim); }

/* ---- colonne droite : les huit prix, tous visibles ---- */
.offer__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem; }
.tier {
  border: 1px solid var(--line);
  background: rgba(12, 14, 18, 0.78);
  -webkit-backdrop-filter: blur(12px);
          backdrop-filter: blur(12px);
  padding: 0.85rem 0.8rem 0.8rem;
  display: grid;
  gap: 0.55rem;
  align-content: start;
}
.tier__head { display: grid; gap: 0.1rem; }
.tier__name { font-size: 0.9375rem; font-weight: 700; color: var(--bone); letter-spacing: -0.01em; }
.tier__tag { font-size: 0.75rem; color: var(--ash-dim); }
.tier__from { font-size: 0.625rem; letter-spacing: 0.12em; color: var(--signal); text-transform: uppercase; }
.tier__rows { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.3rem; }

/* Une ligne EST le bouton : un clic pose le mode et la quantite ensemble. */
.tier__row {
  position: relative;
  width: 100%;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0 0.5rem;
  align-items: baseline;
  height: auto;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  background: transparent;
  text-align: left;
}
.tier__q { font-size: 0.8125rem; color: var(--ash); }
.tier__p {
  font-family: var(--display);
  font-size: 1.375rem;
  font-weight: 700;
  color: var(--bone);
  letter-spacing: -0.02em;
  justify-self: end;
}
.tier__was {
  grid-column: 1;
  font-size: 0.6875rem;
  color: var(--ash-dim);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}
.tier__save {
  grid-column: 2;
  justify-self: end;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  color: var(--signal);
}
.tier__each { grid-column: 1 / -1; font-size: 0.6875rem; color: var(--ash-dim); }

/* Le pack recommande : un cran plus clair, un liseré, un libelle. Trois
   signaux plutot qu'une couleur seule — un daltonien doit le voir aussi. */
.tier__row--star {
  border-color: var(--signal-dim);
  background: rgba(232, 197, 71, 0.08);
  padding-top: 0.7rem;
}
.tier__row--star .tier__p { font-size: 1.625rem; }
.tier__flag {
  position: absolute;
  top: -0.5rem;
  left: 0.55rem;
  font-family: var(--mono);
  font-size: 0.5rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--signal);
  background: var(--void);
  border: 1px solid var(--signal-dim);
  border-radius: 999px;
  padding: 0.08rem 0.38rem;
}
.tier__row:hover { border-color: var(--line-strong); }
.tier__row.is-on {
  border-color: var(--signal);
  background: rgba(232, 197, 71, 0.16);
  box-shadow: inset 0 0 0 1px var(--signal-dim);
}
.tier__row:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

/* ---- responsive ---- */
@media (max-width: 1080px) {
  .offer { grid-template-columns: 1fr; row-gap: 1.5rem; }
  .offer__t { max-width: 20ch; }
  .offer__photo img { -webkit-mask-image: none; mask-image: none; opacity: 0.3; }
  .offer__veil { background: linear-gradient(180deg, var(--surface) 12%, rgba(18, 19, 22, 0.86)); }
  /* le CTA remonte au-dessus des prix seulement quand il n'y a plus de
     colonne : sinon il se retrouve a 600px sous le montant qu'il valide */
  .offer__act { order: 2; }
}
@media (max-width: 560px) {
  .offer__grid { grid-template-columns: 1fr; }
  .tier__row--star .tier__p { font-size: 1.5rem; }
}

/* =========================================================================
   V48 — OFFRE CLIP
   Meme coquille que l'offre shorts : un visiteur qui a compris une grille de
   prix sur ce site ne doit pas reapprendre a en lire une deuxieme. La
   difference : trois paliers riches au lieu de huit lignes seches, donc la
   copy passe en bandeau au-dessus et les cartes prennent toute la largeur.
   ========================================================================= */
.offer--clip { grid-template-columns: 1fr; row-gap: clamp(1.25rem, 2.5vw, 1.75rem); }
.offer--clip .offer__left { max-width: 62ch; }
.offer--clip .offer__t { max-width: 22ch; }
.offer--clip .offer__sub { max-width: 52ch; }
.offer--clip .offer__val { grid-auto-flow: column; justify-content: start; gap: 0 1.75rem; }
.offer__grid--three { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.85rem; }

/* ---- une carte de palier ---- */
.ctier {
  position: relative;
  display: grid;
  gap: 0.35rem;
  justify-items: start;
  text-align: left;
  height: auto;
  padding: 1rem 0.95rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  background: rgba(12, 14, 18, 0.78);
  -webkit-backdrop-filter: blur(12px);
          backdrop-filter: blur(12px);
}
.ctier__name { font-family: var(--display); font-size: 1.0625rem; font-weight: 700; color: var(--bone); }
.ctier__who { font-size: 0.8125rem; color: var(--ash); line-height: 1.35; min-height: 2.2em; }
.ctier__p {
  font-family: var(--display);
  font-size: clamp(1.75rem, 2.6vw, 2.25rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  color: var(--bone);
  line-height: 1.05;
  margin-top: 0.2rem;
}
/* La minute supplementaire est une precision, pas une offre : elle doit se
   lire apres le prix, jamais avant. */
.ctier__mins { font-size: 0.625rem; letter-spacing: 0.06em; color: var(--ash-dim); }
.ctier__get {
  list-style: none; margin: 0.5rem 0 0; padding: 0;
  display: grid; gap: 0.28rem; width: 100%;
}
.ctier__get li {
  position: relative;
  padding-left: 1rem;
  font-size: 0.8125rem;
  color: var(--ash);
  line-height: 1.4;
}
.ctier__get li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.55em;
  width: 6px; height: 6px;
  border-left: 1.5px solid var(--signal);
  border-bottom: 1.5px solid var(--signal);
  transform: rotate(-45deg);
}
.ctier__rev { margin-top: 0.55rem; font-size: 0.5625rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ash-dim); }

.ctier--star { border-color: var(--signal-dim); background: rgba(232, 197, 71, 0.09); }
.ctier--star .ctier__p { color: var(--bone); }
.ctier:hover { border-color: var(--line-strong); }
.ctier.is-on {
  border-color: var(--signal);
  background: rgba(232, 197, 71, 0.16);
  box-shadow: inset 0 0 0 1px var(--signal-dim);
}
.ctier:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

/* ---- pied : option, CTA, accroche bundle, devis ---- */
.offer__foot {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.75rem clamp(1.25rem, 3vw, 2.5rem);
}
.copt {
  display: grid;
  justify-items: start;
  gap: 0.1rem;
  height: auto;
  padding: 0.55rem 0.85rem;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-s);
  background: rgba(12, 14, 18, 0.7);
  text-align: left;
}
.copt__t { font-size: 0.875rem; color: var(--bone); font-weight: 600; }
.copt__p { color: var(--signal); font-weight: 700; }
.copt__n { font-size: 0.75rem; color: var(--ash-dim); }
.copt.is-on { border-style: solid; border-color: var(--signal); background: rgba(232, 197, 71, 0.16); }

.offer--clip .offer__act { justify-self: end; justify-items: end; }
/* L'accroche bundle et la ligne devis passent sous les deux colonnes : ce
   sont des informations de contexte, pas des etapes de la decision. */
.offer__hook { grid-column: 1 / -1; font-size: 0.9375rem; color: var(--ash); }
.offer__quote {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.15rem 0.6rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--line);
}
.offer__quote-l { font-size: 0.875rem; color: var(--bone); font-weight: 600; }
.offer__quote-n { font-size: 0.8125rem; color: var(--ash-dim); }
.offer--clip .offer__trust { grid-column: 1 / -1; }

@media (max-width: 900px) {
  .offer__grid--three { grid-template-columns: 1fr; }
  .offer--clip .offer__val { grid-auto-flow: row; gap: 0.1rem; }
  .ctier__who { min-height: 0; }
  .offer__foot { grid-template-columns: 1fr; }
  .offer--clip .offer__act { justify-self: start; justify-items: start; }
}

/* =========================================================================
   V49 — PACKS
   Ils ouvrent la section commande : la premiere decision n'est pas "quelle
   option" mais "je prends tout ou je compose". Trois cartes, l'etoile sur
   celle du milieu, l'economie en euros ET en pourcentage — le pourcentage
   parle aux petits montants, l'euro aux gros, et on ne sait pas lequel le
   visiteur regarde.
   ========================================================================= */
.packs { margin-bottom: clamp(1.75rem, 3.5vw, 2.5rem); }
.packs__head { max-width: 56ch; margin-bottom: clamp(1rem, 2vw, 1.4rem); }
.packs__t {
  font-family: var(--display);
  font-size: clamp(1.35rem, 2.4vw, 1.9rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.12;
  color: var(--bone);
}
.packs__sub { margin-top: 0.5rem; color: var(--ash); font-size: 0.9375rem; line-height: 1.5; }
.packs__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.85rem; }
.packs__alt { margin-top: 0.9rem; font-size: 0.6875rem; letter-spacing: 0.1em; color: var(--ash-dim); }

.pack {
  position: relative;
  display: grid;
  gap: 0.3rem;
  justify-items: start;
  text-align: left;
  height: auto;
  padding: 1rem 0.95rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  background: var(--surface);
}
.pack__name { font-family: var(--display); font-size: 1.0625rem; font-weight: 700; color: var(--bone); }
.pack__who { font-size: 0.8125rem; color: var(--ash); line-height: 1.35; min-height: 2.2em; }

/* Prix reel dominant, reference barree a cote et plus petite : l'inverse
   donnerait une boutique de promotions permanentes. */
.pack__prices { display: flex; align-items: baseline; gap: 0.5rem; margin-top: 0.35rem; }
.pack__now {
  font-family: var(--display);
  font-size: clamp(1.75rem, 2.6vw, 2.25rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  color: var(--bone);
  line-height: 1.05;
}
.pack__was {
  font-size: 0.9375rem;
  color: var(--ash-dim);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}
.pack__save {
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--signal);
  border: 1px solid var(--signal-dim);
  border-radius: 999px;
  padding: 0.16rem 0.5rem;
}
.pack__lines { list-style: none; margin: 0.6rem 0 0; padding: 0; display: grid; gap: 0.28rem; width: 100%; }
.pack__lines li {
  position: relative;
  padding-left: 1rem;
  font-size: 0.8125rem;
  color: var(--ash);
  line-height: 1.4;
}
.pack__lines li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.55em;
  width: 6px; height: 6px;
  border-left: 1.5px solid var(--signal);
  border-bottom: 1.5px solid var(--signal);
  transform: rotate(-45deg);
}
.pack__cta {
  margin-top: 0.85rem;
  width: 100%;
  text-align: center;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-s);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--bone);
}

.pack--star { border-color: var(--signal-dim); background: rgba(232, 197, 71, 0.07); }
.pack--star .pack__cta { border-color: var(--signal); background: rgba(232, 197, 71, 0.16); }
.pack:hover { border-color: var(--line-strong); }
.pack.is-on {
  border-color: var(--signal);
  background: rgba(232, 197, 71, 0.14);
  box-shadow: inset 0 0 0 1px var(--signal-dim);
}
.pack.is-on .pack__cta { border-color: var(--signal); background: var(--signal); color: var(--void); }
.pack:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

/* Une ligne deja couverte par le pack : ni prix, ni bouton. */
.oline.is-inc { opacity: 0.72; }
.oline__inc {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--signal);
}

@media (max-width: 900px) {
  .packs__grid { grid-template-columns: 1fr; }
  .pack__who { min-height: 0; }
}

/* =========================================================================
   v50 — MICRO-OPTIMISATION DE LA CONVERSION
   Tout ce bloc est additif. Aucune regle existante n'est redefinie, aucune
   animation n'est touchee, aucun token n'est ajoute : les nouvelles classes
   consomment --ash, --ash-dim, --bone, --signal, --line et --mono, exactement
   comme le reste de la page.
   Le principe de dessin est unique et se repete partout ci-dessous : une
   ligne forte en --bone, une ligne secondaire en --ash. Deux niveaux, jamais
   trois. C'est ce qui permet d'ajouter une dizaine de messages sans que la
   page se mette a ressembler a une landing page SaaS.
   ========================================================================= */

/* ---------- §1 hero : preuve de positionnement ----------
   Le filet vertical remplace un encadre. Un encadre aurait cree une carte de
   plus au-dessus de la ligne de flottaison ; un filet de 1px rattache le
   bloc au hero sans rien fermer. */
.hero__pos {
  margin-top: 1.5rem;
  padding-left: 0.95rem;
  border-left: 1px solid var(--line-strong);
  max-width: 46ch;
}
.hero__pos-strong {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(0.95rem, 1.35vw, 1.0625rem);
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--bone);
}
/* Deliberement plus petite ET plus grise. Les deux, pas l'un ou l'autre :
   au meme gris avec une taille plus petite, elle se lit encore comme une
   affirmation concurrente de la premiere. */
.hero__pos-soft {
  margin-top: 0.3rem;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--ash-dim);
}

/* ---------- §2 bande de coherence ----------
   Entre le hero et la carte. Bordee en haut et en bas, sans fond : elle
   separe deux sections au lieu d'en ajouter une troisieme. */
.coh {
  border-block: 1px solid var(--line);
  padding-block: clamp(1.1rem, 2.2vw, 1.5rem);
}
.coh__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(1rem, 3vw, 2.5rem);
  flex-wrap: wrap;
}
.coh__line {
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(0.95rem, 1.6vw, 1.1875rem);
  letter-spacing: -0.01em;
  color: var(--bone);
  max-width: 64ch;
}
.coh__chain {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.35rem 0.55rem;
}
/* La fleche est un ::before sur le maillon suivant, pas un caractere dans le
   HTML : sur mobile la chaine passe a la ligne, et une fleche en fin de ligne
   pendrait dans le vide. Ici elle voyage toujours avec le mot qu'elle
   introduit. */
.coh__link + .coh__link::before {
  content: "\2192";
  margin-right: 0.55rem;
  color: var(--ash-dim);
  font-size: 0.75rem;
}
.coh__link .mono { color: var(--ash-dim); }
.coh__link--end .mono { color: var(--bone); }

/* ---------- §3/§4/§5/§7 la paire forte/secondaire ----------
   Une seule primitive pour les quatre sections. Une classe par emplacement
   aurait donne quatre dessins legerement differents, c'est-a-dire aucun
   systeme. */
.rrl {
  margin-top: 1.35rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.05rem, 1.9vw, 1.3rem);
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--bone);
  max-width: 34ch;
  text-wrap: balance;
}
.rrl__sub {
  margin-top: 0.45rem;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ash);
  max-width: 48ch;
}
.rrl__sub b { font-weight: 600; color: var(--bone); }
/* Section 01 : la colonne de texte est plafonnee a 24ch par .shero, donc la
   paire doit rentrer dans cette largeur au lieu de la forcer. */
.rrl--sound { font-size: clamp(1rem, 1.7vw, 1.2rem); max-width: 22ch; }
.shero__text .rrl__sub { max-width: 34ch; font-size: 0.9rem; }
/* Section 02 et 04 : la phrase anti-gabarit precede la description du
   service, elle a donc besoin d'un peu plus d'air au-dessus. */
.rrl--anti { margin-top: 1.1rem; }
.rrl--clip { margin-top: 1.6rem; max-width: 26ch; }
.rrl__sub--clip { max-width: 44ch; }
.rrl--shorts { margin-top: 1.6rem; }

/* ---------- §7 les trois modes de production du clip ----------
   Le seul element de tout ce lot qui joue en gros. C'est assume : il repond
   a la question "vous ne faites que de l'IA ?", et cette question se pose
   exactement ici, devant le prix le plus eleve du site. */
.cmodes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.9rem;
  margin-top: 1.15rem;
}
.cmodes__i {
  font-family: var(--mono);
  font-size: clamp(0.75rem, 1.15vw, 0.875rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--bone);
}
.cmodes__i + .cmodes__i::before {
  content: "\00b7";
  margin-right: 0.9rem;
  color: var(--signal);
}

/* ---------- §6 les deux modes de production des shorts ---------- */
.modes__intro {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1rem, 1.7vw, 1.2rem);
  letter-spacing: -0.015em;
  color: var(--bone);
}
/* La triade, entre le titre du bloc et son headline. Meme taille et meme
   couleur des deux cotes : c'est la symetrie qui dit "deux choix", pas le
   texte. */
.rp__mode {
  margin-top: 0.5rem;
  color: var(--signal);
  letter-spacing: 0.14em;
}
/* La ligne commune. Filet en haut, sceau a gauche, phrase a droite : elle
   ferme les deux blocs au lieu d'appartenir au second. */
.modes__both {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem 0.9rem;
  margin-top: clamp(2rem, 4vw, 2.75rem);
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--ash);
}
.modes__seal, .seal {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--signal);
  white-space: nowrap;
}
/* ---------- §10 le sceau, hors de la ligne §6 ---------- */
.seal { display: inline-block; }
.seal--inline { margin-left: 0.75rem; }
.offer__left .seal { margin-top: 0.5rem; }

/* =====================================================================
   05 · POURQUOI READY RELEASE — refonte v81
   Aucune grille de quatre, aucun tableau, aucune carte. Hierarchie
   assumee, filets fins, echelle typographique alignee sur le site.
   ===================================================================== */
.section--why { padding-block: clamp(4.5rem, 11vw, 9rem); }
.wblock { margin-top: clamp(4rem, 10vw, 8rem); }

.wsec__t {
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h3);
  line-height: 1.15;
  letter-spacing: -0.03em;
  color: var(--bone);
  max-width: 30ch;
  text-wrap: balance;
}

/* ---------- 01 · le pain point ---------- */
.wpain { max-width: 64ch; }
.wpain__eyebrow {
  color: var(--ash-dim);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.wpain__t {
  margin-top: 1.4rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h2);
  line-height: 1.02;
  letter-spacing: -0.04em;
  color: var(--bone);
}
.wpain__lead {
  margin-top: 1.5rem;
  font-size: var(--fs-lead);
  line-height: 1.6;
  color: var(--ash);
  max-width: 56ch;
}

/* ---------- 02 · la reponse ----------
   Decalee a droite : le passage du probleme a la solution se lit dans le
   deplacement, pas dans un fond de couleur. */
.wans { margin-left: clamp(0rem, 8vw, 9rem); max-width: 54ch; }
.wans__t {
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h3);
  line-height: 1.15;
  letter-spacing: -0.03em;
  color: var(--bone);
  padding-left: clamp(1rem, 2.5vw, 1.75rem);
  border-left: 1px solid var(--signal);
}
.wans__b { color: var(--signal); }
.wans__lead {
  margin-top: 1.25rem;
  padding-left: clamp(1rem, 2.5vw, 1.75rem);
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--ash);
}

/* ---------- 03 · les cinq piliers ----------
   Le dispositif vient du chapitre 04 (.vdep). Seul ajout : une ligne de
   corps sous chaque pilier, absente cote clip ou les libelles suffisaient. */
.vdep--brand { margin-top: clamp(2.5rem, 6vw, 4rem); }
.vdep__d {
  display: block;
  margin-top: 0.55rem;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ash);
  max-width: 46ch;
}
.vdep--brand .vdep__i { padding-top: 1.6rem; padding-bottom: 1.6rem; }
.vdep--brand .vdep__i::before { top: 2.3rem; }

/* ---------- 04 · ce qui rend la coherence possible ----------
   Un argument porteur, trois arguments de soutien. Quatre colonnes egales
   disaient que les quatre pesaient pareil, ce qui est faux. */
.wpil {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: center;
}
.wpil__n {
  display: block;
  color: var(--signal);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.wpil__lead .wpil__t {
  margin-top: 1rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h3);
  line-height: 1.12;
  letter-spacing: -0.03em;
  color: var(--bone);
  max-width: 20ch;
}
.wpil__lead .wpil__b { margin-top: 1.15rem; max-width: 42ch; }

.wpil__rest { display: grid; }
.wpil__i {
  display: grid;
  grid-template-columns: 2.75rem 1fr;
  gap: 0 1.25rem;
  padding: 1.4rem 0;
  border-top: 1px solid var(--line);
  transition-delay: calc(var(--i, 0) * 80ms);
}
.wpil__i:last-child { border-bottom: 1px solid var(--line); }
.wpil__i .wpil__n { color: var(--ash-dim); padding-top: 0.25em; }
.wpil__k {
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--fs-body);
  letter-spacing: -0.01em;
  color: var(--bone);
}
.wpil__i .wpil__b { grid-column: 2; margin-top: 0.4rem; }
.wpil__b { font-size: 0.9375rem; line-height: 1.6; color: var(--ash); }

/* ---------- 05 · le comparatif en deux pistes ----------
   --p (0 -> 1) est ecrit par initWhyTrack(). Valeur par defaut 1 : sans
   JS, la piste s'affiche remplie plutot que vide. */
.wcmp__lead {
  margin-top: 1.15rem;
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--ash);
  max-width: 54ch;
}

.wtrack {
  --p: 1;
  margin-top: clamp(2.5rem, 6vw, 4rem);
  display: grid;
  gap: clamp(2.5rem, 6vw, 4rem);
}
.wtrack__row { position: relative; }
.wtrack__lbl {
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ash-dim);
  margin-bottom: 1.5rem;
}
.wtrack__row--us .wtrack__lbl { color: var(--signal); }

.wtrack__steps {
  position: relative;
  list-style: none;
  padding-left: 0;
  display: grid;
  gap: clamp(1rem, 2.5vw, 2rem);
}
.wtrack__steps--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); width: 60%; }
.wtrack__steps--5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }

/* l'axe : un rail eteint, un remplissage par-dessus */
.wtrack__steps::before,
.wtrack__steps::after {
  content: '';
  position: absolute;
  left: 0; right: 0;
  top: 0;
  height: 1px;
}
.wtrack__steps::before { background: var(--line); }
.wtrack__steps--3::after { background: var(--line-strong); }
.wtrack__steps--5::after {
  background: var(--signal);
  right: auto;
  width: calc(var(--p) * 100%);
  transition: width 0.15s linear;
}
/* la piste courte s'arrete visiblement : le rail ne va pas au bout */
.wtrack__row--auto .wtrack__end {
  position: absolute;
  left: 60%;
  bottom: auto;
  top: calc(1.5rem + 0.7rem + 1px);
  margin-left: 0.9rem;
  transform: translateY(-50%);
  font-size: 0.65rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ash-dim);
  white-space: nowrap;
}

.wtrack__s { padding-top: 1.1rem; }
.wtrack__sn {
  display: block;
  font-family: var(--mono);
  font-size: 0.65rem;
  letter-spacing: 0.14em;
  color: var(--ash-dim);
}
.wtrack__st {
  display: block;
  margin-top: 0.5rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--fs-body);
  letter-spacing: -0.01em;
  color: var(--ash-dim);
  transition: color 0.4s var(--ease);
}
.wtrack__sd {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--ash-dim);
  transition: color 0.4s var(--ease);
}
.wtrack__row--auto .wtrack__st { color: var(--ash); }

/* un cran s'allume quand le remplissage l'a depasse */
.wtrack__row--us .wtrack__s.is-lit .wtrack__sn { color: var(--signal); }
.wtrack__row--us .wtrack__s.is-lit .wtrack__st { color: var(--bone); }
.wtrack__row--us .wtrack__s.is-lit .wtrack__sd { color: var(--ash); }

/* ---------- 06 · conclusion ---------- */
.wend__t {
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h2);
  line-height: 1.05;
  letter-spacing: -0.04em;
  color: var(--bone);
  max-width: 20ch;
}
.wend__b { color: var(--signal); }

/* ---------- respirations ---------- */
@media (max-width: 1080px) {
  .wpil { grid-template-columns: 1fr; gap: 2.5rem; }
  .wpil__lead .wpil__t { max-width: 26ch; }
  .wtrack__steps--5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .wtrack__steps--3 { width: 100%; }
  .wtrack__steps::before,
  .wtrack__steps::after { display: none; }
  .wtrack__s { border-top: 1px solid var(--line); }
  .wtrack__row--auto .wtrack__end { position: static; transform: none; margin: 1rem 0 0; }
  .wtrack__row--us .wtrack__s.is-lit { border-top-color: var(--signal); }
}
@media (max-width: 640px) {
  .wtrack__steps--5,
  .wtrack__steps--3 { grid-template-columns: 1fr; gap: 0; }
  .wpil__i { grid-template-columns: 2.25rem 1fr; gap: 0 1rem; }
  .wans { margin-left: 0; }
  .wpain__t, .wend__t, .wsec__t { max-width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .wpil__i { transition-delay: 0s !important; }
  .wtrack__steps--5::after { transition: none; }
}

/* ---------- §12 amorce des packs ---------- */
.packs__kicker {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1rem, 1.7vw, 1.15rem);
  letter-spacing: -0.015em;
  color: var(--bone);
  margin-bottom: 0.4rem;
}

/* ---------- responsive ----------
   Deux paliers seulement, alignes sur ceux qui existent deja dans ce
   fichier (1024 / 720). Les grilles passent en deux colonnes puis en une ;
   rien n'est masque : chaque phrase ajoutee ici est un argument, et un
   argument masque sur mobile est un argument perdu la ou se fait la moitie
   du trafic. */
@media (max-width: 1024px) {
  /* v81 — .why__grid supprime avec la refonte de la section 05. */
  .coh__inner { gap: 0.9rem; }
}
@media (max-width: 720px) {
  .hero__pos { margin-top: 1.25rem; max-width: none; }
  .coh__line { font-size: 1rem; max-width: none; }
  .coh__chain { gap: 0.3rem 0.45rem; }
  /* v81 — .why__grid et .diff__cols supprimes avec la refonte. */
  .rrl, .rrl--sound, .rrl--clip { max-width: none; }
  .rrl__sub, .rrl__sub--clip, .shero__text .rrl__sub { max-width: none; }
  .modes__both { gap: 0.4rem; }
  .cmodes { gap: 0.4rem 1.2rem; }
  .cmodes__i + .cmodes__i::before { content: none; }
  .seal--inline { margin-left: 0; display: block; margin-top: 0.4rem; }
}

/* =========================================================================
   v51 — HERO CENTRÉ SUR LA VIDÉO DES DANSEURS
   Le hero passe d'un texte aligné à gauche sur une vidéo tierce à un texte
   centré sur le plan des danseurs, servi en local.
   Le point dur mesuré sur la vidéo : la zone centrale est la plus claire du
   cadre entre 4 s et 10 s (luminance p95 jusqu'à 104/255), et les robes
   blanche puis verte passent exactement sous le titre. D'où deux couches :
   un scrim linéaire haut/bas qui protège le header et le bas de section, et
   un scrim RADIAL centré qui n'assombrit que la colonne de lecture. Le reste
   du cadre — les danseurs sur les côtés — garde sa luminosité, donc la vidéo
   reste visible au lieu de disparaître sous un voile uniforme.
   ========================================================================= */

.hero--centered .hero__inner { text-align: center; }
.hero--centered .hero__title { max-width: 18ch; margin-inline: auto; }
.hero--centered .hero__claim,
.hero--centered .hero__pos { margin-inline: auto; }
.hero--centered .hero__sub { max-width: 46ch; margin-inline: auto; }
.hero--centered .hero__pos { max-width: 52ch; }
.hero--centered .hero__actions { justify-content: center; }
.hero--centered .hero__stat--big { margin-inline: auto; justify-content: center; text-align: center; }

/* Colonne de lecture protégée. Les pourcentages suivent la largeur du titre :
   sur écran large la tache sombre reste une colonne, elle ne mange pas tout. */
.hero--centered .hero__video-scrim {
  background:
    radial-gradient(72% 58% at 50% 46%,
      rgba(10,11,13,0.82) 0%, rgba(10,11,13,0.62) 45%,
      rgba(10,11,13,0.18) 78%, rgba(10,11,13,0) 100%),
    linear-gradient(180deg,
      rgba(10,11,13,0.78) 0%, rgba(10,11,13,0.28) 26%,
      rgba(10,11,13,0.34) 62%, rgba(10,11,13,0.92) 100%);
}

/* =========================================================================
   v87 — OUVERTURE DU HERO : LA VIDEO SE MONTRE, PUIS S'EFFACE
   (brief Word du 25/08)

   « la voir complètement sans opacité 1,5 seconde puis au bout de 1.5 sec
   opacité progressive jusqu'à disparaitre complètement à la 3.5 seconde »

   Trois temps, sur une seule horloge de 3,5 s :
     0 → 1,5 s    la vidéo est nue. Le voile est à 0 : rien ne la couvre.
     1,5 → 3,5 s  la vidéo descend à 0, le voile monte à 1, en même temps.
     après 3,5 s  la vidéo n'est plus là. Le hero est le panneau sombre.

   1,5 s sur 3,5 s = 42,86 %. La valeur est écrite en dur dans les deux
   keyframes parce qu'une variable CSS ne peut pas piloter un pourcentage de
   keyframe ; pour changer la cadence il faut donc toucher aux DEUX blocs et
   à la durée. Les deux courbes sont volontairement `linear` : une courbe
   d'accélération sur une disparition se lit comme un raté de lecture.

   Le voile est un FRERE de la vidéo à l'intérieur de .hero__video-bg. C'est
   pour cela que l'animation porte sur `video` et non sur le conteneur :
   faire disparaître le conteneur emporterait le voile avec lui, et le texte
   finirait nu sur le fond au lieu d'être protégé.

   /!\ CONTREPARTIE ASSUMEE, A ARBITRER : pendant les 1,5 premières
   secondes, il n'y a aucun voile sous le titre. Le titre, le claim et le
   sous-titre arrivent en fade-up entre 0,25 s et 0,75 s — donc en plein
   dedans, sur une image de danseurs claire et mouvante. Sur les plans les
   plus lumineux le contraste passe sous le seuil AA pendant ce laps.
   Pour récupérer de la lisibilité sans perdre l'effet : donner au voile un
   plancher (remplacer `opacity: 0` par `opacity: 0.35` aux deux premiers
   crans de hero-scrim-in). Une valeur, un seul endroit.
   ========================================================================= */
@keyframes hero-video-out {
  0%, 42.86% { opacity: 1; }
  100%       { opacity: 0; }
}
@keyframes hero-scrim-in {
  0%, 42.86% { opacity: 0; }
  100%       { opacity: 1; }
}
.hero--centered .hero__video-bg video {
  animation: hero-video-out 3.5s linear forwards;
}
.hero--centered .hero__video-scrim {
  animation: hero-scrim-in 3.5s linear forwards;
}
/* Sous prefers-reduced-motion tout le fond du hero est déjà masqué (règle
   v51 plus haut) : le hero est un aplat sombre dès la première image. Les
   deux animations sont coupées pour que le voile ne reste pas bloqué à
   opacity: 0 si cette règle-là venait à changer. */
@media (prefers-reduced-motion: reduce) {
  .hero--centered .hero__video-bg video,
  .hero--centered .hero__video-scrim { animation: none; }
}

/* Le cadrage ne peut pas être le même sur les deux formats : en 16:9 le plan
   tient dans la largeur, en portrait il faut aller chercher le centre du
   cadre, sinon on affiche un mur et un bras. */
.hero--centered .hero__video-bg video { object-position: 50% 42%; }
@media (max-width: 760px) {
  .hero--centered .hero__video-bg { transform: scale(1.18); }
  .hero--centered .hero__video-bg video { object-position: 52% 38%; }
  .hero--centered .hero__title { max-width: 14ch; }
  .hero--centered .hero__video-scrim {
    background:
      radial-gradient(96% 46% at 50% 44%,
        rgba(10,11,13,0.88) 0%, rgba(10,11,13,0.66) 52%,
        rgba(10,11,13,0.22) 84%, rgba(10,11,13,0) 100%),
      linear-gradient(180deg,
        rgba(10,11,13,0.82) 0%, rgba(10,11,13,0.34) 24%,
        rgba(10,11,13,0.40) 60%, rgba(10,11,13,0.95) 100%);
  }
}

/* =========================================================================
   v51 — ACCROCHE MANUSCRITE DE LA ZONE COMMANDE
   Jouée une fois, à l'entrée dans la zone (.is-in posé par main.js).
   Pas de boucle, pas de clignotement : sous prefers-reduced-motion le bloc
   s'affiche directement à son état final.
   ========================================================================= */

.mkr-slot { justify-self: end; }
.mkr { position: relative; text-align: center; max-width: 30rem; }
.mkr__ink { display: block; width: 100%; height: auto; overflow: visible; }
.mkr__t {
  font-family: var(--display);
  font-size: 40px; font-weight: 800; letter-spacing: -0.02em;
  fill: none; stroke: var(--bone); stroke-width: 1.1;
  paint-order: stroke;
  stroke-dasharray: 1400; stroke-dashoffset: 1400;
}
.mkr__u {
  fill: none; stroke: var(--signal); stroke-width: 5; stroke-linecap: round;
  stroke-dasharray: 480; stroke-dashoffset: 480;
}
.mkr__sub { margin-top: 0.5rem; font-size: 0.95rem; color: var(--ash); }
.mkr__hl {
  background: transparent; color: var(--bone);
  padding: 0.1em 0.3em; border-radius: 2px;
  background-image: linear-gradient(var(--signal-fill), var(--signal-fill));
  background-repeat: no-repeat; background-size: 0% 100%;
}
.mkr.is-in .mkr__t { animation: mkr-write 1.1s ease forwards; }
.mkr.is-in .mkr__u { animation: mkr-write-u 0.5s ease 0.9s forwards; }
.mkr.is-in .mkr__hl { animation: mkr-hl 0.55s ease 1.25s forwards; }
@keyframes mkr-write { to { stroke-dashoffset: 0; fill: var(--bone); } }
@keyframes mkr-write-u { to { stroke-dashoffset: 0; } }
@keyframes mkr-hl { to { background-size: 100% 100%; } }
@media (prefers-reduced-motion: reduce) {
  .mkr__t { stroke-dashoffset: 0; fill: var(--bone); }
  .mkr__u { stroke-dashoffset: 0; }
  .mkr__hl { background-size: 100% 100%; }
  .mkr.is-in .mkr__t, .mkr.is-in .mkr__u, .mkr.is-in .mkr__hl { animation: none; }
}
/* Choix client : masqué sous 900px. En colonne unique ce bloc repousserait
   les trois packs sous la ligne de flottaison, ce que le brief interdit. */
/* .mkr-slot reste dans le DOM : la version lue par les lecteurs d'ecran
   (.sr-only) doit survivre au masquage visuel. */
@media (max-width: 900px) { .mkr { display: none; } }

/* =========================================================================
   v51 — ZONE À LA CARTE
   Volontairement en retrait des packs : des lignes, pas des cartes ; un seul
   niveau typographique ; aucun visuel. Un visiteur indécis doit retomber sur
   les packs, pas se perdre ici.
   ========================================================================= */

.alc {
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: clamp(1.75rem, 3vw, 2.5rem);
  border-top: 1px solid var(--line);
}
.alc__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 0.9rem; }
.alc__t { font-size: clamp(1.05rem, 2vw, 1.3rem); font-weight: 700; letter-spacing: -0.01em; }
.alc__sub { color: var(--ash); font-size: 0.92rem; }
.alc__grid {
  margin-top: 1.4rem;
  display: grid; gap: 0.4rem clamp(1.2rem, 3vw, 2.4rem);
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  align-items: center;
}
.alc__cat-t {
  font-size: var(--fs-micro); letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ash-dim); padding-bottom: 0.5rem; border-bottom: 1px solid var(--line);
}
.alc__rows { list-style: none; margin: 0; padding: 0; }
.alc__row {
  width: 100%; display: grid;
  grid-template-columns: 1fr auto auto; align-items: center; gap: 0.7rem;
  padding: 0.55rem 0; background: none; border: 0; border-bottom: 1px solid var(--line);
  color: var(--bone); font: inherit; font-size: 0.94rem; text-align: left; cursor: pointer;
}
.alc__row:hover { color: #fff; }
.alc__row:hover .alc__x { color: var(--signal); border-color: var(--signal); }
.alc__row:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
.alc__p { color: var(--ash); font-variant-numeric: tabular-nums; }
.alc__x {
  font-size: var(--fs-micro); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ash-dim); border: 1px solid var(--line-strong);
  border-radius: 999px; padding: 0.18rem 0.55rem; min-width: 4.4rem; text-align: center;
}
/* L'état sélectionné ne repose pas sur la couleur seule : le libellé change,
   le fond se remplit et aria-pressed passe à true. */
.alc__row.is-on { color: #fff; }
.alc__row.is-on .alc__x { color: var(--void); background: var(--signal-fill); border-color: transparent; }
.alc__row.is-on .alc__p { color: var(--bone); }
.alc__more { margin-top: 1.4rem; }
.alc__more > summary {
  cursor: pointer; font-size: var(--fs-micro); letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ash-dim);
}
.alc__more > summary:focus-visible { outline: 2px solid var(--signal); outline-offset: 3px; }
.alc__extras { list-style: none; margin: 0.9rem 0 0; padding: 0; display: grid; gap: 0.45rem; }
.alc__extras li { display: grid; grid-template-columns: 1fr auto auto; gap: 0.7rem; font-size: 0.9rem; color: var(--ash); }
.alc__extras .alc__n { color: var(--bone); }
.alc__note { color: var(--ash-dim); font-size: var(--fs-micro); }
.alc__note-b { margin-top: 0.7rem; color: var(--ash-dim); font-size: var(--fs-micro); }
.alc__foot { margin-top: 1.2rem; color: var(--ash-dim); font-size: 0.85rem; }

/* =========================================================================
   v51 — GUIDAGE AU-DESSUS ET SOUS LES PACKS
   ========================================================================= */

.packs__guide { margin-top: 1rem; color: var(--bone); font-size: 0.95rem; }
.packs__routes {
  list-style: none; margin: 1rem 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 0.4rem 1.6rem;
}
.packs__routes li { display: flex; gap: 0.5rem; align-items: baseline; font-size: 0.88rem; }
.packs__route-q { color: var(--ash); }
.packs__route-a { color: var(--signal); font-weight: 600; }
.packs__route-a::before { content: '\2192'; margin-right: 0.35rem; color: var(--ash-dim); }

/* En-tête de la zone commande : le bloc feutre occupe la colonne centrale
   restée vide, la devise garde sa place à droite. */
@media (min-width: 901px) {
  .order__head { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: start; gap: 1.5rem; }
}

/* =========================================================================
   v52 — PANNEAU DE COMMANDE DROIT (.rpan)

   Le probleme resolu : la zone de commande vivait tout en bas, sur ~1400px
   de haut, et le visiteur decidait sans jamais voir son total. Le panneau
   porte la meme decision en peripherie, en miroir du rail de gauche, a
   partir du premier chapitre.

   La largeur. Elle est reservee EN PERMANENCE au-dessus de 1280px, pas au
   moment ou le panneau apparait : reserver au scroll decalerait toute la
   page sous les yeux du visiteur. Le contenu se decale donc vers la gauche
   des le chargement, y compris les carrousels et les scenes plein cadre,
   et le panneau occupe la bande liberee sans jamais recouvrir un texte.

   Le seuil. 1280px, pas 1500px comme le rail de gauche : le rail se glisse
   dans une marge deja vide, le panneau, lui, cree sa place. Sous 1280px il
   n'existe pas et c'est .order__fallback qui vend.
   ========================================================================= */

.rpan { display: none; }

/* La formulation par defaut renvoie vers la grille du bas ; celle du
   panneau la remplace au-dessus de 1280px, la ou le panneau existe.
   Declarees AVANT la media query : a specificite egale, c'est l'ordre
   qui tranche. */
.packs__alt-t { display: inline; }
.packs__alt-t--panel { display: none; }

@media (min-width: 1280px) {
  :root { --rpan-w: clamp(11.5rem, 14vw, 14.5rem); }

  /* Le hero garde toute la largeur : une bande noire a droite d'une video
     plein ecran se lit comme un defaut d'affichage, pas comme une marge.

     v60 — cette reserve etait appliquee a TOUTES les pages, alors que le
     panneau de commande ne vit que sur release.html. Sur careers, contact,
     account, la homepage et les 10 pages SEO, elle poussait tout le
     contenu de 14 vw vers la gauche : un texte annonce comme centre
     arrivait a 100 px du centre reel. Elle est desormais conditionnee a
     .page--panel, pose sur le <body> de release.html et de lui seul. */
  .page--panel main > *:not(.hero),
  .page--panel .site-foot { padding-right: var(--rpan-w); }

  /* Le panneau porte deja la commande, ligne par ligne, en permanence. La
     barre du bas et la copie du bas de page repeteraient le meme panier a
     deux endroits visibles en meme temps. */
  .rbar { display: none !important; }
  body.has-rbar { padding-bottom: 0; }
  .order__fallback { display: none; }

  /* Le panneau porte deja son selecteur de devise. Deux menus de devise
     visibles en meme temps sur le meme ecran posent une question qui n'en
     est pas une : lequel fait foi. Ils pilotent le meme etat, mais le
     visiteur ne peut pas le savoir. */
  .order__head .cur { display: none; }

  /* La phrase change de cible : la grille a la carte n'est plus en bas. */
  .packs__alt-t { display: none; }
  .packs__alt-t--panel { display: inline; }

  .rpan {
    position: fixed;
    top: 4.25rem; right: 0; bottom: 0;   /* sous la barre de navigation */
    width: var(--rpan-w);
    z-index: 60;                      /* au-dessus des scenes, sous la nav */
    display: flex;
    flex-direction: column;
    justify-content: center;
    border-left: 1px solid var(--line);
    opacity: 0;
    visibility: hidden;               /* pas seulement opacity : sinon on
                                         tabule dans un panneau invisible */
    pointer-events: none;
    transition: opacity 0.5s var(--ease);
  }
  /* Le fond et le flou vivent sur une couche separee, pas sur .rpan.
     backdrop-filter cree un bloc conteneur pour les descendants en
     position: fixed : porte par le panneau lui-meme, il enfermait les
     pop-ups a l'interieur du panneau et les faisait rogner. */
  .rpan::before {
    content: '';
    position: absolute; inset: -4.25rem 0 0 0;
    z-index: -1;
    background: linear-gradient(to left,
                rgba(10, 11, 13, 0.94), rgba(10, 11, 13, 0.72) 72%, rgba(10, 11, 13, 0.5));
    -webkit-backdrop-filter: blur(8px);
            backdrop-filter: blur(8px);
    pointer-events: none;
  }
  .rpan.is-on { opacity: 1; visibility: visible; pointer-events: auto; }

  .rpan__in {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    max-height: calc(100vh - 5.75rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 0.9rem 0.75rem 0.9rem 0.9rem;
    scrollbar-width: thin;
  }
  .rpan__in::-webkit-scrollbar { width: 3px; }
  .rpan__in::-webkit-scrollbar-thumb { background: var(--line-strong); }
}

/* ---- en-tete : ce qu'on construit, combien, et la garantie ---- */
/* =========================================================================
   v85 — CITATION MANUSCRITE EN TETE DU PANNEAU

   Le brief demande « discret mais parfaitement lisible », « deux lignes
   maximum », « ne jamais depasser du cadre ni etre coupe sur les cotes ».
   Les trois contraintes se resolvent dans la largeur du panneau, qui est le
   vrai sujet : --rpan-w vaut clamp(11.5rem, 14vw, 14.5rem), soit 184 a
   232 px. A cette largeur, une manuscrite au corps du texte serait illisible
   et une manuscrite lisible deborderait. Le corps est donc fluide et borne
   par la largeur du panneau lui-meme (cqw), pas par le viewport : le texte
   grandit avec son contenant et jamais avec l'ecran.

   Pas d'animation d'ecriture : le .mkr de #order en a une, et la rejouer ici
   ferait de la main un tic de page. Elle est posee, pas tracee.
   ========================================================================= */
.rpan__hand {
  font-family: 'Permanent Marker', 'Bradley Hand', 'Segoe Script',
               'Brush Script MT', cursive;
  font-weight: 400;
  /* Corps derive de la largeur du panneau, pas du viewport. Mesure : dans
     Permanent Marker, une capitale avance de 0,537 em ; la ligne longue
     ("We turn faceless uploads") fait 24 signes, soit 12,89 x le corps. On
     lui laisse 6 % de marge sur la largeur utile, qui vaut --rpan-w moins
     26 px de gouttiere :

         corps = 0,90 x (--rpan-w - 26px) / 12,89 = (--rpan-w - 26px) x 0,0690

     La marge est de 10 % et non de 6 % : a 6 %, la ligne longue tombait a
     155 px pour 155,6 px utiles au plus etroit des trois etats — elle
     passait, mais elle se cassait des qu'on ajoutait le padding droit que
     reclame la rotation. Mesure faite, pas estimee.

     Aux trois etats du panneau : 184 px -> 11,2 px ; 212 px -> 13,0 px ;
     232 px -> 14,4 px. La ligne ne touche jamais le bord, a aucune largeur
     intermediaire — c'est ce que demande « ne jamais depasser du cadre ni
     etre coupe sur les cotes ».

     Le repli 14rem couvre le cas ou la regle serait lue hors de la media
     query >= 1280px, ou --rpan-w n'existe pas. Le panneau y est en
     display:none, mais un calc invalide invaliderait la declaration. */
  /* v86 — le corps triple. La contrainte n'est plus la ligne entiere (le
     <br> a disparu) mais le MOT LE PLUS LONG : « unavoidable », 11 signes,
     soit 5,91 fois le corps. On lui laisse 8 % de marge sur la largeur
     utile (--rpan-w moins 26 px de gouttiere) :

         corps = 0,92 x (--rpan-w - 26px) / 5,91 = (--rpan-w - 26px) x 0,1558

     Aux trois etats : 184 px -> 24,6 px ; 212 px -> 29,0 px ; 232 px ->
     32,1 px. La phrase court alors sur quatre a cinq lignes et remplit la
     colonne, ce que demande « occuper tout l'espace noir ». Aucun mot ne
     peut deborder, puisque le plus long est celui qui fixe le corps. */
  font-size: clamp(1.5rem, calc((var(--rpan-w, 14rem) - 26px) * 0.1558), 2rem);
  line-height: 1.16;
  letter-spacing: 0.005em;
  color: var(--bone);
  /* v86 — plus de halo. A ce corps et avec sept couleurs, une diffusion
     blanche delave les teintes au lieu de les poser. Les couleurs portent
     seules : la plus faible tient 6,4:1 sur le fond. */
  transform: rotate(-1.2deg);
  transform-origin: left center;
  margin: 0 0 0.9rem;
  padding-right: 0.15rem;   /* la rotation deporte la fin de ligne a droite */
  /* v86 — balance est desormais utile : sans <br>, il evite la derniere
     ligne orpheline d'un seul mot. */
  text-wrap: balance;
}

/* -------------------------------------------------------------------------
   v86 — LE DRAPEAU, MOT PAR MOT

   Brief du 25/08 : « chaque mot une couleur comme les couleurs gay pride ».

   Les teintes ne sont PAS celles du drapeau officiel, et c'est deliberé.
   Mesures sur le fond du site (#0A0B0D) :

       violet #750787  2,00:1     brun #613915  1,97:1     noir #000  1,07:1
       indigo #004DFF  3,29:1     vert #008026  3,86:1     rouge #E40303  4,04:1

   Six bandes sur neuf sont sous le seuil AA. Les reprendre telles quelles
   aurait produit l'inverse exact de la consigne, qui demande « plus gros et
   plus LISIBLE ». Chaque bande est donc remontee en luminosite jusqu'a
   passer AA au minimum, en conservant sa teinte :

       rouge 6,43   orange 9,54   jaune 15,12   vert 11,86
       bleu  9,22   violet 8,06   rose 10,55

   Sept mots, sept couleurs : le cycle ne se repete pas.

   Les guillemets restent neutres. Colores, ils deviendraient un huitieme mot
   alors qu'ils sont de la ponctuation.
   ------------------------------------------------------------------------- */
.rpan__w { display: inline; }
.rpan__w--1 { color: #FF5A5A; }   /* rouge   */
.rpan__w--2 { color: #FF9E2C; }   /* orange  */
.rpan__w--3 { color: #FFE14D; }   /* jaune   */
.rpan__w--4 { color: #4BE38A; }   /* vert    */
.rpan__w--5 { color: #63B8FF; }   /* bleu    */
.rpan__w--6 { color: #C88BFF; }   /* violet  */
.rpan__w--7 { color: #F5A9B8; }   /* rose    */

.rpan__q { color: var(--bone); opacity: 0.5; }

/* Mode contraste force : le systeme impose ses propres couleurs de texte et
   le drapeau disparait. On garde la phrase lisible plutot que de lutter. */
@media (forced-colors: active) {
  .rpan__w, .rpan__q { color: CanvasText; }
}

/* Le repli system n'est pas decoratif : si le woff2 manque, la phrase reste
   manuscrite sur macOS/iOS et Windows. Ce qu'on refuse, c'est qu'elle
   retombe dans la grotesque du reste du panneau — elle se lirait alors comme
   un sous-titre du produit, ce qu'elle n'est pas. */

.rpan__head { display: flex; flex-direction: column; gap: 0.15rem; }
.rpan__eyebrow { font-size: 0.625rem; letter-spacing: 0.12em; color: var(--ash); }
.rpan__amt {
  font-family: var(--display);
  font-size: 1.25rem; font-weight: 600; letter-spacing: -0.02em;
  color: var(--bone); line-height: 1.15;
}
.rpan__amt.is-live { color: var(--signal); }
.rpan__seal {
  font-size: 0.5625rem; letter-spacing: 0.06em; line-height: 1.4;
  color: var(--ash-dim);
}

/* ---- packs : 60 % de l'attention, une ligne chacun ----
   Titre et prix seulement. Le detail complet (promesse, contenu, economie,
   bouton) vit dans la pop-up : il est dans le DOM, donc lisible par un
   lecteur d'ecran et indexable, mais il n'allonge pas le panneau. */
.rpan__packs { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
.rpan__pitem { position: relative; }
.rpan__pack {
  position: relative;
  width: 100%;
  display: block;
  text-align: left;
  background: rgba(242, 240, 235, 0.03);
  border: 1px solid transparent;
  border-radius: var(--radius-s);
  padding: 0.4rem 0.5rem;
  color: inherit;
  font: inherit;
  cursor: pointer;
  transition: background 0.25s var(--ease), border-color 0.25s var(--ease);
}
.rpan__pack:hover, .rpan__pack:focus-visible { background: rgba(242, 240, 235, 0.07); border-color: var(--line-strong); }
.rpan__pack.is-on { border-color: var(--signal); background: rgba(232, 197, 71, 0.12); }
.rpan__pack.is-star .rpan__pn { color: var(--bone); }
.rpan__prow { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; }
/* Le nom et son badge sont empiles, pas cote a cote : a 184px de large,
   "Launch" + "MOST CHOSEN" + le prix sur une meme ligne faisaient passer le
   badge a la ligne au milieu du mot. Une seule ligne gagnee, sur un seul
   pack. */
.rpan__pn {
  font-family: var(--display); font-size: 0.8125rem; font-weight: 600;
  color: var(--bone); display: flex; flex-direction: column;
  align-items: flex-start; gap: 0.1rem; min-width: 0;
}
.rpan__pp { font-size: 0.75rem; color: var(--ash); white-space: nowrap; }
.rpan__pack.is-on .rpan__pp { color: var(--signal); }
.rpan__flag {
  font-family: var(--mono, var(--body));
  font-size: 0.5rem; letter-spacing: 0.08em; text-transform: uppercase;
  font-weight: 400; white-space: nowrap;
  color: var(--signal); border: 1px solid var(--signal-dim);
  border-radius: 999px; padding: 0.02rem 0.3rem; line-height: 1.5;
}

/* ---- separateur ---- */
.rpan__or {
  display: flex; align-items: center; gap: 0.5rem;
  margin: 0.15rem 0; font-size: 0.5625rem; letter-spacing: 0.1em;
  color: var(--ash-dim); text-transform: uppercase;
}
.rpan__or::before, .rpan__or::after {
  content: ''; flex: 1; height: 1px; background: var(--line);
}

/* ---- options unitaires : chemin secondaire, visible mais discret ---- */
.rpan__opts { display: flex; flex-direction: column; gap: 1px; }
.rpan__cat {
  font-size: 0.5625rem; letter-spacing: 0.12em; color: var(--ash-dim);
  margin: 0.5rem 0 0.1rem; text-transform: uppercase;
}
.rpan__opt {
  position: relative;
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: baseline;
  gap: 0.4rem;
  background: none; border: 0; border-radius: var(--radius-s);
  padding: 0.3rem 0.35rem;
  color: inherit; font: inherit; text-align: left; cursor: pointer;
  transition: background 0.2s var(--ease);
}
.rpan__opt:hover, .rpan__opt:focus-visible { background: rgba(242, 240, 235, 0.06); }
.rpan__on {
  font-size: 0.75rem; color: var(--bone); line-height: 1.25;
  display: flex; flex-direction: column;
}
.rpan__hint { font-style: normal; font-size: 0.5625rem; color: var(--ash-dim); letter-spacing: 0.04em; }
.rpan__op { font-size: 0.6875rem; color: var(--ash); white-space: nowrap; }
.rpan__ox {
  font-size: 0.5625rem; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ash-dim);
}
.rpan__opt.is-on .rpan__ox, .rpan__grp.is-on .rpan__ox { color: var(--signal); }
.rpan__opt.is-on .rpan__op, .rpan__grp.is-on .rpan__op { color: var(--signal); }
.rpan__grp.is-inc .rpan__op, .rpan__grp.is-inc .rpan__ox { color: var(--ash); }

/* ---- groupes a variantes ----
   Huit paliers de shorts et trois de video ne tiennent pas dans un panneau
   sans le transformer en second mur de prix. La ligne montre l'etat, la
   liste reelle s'ouvre au survol comme au clic — le survol seul ecarterait
   tout ce qui n'a pas de souris. */
.rpan__grp { position: relative; }

/* ---- pop-ups ----
   Elles s'ouvrent VERS LA GAUCHE, jamais vers la droite : le panneau est
   colle au bord de la fenetre, une pop-up a droite sortirait de l'ecran. */
.rpan__pop {
  position: fixed;                     /* cale par release.js sur son
                                          declencheur : voir placePop() */
  top: 0; right: calc(100% + 0.55rem);
  width: 15rem;
  display: flex; flex-direction: column; gap: 0.35rem;
  padding: 0.7rem 0.8rem;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-m);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.55);
  opacity: 0; visibility: hidden; transform: translateX(0.4rem);
  transition: opacity 0.2s var(--ease), transform 0.2s var(--ease), visibility 0.2s;
  pointer-events: none;
  z-index: 5;
  text-align: left;
}
.rpan__pack:hover .rpan__pop,
.rpan__pack:focus-visible .rpan__pop,
.rpan__opt:hover .rpan__pop,
.rpan__opt:focus-visible .rpan__pop {
  opacity: 1; visibility: visible; transform: none;
}
.rpan__grp.is-open .rpan__pop--grp,
.rpan__grp:hover .rpan__pop--grp,
.rpan__grp:focus-within .rpan__pop--grp {
  opacity: 1; visibility: visible; transform: none; pointer-events: auto;
}
.rpan__pop--grp { top: auto; bottom: 0; }

.rpan__pop-who { font-size: 0.8125rem; color: var(--bone); line-height: 1.35; }
.rpan__pop-lines { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.2rem; }
.rpan__pop-lines li {
  font-size: 0.75rem; color: var(--ash); line-height: 1.4;
  padding-left: 0.8rem; position: relative;
}
.rpan__pop-lines li::before {
  content: '\2713'; position: absolute; left: 0; color: var(--signal); font-size: 0.7rem;
}
.rpan__pop-price { display: flex; align-items: baseline; gap: 0.5rem; }
.rpan__pop-was { font-size: 0.75rem; color: var(--ash-dim); text-decoration: line-through; }
.rpan__pop-save { font-size: 0.6875rem; color: var(--signal); letter-spacing: 0.02em; }
.rpan__pop-cta {
  display: block; margin-top: 0.2rem;
  text-align: center; font-size: 0.75rem; font-weight: 600;
  color: var(--bone); background: rgba(232, 197, 71, 0.16);
  border: 1px solid var(--signal-dim); border-radius: var(--radius-s);
  padding: 0.4rem 0.5rem;
}
.rpan__pop-eta { font-size: 0.5625rem; letter-spacing: 0.06em; color: var(--ash-dim); }
.rpan__pop-t {
  font-size: 0.5625rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ash-dim); margin-top: 0.3rem;
}
.rpan__sub {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 0.5rem; align-items: baseline;
  width: 100%; background: none; border: 0; border-radius: var(--radius-s);
  padding: 0.28rem 0.35rem; color: inherit; font: inherit;
  text-align: left; cursor: pointer;
  transition: background 0.2s var(--ease);
}
.rpan__sub:hover, .rpan__sub:focus-visible { background: rgba(242, 240, 235, 0.07); }
.rpan__sub.is-on { background: rgba(232, 197, 71, 0.14); }
.rpan__sn { font-size: 0.8125rem; color: var(--bone); }
.rpan__sp { font-size: 0.75rem; color: var(--ash); white-space: nowrap; }
.rpan__sx {
  font-size: 0.5625rem; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ash-dim);
}
.rpan__sub.is-on .rpan__sx, .rpan__sub.is-on .rpan__sp { color: var(--signal); }

/* ---- total et paiement, colles en bas du panneau ----
   sticky, pas simplement en fin de liste. Sur un portable 1366x768 le
   contenu du panneau mesure ~764px pour ~676px disponibles : sans cette
   regle, le total et le bouton de paiement ne sont atteignables qu'apres un
   defilement interne que rien n'annonce. Le fond opaque est necessaire :
   les lignes d'options passent dessous. */
.rpan__foot {
  position: sticky;
  bottom: 0;
  z-index: 2;
  display: flex; flex-direction: column; gap: 0.3rem;
  border-top: 1px solid var(--line);
  padding: 0.6rem 0.75rem 0.9rem 0.9rem;
  margin: 0.3rem -0.75rem -0.9rem -0.9rem;
  background: var(--void);
}
.rpan__det {
  align-self: flex-start;
  background: none; border: 0; padding: 0;
  font: inherit; font-size: 0.5625rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ash); cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
}
.rpan__det:hover { color: var(--bone); }
.rpan__list { margin: 0.2rem 0; padding: 0; list-style: none; }
.rpan__list .oline { font-size: 0.6875rem; }
.rpan__list .oline__eta, .rpan__list .oline__sub { font-size: 0.5625rem; }
.rpan__row {
  display: flex; justify-content: space-between; gap: 0.5rem;
  font-size: 0.6875rem; color: var(--ash);
}
.rpan__row--total {
  font-family: var(--display); font-size: 0.9375rem; font-weight: 600;
  color: var(--bone); letter-spacing: -0.01em;
}
.rpan__save { margin: 0; font-size: 0.625rem; color: var(--signal); }
.rpan__cta { margin-top: 0.35rem; padding: 0.55rem 0.5rem; font-size: 0.75rem; }
.rpan__micro { margin: 0; font-size: 0.5rem; letter-spacing: 0.05em; color: var(--ash-dim); line-height: 1.4; }
.rpan__cur { margin: 0.2rem 0 0; }
.rpan__cur .cur select { font-size: 0.625rem; }

/* ---- fenetres courtes ----
   1366x768 est la resolution la plus repandue sur portable et c'est celle
   qui laisse le moins de hauteur au panneau. On resserre plutot que de
   retirer une ligne : chaque option retiree ici est une option que le
   visiteur ne verra jamais, le panneau etant le seul chemin d'achat
   au-dessus de 1280px. */
@media (min-width: 1280px) and (max-height: 830px) {
  .rpan__in { gap: 0.5rem; padding-block: 0.6rem; max-height: calc(100vh - 5rem); }
  .rpan__amt { font-size: 1.0625rem; }
  .rpan__seal { display: none; }          /* repris mot pour mot sous les packs */
  .rpan__pack { padding-block: 0.3rem; }
  .rpan__cat { margin-top: 0.35rem; }
  .rpan__opt { padding-block: 0.22rem; }
  .rpan__cur { display: none; }           /* devise : celle du pied de page */
  .rpan__micro { font-size: 0.4375rem; }
}

@media (prefers-reduced-motion: reduce) {
  .rpan, .rpan__pop { transition: none; }
}


/* =========================================================================
   V53 — RELANCE SUR LA CARTE DES QUATRE COMPOSANTS (.epop)

   Pourquoi ici. #release-map est le dernier ecran ou le visiteur peut croire
   qu'il a compris l'offre : quatre cartes, quatre prix d'entree, une sortie
   possible. Les packs vivent dans le panneau de commande, et le panneau ne
   s'allume qu'au premier chapitre. Entre les deux, personne ne dit qu'il y a
   mieux que l'unite. La relance dit exactement cela, une fois.

   Pourquoi ce n'est pas une carte arrondie. Le brief demande une composition
   ouverte plutot qu'une bulle : pas de fond plein, pas de rayon, pas d'ombre
   portee. Ce qui tient le bloc, c'est un filet vertical a gauche — le meme
   vocabulaire que .hero__pos — et une nappe lumineuse tres diffuse derriere
   le texte. La profondeur vient de la lumiere, pas d'un cadre.

   Pourquoi elle n'est pas collee au bord droit. Au-dessus de 1280px le bord
   droit appartient au panneau de commande : `--rpan-w` lui est reserve en
   permanence par le CSS, meme quand le panneau est encore transparent. Une
   relance calee sur le bord aurait fonctionne tant que le panneau est eteint,
   puis l'aurait chevauche exactement a l'instant ou les deux se croisent. La
   relance se cale donc contre la lisiere interieure de la reserve.
   ========================================================================= */
.epop {
  position: fixed;
  z-index: 55;                      /* sous la nav (70) et sous .rpan (60) */
  top: 50%;
  right: clamp(1.25rem, 3vw, 2.5rem);
  transform: translateY(-50%);
  width: min(19rem, 32vw);
  padding: 0.2rem 0 0.2rem 1.05rem;
  border-left: 1px solid var(--signal);
  pointer-events: none;             /* seuls les enfants recoivent le clic */
}
.epop[hidden] { display: none; }

/* La nappe. Elle deborde volontairement du bloc : une lueur qui s'arrete au
   bord redessine le rectangle qu'on cherche a eviter. */
.epop::before {
  content: '';
  position: absolute;
  inset: -2.5rem -3rem -2.5rem -2rem;
  background: radial-gradient(60% 55% at 30% 50%,
              rgba(232, 197, 71, 0.16), rgba(232, 197, 71, 0.05) 45%, transparent 72%);
  pointer-events: none;
  z-index: -1;
}

/* Entree : glissement depuis la droite + fondu + une legere remontee. Les
   trois en meme temps, sur une courbe qui depasse a peine, d'ou l'effet de
   ressort demande sans recourir a une librairie. */
.epop__go {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.55rem;
  width: 100%;
  text-align: left;
  cursor: pointer;
  pointer-events: auto;
  opacity: 0;
  transform: translate3d(2.5rem, 0.75rem, 0);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
.epop.is-on .epop__go { opacity: 1; transform: none; }
.epop.is-out .epop__go { opacity: 0; transform: translate3d(2rem, 0, 0); }

/* Hierarchie : la premiere ligne recule, les deux suivantes portent le
   message, la derniere porte la couleur. Trois niveaux, pas quatre. */
.epop__lead {
  font-family: var(--display);
  font-size: 0.8125rem;
  font-weight: 400;
  letter-spacing: 0.01em;
  line-height: 1.4;
  color: var(--ash);
}
.epop__hook {
  font-family: var(--display);
  font-size: clamp(1.0625rem, 1.55vw, 1.3125rem);
  font-weight: 800;
  letter-spacing: -0.028em;         /* serre : c'est ce qui fait le poids */
  line-height: 1.14;
  color: var(--bone);
}
.epop__cta {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.15rem;
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--signal);
  transition: color 0.3s var(--ease);
}

/* La fleche est le seul element en mouvement permanent. Elle ne clignote pas
   et ne rebondit pas sechement : elle descend et remonte, longuement, pour
   dire la direction sans reclamer l'attention. */
.epop__arrow {
  display: inline-block;
  font-size: 0.9375rem;
  line-height: 1;
  animation: epopFall 2s var(--ease) infinite;
}
@keyframes epopFall {
  0%, 100% { transform: translateY(0);     opacity: 0.75; }
  45%      { transform: translateY(0.4rem); opacity: 1; }
}

.epop__go:hover .epop__cta { color: var(--bone); }
.epop__go:hover .epop__arrow { animation-duration: 1.1s; }
.epop__go:hover { transform: translateY(-2px); }
.epop__go:focus-visible { outline: 1px solid var(--signal); outline-offset: 6px; }

/* La croix. Discrete par defaut, elle ne se revele qu'au survol du bloc —
   mais elle reste atteignable au clavier en permanence. */
.epop__x {
  position: absolute;
  top: -0.35rem; right: -0.35rem;
  width: 1.35rem; height: 1.35rem;
  display: grid; place-items: center;
  font-size: 0.9rem;
  line-height: 1;
  color: var(--ash-dim);
  cursor: pointer;
  pointer-events: auto;
  opacity: 0;
  transition: opacity 0.3s var(--ease), color 0.3s var(--ease);
}
.epop:hover .epop__x, .epop__x:focus-visible { opacity: 1; }
.epop__x:hover { color: var(--bone); }

/* ---- au-dessus de 1280px : la relance vit DANS la bande reservee ----
   Premier jet : la relance etait calee contre la lisiere interieure de la
   reserve, a `right: calc(var(--rpan-w) + 0.75rem)`. En rendu, a 1600px, elle
   se posait sur les cartes 03 et 04. Exactement le defaut du rail de gauche,
   reproduit de l'autre cote : un bloc flottant pose sur une grille qui va
   jusqu'au bord de sa colonne.

   Elle occupe donc la bande que le panneau de commande occupera. Cette bande
   est vide par construction au-dessus de 1280px — `main > *` porte deja un
   `padding-right: var(--rpan-w)` — donc rien ne peut se trouver dessous,
   quelle que soit la largeur. Et le raccord se lit : la relance dit d'aller
   voir les packs, elle apparait a l'endroit exact ou les packs vont
   apparaitre. */
@media (min-width: 1280px) {
  .epop {
    right: 0;
    width: var(--rpan-w);
    padding: 0.2rem 0.7rem 0.2rem 0.85rem;
  }
  /* la colonne est etroite : le titre descend d'un cran, sinon chaque ligne
     se brise au milieu d'un mot */
  /* Le <br> du brief est CONSERVE. Premier jet : il etait masque en
     display:none pour laisser la largeur decider des retours — et masquer un
     <br> supprime aussi l'espace qu'il portait. En rendu, la phrase se lisait
     "The artists who blow upgo for the bundles." Deux mots colles, dans la
     seule ligne du site qui doit convaincre. */
  .epop__hook { font-size: clamp(0.9375rem, 1.15vw, 1.125rem); }
  .epop::before { inset: -2rem -0.5rem -2rem -1.5rem; }
}

/* ---- entre 861 et 1279px : pas de bande reservee, donc pas de bloc
   flottant. La composition passe en barre basse, comme sur telephone : une
   barre ne recouvre jamais une colonne de texte, un bloc lateral si. ---- */

/* ---- telephone : barre basse ----
   Un bloc flottant a droite couvre le tiers d'un ecran de telephone. La
   composition passe donc a l'horizontale, sur une seule ligne, ancree en bas
   au-dessus de la barre de release existante. */
@media (max-width: 1279px) {
  .epop {
    top: auto;
    bottom: calc(var(--rbar-h) + var(--lrail-h, 0px) + 0.6rem);
    left: 0.75rem; right: 0.75rem;
    width: auto;
    transform: none;
    padding: 0.7rem 0.9rem;
    border-left: 0;
    border-top: 1px solid var(--signal);
    background: rgba(10, 11, 13, 0.92);
    -webkit-backdrop-filter: blur(10px);
            backdrop-filter: blur(10px);
  }
  .epop::before { inset: 0; }
  .epop__go {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    transform: translate3d(0, 1.25rem, 0);
  }
  .epop.is-out .epop__go { transform: translate3d(0, 1rem, 0); }
  .epop__hook { font-size: 0.9375rem; line-height: 1.25; }
  .epop__cta { margin-top: 0; white-space: nowrap; }
  .epop__x { top: 0.15rem; right: 0.3rem; opacity: 1; }
}
/* sous 720px la premiere ligne saute : trois blocs ne tiennent pas sur une
   barre de telephone sans que le titre passe a 12px */
@media (max-width: 720px) {
  .epop__lead { display: none; }
  .epop__hook { font-size: 0.875rem; }
}

/* ---- mouvement reduit : le composant survit, l'animation non ---- */
@media (prefers-reduced-motion: reduce) {
  .epop__go { transition: none; transform: none; }
  .epop.is-on .epop__go, .epop.is-out .epop__go { transform: none; }
  .epop__go:hover { transform: none; }
  .epop__arrow { animation: none; opacity: 1; }
}

/* =========================================================================
   V54 — EXEMPLES DE CLIP : LECTEURS A LA DEMANDE (.ccase)

   Remplace le carrousel `.rail` de la section 04. Deux raisons, dans cet
   ordre d'importance :

   1. Le carrousel demarre ses videos seul des 40 % de visibilite. Un extrait
      de 30 s en 1080p avec son pese 14 Mo : le carrousel l'aurait impose a
      chaque visiteur, telephone compris. Ici le poster s'affiche, la source
      n'est ecrite qu'au premier clic.
   2. Trois emplacements \"Clip example\" cote a cote ne prouvaient rien. Un
      seul lecteur par ligne, pleine largeur de la colonne : on regarde un
      clip, on ne le survole pas.
   ========================================================================= */
.ccases {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  display: flex;
  flex-direction: column;
  gap: clamp(2rem, 4vw, 3rem);
}

.ccase { margin: 0; }

.ccase__stage {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
}
.ccase__v { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Le bouton couvre toute la scene : sur un poster de 1200px de large, une
   pastille de 64px au centre demande de viser. Il disparait des que la
   lecture commence, les controles natifs prennent le relais. */
.ccase__play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: linear-gradient(180deg, rgba(10,11,13,0.28), rgba(10,11,13,0.52));
  cursor: pointer;
  transition: background 0.35s var(--ease), opacity 0.3s var(--ease);
}
.ccase.is-playing .ccase__play { opacity: 0; pointer-events: none; }
.ccase__play:hover { background: linear-gradient(180deg, rgba(10,11,13,0.18), rgba(10,11,13,0.42)); }

.ccase__tri {
  width: clamp(3.25rem, 5vw, 4.25rem);
  aspect-ratio: 1;
  border-radius: 50%;
  border: 1px solid rgba(242, 240, 235, 0.55);
  background: rgba(10, 11, 13, 0.35);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  display: grid;
  place-items: center;
  transition: transform 0.35s var(--ease-out-expo), border-color 0.35s var(--ease);
}
/* le triangle, en CSS : un SVG de plus pour trois traits ne se justifie pas */
.ccase__tri::after {
  content: '';
  border-style: solid;
  border-width: 0.42rem 0 0.42rem 0.68rem;
  border-color: transparent transparent transparent var(--bone);
  margin-left: 0.18rem;
}
.ccase__play:hover .ccase__tri { transform: scale(1.07); border-color: var(--bone); }
.ccase__play:focus-visible { outline: 2px solid var(--signal); outline-offset: -4px; }

.ccase__meta {
  position: absolute;
  right: 0.75rem; bottom: 0.7rem;
  font-size: 0.5625rem;
  letter-spacing: 0.12em;
  color: var(--bone);
  background: rgba(10, 11, 13, 0.62);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.18rem 0.55rem;
  pointer-events: none;
}
.ccase.is-playing .ccase__meta { opacity: 0; transition: opacity 0.3s var(--ease); }

.ccase__cap {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin-top: 0.9rem;
  max-width: 54ch;
}
.ccase__k { color: var(--signal); letter-spacing: 0.14em; }
.ccase__t {
  font-family: var(--display);
  font-size: clamp(1.05rem, 1.8vw, 1.3rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--bone);
}
.ccase__c { font-size: 0.9375rem; line-height: 1.55; color: var(--ash); }

@media (prefers-reduced-motion: reduce) {
  .ccase__play, .ccase__tri { transition: none; }
  .ccase__play:hover .ccase__tri { transform: none; }
}


/* =========================================================================
   v57 — CHARTE TYPOGRAPHIQUE SOFTRIVER
   Trois familles, une par role, plus un renfort. Les valeurs ci-dessous
   corrigent ce que le seul changement de famille ne corrige pas : sur fond
   noir le texte clair "gonfle" (halation), donc les graisses descendent
   d'un cran et le tracking remonte legerement. Inter Tight est plus etroite
   qu'Helvetica, elle supporte un negatif plus franc dans les grandes
   tailles ; Manrope est plus large, elle en demande moins.
   ========================================================================= */

/* ---------- Titres : Inter Tight ---------- */
h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 700;
  /* Inter Tight est deja plus etroite qu'Helvetica : le -0.02em d'origine
     s'y lit comme un -0.035em. On redescend, et on rend au mot l'espace que
     le tracking negatif lui prend, sinon les mots se touchent aux grandes
     tailles. */
  letter-spacing: -0.018em;
  word-spacing: 0.05em;
}
/* Au-dela de ~3rem le negatif doit augmenter, en dessous il doit disparaitre :
   un h4 a -0.028em se lit serre. */
h3 { font-weight: 650; letter-spacing: -0.012em; word-spacing: 0.03em; }
h4 { font-weight: 650; letter-spacing: -0.004em; word-spacing: 0.02em; }

.hero__title,
.map-title,
.shero__t,
.sec-h__t {
  font-weight: 700;
  letter-spacing: -0.022em;
  word-spacing: 0.07em;
}

/* Le titre du hero fait trois lignes depuis la v56. 26ch : en dessous le
   navigateur casse une quatrieme ligne et le decoupage manuel ne veut
   plus rien dire. Inter Tight etant plus etroite, on peut remonter la
   taille par rapport a la v56. */
.hero--centered .hero__title--long,
.hero__title--long {
  font-size: clamp(2.3rem, 6vw, 5.4rem);
  max-width: 26ch;
}
@media (max-width: 760px) {
  .hero--centered .hero__title--long {
    font-size: clamp(2rem, 8.5vw, 2.8rem);
    max-width: 24ch;
  }
}

.hero__claim,
.hero__pos-strong { font-family: var(--display); font-weight: 700; letter-spacing: -0.012em; word-spacing: 0.05em; }

/* ---------- Corps, navigation, UI : Manrope ---------- */
/* Manrope a une chasse d'espace-mot etroite : sans compensation, "Full Video
   Clip" se lit "FullVideoClip" dans la navigation et les cartes. */
body {
  font-family: var(--body);
  font-weight: 400;
  letter-spacing: 0.002em;
  word-spacing: 0.05em;
}
.nav__link {
  font-family: var(--body);
  font-weight: 500;
  letter-spacing: 0.006em;
  word-spacing: 0.08em;
}
.brand { font-family: var(--display); font-weight: 800; letter-spacing: -0.02em; }
.btn { font-family: var(--body); font-weight: 600; letter-spacing: 0.012em; word-spacing: 0.06em; }
.lead { font-weight: 400; }
input, select, textarea, button { font-family: var(--body); }

/* ---------- Capitales a tracking large : Plus Jakarta Sans ----------
   Le tracking d'origine est conserve ; seule la graisse monte de 400 a 500,
   parce que Plus Jakarta Sans a un fut plus fin que la monospace qu'elle
   remplace et qu'a 0.75rem sur fond noir elle disparaissait. */
.mono {
  font-family: var(--caps);
  font-weight: 500;
  letter-spacing: 0.09em;
  word-spacing: 0.12em;
  font-feature-settings: 'tnum' 1, 'kern' 1;
}
.eyebrow,
.mono-label,
.hero__reassure,
.ab__switch button,
.copen__line,
.why-price h4,
.vis__spine,
.epop__cta {
  font-family: var(--caps);
  font-weight: 600;
}
.eyebrow { letter-spacing: 0.2em; }
.mono-label { letter-spacing: 0.13em; }

/* Toutes les micro-etiquettes en capitales : meme famille, meme graisse,
   meme compensation d'espace-mot que .mono. Sans elle "Most popular" se
   lit "MOSTPOPULAR" une fois passe en capitales. */
.tier__flag, .price-card__badge, .bsum__badge, .pack__flag,
.chip, .mono-tag, .tag, .rea__k, .packs__kicker {
  font-family: var(--caps);
  font-weight: 600;
  word-spacing: 0.14em;
}

/* Les titres qui ne sont pas des <h> mais portent quand meme la voix
   display : meme compensation d'espace-mot que les <h>. */
.map-card__title, .ccase__t, .diff__t, .faq__q, .offer__t, .packs__t,
.mantra, .coh__line, .sum__punch, .rp__head, .epop__hook, .epop__lead,
.modes__intro, .conv__droptitle, .rrl, .clip-pos, .mkr__t {
  word-spacing: 0.06em;
}

/* ---------- Renfort Montserrat : uniquement les numeraux tres gras ----------
   Trois endroits, pas un de plus. Montserrat a des chiffres plus larges et
   plus geometriques qui tiennent mieux a tres grande taille que ceux
   d'Inter Tight ; partout ailleurs elle ferait doublon. */
.hero__stat-num,
.hero__hint-n,
.chapter__num {
  font-family: var(--heavy);
  font-weight: 800;
  letter-spacing: -0.03em;
  font-feature-settings: 'tnum' 1;
}

/* ---------- Chiffres en colonne ----------
   Prix, compteurs et minutages doivent rester alignes maintenant que la
   monospace est partie. */
.tier__p, .pack__p, .ctier__p, .alc__p, .vnl__time,
.np-times, .map-count, .rbar__total, .bsum__v {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* =========================================================================
   v58 — NOUVELLE HOMEPAGE
   La page unique est coupee en deux : index.html oriente, release.html
   porte le detail. Ce bloc ne style que ce qui est neuf. Tout le reste
   (hero, coh, cartes, packs, panneau de commande) reutilise les classes
   existantes sans modification.
   ========================================================================= */

/* ---------- Section 02 : introduction ---------- */
.home-intro__head { max-width: 62ch; }
.home-intro__t {
  font-size: var(--fs-h2);
  margin-top: 1.1rem;
}
.home-intro__lead { margin-top: 1.1rem; max-width: 52ch; }

.home-intro__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.5rem, 3vw, 3rem);
  margin-top: clamp(3rem, 6vw, 5rem);
  border-top: 1px solid var(--line);
  padding-top: clamp(2rem, 4vw, 3rem);
}
.home-intro__i { display: flex; flex-direction: column; gap: 0.65rem; }
.home-intro__n { color: var(--signal); }
.home-intro__it { font-size: var(--fs-h3); }
.home-intro__ip { color: var(--ash); max-width: 34ch; }

/* ---------- Section 03 : offre + capture ---------- */
.home-offer__head { max-width: 62ch; }
.home-offer__t { font-size: var(--fs-h2); margin-top: 1.1rem; }
.home-offer__head .lead { margin-top: 1.1rem; }

.home-cap { margin: clamp(2.5rem, 5vw, 4rem) 0 0; }
.home-cap__img,
.home-cap__ph {
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-m);
  display: block;
}
.home-cap__img { object-fit: cover; border: 1px solid var(--line); }

/* Le cadre d'attente. Il occupe exactement la place du visuel final, pour
   que le remplacement ne deplace rien sur la page. */
.home-cap__ph {
  background: var(--surface);
  border: 1px dashed var(--line-strong);
  display: grid;
  place-content: center;
  gap: 0.6rem;
  text-align: center;
  padding: 2rem;
}
.home-cap__tag { color: var(--signal); }
.home-cap__path { color: var(--ash-dim); font-size: var(--fs-micro); }
.home-cap__cap { margin-top: 0.9rem; color: var(--ash-dim); }

/* ---------- Section 05 : sortie vers les packs ---------- */
.home-next { text-align: center; }
.home-next__t { font-size: var(--fs-h2); }
.home-next__p { margin: 1.1rem auto 0; }
.home-next__a {
  margin-top: 2rem;
  display: flex; flex-wrap: wrap; gap: 0.85rem;
  justify-content: center;
}

/* ---------- Barre de retour, en tete de release.html ---------- */
.backbar {
  border-bottom: 1px solid var(--line);
  padding-top: 5.5rem;   /* le header est en position: fixed */
}
.backbar__in {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
  padding-block: 0.9rem;
}
.backbar__link {
  display: inline-flex; align-items: center; gap: 0.55rem;
  font-family: var(--body); font-weight: 600; font-size: 0.92rem;
  color: var(--bone);
  transition: color 0.3s var(--ease);
}
.backbar__link:hover { color: var(--signal); }
.backbar__arrow { transition: transform 0.35s var(--ease); }
.backbar__link:hover .backbar__arrow { transform: translateX(-4px); }
.backbar__here { color: var(--ash-dim); }

/* ---------- Responsive ---------- */
@media (max-width: 980px) {
  .home-intro__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .home-intro__grid { grid-template-columns: 1fr; gap: 2rem; }
  .home-next__a { flex-direction: column; }
  .home-next__a .btn { width: 100%; justify-content: center; }
  .backbar__here { display: none; }
  .backbar { padding-top: 4.75rem; }
}

/* v58 — les quatre vignettes menent a une ancre de release.html. Sans marge
   de defilement, la section arrive collee au bord haut et passe sous le
   header, qui est en position: fixed. Le visiteur atterrit alors sur le
   milieu du premier paragraphe. */
#sound, #visuals, #shorts, #clip, #order, #faq, #why,
#ch-01, #ch-02, #ch-03, #ch-04 { scroll-margin-top: 6.5rem; }
@media (max-width: 760px) {
  #sound, #visuals, #shorts, #clip, #order, #faq, #why,
  #ch-01, #ch-02, #ch-03, #ch-04 { scroll-margin-top: 5rem; }
}

/* =========================================================================
   v59 — PAGE CAREERS
   L'agencement vient du modele fourni : hero centre, rangee de cartes
   avantages, grille de quatre benefices, quatre etapes. L'habillage est
   celui de Ready Release : fond noir, Inter Tight / Manrope / Plus Jakarta
   Sans, bouton bleu existant, memes rayons et memes hairlines. Aucun token
   nouveau n'est cree ; tout consomme --bone, --ash, --signal, --line,
   --surface et --radius-*.
   ========================================================================= */

/* ---------- 01 · Hero ---------- */
.car-hero {
  padding-top: clamp(8rem, 16vw, 12rem);
  padding-bottom: clamp(3.5rem, 8vw, 6rem);
  border-bottom: 1px solid var(--line);
}
.car-hero__in { text-align: center; }

.car-hero__t {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(2.1rem, 5.2vw, 4.2rem);
  line-height: 1.04;
  letter-spacing: -0.022em;
  word-spacing: 0.07em;
  margin: 1.25rem auto 0;
  max-width: 22ch;
  text-wrap: balance;
}
/* Le modele colore trois mots du titre. On garde le principe et on prend la
   couleur d'accent du site, pas celle du modele. */
.car-hl { color: var(--signal); }

.car-hero__sub {
  margin: 1.5rem auto 0;
  max-width: 56ch;
  color: var(--ash);
}
.car-hero__a { margin-top: 2.25rem; }

.car-cta__arrow {
  display: inline-block;
  transition: transform 0.35s var(--ease);
}
.car-cta:hover .car-cta__arrow { transform: translateX(4px); }

/* ---------- 01b · Les cinq raisons ----------
   v60 — c'etait une bande unique decoupee en cinq cellules par des filets :
   ca se lisait comme un tableau, pas comme cinq raisons. Le modele pose
   cinq cartes separees, chacune avec sa pastille d'icone. On reprend ce
   principe, avec nos couleurs.

   Cinq colonnes egales sur grand ecran. Sous 1100px la cinquieme tomberait
   seule sur une deuxieme ligne : on passe a trois, puis a deux, plutot que
   de laisser un orphelin. */
.car-perks {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: clamp(0.85rem, 1.6vw, 1.25rem);
  margin-top: clamp(3.5rem, 7vw, 5.5rem);
}
.car-perk {
  background: var(--surface);
  border: 1px solid transparent;
  border-radius: 16px;
  padding: clamp(1.75rem, 3vw, 2.5rem) 1.25rem clamp(1.5rem, 2.6vw, 2rem);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.4rem;
  text-align: center;
  transition: background 0.35s var(--ease), border-color 0.35s var(--ease),
              transform 0.35s var(--ease);
}
.car-perk:hover {
  background: var(--surface-2);
  border-color: var(--line);
  transform: translateY(-3px);
}

/* La pastille : carre arrondi, fond un cran plus clair, filet fin, icone a
   l'accent. C'est le seul endroit de la page ou l'accent est massif — il
   guide l'oeil le long de la rangee. */
.car-perk__ico {
  /* v61 — la pastille passe de 54 a 72px et l'icone de 24 a 44px. Le jeu
     fourni est dessine au trait, avec des filets de vitesse et des details
     (reliure, rayons, pied d'ecran) que le SVG geometrique precedent
     n'avait pas : sous 40px il se refermait en tache. */
  width: 72px; height: 72px;
  flex: none;
  display: grid; place-items: center;
  border-radius: 18px;
  background: var(--void-2);
  border: 1px solid var(--line);
  box-shadow: 0 1px 0 rgba(242, 240, 235, 0.04) inset;
  transition: border-color 0.35s var(--ease), background 0.35s var(--ease);
}
.car-perk__ico img {
  width: 44px; height: 44px;
  display: block;
  /* Les cinq fichiers sont deja a la couleur d'accent. Le survol les
     eclaircit legerement plutot que de les recolorer : un filtre de teinte
     sur une image deja teintee derive vers le cyan. */
  transition: filter 0.35s var(--ease);
}
.car-perk:hover .car-perk__ico { border-color: var(--signal); background: var(--surface); }
.car-perk:hover .car-perk__ico img { filter: brightness(1.18); }

.car-perk__t {
  font-family: var(--display);
  font-weight: 650;
  font-size: 1rem;
  line-height: 1.35;
  letter-spacing: -0.008em;
  max-width: 17ch;
}

/* ---------- 02 · Benefices ---------- */
.car-ben__head { text-align: center; }
.car-ben__t {
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h2);
  line-height: 1.06;
  letter-spacing: -0.02em;
  word-spacing: 0.06em;
  margin-inline: auto;
  max-width: 26ch;
  text-wrap: balance;
}
.car-ben__sub { margin: 1.5rem auto 0; max-width: 54ch; color: var(--ash); }

.car-cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1rem, 2vw, 1.5rem);
  margin-top: clamp(3rem, 6vw, 4.5rem);
}
.car-cards { align-items: stretch; }
/* v60 — le modele teinte ces quatre cartes avec sa couleur d'accent, sans
   filet, en grand rayon. On fait pareil avec la notre : un aplat bleu a
   9% sur le noir donne l'equivalent du lavande sur blanc. Le filet a
   disparu : sur un fond deja teinte, il ajoutait un troisieme bord au
   meme endroit. Sur fond noir il faut monter a 16% : un aplat a 9% que
   l'oeil percoit sur du blanc disparait sur du #0A0B0D. */
.car-card {
  background: rgba(232, 197, 71, 0.16);
  border: 1px solid transparent;
  border-radius: 18px;
  padding: clamp(1.75rem, 3vw, 2.35rem);
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  transition: background 0.35s var(--ease), border-color 0.35s var(--ease),
              transform 0.35s var(--ease);
}
.car-card:hover {
  background: rgba(232, 197, 71, 0.22);
  border-color: rgba(232, 197, 71, 0.35);
  transform: translateY(-3px);
}
.car-card__t {
  font-family: var(--display);
  font-weight: 650;
  font-size: 1.25rem;
  letter-spacing: -0.014em;
}
.car-card__p { color: var(--ash); font-size: 0.97rem; line-height: 1.62; }

/* ---------- 03 · Les quatre etapes ----------
   Une <ol> : l'ordre porte le sens et doit etre entendu, pas seulement vu. */
.car-flow {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.25rem, 3vw, 2.5rem);
  list-style: none;
  counter-reset: none;
}
.car-step {
  display: flex;
  flex-direction: column;
  gap: 1.35rem;
  padding-bottom: 2.25rem;
  border-bottom: 1px solid var(--line);
}
/* v62 — pastille Step. 112px sur grand ecran : au-dela le disque prend le
   pas sur le titre qu'il annonce, en-deca le chiffre cesse d'etre lisible. */
.car-step__badge {
  width: 112px; height: 112px;
  display: block;
  flex: none;
}

.car-step__t {
  font-family: var(--display);
  font-weight: 650;
  font-size: 1.3rem;
  line-height: 1.32;
  letter-spacing: -0.014em;
  max-width: 20ch;
}
.car-steps__a { margin-top: clamp(3rem, 6vw, 4.5rem); text-align: center; }
.car-steps { padding-bottom: clamp(3.5rem, 7vw, 5.5rem); }

/* Les etapes prolongent les benefices : elles repondent a "et concretement,
   comment je postule ?". Deux paddings de section pleins entre les deux
   coupaient cette suite en deux pages distinctes. */
.car-steps { padding-top: clamp(1.5rem, 3vw, 2.5rem); }

/* ---------- Responsive ---------- */
@media (max-width: 1100px) {
  .car-perks { grid-template-columns: repeat(3, 1fr); }
  .car-cards { grid-template-columns: repeat(2, 1fr); }
  .car-flow  { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 700px) {
  .car-perks { grid-template-columns: repeat(2, 1fr); }
  .car-perk__ico { width: 64px; height: 64px; border-radius: 16px; }
  .car-perk__ico img { width: 40px; height: 40px; }
  .car-step__badge { width: 92px; height: 92px; }
  .car-hero__t { max-width: 16ch; }
  /* Le <br> du titre est pense pour le grand ecran ; sur mobile il coupe
     au mauvais endroit et on laisse le navigateur decider. */
  .car-hero__t br, .car-ben__t br { display: none; }
}
@media (max-width: 460px) {
  .car-perks { grid-template-columns: 1fr; }
  .car-cards { grid-template-columns: 1fr; }
  .car-flow  { grid-template-columns: 1fr; }
  .car-hero__a .btn, .car-steps__a .btn { width: 100%; justify-content: center; }
}

/* =========================================================================
   v59 — HERO DE LA HOMEPAGE : RESERVE APRES RETRAIT
   Trois blocs sont partis (phrase de positionnement, compteur 50M+, invite
   de defilement). Sans reserve, le titre remonte au centre exact de l'ecran
   et le hero se relit comme une page d'attente. Cette hauteur tient la
   place jusqu'a ce que quelque chose vienne la remplir.
   ========================================================================= */
.hero__void { min-height: clamp(6rem, 18vh, 12rem); }
@media (max-width: 760px) { .hero__void { min-height: clamp(4rem, 12vh, 7rem); } }

/* =========================================================================
   v62 — BANDEAU DU HERO
   Neuf tuiles 2:3, toutes de meme taille, entierement visibles : pas de
   defilement, pas de debordement. Le hero est en pleine largeur, le
   bandeau prend donc sa propre largeur maximale, plus large que le
   --container : a 1320px les tuiles tombent a 138px et les visages ne se
   lisent plus.
   ========================================================================= */
.bnd {
  --bnd-gap: clamp(0.4rem, 0.75vw, 0.75rem);
  display: grid;
  grid-template-columns: repeat(9, 1fr);
  gap: var(--bnd-gap);
  /* Le bandeau sort du --container (1320px) : a cette largeur les neuf
     tuiles tombent a 125px et les visages cessent de se lire. Il reprend
     donc la largeur de la fenetre, moins les gouttieres, plafonnee a
     1600px. left+translate le recentre sans marge negative, qui aurait
     provoque un debordement horizontal sur les petites fenetres. */
  width: min(1600px, 100vw - 2 * var(--gutter));
  margin: clamp(1.5rem, 3vw, 2.5rem) auto 0;
  position: relative;
  left: 50%;
  transform: translateX(-50%);
  list-style: none;
  padding: 0;
}
.bnd__i {
  position: relative;
  aspect-ratio: 2 / 3;
  border-radius: clamp(6px, 0.7vw, 12px);
  overflow: hidden;
  background: var(--surface);
  /* Un filet tres fin : sans lui, une photo a fond sombre se fond dans la
     page et la tuile disparait au lieu de faire partie d'une rangee. */
  box-shadow: inset 0 0 0 1px rgba(242, 240, 235, 0.08);
}
.bnd__img,
.bnd__team-img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}

/* --- La case equipe --------------------------------------------------- */
.bnd__team { position: relative; width: 100%; height: 100%; }
.bnd__team-img {
  position: absolute; inset: 0;
  opacity: 0;
  transition: opacity 0.55s var(--ease);
}
.bnd__team-img.is-on { opacity: 1; }

/* L'etiquette sert de bequille au noir et blanc : sur un ecran ou les sept
   portraits passent vite, elle nomme ce qu'on regarde. */
.bnd__tag {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 1.6rem 0.4rem 0.5rem;
  text-align: center;
  font-size: 0.625rem;
  letter-spacing: 0.16em;
  color: #F2F0EB;
  background: linear-gradient(180deg, rgba(10,11,13,0) 0%, rgba(10,11,13,0.78) 60%);
  pointer-events: none;
}
.bnd__i--team { box-shadow: inset 0 0 0 1px rgba(232, 197, 71, 0.55); }

/* --- Responsive -------------------------------------------------------
   Neuf tuiles sur une ligne cessent d'etre lisibles bien avant le mobile :
   a 900px chacune ferait 90px de large. On passe donc a 5 puis a 3 par
   ligne. La case equipe garde sa place dans le flux, elle n'est pas
   deplacee — l'ordre de lecture reste celui du desktop. */
@media (max-width: 1100px) {
  .bnd { grid-template-columns: repeat(5, 1fr); }
}
@media (max-width: 620px) {
  .bnd { grid-template-columns: repeat(3, 1fr); }
  .bnd__tag { font-size: 0.5625rem; letter-spacing: 0.1em; padding-top: 1.1rem; }
}

/* Mouvement reduit : la rotation s'arrete sur la premiere photo. Sept
   images qui se remplacent en boucle sont exactement ce que ce reglage
   systeme demande de suspendre. */
@media (prefers-reduced-motion: reduce) {
  .bnd__team-img { transition: none; }
}

/* =========================================================================
   v63 — PREUVE SOCIALE + AGRANDISSEMENT AU SURVOL
   ========================================================================= */

/* ---------- Bandeau des plateformes ---------- */
.trust {
  margin-top: clamp(1.75rem, 3.5vw, 2.75rem);
  text-align: center;
}
.trust__lead {
  color: var(--ash-dim);
  font-size: var(--fs-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.trust__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(2rem, 5vw, 4rem);
  margin-top: 1.25rem;
  list-style: none;
  padding: 0;
}
.trust__logo {
  /* Discret mais lisible : 26px de haut, la largeur suit le dessin. Les
     marques n'ont pas la meme masse optique a hauteur egale — les trois
     compensations ci-dessous les remettent au meme poids a l'oeil. */
  height: 28px;
  width: auto;
  display: block;
  opacity: 0.82;
  transition: opacity 0.3s var(--ease);
}
.trust__row:hover .trust__logo { opacity: 0.55; }
.trust__row .trust__i:hover .trust__logo { opacity: 1; }

/* Compensation optique */
.trust__logo--apple-music   { height: 26px; }   /* dessin plein, parait plus lourd */
.trust__logo--youtube-music { height: 30px; }   /* cercle ajoure, parait plus leger */
.trust__logo--tiktok        { height: 27px; }

@media (max-width: 620px) {
  .trust__row { gap: 1.5rem 2rem; }
  .trust__logo { height: 22px; }
  .trust__logo--apple-music { height: 20px; }
  .trust__logo--youtube-music { height: 24px; }
  .trust__logo--tiktok { height: 21px; }
}

/* ---------- Agrandissement de la vignette au survol ----------
   La tuile entiere grandit, pas seulement l'image : agrandir l'image dans
   un cadre fixe recadre la photo au lieu de la montrer. La grille passe donc
   en overflow visible et la tuile survolee monte d'un cran en z-index.

   L'origine de la transformation est deplacee sur les tuiles de bord : sans
   ca, la premiere sort par la gauche et la derniere par la droite, et le
   navigateur ajoute une barre de defilement horizontale. */
.bnd { overflow: visible; }
.bnd__i {
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
  will-change: transform;
}
@media (hover: hover) and (pointer: fine) {
  .bnd__i:hover {
    transform: scale(1.5);
    z-index: 5;
    box-shadow: inset 0 0 0 1px rgba(242, 240, 235, 0.16),
                0 18px 44px rgba(0, 0, 0, 0.55);
  }
  .bnd__i--team:hover {
    box-shadow: inset 0 0 0 1px rgba(232, 197, 71, 0.75),
                0 18px 44px rgba(0, 0, 0, 0.55);
  }
  .bnd__i:first-child:hover  { transform-origin: left center; }
  .bnd__i:last-child:hover   { transform-origin: right center; }
  .bnd__i:nth-child(2):hover { transform-origin: 25% center; }
  .bnd__i:nth-child(8):hover { transform-origin: 75% center; }
}
/* Sur les grilles repliees, ce sont d'autres tuiles qui touchent les bords. */
@media (hover: hover) and (max-width: 1100px) {
  .bnd__i:nth-child(2):hover, .bnd__i:nth-child(8):hover { transform-origin: center; }
  .bnd__i:nth-child(5n+1):hover { transform-origin: left center; }
  .bnd__i:nth-child(5n):hover   { transform-origin: right center; }
}
@media (hover: hover) and (max-width: 620px) {
  .bnd__i:nth-child(5n+1):hover, .bnd__i:nth-child(5n):hover { transform-origin: center; }
  .bnd__i:nth-child(3n+1):hover { transform-origin: left center; }
  .bnd__i:nth-child(3n):hover   { transform-origin: right center; }
}
@media (prefers-reduced-motion: reduce) {
  .bnd__i, .bnd__i:hover { transition: none; transform: none; }
}

/* =========================================================================
   v64 — BANDEAU DE COHERENCE REECRIT, CASE EQUIPE AGRANDIE,
         BANDEAU DE TEMOIGNAGES DEFILANT
   ========================================================================= */

/* ---------- §1 Bandeau de coherence : separateur point median ----------
   La regle de base met une fleche entre deux maillons. Une fleche raconte
   une sequence ("ceci mene a cela") ; le nouveau rail est une enumeration
   de quatre livrables. Le point median est monte a 1.1rem parce qu'a la
   taille du .mono (0.75rem) il disparait purement et simplement. */
.coh__chain--dots .coh__link + .coh__link::before {
  content: "\00B7";
  font-size: 1.1rem;
  line-height: 0;
  position: relative;
  top: 0.06em;
}

/* Les deux blocs restent aux deux extremites tant qu'ils tiennent sur une
   ligne — c'est la mise en page d'origine. Des qu'ils passent a la ligne,
   space-between colle la phrase a gauche et le rail a gauche aussi, et
   l'ensemble se lit de travers : ils sont alors centres tous les deux. */
@media (max-width: 760px) {
  .coh__inner { justify-content: center; text-align: center; }
  .coh__chain { justify-content: center; }
}

/* ---------- §2 Case equipe : +13 % ----------
   La rangee est une grille de neuf tuiles egales. Pour agrandir la seule
   tuile centrale sans provoquer de debordement horizontal, c'est la
   COLONNE qui s'elargit (1.13fr contre 1fr) : les huit autres se
   repartissent la difference, la somme des colonnes reste 100 %.

   Consequence voulue : `aspect-ratio: 2/3` rend la tuile centrale plus
   HAUTE en meme temps que plus large. La rangee grandit donc en hauteur et
   les huit autres tuiles, qui ne s'etirent plus (`align-items: center`),
   se centrent verticalement. La case equipe depasse en haut et en bas :
   c'est exactement ce qui la fait ressortir. */
.bnd {
  grid-template-columns: repeat(4, 1fr) 1.13fr repeat(4, 1fr);
  align-items: center;
}
.bnd__i--team {
  z-index: 2;
  box-shadow: inset 0 0 0 1px rgba(232, 197, 71, 0.55),
              0 14px 36px rgba(0, 0, 0, 0.5);
}

/* 5 colonnes : 9 tuiles se repartissent en 5 + 4. La case equipe est la
   cinquieme, donc seule occupante de la colonne 5 — l'elargir n'affecte
   aucune autre tuile. */
@media (max-width: 1100px) {
  .bnd { grid-template-columns: repeat(4, 1fr) 1.13fr; }
}

/* 3 colonnes : la colonne 2 contient les tuiles 2, 5 ET 8. L'elargir en
   agrandirait trois au lieu d'une. On repasse donc en colonnes egales et
   c'est la tuile elle-meme qui deborde de sa colonne, recentree par des
   marges negatives. Volontairement en width/margin et non en `transform` :
   un transform serait annule par la regle `prefers-reduced-motion` de la
   v63, qui remet `transform: none` sur toutes les tuiles. */
@media (max-width: 620px) {
  .bnd { grid-template-columns: repeat(3, 1fr); }
  .bnd__i--team { width: 112%; margin-inline: -6%; }
}

/* Le libelle passe de 8 a 19 caracteres : deux lignes en desktop, trois au
   pire en 3 colonnes. Le degrade de fond doit donc monter plus haut, sinon
   la premiere ligne se retrouve sur la photo nue et devient illisible. */
.bnd__tag {
  line-height: 1.3;
  padding-top: 2.5rem;
}
@media (max-width: 620px) {
  .bnd__tag { padding-top: 1.6rem; letter-spacing: 0.06em; }
}

/* ---------- §3 Bandeau de temoignages ----------
   Pas de bordure haute : le .coh qui le precede porte deja la sienne en
   bas. Deux filets adjacents donneraient un trait de 2px la ou tout le
   reste de la page est a 1px. */
.tst {
  --tst-gap: clamp(2.25rem, 4vw, 3.5rem);
  --tst-dur: 78s;
  border-bottom: 1px solid var(--line);
  padding-block: clamp(1.1rem, 2.2vw, 1.6rem);
  overflow: hidden;
}

/* Le fondu sur les bords evite que les vignettes n'apparaissent et ne
   disparaissent par une coupe nette au ras de la fenetre. */
.tst__viewport {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
}

.tst__track {
  display: flex;
  align-items: center;
  width: max-content;
  margin: 0;
  padding: 0;
  list-style: none;
  animation: tst-scroll var(--tst-dur) linear infinite;
  will-change: transform;
}

/* -50 % = exactement une copie, a condition que l'ecart soit porte par
   chaque vignette (margin-right, y compris la derniere) et non par un
   `gap` sur la piste. Voir le commentaire dans index.html. */
@keyframes tst-scroll {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

.tst__i {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 0.875rem;
  margin-right: var(--tst-gap);
}

.tst__av {
  width: clamp(44px, 4vw, 56px);
  height: clamp(44px, 4vw, 56px);
  border-radius: 50%;
  display: block;
  flex: 0 0 auto;
  /* Le filet remplace l'anneau de story des captures d'origine, qui a ete
     retire : sans lui, une photo a fond sombre n'a plus de bord du tout. */
  box-shadow: inset 0 0 0 1px rgba(242, 240, 235, 0.14),
              0 0 0 1px rgba(242, 240, 235, 0.10);
  transition: box-shadow 0.3s var(--ease);
}

.tst__body { max-width: 34ch; }

.tst__name {
  display: block;
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  color: var(--ash-dim);
  white-space: nowrap;
  transition: color 0.3s var(--ease);
}

.tst__quote {
  margin: 0.2rem 0 0;
  font-family: var(--body);
  font-size: 0.875rem;
  line-height: 1.45;
  color: var(--bone);
  text-wrap: balance;
}

/* Survol : la piste s'arrete, et la vignette visee reprend du contraste.
   Sans la pause, un temoignage qui accroche l'oeil est deja parti quand on
   finit de le lire. Sur ecran tactile il n'y a pas de survol : la piste ne
   s'arrete jamais, ce qui est le comportement attendu. */
@media (hover: hover) and (pointer: fine) {
  .tst:hover .tst__track { animation-play-state: paused; }
  .tst__i:hover .tst__name { color: var(--ash); }
  .tst__i:hover .tst__av {
    box-shadow: inset 0 0 0 1px rgba(242, 240, 235, 0.2),
                0 0 0 1px rgba(232, 197, 71, 0.55);
  }
}

/* Mouvement reduit : la piste s'immobilise et devient defilable a la main.
   La seconde copie est retiree — elle n'existe que pour la boucle, et un
   defilement manuel sur du contenu double serait deroutant. */
@media (prefers-reduced-motion: reduce) {
  .tst__track { animation: none; width: auto; }
  .tst__i--dup { display: none; }
  .tst__viewport { overflow-x: auto; scrollbar-width: none; }
  .tst__viewport::-webkit-scrollbar { display: none; }
  /* La piste demarre a zero au lieu de defiler : le fondu de gauche
     mangerait la premiere vignette en permanence. Seul celui de droite
     reste, il annonce qu'il y a la suite. */
  .tst__viewport {
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 95%, transparent 100%);
            mask-image: linear-gradient(90deg, #000 0, #000 95%, transparent 100%);
  }
}

@media (max-width: 620px) {
  .tst { --tst-dur: 56s; }
  .tst__quote { font-size: 0.8125rem; }
  .tst__body { max-width: 30ch; }
}

/* =========================================================================
   v65 — SECTION "WHAT READY RELEASE IS" (modele SoftRiver) + CTA DU HERO
   ========================================================================= */

/* ---------- CTA du hero ----------
   `hero__actions--reserved` portait `pointer-events: none` : la classe est
   remplacee, pas completee. Le bouton est centre parce que tout le hero
   l'est (`hero--centered`), et la marge haute reprend celle de la reserve
   d'origine pour que rien ne se recompose au-dessus. */
.hero__actions--cta {
  justify-content: center;
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
}
/* Un fantome sur fond sombre passe inapercu a cet endroit precis : le hero a
   une video derriere lui, et une bordure a 18 % d'opacite disparait sur les
   images claires de la boucle. Le fond translucide + le flou garantissent le
   contraste quelle que soit l'image du moment, sans passer au bouton plein
   qui, lui, ferait doublon avec les CTA de commande plus bas. */
.hero__cta {
  --pad-y: 0.95rem; --pad-x: 1.9rem;
  background: rgba(10, 11, 13, 0.55);
  -webkit-backdrop-filter: blur(8px);
          backdrop-filter: blur(8px);
  border-color: rgba(242, 240, 235, 0.28);
}
.hero__cta:hover {
  background: rgba(10, 11, 13, 0.75);
  border-color: var(--bone);
}

/* ---------- Section SoftRiver ---------- */
.swr {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.82fr);
  gap: clamp(2.5rem, 6vw, 6rem);
  align-items: center;
}

/* Le paragraphe est un h2 : la mise en forme de titre par defaut est donc
   remise a plat, sinon il arrive en --fs-h2 (jusqu'a 4,25rem) alors que le
   modele demande un corps de paragraphe large, pas un titre de section. */
.swr__lead {
  margin: 0;
  font-family: var(--display);
  font-weight: 500;
  /* Le modele tient son paragraphe en trois lignes sur un conteneur de
     ~1800 px ; le notre fait 1320 px. A taille absolue egale, le meme texte
     passait a quatre lignes. La taille RELATIVE du modele (~1,95vw) est
     donc ce qui a ete repris, pas sa taille en pixels : c'est ce qui rend
     les trois lignes, mesure a 2,15rem au plafond. */
  font-size: clamp(1.5rem, 2.35vw, 2.15rem);
  line-height: 1.28;
  letter-spacing: -0.018em;
  color: var(--bone);
  /* Le modele tient le paragraphe en trois lignes. A 20ch il en faisait
     cinq, ce qui le fait basculer du cote "titre empile" au lieu du cote
     "paragraphe large" : 30ch donne 47 a 49 signes par ligne, soit la
     longueur de ligne du modele. La contrainte reelle vient de la colonne
     de grille (616 px mesures) ; ce plafond ne sert que sur les tres
     grandes fenetres, ou la colonne devient plus large que la ligne utile. */
  max-width: 34ch;
}
/* <b> et non <span> : le mot est mis en evidence, pas seulement colore.
   font-weight remis a l'identique pour que la couleur soit le seul signal —
   une graisse en plus ferait deux accents concurrents sur le meme mot. */
.swr__kw { font-weight: inherit; color: var(--signal); }

/* Remplissage colonne par colonne : trois rangees, le flux descend puis
   passe a droite. C'est ce qui permet a l'ordre du DOM d'etre 1-2-3-4-5-6,
   donc l'ordre de lecture a l'ecran ET pour un lecteur d'ecran. */
.swr__grid {
  display: grid;
  grid-auto-flow: column;
  grid-template-rows: repeat(3, auto);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(1.5rem, 3.5vw, 3.25rem);
  margin: clamp(2.5rem, 5vw, 4rem) 0 0;
  padding: 0;
  list-style: none;
}
.swr__i {
  font-family: var(--body);
  font-size: clamp(0.9375rem, 1.05vw, 1.0625rem);
  line-height: 1.4;
  color: var(--bone);
  padding-block: clamp(0.85rem, 1.5vw, 1.15rem);
  border-bottom: 1px solid var(--line);
}
/* Le filet du haut n'existe que sur les deux premiers : le modele ferme
   chaque point par une ligne basse, et une ligne haute sur les six
   donnerait des doubles filets entre les rangees. */
.swr__i:nth-child(1),
.swr__i:nth-child(4) { padding-top: 0; }

/* ---------- Le cadre de droite ---------- */
.swr__fig { margin: 0; }
.swr__img,
.swr__ph {
  display: block;
  width: 100%;
  /* 4:3 et non un portrait : le modele place un cadre paysage. En 4:5 le
     cadre imposait a la section une hauteur ou la colonne de texte flottait
     au milieu de deux grands vides. */
  aspect-ratio: 4 / 3;
  border-radius: clamp(14px, 1.4vw, 22px);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
}
.swr__img { object-fit: cover; }

/* Le remplacant doit se voir comme un remplacant : hachures et chemin du
   fichier. Une zone grise unie se confond avec une image qui n'a pas
   charge, et personne ne saurait qu'il manque quelque chose. */
.swr__ph {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  text-align: center;
  padding: 1.5rem;
  background:
    repeating-linear-gradient(135deg,
      rgba(242, 240, 235, 0.035) 0 10px,
      transparent 10px 20px),
    var(--surface);
  box-shadow: inset 0 0 0 1px var(--line-strong),
              0 24px 60px rgba(0, 0, 0, 0.55);
}
.swr__ph-tag { color: var(--ash); font-size: 0.6875rem; letter-spacing: 0.16em; }
.swr__ph-path {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  color: var(--ash-dim);
}

/* Sous 980 px la colonne de texte descend a une largeur ou le paragraphe
   casse en lignes de trois mots. Les deux colonnes passent l'une sous
   l'autre, le visuel en premier — c'est lui qui tient l'attention sur un
   ecran ou l'on ne voit qu'un bloc a la fois. */
@media (max-width: 980px) {
  .swr { grid-template-columns: minmax(0, 1fr); gap: clamp(2rem, 5vw, 3rem); }
  .swr__lead { max-width: 24ch; }
  .swr__fig { order: -1; }
  .swr__img, .swr__ph { aspect-ratio: 16 / 10; }
}

/* En une seule colonne, le remplissage par colonne n'a plus de sens : on
   repasse en flux normal, l'ordre du DOM (1 a 6) devient l'ordre affiche. */
@media (max-width: 720px) {
  .swr__grid {
    grid-auto-flow: row;
    grid-template-rows: auto;
    grid-template-columns: minmax(0, 1fr);
  }
  .swr__i:nth-child(4) { padding-top: clamp(0.85rem, 1.5vw, 1.15rem); }
}

/* =========================================================================
   v66 — CTA DU HERO, COMPARAISON, CINQ BENEFICES
   ========================================================================= */

/* ---------- Le bouton du hero ----------
   Consigne : plus grand, forme affirmee, contraste maximal, hover vivant.
   Sans le blanc plein, reserve au parcours de commande : le contraste vient
   du fond opaque (et non plus translucide a 55 %, qui laissait la video
   traverser le bouton) et d'une bordure a pleine opacite. */
.hero__cta--strong {
  --pad-y: 1.15rem; --pad-x: 2.5rem;
  background: var(--void);
  -webkit-backdrop-filter: none;
          backdrop-filter: none;
  border: 2px solid var(--bone);
  /* Le systeme est anguleux partout (--radius-s = 4px). Un bouton en pilule
     aurait ete la seule forme arrondie de la page : plus doux, pas plus
     affirme. */
  border-radius: var(--radius-s);
  color: var(--bone);
  font-family: var(--caps);
  font-weight: 700;
  font-size: clamp(0.95rem, 1.15vw, 1.0625rem);
  letter-spacing: 0.01em;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.55);
}
.hero__cta--strong:hover,
.hero__cta--strong:focus-visible {
  background: rgba(242, 240, 235, 0.14);
  border-color: var(--bone);
  transform: translateY(-3px);
  box-shadow: 0 20px 52px rgba(0, 0, 0, 0.65);
}
.hero__cta--strong .btn__arrow { margin-left: 0.15rem; }

/* La cible du bouton. Le header est colle en haut : sans marge de defilement,
   l'ancre arrive sous la barre et le titre de la section est mange. */
#release-map { scroll-margin-top: 6.5rem; }
@media (max-width: 720px) { #release-map { scroll-margin-top: 5rem; } }

/* ---------- Comparaison ---------- */
.cmp__head { text-align: center; max-width: 56ch; margin-inline: auto; }
.cmp__proof {
  display: inline-flex; align-items: center; gap: 0.55rem;
  margin-bottom: clamp(1.1rem, 2vw, 1.6rem);
}
.cmp__stars { display: inline-flex; gap: 2px; color: #F5B942; }
.cmp__stars svg { fill: currentColor; }
.cmp__proof-t {
  font-family: var(--caps);
  font-size: var(--fs-micro);
  letter-spacing: 0.08em;
  color: var(--ash);
}
.cmp__t {
  font-size: var(--fs-h2);
  max-width: 18ch;
  margin-inline: auto;
  text-wrap: balance;
}
.cmp__sub {
  margin-top: clamp(0.9rem, 1.6vw, 1.25rem);
  font-size: var(--fs-lead);
  color: var(--ash);
  max-width: 44ch;
  margin-inline: auto;
  text-wrap: balance;
}

.cmp__cols {
  margin-top: clamp(2.5rem, 6vw, 4.5rem);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.25rem, 4vw, 3.5rem);
  max-width: 940px;
  margin-inline: auto;
  align-items: center;
}
.cmp__col-t {
  font-family: var(--caps);
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin-bottom: clamp(1.1rem, 2.2vw, 1.6rem);
}
.cmp__col--old .cmp__col-t { color: var(--ash-dim); }
.cmp__col--rr  .cmp__col-t { color: var(--bone); }

.cmp__list { display: grid; gap: clamp(0.85rem, 1.6vw, 1.15rem); }
.cmp__li {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  align-items: center;
  gap: 0.85rem;
  font-size: clamp(1rem, 1.35vw, 1.1875rem);
  line-height: 1.35;
}
.cmp__col--old .cmp__li { color: var(--ash); }
.cmp__col--rr  .cmp__li { color: var(--bone); }

.cmp__x {
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  justify-self: center;
  border-radius: 50%;
  background: rgba(242, 240, 235, 0.06);
  color: var(--ash-dim);
}
/* La marque en pastille. Les lunettes sont larges (2,1:1) : c'est la LARGEUR
   qui est fixee, la hauteur suit, sinon le trait s'epaissit d'une ligne a
   l'autre selon la casse du texte a cote. */
.cmp__mark {
  width: 34px; height: auto;
  justify-self: center;
}

@media (max-width: 720px) {
  .cmp__cols { grid-template-columns: minmax(0, 1fr); gap: 2.25rem; }
  .cmp__t { max-width: none; }
}

/* ---------- Les cinq benefices ----------
   Cartes claires sur fond sombre. Le gris des cartes est celui du visuel
   fourni (#F5F5F5) : les tuiles d'icones emportent ce fond, toute autre
   valeur ferait apparaitre un carre plus clair au milieu de la carte. */
.ben__grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(0.75rem, 1.6vw, 1.5rem);
}
.ben__card {
  background: #F5F5F5;
  border-radius: clamp(14px, 1.6vw, 22px);
  padding: clamp(1.1rem, 2vw, 1.75rem) clamp(0.75rem, 1.4vw, 1.25rem) clamp(1.5rem, 2.6vw, 2.25rem);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: clamp(0.9rem, 1.8vw, 1.4rem);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
}
.ben__icon {
  width: clamp(88px, 8vw, 120px);
  height: auto;
  border-radius: 12px;
}
/* Le visuel d'origine ecrit les libelles en blanc sur ce gris : illisible
   des qu'on quitte la capture. Le texte est repris en gris fonce, seul
   changement par rapport au visuel fourni. Voir CHANGELOG-v66.md §5. */
.ben__t {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(0.9375rem, 1.15vw, 1.0625rem);
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: #2A2C30;
}

@media (max-width: 1080px) {
  .ben__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .ben__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ben__card:last-child { grid-column: 1 / -1; }
}

/* ---------- v66.1 — le cadre photo ne fabrique plus la hauteur ----------
   Le cadre etait en 4:3 : c'est LUI qui imposait la hauteur de la rangee,
   la colonne de texte flottait au milieu, et la section gagnait plusieurs
   centaines de pixels de noir pour rien.

   Inversion : la rangee est mesuree par le TEXTE seul. L'image est sortie du
   flux (`position: absolute`) — un element hors flux ne compte pas dans le
   calcul de la hauteur — et `align-items: stretch` la fait remplir la
   hauteur ainsi obtenue. Elle ne peut donc plus depasser ni en haut ni en
   bas, quelle que soit la largeur de l'ecran.

   Le fichier source est reexporte en 16:9 : la coupe finale est faite par
   `object-fit: cover`, mais partir d'un 4:3 aurait fait perdre a `cover`
   soit la source de lumiere, soit le mur de mains.

   Sous 981 px les deux colonnes sont l'une sous l'autre : plus de texte a
   cote, donc rien a aligner. La regle 16:10 deja en place reprend la main,
   ce bloc ne s'y applique pas. */
@media (min-width: 981px) {
  .swr { align-items: stretch; }
  .swr__fig {
    position: relative;
    min-height: 280px;   /* garde-fou : ne remonte la rangee que si le texte
                            devenait anormalement court */
  }
  .swr__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    aspect-ratio: auto;  /* annule le 4:3 : la hauteur vient du texte */
    object-fit: cover;
    object-position: 50% 45%;
  }
}

/* =========================================================================
   v67 — RESPIRATION DES SECTIONS, CTA DU HERO, BANDEAU DEFILANT
   ========================================================================= */

/* ---------- §1 La zone noire entre « What Ready Release is » et la
   comparaison ----------
   Les deux sections portent chacune `padding-block: var(--section-y)`, soit
   jusqu'a 11rem. Empilees, elles fabriquaient jusqu'a 22rem de noir sans
   rien dedans : le visiteur perdait le fil entre la photo et la ligne
   « Trusted by independent artists ». Les deux marges qui se font face sont
   reduites, celles de l'autre cote de chaque section ne bougent pas — le
   rythme du reste de la page est intact. */
.swr { padding-bottom: clamp(2.25rem, 4.5vw, 4rem); }
.cmp { padding-top:    clamp(2.25rem, 4.5vw, 4rem); }

/* ---------- §2 Le CTA du hero remonte ----------
   Le libelle passe a « See what makes the difference », en gras. La
   destination ne change pas (#release-map).
   Les marges hautes du bouton et du bandeau de plateformes sont reduites :
   c'est tout le bas du hero qui remonte d'un bloc, sans qu'aucun element ne
   change de place les uns par rapport aux autres. */
.hero__actions--cta { margin-top: clamp(0.7rem, 1.4vw, 1.15rem); }
.hero__cta--strong strong { font-weight: 800; }
.trust { margin-top: clamp(0.85rem, 1.7vw, 1.35rem); }

/* ---------- §3 Le bandeau : huit vignettes qui defilent derriere une case
   centrale fixe ----------
   La grille de neuf tuiles est remplacee par un rail continu. `display:
   block` suffit a neutraliser toutes les regles `grid-template-columns` des
   versions precedentes, qui restent inertes sans etre supprimees.

   Pleine largeur d'ecran : le bandeau sort du conteneur par le couple
   left:50% / translateX(-50%). Un debordement horizontal de la largeur de
   la barre de defilement est possible sur Windows (100vw la compte, pas
   `100%`) ; `overflow-x: hidden` sur le body, deja en place, l'absorbe.

   La hauteur : la case centrale fait 1,5x la largeur d'une vignette, donc
   2,25x sa hauteur en 2/3. Elle depasse de 0,375 largeur en haut et en bas
   — d'ou le padding vertical, calcule pour que le bandeau reserve
   exactement la place qu'elle prend, sans rogner ni sur le hero ni sur la
   section suivante. */
.bnd--flow {
  --bnd-tw: clamp(92px, 9vw, 168px);
  --bnd-gap: clamp(0.4rem, 0.75vw, 0.75rem);
  display: block;
  position: relative;
  width: 100vw;
  max-width: 100vw;
  left: 50%;
  transform: translateX(-50%);
  margin: clamp(1.1rem, 2.4vw, 2rem) 0 0;
  padding-block: calc(var(--bnd-tw) * 0.375);
  list-style: none;
}
/* C'est le rail qui coupe, pas le bandeau : la case centrale est en dehors
   du rail et doit pouvoir depasser en hauteur sans etre rognee. */
.bnd__rail { overflow: hidden; }
.bnd__track {
  display: flex;
  width: max-content;
  margin: 0; padding: 0;
  list-style: none;
  animation: bnd-flow 40s linear infinite;
  will-change: transform;
}
@keyframes bnd-flow {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
.bnd--flow .bnd__i {
  flex: 0 0 auto;
  width: var(--bnd-tw);
  margin-right: var(--bnd-gap);   /* et non `gap` : voir le commentaire du HTML */
}
.bnd__center {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  z-index: 3;
  width: calc(var(--bnd-tw) * 1.5);
}
/* Le fond opaque est ce qui fait la disparition : sans lui, les vignettes se
   verraient par transparence au lieu de passer derriere. */
.bnd--flow .bnd__center .bnd__i {
  width: 100%;
  margin: 0;
  background: var(--void);
}

/* Les tuiles bougent : un survol qui les agrandit se declencherait et se
   perdrait en permanence sous le curseur. Il est neutralise ici seulement,
   la grille des autres pages garde le sien. */
@media (hover: hover) and (pointer: fine) {
  .bnd--flow .bnd__i:hover { transform: none; box-shadow: inset 0 0 0 1px rgba(242, 240, 235, 0.08); }
  .bnd--flow .bnd__i--team:hover {
    box-shadow: inset 0 0 0 1px rgba(232, 197, 71, 0.75),
                0 14px 36px rgba(0, 0, 0, 0.5);
  }
}
/* La v64 elargissait la case equipe a 112 % sous 620px pour la faire
   deborder de sa colonne de grille. Il n'y a plus de grille : la regle
   decalerait la case de son axe. */
@media (max-width: 620px) {
  .bnd--flow .bnd__i--team { width: 100%; margin-inline: 0; }
}
/* Un defilement infini est exactement ce que ce reglage systeme demande de
   suspendre. Les vignettes restent en place, la case centrale aussi. */
@media (prefers-reduced-motion: reduce) {
  .bnd__track { animation: none; }
}

/* =========================================================================
   v67.1 — SECTION DE COMPARAISON : TEXTES AGRANDIS ET RECENTRES
   ========================================================================= */

/* La hierarchie demandee : le sous-titre gris reste plus grand que les
   listes du bas, et les deux montent d'environ un facteur deux. Le h2
   au-dessus n'est pas touche — il est deja a 4,25rem, le doubler le ferait
   sortir de l'ecran. Les bornes basses des clamp sont calculees pour qu'il
   reste plus grand que le sous-titre a TOUTES les largeurs : sans ca, sous
   400px, le h2 (min 2rem) passait sous un sous-titre double. */
.cmp__sub {
  font-size: clamp(1.5rem, 3vw, 2.5rem);   /* etait clamp(1.05, 1.6vw, 1.35) */
  line-height: 1.3;
  max-width: 26ch;
}

/* Les deux colonnes reprennent toute la largeur du conteneur : a 2,125rem,
   « Sound that still feels like a demo » ne tient plus dans une colonne de
   470px, et la ligne cassait en deux. */
.cmp__cols {
  max-width: none;
  gap: clamp(1.5rem, 4vw, 3.5rem);
}

/* Le recentrage. Avant, chaque colonne etait collee a gauche de sa moitie :
   la colonne de droite, plus courte que sa colonne, laissait un vide a
   droite et l'ensemble se lisait decale vers la gauche. Chaque colonne
   devient une pile centree, et la liste garde sa largeur naturelle
   (`fit-content`) — les puces restent alignees entre elles, c'est le bloc
   entier qui se centre. Aligner le TEXTE au centre aurait desaligne les
   debuts de ligne les uns par rapport aux autres. */
.cmp__col {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.cmp__col-t {
  font-size: clamp(0.9375rem, 1.2vw, 1.25rem);
  letter-spacing: 0.12em;
  margin-bottom: clamp(1.4rem, 2.6vw, 2.1rem);
}
.cmp__list {
  width: -moz-fit-content;
  width: fit-content;
  gap: clamp(1rem, 1.9vw, 1.5rem);
}
.cmp__li {
  font-size: clamp(1.3rem, 2.4vw, 2.125rem);   /* etait clamp(1, 1.35vw, 1.1875) */
  grid-template-columns: clamp(40px, 3.6vw, 58px) minmax(0, 1fr);
  gap: clamp(0.85rem, 1.3vw, 1.15rem);
}

/* Les pastilles suivent le texte : a 34px de large sous une ligne de 34px,
   la marque devenait un detail au lieu d'une puce. */
.cmp__x {
  width: clamp(30px, 2.6vw, 40px);
  height: clamp(30px, 2.6vw, 40px);
}
.cmp__x svg { width: 62%; height: 62%; }
.cmp__mark { width: clamp(38px, 3.4vw, 56px); }

/* =========================================================================
   v68 — CE QUE CONTIENT UNE RELEASE : SEPT LIVRABLES
   Le bloc de sortie precedent (.home-next) n'est plus utilise sur la home.
   Ses regles restent en place, inertes, comme .home-offer depuis la v66 :
   les retirer est un nettoyage a faire en une passe dediee, avec
   verification des autres pages.
   ========================================================================= */

/* Le titre est volontairement etroit (24ch) et la phrase large (52ch) :
   ce contraste de mesure fait lire l'un comme un titre et l'autre comme un
   appui, avant meme la difference de taille. */
.dlv__head {
  text-align: center;
  margin-bottom: clamp(3rem, 6vw, 5.5rem);
}
.dlv__ht {
  font-size: var(--fs-h2);
  max-width: 24ch;
  margin-inline: auto;
  text-wrap: balance;
}
.dlv__hs {
  margin: clamp(1.1rem, 2vw, 1.6rem) auto 0;
  max-width: 52ch;
  font-size: var(--fs-lead);
  color: var(--ash);
  line-height: 1.55;
  text-wrap: balance;
}

/* ---------- La grille : 2 / 3 / 2 ----------
   Six colonnes de base. Les deux premieres cartes en prennent 3, les trois
   suivantes 2, les deux dernieres 3. La hauteur d'image ne depend pas de la
   largeur de la carte : elle est fixee, donc les trois rangees s'alignent
   au pixel malgre des proportions differentes. C'est exactement ce qui fait
   tenir le rythme de la reference. */
.dlv__grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  column-gap: clamp(1.25rem, 2.4vw, 2.25rem);
  row-gap: clamp(2.75rem, 5vw, 4.5rem);
  list-style: none;
  margin: 0; padding: 0;
}
.dlv__i:nth-child(-n+2)               { grid-column: span 3; }
.dlv__i:nth-child(n+3):nth-child(-n+5) { grid-column: span 2; }
.dlv__i:nth-child(n+6)                { grid-column: span 3; }

.dlv__img,
.dlv__ph {
  display: block;
  width: 100%;
  height: clamp(200px, 21vw, 360px);
  border-radius: clamp(10px, 1.1vw, 18px);
  object-fit: cover;
}

/* Le remplacant doit se lire comme un emplacement tenu, pas comme une image
   qui n'a pas charge : fond de la meme famille que les surfaces du site,
   halo bleu tres bas, filet interieur, et le jeton d'implantation ecrit en
   clair. Pas de hachures ici — a cette taille et repete sept fois, le motif
   devient le sujet de la section. */
.dlv__ph {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(120% 90% at 50% 0%,
      rgba(232, 197, 71, 0.10) 0%,
      rgba(232, 197, 71, 0) 62%),
    linear-gradient(180deg, var(--surface-2) 0%, var(--surface) 100%);
  box-shadow: inset 0 0 0 1px var(--line),
              0 18px 44px rgba(0, 0, 0, 0.45);
}
.dlv__ph-n {
  position: absolute;
  top: clamp(0.75rem, 1.2vw, 1.1rem);
  left: clamp(0.85rem, 1.3vw, 1.25rem);
  font-family: var(--heavy);
  font-weight: 800;
  font-size: clamp(0.75rem, 0.95vw, 0.875rem);
  letter-spacing: 0.06em;
  color: var(--ash-dim);
}
.dlv__ph-tag {
  font-size: clamp(0.625rem, 0.85vw, 0.75rem);
  letter-spacing: 0.18em;
  color: var(--ash);
  text-align: center;
  padding-inline: 1rem;
}

.dlv__t {
  margin-top: clamp(1.1rem, 1.9vw, 1.6rem);
  font-size: clamp(1.15rem, 1.7vw, 1.5rem);
  letter-spacing: -0.015em;
  line-height: 1.2;
}
.dlv__d {
  margin-top: clamp(0.5rem, 0.9vw, 0.75rem);
  font-size: clamp(0.9375rem, 1.05vw, 1.0625rem);
  line-height: 1.55;
  color: var(--ash);
  max-width: 44ch;
}

/* ---------- Le CTA de fin ---------- */
.dlv__cta {
  margin-top: clamp(3.5rem, 7vw, 6rem);
  text-align: center;
}
.dlv__cta-t { font-size: var(--fs-h3); }
.dlv__cta-p {
  margin-top: 0.85rem;
  color: var(--ash);
  font-size: var(--fs-lead);
}
.dlv__cta-a { margin-top: clamp(1.5rem, 2.6vw, 2.25rem); }

/* ---------- Tablette : deux colonnes egales ----------
   Les spans de la grille a six colonnes sont remis a plat un par un, sans
   `!important` : les selecteurs sont les memes, la media query gagne parce
   qu'elle vient apres. */
@media (max-width: 1000px) {
  .dlv__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dlv__i:nth-child(-n+2),
  .dlv__i:nth-child(n+3):nth-child(-n+5),
  .dlv__i:nth-child(n+6) { grid-column: span 1; }
  /* Sept cartes sur deux colonnes : la septieme est seule sur sa ligne.
     Elle prend toute la largeur plutot que de rester orpheline a gauche. */
  .dlv__i:last-child { grid-column: 1 / -1; }
  .dlv__i:last-child .dlv__d { max-width: 60ch; }
}

@media (max-width: 620px) {
  .dlv__grid { grid-template-columns: minmax(0, 1fr); row-gap: clamp(2.25rem, 7vw, 3rem); }
  .dlv__i:last-child { grid-column: auto; }
  .dlv__img, .dlv__ph { height: clamp(190px, 52vw, 260px); }
  .dlv__d { max-width: none; }
}


/* =========================================================================
   v70 — DECLARATION DE MARQUE, HAUT DE LA COMPARAISON, HIERARCHIE DES
         DEUX COLONNES, BENEFICES SANS CARTES
   Tout est ajoute EN FIN DE FICHIER et gagne par l'ordre de cascade : aucune
   regle des versions precedentes n'est reecrite ni supprimee, y compris
   celles devenues inertes (.cmp__proof, .ben__card gris). Rien de nouveau
   n'est introduit dans la palette : --void, --bone, --ash, --ash-dim,
   --signal, --line et --ease seulement.
   ========================================================================= */

/* -------------------------------------------------------------------------
   §2 — LA DECLARATION DE MARQUE SOUS LE BANDEAU
   La zone passe de ligne courante a statement. Trois leviers : la taille
   (elle triple), la coupe en deux lignes, et le contraste entre les deux
   moities de la promesse. La bande garde ses deux filets et son absence de
   fond : elle separe toujours deux sections, elle n'en cree pas une
   troisieme.
   ------------------------------------------------------------------------- */
.coh:has(.coh__inner--stmt) {
  padding-block: clamp(3rem, 7vw, 6rem);
}
/* Repli pour les moteurs sans :has() — la valeur y est simplement la
   valeur de base de la v64, la section reste lisible, juste plus serree. */
@supports not selector(:has(*)) {
  .coh { padding-block: clamp(2.25rem, 5vw, 4rem); }
}

.coh__inner--stmt {
  align-items: flex-end;
  /* Deux gouttieres distinctes. Horizontalement la phrase et le rail sont
     largement separes ; verticalement, quand le rail passe a la ligne, 4rem
     de vide entre les deux le detacheraient de la declaration au lieu de la
     signer. */
  gap: clamp(1rem, 1.8vw, 1.75rem) clamp(1.5rem, 4vw, 4rem);
}
.coh__line--stmt {
  font-weight: 600;
  font-size: clamp(1.75rem, 5.6vw, 4.5rem);
  line-height: 1.06;
  letter-spacing: -0.03em;
  max-width: 20ch;
  text-wrap: balance;
}
/* La coupe est portee par le passage en display:block et non par un <br> :
   sous 760px la composition passe naturellement a trois lignes, ce qu'un
   <br> aurait empeche. */
.coh__l1,
.coh__l2 { display: block; }
.coh__l1 { color: var(--ash); font-weight: 500; }
/* Le point d'ancrage. La deuxieme moitie ne change ni de police ni de
   couleur de base : elle gagne du poids et passe au blanc plein, le reste
   de la phrase recule en gris. Le contraste fait le travail, pas un
   degrade. */
.coh__l2 { color: var(--bone); font-weight: 800; }

/* La navigation secondaire reste secondaire : elle ne grandit pas, elle
   gagne seulement en contraste et en interlettrage. */
/* `space-between` ne tient que tant que les deux blocs sont sur la MEME
   ligne. Des que le rail passe a la ligne — ce qui arrive des le desktop,
   la declaration faisant pres de 1000px a sa taille maximale — il se
   retrouve seul sur sa ligne et space-between le colle a gauche. La marge
   automatique le maintient a droite dans les deux cas. */
.coh__inner--stmt .coh__chain {
  gap: 0.35rem 0.75rem;
  padding-bottom: 0.35rem;
  margin-left: auto;
}
.coh__inner--stmt .coh__link .mono { color: var(--ash); letter-spacing: 0.14em; }
.coh__inner--stmt .coh__link--end .mono { color: var(--bone); font-weight: 700; }

/* ---- Animation d'entree ----
   L'observateur est celui de main.js : la classe `reveal` est deja posee
   sur le conteneur, .is-in arrive quand la zone entre dans le viewport et
   l'observation est levee — l'animation ne se rejoue jamais.

   `.reveal` fait deja monter le bloc entier. Ici on ne rajoute PAS un
   second deplacement du meme bloc : les enfants ne bougent qu'en opacite
   et sur quelques pixels, decales dans le temps. C'est ce qui donne la
   revelation en trois temps sans que quoi que ce soit ne saute. */
.coh__inner--stmt .coh__l1,
.coh__inner--stmt .coh__l2,
.coh__inner--stmt .coh__link {
  opacity: 0;
  transform: translateY(10px);
}
.coh__inner--stmt.is-in .coh__l1 { animation: coh-rise 0.85s var(--ease) 0.05s both; }
.coh__inner--stmt.is-in .coh__l2 { animation: coh-rise 0.85s var(--ease) 0.28s both; }
.coh__inner--stmt.is-in .coh__link {
  animation: coh-rise 0.6s var(--ease) calc(0.85s + var(--s) * 0.09s) both;
}
@keyframes coh-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* Le « flash ». Un seul passage, une seule fois, apres que la phrase soit
   posee : la luminosite monte brievement et redescend. Ce n'est PAS un
   clignotement — la sequence ne boucle pas et la valeur de repos est
   l'etat final. `filter` est le seul moyen d'obtenir le coup de lumiere
   sans repeindre le texte ; il est isole sur cette ligne et dure 0,7 s. */
.coh__inner--stmt.is-in .coh__l2 {
  animation:
    coh-rise 0.85s var(--ease) 0.28s both,
    coh-hit  0.7s  var(--ease) 1.05s both;
}
@keyframes coh-hit {
  0%   { filter: none; }
  35%  { filter: brightness(1.32) drop-shadow(0 0 18px rgba(232, 197, 71, 0.45)); }
  100% { filter: none; }
}

@media (max-width: 760px) {
  .coh__inner--stmt { align-items: center; }
  .coh__inner--stmt .coh__chain { margin-left: 0; }   /* la v64 recentre les
                                                         deux blocs a cette
                                                         largeur */
  .coh__line--stmt { max-width: none; font-size: clamp(1.6rem, 8vw, 2.5rem); }
}
/* Le reglage systeme demande la suppression des animations, pas du contenu :
   l'etat final est pose directement, sans transition ni filtre. */
@media (prefers-reduced-motion: reduce) {
  .coh__inner--stmt .coh__l1,
  .coh__inner--stmt .coh__l2,
  .coh__inner--stmt .coh__link {
    opacity: 1; transform: none; animation: none !important; filter: none;
  }
}

/* -------------------------------------------------------------------------
   §3 — HAUT DE LA COMPARAISON : DEUX LIGNES, ET LE NOIR MORT EN MOINS
   La ligne de preuve sociale est retiree du HTML. Restait le vide qu'elle
   occupait : le titre est elargi pour tomber en deux lignes au lieu de
   trois, et les trois marges qui se suivaient (bas de .swr, haut de .cmp,
   haut de .cmp__cols) sont resserrees. Aucune autre section ne bouge.
   ------------------------------------------------------------------------- */
/* Le titre restait sur trois lignes malgre l'elargissement : ce n'etait pas
   `.cmp__t` qui bridait mais `.cmp__head`, en `max-width: 56ch`. Un `ch` se
   mesure sur la police de l'element qui porte la regle — ici le conteneur, a
   16px : 56ch valaient environ 500px, quelle que soit la taille du h2 a
   l'interieur. La mesure passe donc en pixels, la seule unite qui ne depende
   pas de la police du parent. */
.cmp__head { max-width: min(100%, 1100px); }
.cmp__t {
  max-width: none;
  font-size: clamp(2rem, 5vw, 4.5rem);
  line-height: 1.02;
}
.swr { padding-bottom: clamp(1.5rem, 3vw, 2.5rem); }
.cmp { padding-top:    clamp(1.5rem, 3vw, 2.5rem); }
.cmp__cols { margin-top: clamp(2rem, 4.5vw, 3.25rem); }

/* -------------------------------------------------------------------------
   §4 — LES DEUX COLONNES : QUI EST LE PROBLEME, QUI EST LA SOLUTION
   Aucun texte, aucun prix, aucun ordre, aucune icone ne change. Ce qui
   change est le rang : la colonne de gauche recule, celle de droite avance,
   et un filet tres fin separe les deux mondes.
   ------------------------------------------------------------------------- */

/* La separation. Un pseudo-element sur la grille, pas une bordure de
   colonne : une bordure suivrait la hauteur de la colonne la plus haute et
   depasserait sous la plus courte. Ici le filet est centre, en degrade,
   et s'eteint a ses deux extremites — il structure sans decouper. */
.cmp__cols--rank { position: relative; }
@media (min-width: 721px) {
  .cmp__cols--rank::before {
    content: "";
    position: absolute;
    top: 0.5rem; bottom: 0.5rem; left: 50%;
    width: 1px;
    transform: translateX(-50%);
    background: linear-gradient(
      180deg,
      rgba(242, 240, 235, 0) 0%,
      rgba(242, 240, 235, 0.10) 22%,
      rgba(232, 197, 71, 0.22) 50%,
      rgba(242, 240, 235, 0.10) 78%,
      rgba(242, 240, 235, 0) 100%);
    pointer-events: none;
  }
}

/* Gauche : lisible, jamais illisible. Le contraste baisse, la saturation
   aussi ; la taille et la position ne bougent pas — sinon la comparaison
   ligne a ligne ne tient plus. */
.cmp__col--old { filter: saturate(0.72); }
.cmp__col--old .cmp__col-t { color: var(--ash-dim); }
.cmp__col--old .cmp__li { color: #7C828C; }
.cmp__col--old .cmp__x {
  background: rgba(242, 240, 235, 0.045);
  color: #565B64;
  box-shadow: none;
}

/* Droite : le point focal. Le titre gagne un accent bleu sous la ligne —
   quatre caracteres de large, pas une barre : il marque, il ne souligne
   pas. Le texte passe au blanc plein. */
.cmp__col--rr .cmp__col-t {
  position: relative;
  color: var(--bone);
  padding-bottom: 0.7rem;
}
.cmp__col--rr .cmp__col-t::after {
  content: "";
  position: absolute;
  left: 50%; bottom: 0;
  width: 2.25rem; height: 2px;
  transform: translateX(-50%) scaleX(0);
  transform-origin: 50% 50%;
  background: var(--signal);
  border-radius: 2px;
}
.cmp__cols--rank.is-in .cmp__col--rr .cmp__col-t::after {
  transform: translateX(-50%) scaleX(1);
  transition: transform 0.7s var(--ease) 0.55s;
}
.cmp__col--rr .cmp__li { color: #FFFFFF; font-weight: 500; }

/* L'alignement demande : meme zone de largeur pour les cinq puces des deux
   colonnes, meme distance au texte, memes debuts de ligne. La colonne de
   gauche de la grille est deja commune aux deux listes ; ce qui manquait
   est la BOITE de la marque, qui n'avait pas de hauteur propre et se
   calait sur le trait de l'image. */
.cmp__mark {
  display: block;
  width: clamp(38px, 3.4vw, 56px);
  height: auto;
  justify-self: center;
  /* Un halo bleu tres bas, pose une fois. Il rend les lunettes plus nettes
     sur le noir sans les colorer : le glyphe reste blanc. */
  filter: drop-shadow(0 0 6px rgba(232, 197, 71, 0.30));
}
.cmp__li { align-items: center; }

/* ---- Animation d'entree : gauche, puis droite, puis les quatre lignes ----
   Le decalage entre les deux colonnes est ce qui raconte la comparaison :
   on lit le probleme, puis la solution arrive. 0,18 s suffisent — au-dela
   ce n'est plus une revelation, c'est une attente. */
.cmp__cols--rank .cmp__col--old .cmp__li,
.cmp__cols--rank .cmp__col--rr  .cmp__li,
.cmp__cols--rank .cmp__col-t { opacity: 0; transform: translateY(12px); }

.cmp__cols--rank.is-in .cmp__col--old .cmp__col-t { animation: cmp-rise 0.6s var(--ease) 0.05s both; }
.cmp__cols--rank.is-in .cmp__col--rr  .cmp__col-t { animation: cmp-rise 0.6s var(--ease) 0.23s both; }
.cmp__cols--rank.is-in .cmp__col--old .cmp__li {
  animation: cmp-rise 0.55s var(--ease) calc(0.18s + var(--s) * 0.07s) both;
}
.cmp__cols--rank.is-in .cmp__col--rr .cmp__li {
  animation: cmp-rise 0.55s var(--ease) calc(0.42s + var(--s) * 0.09s) both;
}
@keyframes cmp-rise {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .cmp__cols--rank .cmp__col-t,
  .cmp__cols--rank .cmp__li {
    opacity: 1; transform: none; animation: none !important;
  }
  .cmp__cols--rank .cmp__col--rr .cmp__col-t::after {
    transform: translateX(-50%) scaleX(1); transition: none;
  }
}

/* -------------------------------------------------------------------------
   §5 — LES CINQ BENEFICES : PLUS DE CARTES
   La carte grise disparait entierement : fond, rayon, ombre, padding. Les
   cinq blocs sont poses sur le noir de la section. Le contraste passe de
   « gris fonce sur gris clair » a « blanc sur noir » : les libelles sont
   plus lisibles apres qu'avant, pas moins.
   ------------------------------------------------------------------------- */
.ben--flat .ben__grid {
  gap: clamp(1.75rem, 4vw, 3.5rem) clamp(1rem, 3vw, 2.75rem);
  align-items: center;
}
.ben--flat .ben__card {
  background: none;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
  gap: clamp(1rem, 2.2vw, 1.6rem);
}
/* La boite de l'icone a une hauteur FIXE. Les cinq glyphes n'ont pas la
   meme hauteur utile (la note de musique est haute, le duo de silhouettes
   est large et bas) : sans hauteur commune, les cinq libelles se decalent
   verticalement les uns par rapport aux autres et la rangee perd sa ligne
   de base. */
.ben--flat .ben__mark {
  display: flex;
  align-items: center;
  justify-content: center;
  /* LARGEUR ET HAUTEUR, pas seulement la hauteur. `width: auto` sur une image
     en `height: 100%` dans un conteneur flex donne une largeur nulle tant que
     le fichier n'est pas charge — et comme les icones sont en `loading=lazy`,
     c'est l'etat au moment ou la rangee est mesuree : la boite tombe a 0 de
     large et l'image deborde par-dessus le libelle. Les cinq sources sont
     carrees (240x240), la boite l'est donc aussi. */
  width:  clamp(68px, 6.6vw, 96px);
  height: clamp(68px, 6.6vw, 96px);
  flex: none;
}
.ben--flat .ben__icon {
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: 0;
}
.ben--flat .ben__t {
  color: var(--bone);
  font-weight: 600;
  font-size: clamp(0.9375rem, 1.2vw, 1.125rem);
  line-height: 1.3;
}

/* ---- Apparition sequentielle 01 -> 05 ----
   L'icone d'abord, le libelle juste apres : c'est la hierarchie demandee,
   rendue par le temps autant que par la taille. */
.ben--flat .ben__mark,
.ben--flat .ben__t { opacity: 0; transform: translateY(12px); }

.ben--flat .ben__grid.is-in .ben__mark {
  animation:
    ben-rise  0.65s var(--ease) calc(var(--s) * 0.11s) both,
    ben-flash 0.75s var(--ease) calc(var(--s) * 0.11s + 0.2s) both;
}
.ben--flat .ben__grid.is-in .ben__t {
  animation: ben-rise 0.6s var(--ease) calc(var(--s) * 0.11s + 0.16s) both;
}
@keyframes ben-rise {
  from { opacity: 0; transform: translateY(12px) scale(0.96); }
  to   { opacity: 1; transform: none; }
}
/* Le coup de lumiere a l'apparition. Il ne RESTE pas autour de l'icone :
   la derniere image de la sequence est l'etat neutre, et l'animation ne
   boucle pas. */
@keyframes ben-flash {
  0%   { filter: none; }
  30%  { filter: drop-shadow(0 0 14px rgba(242, 240, 235, 0.55)); }
  100% { filter: none; }
}

/* ---- Micro-interaction au survol : quelques pixels, rien d'autre ----
   Pas de carte qui se souleve, pas de bordure, pas de halo permanent. */
@media (hover: hover) and (pointer: fine) {
  .ben--flat .ben__card {
    transition: transform 0.35s var(--ease);
  }
  .ben--flat .ben__card:hover { transform: translateY(-4px); }
  .ben--flat .ben__card .ben__icon { transition: filter 0.35s var(--ease); }
  .ben--flat .ben__card:hover .ben__icon {
    filter: drop-shadow(0 0 10px rgba(232, 197, 71, 0.38));
  }
}

/* Cinq colonnes tiennent tres bien sans carte : ce qui les serrait etait le
   padding de la carte, pas le texte. La rupture a 1080px de la v66 reste,
   elle passe a 3 puis 2 colonnes. */
@media (max-width: 640px) {
  .ben--flat .ben__grid { gap: clamp(1.75rem, 6vw, 2.5rem) 1.25rem; }
}

@media (prefers-reduced-motion: reduce) {
  .ben--flat .ben__mark,
  .ben--flat .ben__t {
    opacity: 1; transform: none; animation: none !important; filter: none;
  }
  .ben--flat .ben__card,
  .ben--flat .ben__card:hover { transform: none; transition: none; }
}

/* -------------------------------------------------------------------------
   §6 — LES TROIS CONTENEURS `reveal` DE LA v70 NE BOUGENT PAS EUX-MEMES
   `.reveal` fait deux choses : il declenche l'observateur de main.js ET il
   fait monter l'element de 28px. Ici on ne veut que la premiere. Sans ca,
   le conteneur monte de 28px pendant que ses enfants montent de 10 a 12px
   chacun avec leur propre retard : deux mouvements simultanes sur le meme
   contenu, et l'echelonnement ne se lit plus. La classe reste, l'observateur
   reste, seul le deplacement du parent est neutralise.
   ------------------------------------------------------------------------- */
.coh__inner--stmt.reveal,
.cmp__cols--rank.reveal,
.ben--flat .ben__grid.reveal {
  opacity: 1;
  transform: none;
  transition: none;
}

/* La coupe du titre est explicite au-dessus de 720px. Laissee a
   `text-wrap: balance`, elle tombait a l'interieur de « world-class, » : le
   navigateur coupait sur le trait d'union et affichait « to world- / class, ».
   Le <br> ne change aucun mot ; sous 720px il est neutralise et la coupe
   redevient automatique, la ligne complete n'y tenant de toute facon pas. */
@media (max-width: 720px) {
  .cmp__t-br { display: none; }
}

/* Sous 720px le <br> est neutralise et la coupe redevient automatique — et
   le navigateur reprend son mauvais reflexe : il coupe SUR le trait d'union
   de « world-class, » et affiche « to world- / class, ». Le mot compose est
   donc rendu insecable. Aucun caractere n'est ajoute ni retire : le <span>
   n'entoure que du texte existant. */
.cmp__t .nowrap { white-space: nowrap; }


/* =========================================================================
   v71 — LA COMPARAISON SOUS LE STATEMENT : SIX LIGNES DEVIENNENT
         TROIS TRANSFORMATIONS
   Aucun mot, aucun ordre, aucune police, aucune couleur de palette ne
   change. Tout est ajoute en fin de fichier et gagne par la cascade ; les
   regles v65 de `.swr__grid` et `.swr__i` restent en place.

   Le mecanisme : le remplissage `grid-auto-flow: column` sur trois rangees
   fait deja que les elements 1-3 sont la colonne gauche et 4-6 la droite,
   et que 1/4, 2/5, 3/6 partagent une rangee. Toute la hierarchie se deduit
   donc du rang en :nth-child — pas une classe de plus dans le HTML.
   ========================================================================= */

/* ---------- §1 Respiration : trois blocs, pas six lignes ----------
   Le regroupement en paires demande par le brief se fait UNIQUEMENT par
   l'espacement et l'alignement. Aucun numero, aucun label, aucune icone
   n'est ajoute : la rangee devient assez haute et assez espacee de sa
   voisine pour se lire comme une unite. */
.swr__grid--rank {
  position: relative;
  margin-top: clamp(3.25rem, 6.5vw, 5.25rem);   /* etait clamp(2.5, 5vw, 4) */
  row-gap: clamp(0.9rem, 1.8vw, 1.6rem);
  column-gap: clamp(2.25rem, 5vw, 4.5rem);      /* etait clamp(1.5, 3.5vw, 3.25) */
}
.swr__grid--rank .swr__i {
  position: relative;
  padding-block: clamp(1.05rem, 1.9vw, 1.5rem);
  transition: color 0.4s var(--ease), opacity 0.4s var(--ease);
}

/* ---------- §2 Les separateurs deviennent des lignes de rythme ----------
   Le filet plein de bord a bord se lit comme une bordure de tableau. Il est
   remplace par un degrade qui s'eteint du cote de l'axe central : la ligne
   part du bord exterieur, la ou commence le regard, et disparait avant de
   toucher la separation. Elle rythme, elle n'encadre pas.

   `border-bottom-color: transparent` plutot qu'une suppression : la ligne
   garde son 1px d'epaisseur dans le calcul de hauteur, donc aucun decalage
   de mise en page par rapport a la v70. */
.swr__grid--rank .swr__i { border-bottom-color: transparent; }
.swr__grid--rank .swr__i::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  transition: opacity 0.4s var(--ease);
}
/* Colonne gauche : la ligne s'eteint vers la droite, donc vers l'axe. */
.swr__grid--rank .swr__i:nth-child(-n+3)::after {
  background: linear-gradient(90deg,
    rgba(242, 240, 235, 0.13) 0%,
    rgba(242, 240, 235, 0.05) 62%,
    rgba(242, 240, 235, 0) 92%);
}
/* Colonne droite : la ligne s'allume depuis l'axe et se prolonge plus loin.
   Meme geste, sens inverse — c'est ce qui fait lire la traversee. */
.swr__grid--rank .swr__i:nth-child(n+4)::after {
  background: linear-gradient(90deg,
    rgba(232, 197, 71, 0.28) 0%,
    rgba(242, 240, 235, 0.22) 26%,
    rgba(242, 240, 235, 0.10) 100%);
}

/* ---------- §3 La hierarchie gauche / droite ----------
   Le brief demande une difference RESSENTIE, pas criee : la taille ne bouge
   pas, la police non plus. Seuls la luminosite, la graisse et
   l'interlettrage travaillent. */
.swr__grid--rank .swr__i:nth-child(-n+3) {
  color: #A8ADB6;          /* entre --ash et --bone : recule sans devenir gris */
  font-weight: 400;
}
.swr__grid--rank .swr__i:nth-child(n+4) {
  color: #FFFFFF;
  font-weight: 600;
  letter-spacing: -0.006em;
}

/* ---------- §4 L'axe central ----------
   Une ligne de transition, pas une bordure de tableau : elle est plus
   claire au milieu, s'eteint a ses deux extremites, et se DESSINE de haut
   en bas a l'entree dans le viewport. `transform: scaleY` et non `height` :
   aucun recalcul de mise en page pendant l'animation.

   Elle est posee au centre de la gouttiere (`left: 50%` sur une grille de
   deux colonnes egales), donc elle ne touche jamais le texte. */
.swr__grid--rank::before {
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: 50%;
  width: 1px;
  transform: translateX(-50%) scaleY(0);
  transform-origin: 50% 0;
  background: linear-gradient(180deg,
    rgba(232, 197, 71, 0) 0%,
    rgba(232, 197, 71, 0.30) 26%,
    rgba(232, 197, 71, 0.42) 50%,
    rgba(232, 197, 71, 0.30) 74%,
    rgba(232, 197, 71, 0) 100%);
  pointer-events: none;
  transition: transform 0.75s var(--ease) 0.42s, opacity 0.4s var(--ease);
}
.swr__grid--rank.is-in::before { transform: translateX(-50%) scaleY(1); }

/* ---------- §5 La sequence d'entree ----------
   gauche (3 lignes) -> l'axe se dessine -> droite (3 lignes, revelation
   plus marquee). Total 1,35 s, dans la fourchette demandee.

   La colonne droite part de plus bas (14px contre 8px) et d'un contraste
   plus faible : c'est elle qui « arrive », la gauche est deja la. */
.swr__grid--rank .swr__i { opacity: 0; }
.swr__grid--rank.is-in .swr__i:nth-child(1) { animation: swr-l 0.6s var(--ease) 0.10s both; }
.swr__grid--rank.is-in .swr__i:nth-child(2) { animation: swr-l 0.6s var(--ease) 0.19s both; }
.swr__grid--rank.is-in .swr__i:nth-child(3) { animation: swr-l 0.6s var(--ease) 0.28s both; }
.swr__grid--rank.is-in .swr__i:nth-child(4) { animation: swr-r 0.7s var(--ease) 0.66s both; }
.swr__grid--rank.is-in .swr__i:nth-child(5) { animation: swr-r 0.7s var(--ease) 0.75s both; }
.swr__grid--rank.is-in .swr__i:nth-child(6) { animation: swr-r 0.7s var(--ease) 0.84s both; }

@keyframes swr-l {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
/* La montee de contraste de la phase 4 : la ligne arrive volontairement
   sous-exposee et gagne sa luminosite finale en fin de course. */
@keyframes swr-r {
  0%   { opacity: 0;    transform: translateY(14px); filter: brightness(0.62); }
  70%  { opacity: 1;    transform: none;             filter: brightness(0.88); }
  100% { opacity: 1;    transform: none;             filter: none; }
}

/* ---------- §6 Le survol : du focus, pas du mouvement ----------
   Souris fine uniquement. Au survol d'une ligne Ready Release, cette ligne
   et son separateur montent en luminosite, l'axe reagit legerement, et la
   colonne gauche recule d'un cran de plus. Aucun deplacement, aucun zoom,
   aucune bordure. */
@media (hover: hover) and (pointer: fine) {
  .swr__grid--rank .swr__i:nth-child(n+4):hover { color: #FFFFFF; }
  .swr__grid--rank .swr__i:nth-child(n+4):hover::after { opacity: 1; }
  .swr__grid--rank .swr__i:nth-child(n+4)::after { opacity: 0.8; }

  /* :has() sert ici a faire reagir des ELEMENTS VOISINS au survol d'un
     enfant, ce qu'aucun autre selecteur ne permet. Sans support, la ligne
     survolee s'eclaire quand meme (regles ci-dessus) : seul l'effet de
     recul de la colonne opposee est perdu. Degradation propre. */
  .swr__grid--rank:has(.swr__i:nth-child(n+4):hover) .swr__i:nth-child(-n+3) {
    opacity: 0.55;
  }
  .swr__grid--rank:has(.swr__i:nth-child(n+4):hover)::before {
    opacity: 1;
    filter: brightness(1.4);
  }
}

/* ---------- §7 Mobile : la paire reste la paire ----------
   Sous 720px la v65 repasse en une colonne, ce qui donne les trois lignes
   de gauche puis les trois de droite : la paire est cassee, et avec elle
   l'idee de transformation. `order` retablit l'alternance 1-4-2-5-3-6.

   A NOTER : l'ordre du DOM reste 1..6, l'ordre affiche devient 1-4-2-5-3-6.
   Un lecteur d'ecran annonce donc les trois lignes de gauche puis les trois
   de droite. Les six enonces sont autonomes et la liste reste intelligible
   dans les deux ordres, mais la divergence est reelle et assumee ici.

   L'axe vertical n'a plus de sens en une colonne : il devient un trait
   horizontal court entre les deux moitiees de chaque paire. */
@media (max-width: 720px) {
  .swr__grid--rank::before { display: none; }

  .swr__grid--rank .swr__i:nth-child(1) { order: 1; }
  .swr__grid--rank .swr__i:nth-child(4) { order: 2; }
  .swr__grid--rank .swr__i:nth-child(2) { order: 3; }
  .swr__grid--rank .swr__i:nth-child(5) { order: 4; }
  .swr__grid--rank .swr__i:nth-child(3) { order: 5; }
  .swr__grid--rank .swr__i:nth-child(6) { order: 6; }

  /* La ligne de gauche ne ferme plus rien : elle introduit celle de droite.
     Son filet devient donc un trait court, decale, qui se lit comme un
     « puis » et non comme une fin de rangee. */
  .swr__grid--rank .swr__i:nth-child(-n+3) {
    padding-bottom: clamp(0.55rem, 1.6vw, 0.75rem);
  }
  .swr__grid--rank .swr__i:nth-child(-n+3)::after {
    left: 0; right: auto; width: 1.75rem;
    background: rgba(232, 197, 71, 0.45);
  }
  .swr__grid--rank .swr__i:nth-child(n+4) {
    padding-top: clamp(0.55rem, 1.6vw, 0.75rem);
    padding-bottom: clamp(1.6rem, 4vw, 2.25rem);   /* le vide entre paires */
  }
  .swr__grid--rank .swr__i:nth-child(n+4)::after {
    background: linear-gradient(90deg,
      rgba(242, 240, 235, 0.13) 0%,
      rgba(242, 240, 235, 0) 88%);
  }
  .swr__grid--rank .swr__i:nth-child(6)::after { display: none; }
}

/* ---------- §8 Le conteneur ne bouge pas lui-meme ----------
   Meme raison qu'au §6 de la v70 : `.reveal` sert ici d'INTERRUPTEUR, pas
   d'animation. Son propre deplacement de 28px se superposerait aux six
   deplacements echelonnes des enfants. */
.swr__grid--rank.reveal { opacity: 1; transform: none; transition: none; }

/* ---------- §9 Mouvement reduit ----------
   Etat final pose directement : couleurs, graisses et axe sont conserves,
   seules les animations disparaissent. La hierarchie ne depend d'aucune
   animation — elle tient au contraste seul. */
@media (prefers-reduced-motion: reduce) {
  .swr__grid--rank .swr__i {
    opacity: 1; transform: none; filter: none; animation: none !important;
    transition: none;
  }
  .swr__grid--rank::before {
    transform: translateX(-50%) scaleY(1); transition: none;
  }
}


/* =========================================================================
   v72 — LES SIX LIGNES GRANDISSENT, LES SEPT CADRES SE REMPLISSENT
   Ajoute en fin de fichier : aucune regle anterieure n'est reecrite ni
   supprimee, ce bloc gagne par l'ordre de la cascade.
   ========================================================================= */

/* -------------------------------------------------------------------------
   §1 — LA TAILLE DES SIX LIGNES « We believe… »

   Constat de depart : ces six lignes et les quatre lignes du bloc de
   comparaison etaient DEJA dans la meme police (Manrope, var(--body)). Ce
   que l'oeil lisait comme « une autre police » etait un ecart de taille :
   15 px ici contre 34 px la-bas. C'est donc la taille qui bouge, et elle
   seule — pas la famille, pas les mots, pas l'ordre.

   Pourquoi pas 34 px exactement : le bloc de comparaison dispose d'une
   demi-page (~600 px par colonne). Ces six lignes vivent dans la colonne de
   texte de la section, elle-meme divisee en deux — soit ~300 px par
   colonne. A 34 px, « Sound industry-standard » mesure ~400 px : les cinq
   lignes les plus longues passeraient sur deux lignes chacune, et la
   grille de trois rangees deviendrait un pave. 24 px au plafond est la
   plus grande valeur qui tient chaque enonce sur UNE ligne, et l'ecart
   avec le statement au-dessus (34,4 px) reste lisible comme une
   hierarchie. Le gain reel est de +59 % sur la taille du glyphe.

   La gouttiere se resserre de 4,5 a 3,5rem : a 24 px, deux colonnes de
   texte separees par 72 px se lisaient comme deux listes independantes. */
.swr__grid--rank {
  column-gap: clamp(1.75rem, 3.6vw, 3.5rem);
  row-gap: clamp(1.1rem, 2.1vw, 1.9rem);
}
.swr__grid--rank .swr__i {
  font-size: clamp(1.125rem, 1.7vw, 1.5rem);
  line-height: 1.3;
  padding-block: clamp(1.15rem, 2.1vw, 1.7rem);
}
/* A cette taille, -0.006em ne se voit plus : le meme resserrement optique
   demande 2,5 fois plus. La colonne droite garde son avance de graisse. */
.swr__grid--rank .swr__i:nth-child(n+4) { letter-spacing: -0.015em; }
.swr__grid--rank .swr__i:nth-child(-n+3) { letter-spacing: -0.008em; }

/* Le statement au-dessus n'a pas change de taille, mais la liste s'est
   rapprochee de lui : l'ecart qui les separait a ete calcule pour un corps
   de 15 px. */
.swr__grid--rank { margin-top: clamp(2.75rem, 5.5vw, 4.5rem); }

/* Sous 980 px la colonne de texte prend toute la largeur : les deux
   colonnes de lignes passent a ~430 px chacune et peuvent donc porter le
   corps du bloc de comparaison sans casser. */
@media (max-width: 980px) and (min-width: 721px) {
  .swr__grid--rank .swr__i { font-size: clamp(1.25rem, 3vw, 1.75rem); }
}
/* En une colonne, plus rien ne contraint la longueur de ligne. */
@media (max-width: 720px) {
  .swr__grid--rank .swr__i { font-size: clamp(1.15rem, 5vw, 1.6rem); }
}


/* -------------------------------------------------------------------------
   §2 — LE CADRE COMMUN DES SEPT LIVRABLES

   `.dlv__ph` etait le cadre d'attente : fond, halo, filet interieur, rayon.
   `.dlv__frame` reprend exactement ces valeurs et devient le cadre qui
   CONTIENT un media. Les deux coexistent : `.dlv__ph` reste en place pour
   toute case qui redeviendrait vide.

   `overflow: hidden` est la seule addition de fond : sans lui, une video en
   `object-fit: cover` deborderait des coins arrondis. */
.dlv__frame {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: clamp(200px, 21vw, 360px);
  border-radius: clamp(10px, 1.1vw, 18px);
  overflow: hidden;
  background:
    radial-gradient(120% 90% at 50% 0%,
      rgba(232, 197, 71, 0.10) 0%,
      rgba(232, 197, 71, 0) 62%),
    linear-gradient(180deg, var(--surface-2) 0%, var(--surface) 100%);
  box-shadow: inset 0 0 0 1px var(--line),
              0 18px 44px rgba(0, 0, 0, 0.45);
}

/* Le numero de place reste ce qu'il etait, mais il passe maintenant AU
   DESSUS d'un media. Un voile local sous le chiffre plutot qu'un scrim sur
   toute l'image : le sujet reste a pleine luminosite. */
.dlv__frame .dlv__ph-n {
  z-index: 2;
  color: rgba(242, 240, 235, 0.92);
  padding: 0.15rem 0.45rem;
  border-radius: 4px;
  background: rgba(10, 11, 13, 0.55);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
}

/* <picture> est inline par defaut : sans ce display:block il ne prend pas
   la hauteur du cadre et l'image se cale sur sa ligne de base. */
.dlv__pic { display: block; width: 100%; height: 100%; }

.dlv__frame .dlv__img {
  width: 100%;
  height: 100%;
  border-radius: 0;      /* le rayon est porte par le cadre, pas par le media */
  object-fit: cover;
}

/* ---------- Le regime FIT : la case 04 ----------
   Le media est contenu, pas recadre. Une marge interieure evite que le
   mockup ne touche le filet du cadre — colle au bord, un rendu d'interface
   se lit comme une capture ratee plutot que comme un ecran presente. */
.dlv__frame--fit .dlv__pic { padding: clamp(0.5rem, 1vw, 0.9rem); }
.dlv__frame--fit .dlv__img { object-fit: contain; }


/* -------------------------------------------------------------------------
   §3 — LA CASE 03 : DEUX VIDEOS QUI ALTERNENT

   C'est le seul endroit de la page ou une case alterne. 5 000 ms par video,
   fondu croise de 500 ms — la meme duree de fondu que les cartes
   `data-seq` de la section 04, pour que les deux mecanismes ne se lisent
   pas comme deux systemes differents.

   Les deux plans sont ramenes au CARRE a l'encodage. C'est le point qui
   rend l'alternance possible : les fichiers livres etaient tous deux en
   1080x1080, mais l'un portait une image 16:9 letterboxee et l'autre une
   image 9:16 pillarboxee. Recadrer chacun sur son contenu reel puis les
   ramener a une meme forme est la seule facon d'eviter que la case ne
   change de proportion toutes les cinq secondes. */
.dlv__sq {
  position: relative;
  display: block;
  height: 100%;
  aspect-ratio: 1 / 1;
  max-width: 100%;
  border-radius: clamp(6px, 0.8vw, 12px);
  overflow: hidden;
  background: #000;
}
.dlv__v {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.5s var(--ease);
}
.dlv__v.is-on { opacity: 1; }

/* La case 07 : une seule video, qui remplit le cadre entier. */
.dlv__v--fill { position: absolute; inset: 0; border-radius: 0; }

/* Sans JS, la case doit montrer quelque chose : la premiere video est donc
   visible PAR DEFAUT, poster compris. Le JS ne prend la main qu'apres avoir
   pose `is-live` sur le cadre — c'est a partir de la seulement que
   l'opacite est pilotee par `is-on`. Un cadre vide n'est ainsi jamais
   possible, quel que soit l'etat du navigateur. */
.dlv__frame--seq .dlv__v:first-child { opacity: 1; }
.dlv__frame--seq.is-live .dlv__v { opacity: 0; }
.dlv__frame--seq.is-live .dlv__v.is-on { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .dlv__v { transition: none; }
}


/* -------------------------------------------------------------------------
   §4 — LES DEUX RUPTURES DEJA EN PLACE S'APPLIQUENT AU NOUVEAU CADRE
   Les media queries de la v68 ne connaissaient que `.dlv__img` et
   `.dlv__ph`. Elles sont reprises ici pour `.dlv__frame`, aux memes
   valeurs et aux memes seuils. */
@media (max-width: 620px) {
  .dlv__frame { height: clamp(190px, 52vw, 260px); }
}


/* =========================================================================
   v73 — LA SECTION PROCESS
   Ajoute en fin de fichier : aucune regle anterieure n'est reecrite ni
   supprimee. Toutes les regles sont prefixees `.hproc` — aucune ne peut
   atteindre un autre bloc de la page.
   ========================================================================= */

/* La section vit A L'INTERIEUR de `.dlv` (voir le commentaire dans
   index.html). Elle doit donc fabriquer elle-meme sa respiration haute,
   sinon elle se colle a la derniere rangee de livrables. La respiration
   basse est laissee au `margin-top` du CTA, deja en place. */
.hproc {
  margin-top: clamp(5.5rem, 11vw, 10rem);
}

.hproc__head {
  text-align: center;
  margin-bottom: clamp(3.5rem, 7vw, 6rem);
}
/* Meme corps que le titre de la section hote : les deux titres se suivent a
   quelques centaines de pixels, un ecart de taille se lirait comme une
   hierarchie qui n'existe pas. */
.hproc__ht {
  font-size: var(--fs-h2);
  max-width: 20ch;
  margin-inline: auto;
  text-wrap: balance;
}
.hproc__hs {
  margin: clamp(1rem, 1.8vw, 1.5rem) auto 0;
  max-width: 46ch;
  font-size: var(--fs-lead);
  color: var(--ash);
  line-height: 1.55;
}

.hproc__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  row-gap: clamp(3rem, 6vw, 5.5rem);
}

/* ---------- Un bloc : illustration a gauche, texte a droite ----------
   Les trois blocs sont identiques, sans alternance. C'est ce que fait la
   reference, et c'est ce qui tient la colonne de lecture : le regard
   descend tout droit sur les titres, sans traverser la page a chaque
   etape.

   1.15fr / 1fr : l'illustration est l'element important de la section,
   mais la colonne de texte doit rester au-dessus de 40ch pour que les
   paragraphes gardent des lignes lisibles. */
.hproc__step {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}
/* Le filet ferme l'etape et annonce la suivante. Il n'existe pas sous la
   troisieme : c'est le CTA qui suit, et deux separations empilees a cet
   endroit feraient lire une fin de page. */
.hproc__step:not(:last-child) {
  padding-bottom: clamp(3rem, 6vw, 5.5rem);
  border-bottom: 1px solid var(--line);
}

/* ---------- Le cadre de l'illustration ----------
   Meme grammaire que `.dlv__frame` de la v72 : rayon, filet interieur,
   ombre portee. Le fond n'est PAS repris : chaque SVG porte deja son
   propre fond sombre et sa trame, de facon a rester lisible meme ouvert
   seul dans un onglet. */
.hproc__fig {
  margin: 0;
  border-radius: clamp(10px, 1.1vw, 18px);
  overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--line),
              0 22px 52px rgba(0, 0, 0, 0.42);
}
.hproc__img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}

/* ---------- La colonne de texte ---------- */
.hproc__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin: 0;
  padding: 0.4rem 0.9rem 0.4rem 0.75rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-family: var(--display);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--bone);
}
.hproc__dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--signal);
  flex: none;
}
.hproc__st {
  margin-top: clamp(1.1rem, 2vw, 1.6rem);
  font-size: var(--fs-h3);
  letter-spacing: -0.02em;
  line-height: 1.15;
}
/* 46ch et non la largeur de la colonne : la consigne demande des lignes
   courtes et beaucoup d'espace negatif. Sur grand ecran la colonne fait
   plus de 60ch, ce qui donnerait un pave de documentation. */
.hproc__d {
  margin-top: clamp(0.85rem, 1.5vw, 1.25rem);
  max-width: 46ch;
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--ash);
}

/* ---------- Rupture ----------
   Sous 900 px les deux colonnes passent l'une sous l'autre, illustration
   en premier : c'est deja l'ordre du DOM, aucun `order` n'est necessaire
   et l'ordre annonce reste l'ordre affiche. */
@media (max-width: 900px) {
  .hproc__step {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(1.5rem, 4vw, 2.25rem);
  }
  .hproc__d { max-width: none; }
}

/* L'animation est celle qui existe deja : `.reveal` et son observateur.
   Rien n'a ete ajoute — pas de rotation, pas de parallaxe, pas de
   flottement. Le bloc monte de 28 px une fois et ne rejoue jamais. Sous
   `prefers-reduced-motion`, la regle de la ligne 524 pose l'etat final
   sans transition ; elle couvre `.hproc__step` sans modification. */

/* La consigne demande explicitement que le CTA qui suit ne semble pas
   colle. Son propre `margin-top` (3,5rem au plancher) suffisait a peine
   sur petit ecran : la troisieme etape ajoute donc sa propre respiration
   basse, sans toucher au CTA lui-meme. */
.hproc__step:last-child {
  padding-bottom: clamp(1.75rem, 3.5vw, 3rem);
}


/* =========================================================================
   v74 — TROIS AJOUTS, AUCUNE REECRITURE

   1. `.fsig`  — la signature du fondateur, entre la carte du release et
                 « Everything your artist brand needs… ».
   2. `.pkbtn` — le bouton blanc « Check out our packages ».
   3. `.hpk`   — les trois packs, en bas de la home.

   Tout est prefixe. Aucune regle anterieure n'est modifiee ni supprimee.
   Le renommage `.proc` -> `.hproc` de cette version est traite plus haut,
   dans le bloc v73 lui-meme : c'etait une collision de noms avec le bloc
   des 13 etapes de release.html, pas un ajout.
   ========================================================================= */

/* -------------------------------------------------------------------------
   §1 — LA CITATION MANUSCRITE

   Le brief demande une manuscrite « fine, elegante, contemporaine, tres
   lisible » et exclut explicitement le feutre decoratif. Permanent Marker,
   la seule manuscrite deja embarquee (bloc des plateformes, v35), est
   precisement ce qui est exclu : elle n'est pas reutilisee.

   Caveat (SIL Open Font License) est chargee depuis Google Fonts, faute de
   fichier local. C'est LE point a reprendre avant mise en ligne : c'est la
   seule dependance a un tiers de tout le site, et elle transmet l'IP du
   visiteur a Google. Voir MISSING-CONTENT.md §v74 — le passage en
   auto-heberge est un @font-face de quatre lignes et un woff2 depose dans
   /assets/fonts/, rien de plus.

   La pile de repli n'est pas decorative : si Caveat ne charge pas, la
   citation reste manuscrite sur macOS/iOS et sur Windows, et retombe sur
   l'italique du corps ailleurs — jamais sur une cursive de mariage. */
:root {
  --hand: 'Caveat', 'Segoe Script', 'Bradley Hand', 'Noteworthy', cursive;
}

.fsig {
  /* Aucun cadre, aucune carte, aucun fond : le bandeau est POSE dans le
     flux. Le seul marqueur de separation est un filet haut a 5,5 %
     d'opacite, plus clair que `--line` : il se lit comme un changement de
     respiration, pas comme une bordure.

     Une insertion, pas une section : la respiration est celle d'un
     paragraphe long, pas celle d'un chapitre. `--section-y` vaut le double
     et aurait fabrique exactement la grande section que le brief refuse. */
  border-top: 1px solid rgba(255, 255, 255, 0.055);
  padding-block: clamp(2.25rem, 4.5vw, 3.75rem);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: clamp(1.25rem, 3vw, 2.5rem);
  align-items: center;
}

/* Aucun cadre, aucune carte, aucun fond : le bandeau est POSE dans le flux.
   Le seul marqueur de separation est un filet haut a 6 % d'opacite, plus
   clair que `--line`, qui se lit comme un changement de respiration et non
   comme une bordure. */

/* ---------- La photo ----------
   Portrait editorial compact, jamais dominant : sa largeur est plafonnee a
   120 px, soit environ 9 % de la colonne utile. Pas de cercle, pas d'avatar,
   pas de bordure — un rayon de 10 px, celui des cadres du site. */
.fsig__ph {
  display: block;
  width: clamp(80px, 8.5vw, 120px);
  border-radius: 10px;
  overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--line);
}
.fsig__ph img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
}

.fsig__body { min-width: 0; }

/* ---------- La citation ----------
   Assez grande pour se lire comme une pensee, pas assez pour devenir un
   titre : elle plafonne a 1,85rem quand `--fs-h3` du site est au-dessus.
   La mesure est bornee a 54ch pour qu'elle tienne en trois ou quatre
   lignes courtes, comme une note ecrite a la main. */
.fsig__q {
  margin: 0;
  max-width: 54ch;
  font-family: var(--hand);
  font-weight: 500;
  font-size: clamp(1.3rem, 2.1vw, 1.85rem);
  line-height: 1.35;
  letter-spacing: 0.005em;
  color: var(--bone);
}
.fsig__q p { margin: 0; }

/* ---------- La signature ----------
   Typographie Ready Release, et volontairement plus discrete que la
   citation : c'est la citation qui porte le bandeau, pas la fonction. */
.fsig__by {
  margin: clamp(0.7rem, 1.4vw, 1rem) 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.45rem 0.7rem;
}
.fsig__name {
  font-family: var(--display);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--bone);
}
.fsig__role {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash-dim);
}

/* ---------- Rupture ----------
   La photo RESTE a gauche sous 720 px : la consigne l'autorise tant que la
   largeur suit, et a 80 px elle suit. Le bandeau ne devient donc jamais une
   pile verticale — c'est la contrainte n°6 du brief. */
@media (max-width: 720px) {
  .fsig { gap: 1rem; align-items: start; }
  .fsig__q { font-size: clamp(1.15rem, 4.6vw, 1.45rem); }
}

/* -------------------------------------------------------------------------
   §2 — LE BOUTON BLANC « CHECK OUT OUR PACKAGES »

   Forme de la reference : pilule pleine, libelle a gauche, chevron dans un
   disque a droite. Couleur imposee : blanc plein.

   A NOTER — ce bouton leve la regle posee en v66/v67 (« le blanc plein est
   reserve au parcours de commande »). C'est une decision explicite, pas un
   oubli : consignee dans MISSING-CONTENT.md §v74. Aucun autre CTA de la
   page n'a ete repeint. */
.pkbtn-wrap {
  /* La consigne demande de ne pas fabriquer d'espace noir inutile : la
     marge haute est courte, et c'est `.hproc` qui suit qui porte deja sa
     propre respiration. */
  margin: clamp(2.25rem, 4vw, 3.25rem) 0 0;
  text-align: center;
}
.pkbtn {
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.95rem 0.95rem 0.95rem 1.85rem;
  border-radius: 999px;
  background: #fff;
  color: #0A0B0D;
  font-family: var(--caps);
  font-size: clamp(0.95rem, 1.15vw, 1.0625rem);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1;
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.pkbtn:hover {
  transform: translateY(-2px);
  box-shadow: 0 14px 34px rgba(255, 255, 255, 0.14);
}
.pkbtn:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
.pkbtn__ic {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  /* Le disque du chevron est le meme blanc, assombri : sur la reference il
     se detache du bouton sans introduire de seconde couleur. */
  background: rgba(10, 11, 13, 0.09);
}
.pkbtn__ic svg { width: 0.7rem; height: 0.7rem; display: block; }
@media (prefers-reduced-motion: reduce) {
  .pkbtn { transition: none; }
  .pkbtn:hover { transform: none; }
}

/* « Ne pas creer d'espace noir inutile entre les sections. » Le bouton
   s'intercale entre la grille et le Process : sans cette regle, sa hauteur
   et sa marge s'ADDITIONNENT aux 10rem que `.hproc` se donnait quand elle
   suivait directement la grille. La respiration haute du Process est donc
   reduite de moitie lorsqu'il est precede du bouton — et seulement dans ce
   cas, le selecteur adjacent ne peut pas atteindre une autre page. Solde
   reel ajoute a la page : environ 36 px au lieu de 114. */
.pkbtn-wrap + .hproc { margin-top: clamp(3rem, 6vw, 5rem); }

/* -------------------------------------------------------------------------
   v75 — SECTION PRICING DE LA HOME

   Remplace integralement le bloc `.hpk` de la v74. Plus aucune regle `.hpk`
   n'est conservee : les classes ne sont plus utilisees dans aucune page.

   FOND SOMBRE, PAS BLANC. Le document de cadrage demandait un fond blanc.
   Le site entier tourne sur --void (#0A0B0D) et --bone : une section blanche
   au milieu aurait lu comme un bloc colle, pas comme une section premium.
   L'intention du brief — respiration, bleu profond, bordures fines, aucune
   couleur parasite — est tenue dans la palette du site.

   POUR PASSER EN BLANC malgre tout : ajouter la classe `rrp--light` sur la
   <section>. Tout le bloc bascule, aucun autre fichier a toucher. La regle
   est ecrite plus bas et volontairement gardee courte pour rester lisible.
   ------------------------------------------------------------------------- */
.rrp {
  --rrp-bg: transparent;
  --rrp-card: var(--surface);
  --rrp-ink: var(--bone);
  --rrp-dim: var(--ash);
  --rrp-faint: var(--ash-dim);
  --rrp-line: var(--line);
  --rrp-line-2: var(--line-strong);
  --rrp-blue: var(--signal);
  --rrp-blue-deep: var(--signal-fill);
  background: var(--rrp-bg);
}

/* ---------------------------------------------------------------- en-tete */
.rrp__head { max-width: 68ch; margin: 0 auto clamp(2rem, 4vw, 3.25rem); text-align: center; }
.rrp__kicker {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--rrp-blue);
  margin: 0 0 1rem;
}
.rrp__t {
  font-family: var(--display);
  font-size: var(--fs-h2);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.06;
  color: var(--rrp-ink);
  margin: 0;
  text-wrap: balance;
}
.rrp__sub {
  margin: 1.1rem auto 0;
  /* v76 — la mesure passe de 62ch a 860px. En `ch`, la largeur se calculait
     sur la police de l'element : le paragraphe tombait a ~560px et se lisait
     comme un pave de quatre lignes courtes centrees. En pixels, il tient sur
     deux a trois lignes larges. */
  max-width: min(100%, 860px);
  text-wrap: pretty;
  color: var(--rrp-dim);
  font-size: var(--fs-body);
  line-height: 1.6;
}
.rrp__pos {
  margin: 1.6rem auto 0;
  max-width: min(100%, 720px);
  text-wrap: balance;
  font-family: var(--display);
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.35;
  color: var(--rrp-ink);
}
/* v76 — une seule ligne, tenue sur une seule ligne tant que la place le
   permet. Le paragraphe de quatre lignes qui occupait cette place est
   supprime : il redisait ce que les cartes disent en detail. */
.rrp__pos--2 {
  margin-top: 0.85rem;
  font-family: var(--body);
  font-size: 1rem;
  font-weight: 400;
  color: var(--rrp-dim);
  line-height: 1.5;
  max-width: min(100%, 780px);
}

/* ----------------------------------------------------------------- toggle */
.rrp__toggle {
  display: flex;
  width: max-content;
  gap: 2px;
  padding: 3px;
  margin: 0 auto;
  border: 1px solid var(--rrp-line);
  border-radius: 999px;
  background: var(--rrp-card);
}
.rrp__tbtn {
  appearance: none;
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 0.55rem 1.35rem;
  border-radius: 999px;
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--rrp-dim);
  transition: color 0.25s var(--ease), background 0.25s var(--ease);
}
.rrp__tbtn:hover { color: var(--rrp-ink); }
.rrp__tbtn.is-on { color: var(--void); background: var(--rrp-blue-deep); }
.rrp__tbtn:focus-visible { outline: 2px solid var(--rrp-blue); outline-offset: 2px; }

.rrp__lead {
  margin: 1.25rem auto clamp(1.75rem, 3vw, 2.5rem);
  text-align: center;
  color: var(--rrp-dim);
  font-size: 0.9375rem;
}

/* ------------------------------------------------------------------ grille
   Trois colonnes egales. La carte du milieu ne prend pas plus de place :
   elle est surelevee et bordee de bleu. Elargir une colonne casserait
   l'alignement des lignes de livrables entre les trois cartes, qui est
   precisement ce qui rend la comparaison lisible. */
.rrp__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 1.8vw, 1.6rem);
  align-items: center;
}

.rrp__card {
  position: relative;
  border: 1px solid var(--rrp-line);
  border-radius: var(--radius-m);
  background: var(--rrp-card);
  transition: border-color 0.3s var(--ease), transform 0.3s var(--ease);
}
.rrp__card:hover { border-color: var(--rrp-line-2); }
.rrp__body {
  display: flex;
  flex-direction: column;
  padding: clamp(1.5rem, 2.4vw, 2.25rem) clamp(1.35rem, 2vw, 1.9rem) clamp(1.4rem, 2vw, 1.85rem);
  transition: opacity 0.22s var(--ease);
}
.rrp__card.is-swapping .rrp__body { opacity: 0; }

.rrp__card--star {
  border-color: rgba(232, 197, 71, 0.45);
  background: linear-gradient(180deg, rgba(232, 197, 71, 0.09), rgba(232, 197, 71, 0.02) 55%, transparent), var(--rrp-card);
  box-shadow: 0 24px 60px -32px rgba(232, 197, 71, 0.75);
  transform: translateY(-10px);
}
.rrp__flag {
  position: absolute;
  top: 0; left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--void);
  background: var(--rrp-blue-deep);
  border-radius: 999px;
  padding: 0.28rem 0.85rem;
  white-space: nowrap;
}

/* --------------------------------------------------------- corps de carte
   Ordre impose par le brief : nom, promesse, prix, valeur, livrables, CTA,
   garantie, rarete. Le prix n'est jamais le seul element dominant. */
.rrp__name {
  font-family: var(--display);
  font-size: clamp(1.15rem, 1.7vw, 1.4rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--rrp-ink);
  margin: 0;
}
.rrp__promise {
  margin: 0.45rem 0 0;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--rrp-dim);
  min-height: 2.9em;
}
.rrp__price { margin: 1.1rem 0 0; display: flex; align-items: baseline; gap: 0.5rem; }
.rrp__amount {
  font-family: var(--display);
  font-size: clamp(2.1rem, 3.2vw, 2.85rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1;
  color: var(--rrp-ink);
  font-variant-numeric: tabular-nums;
}
.rrp__save {
  margin: 0.7rem 0 0;
  align-self: flex-start;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--rrp-blue);
  border: 1px solid rgba(232, 197, 71, 0.45);
  border-radius: 999px;
  padding: 0.28rem 0.7rem;
  line-height: 1.3;
}
.rrp__under {
  margin: 0.75rem 0 0;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--rrp-faint);
}

.rrp__group {
  margin: clamp(1.35rem, 2.2vw, 1.75rem) 0 0;
  padding-top: clamp(1.1rem, 1.8vw, 1.4rem);
  border-top: 1px solid var(--rrp-line);
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--rrp-faint);
}
.rrp__group--opt { color: var(--rrp-blue); }

.rrp__feats { list-style: none; margin: 0.95rem 0 0; padding: 0; display: grid; gap: 0.95rem; }
.rrp__feat { position: relative; padding-left: 1.4rem; }
.rrp__feat::before {
  content: '';
  position: absolute;
  left: 0; top: 0.42em;
  width: 7px; height: 7px;
  border-left: 1.5px solid var(--rrp-blue);
  border-bottom: 1.5px solid var(--rrp-blue);
  transform: rotate(-45deg);
}
.rrp__feat-t {
  display: block;
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--rrp-ink);
  line-height: 1.35;
}
.rrp__feat-d {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--rrp-dim);
}
.rrp__opt {
  margin: 0.7rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--rrp-dim);
}
.rrp__opt span { color: var(--rrp-ink); font-weight: 700; }

.rrp__note {
  margin: clamp(1.1rem, 1.8vw, 1.5rem) 0 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--rrp-faint);
}

/* Le CTA est pousse en bas : les trois boutons s'alignent quel que soit le
   nombre de livrables au-dessus. */
.rrp__cta {
  appearance: none;
  cursor: pointer;
  display: block;
  width: 100%;
  margin-top: clamp(1.25rem, 2.2vw, 1.75rem);
  padding: 0.85rem 1rem;
  border: 1px solid var(--rrp-line-2);
  border-radius: var(--radius-s);
  background: transparent;
  font-family: var(--body);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--rrp-ink);
  transition: background 0.25s var(--ease), border-color 0.25s var(--ease), opacity 0.25s var(--ease);
}
.rrp__cta::after { content: ' \2192'; }
.rrp__cta:hover { border-color: var(--rrp-ink); background: rgba(242, 240, 235, 0.06); }
.rrp__cta:focus-visible { outline: 2px solid var(--rrp-blue); outline-offset: 2px; }
.rrp__cta.is-busy { opacity: 0.55; cursor: progress; }
.rrp__card--star .rrp__cta {
  border-color: transparent;
  background: var(--rrp-blue-deep);
  color: var(--void);
}
.rrp__card--star .rrp__cta:hover { background: #F2D56D; }

.rrp__guarantee {
  margin: 0.8rem 0 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  font-size: 0.75rem;
  color: var(--rrp-dim);
}
/* Bouclier minimaliste, dessine en CSS : pas d'icone a charger pour une
   ligne de 12 px. */
.rrp__shield {
  width: 11px; height: 13px;
  flex: 0 0 auto;
  background: var(--rrp-blue);
  clip-path: polygon(50% 0%, 100% 22%, 100% 62%, 50% 100%, 0% 62%, 0% 22%);
  opacity: 0.85;
}
.rrp__scarce {
  margin: 0.55rem 0 0;
  text-align: center;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--rrp-faint);
}
.rrp__reco {
  margin: 1rem 0 0;
  padding-top: 0.9rem;
  border-top: 1px solid var(--rrp-line);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--rrp-dim);
  font-style: italic;
}

/* ------------------------------------------------------------ aide au choix */
.rrp__guide {
  margin: clamp(2.5rem, 5vw, 4rem) auto 0;
  max-width: var(--container-narrow);
  padding: clamp(1.5rem, 2.6vw, 2.25rem);
  border: 1px solid var(--rrp-line);
  border-radius: var(--radius-m);
  text-align: center;
}
.rrp__guide-t {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--rrp-faint);
}
.rrp__guide-l {
  list-style: none;
  margin: 1.35rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}
.rrp__guide-l li { display: grid; gap: 0.2rem; }
.rrp__guide-n { font-family: var(--display); font-weight: 700; color: var(--rrp-ink); font-size: 1rem; }
.rrp__guide-d { font-size: 0.8125rem; color: var(--rrp-dim); }
.rrp__guide-p {
  margin: 1.5rem auto 0;
  max-width: 58ch;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--rrp-dim);
}

/* ------------------------------------------------------- pourquoi ce prix */
.rrp__why {
  margin: clamp(2.5rem, 5vw, 4rem) auto 0;
  max-width: 68ch;
  text-align: center;
}
.rrp__why-k {
  margin: 0 0 1.1rem;
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--rrp-blue);
}
.rrp__why-p {
  margin: 0 0 0.85rem;
  font-size: var(--fs-body);
  line-height: 1.65;
  color: var(--rrp-dim);
}
.rrp__why-s {
  margin: 1.2rem 0 0;
  font-family: var(--display);
  font-size: clamp(1.05rem, 1.7vw, 1.35rem);
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--rrp-ink);
}

/* -------------------------------------------------------------- conclusion */
.rrp__end {
  margin: clamp(2.5rem, 5vw, 4rem) auto 0;
  max-width: 62ch;
  text-align: center;
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid var(--rrp-line);
}
.rrp__end-t {
  margin: 0;
  font-family: var(--display);
  font-size: var(--fs-h3);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.15;
  color: var(--rrp-ink);
}
.rrp__end-p {
  margin: 0.9rem 0 0;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--rrp-dim);
}
.rrp__end-cta {
  display: inline-block;
  margin-top: 1.35rem;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--rrp-blue);
  border-bottom: 1px solid rgba(232, 197, 71, 0.4);
  padding-bottom: 2px;
}
.rrp__end-cta:hover { border-bottom-color: var(--rrp-blue); }

.rrp__foot {
  margin: clamp(1.6rem, 3vw, 2.5rem) 0 0;
  text-align: center;
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.1em;
  color: var(--rrp-faint);
}

#packages { scroll-margin-top: 6.5rem; }

/* ------------------------------------------------------------- responsive
   Pas de trois colonnes ecrasees. Sous 1080 px les cartes s'empilent, dans
   l'ordre Release / Launch / Complete, et Launch garde son badge et sa
   bordure bleue : c'est la seule hierarchie a preserver en mobile. */
@media (max-width: 1080px) {
  .rrp__grid { grid-template-columns: minmax(0, 1fr); max-width: 560px; margin-inline: auto; gap: 1.75rem; }
  .rrp__card--star { transform: none; }
  .rrp__promise { min-height: 0; }
  .rrp__guide-l { grid-template-columns: minmax(0, 1fr); gap: 0.9rem; }
  .rrp__guide-l li { display: flex; gap: 0.5rem; justify-content: center; align-items: baseline; }
}
@media (max-width: 640px) {
  .rrp__head { text-align: left; }
  .rrp__lead { text-align: left; }
  .rrp__toggle { width: 100%; }
  .rrp__tbtn { flex: 1; text-align: center; }
  #packages { scroll-margin-top: 5rem; }
}
@media (prefers-reduced-motion: reduce) {
  .rrp__card, .rrp__body, .rrp__cta { transition: none; }
}

/* -------------------------------------------------------------------------
   VARIANTE CLAIRE — ajouter `rrp--light` sur la <section> pour l'activer.
   Elle ne redefinit que les jetons du bloc : aucune regle ci-dessus n'est
   dupliquee. Livree non activee : a comparer en situation avant de trancher.
   ------------------------------------------------------------------------- */
.rrp--light {
  --rrp-bg: #FFFFFF;
  --rrp-card: #FFFFFF;
  --rrp-ink: #0A0B0D;
  --rrp-dim: #4A505B;
  --rrp-faint: #7A828F;
  --rrp-line: rgba(10, 11, 13, 0.10);
  --rrp-line-2: rgba(10, 11, 13, 0.22);
  --rrp-blue: #E8C547;
  --rrp-blue-deep: #BCA047;
  padding-inline: var(--gutter);
}
.rrp--light .rrp__card { box-shadow: 0 1px 2px rgba(10, 11, 13, 0.04); }
.rrp--light .rrp__card--star {
  background: #FFFFFF;
  border-color: rgba(232, 197, 71, 0.35);
  box-shadow: 0 24px 60px -34px rgba(232, 197, 71, 0.45);
}
.rrp--light .rrp__cta:hover { background: rgba(10, 11, 13, 0.04); }
.rrp--light .rrp__card--star .rrp__cta:hover { background: #F2D56D; }

/* =========================================================================
   v76 — RESSERRAGE VERTICAL, VIGNETTES DU PROCESS, BLOC COMPARATIF,
         TEMOIGNAGES VIDEO

   Cinq corrections issues des captures. Chacune est ecrite ici, en fin de
   feuille, et surcharge la regle d'origine sans la modifier : les blocs
   v72 / v73 / v74 restent lisibles tels qu'ils ont ete ecrits.
   ========================================================================= */

/* -------------------------------------------------------------------------
   §1 — L'ESPACE NOIR ENTRE LE TEMOIGNAGE DU FONDATEUR ET « EVERYTHING YOUR
        ARTIST BRAND NEEDS »

   `.fsig` fermait sur 3,75rem, puis `.section` rouvrait sur `--section-y`,
   soit jusqu'a 11rem. Les deux s'additionnaient : pres de 15rem de noir
   pour un simple changement de sujet. Le bas de la section est reduit dans
   le meme mouvement, parce que le bloc video qui s'y trouve maintenant est
   suivi immediatement de la grille de prix.
   ------------------------------------------------------------------------- */
.dlv {
  padding-top: clamp(2.5rem, 5vw, 4.5rem);
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
}
.dlv__head { margin-bottom: clamp(2.25rem, 4.5vw, 3.75rem); }
/* La section de prix rouvrait elle aussi sur `--section-y` juste apres. */
.rrp { padding-top: clamp(3rem, 6vw, 5rem); }

/* -------------------------------------------------------------------------
   §2 — LES TROIS VIGNETTES DU PROCESS

   Elles occupaient plus de la moitie de la largeur utile, donc environ
   360px de haut chacune en 3:2, face a une colonne de texte qui en fait
   210. La liste est ramenee a 1000px et les deux colonnes deviennent
   egales : l'illustration tombe a ~470px de large, soit ~313px de haut.
   Elle depasse encore le texte en haut et en bas, mais de peu — ce qui
   etait la demande, et ce qui garde l'image comme element principal.

   Les gouttieres verticales suivent : une etape ne peut pas etre plus
   espacee de la suivante qu'elle n'est haute.
   ------------------------------------------------------------------------- */
.hproc__list {
  max-width: 920px;
  margin-inline: auto;
  row-gap: clamp(2rem, 4vw, 3.25rem);
}
/* Sous 901px la regle d'origine empile les deux colonnes. Elle est ecrite
   PLUS HAUT dans cette feuille : une declaration sans media query ici la
   ecraserait et ramenerait deux colonnes sur telephone. D'ou le
   `min-width`. */
@media (min-width: 901px) {
  .hproc__step {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(1.5rem, 3.5vw, 3.5rem);
  }
}
.hproc__step:not(:last-child) { padding-bottom: clamp(2rem, 4vw, 3.25rem); }
.hproc__head { margin-bottom: clamp(2.25rem, 4.5vw, 3.75rem); }
.hproc { margin-top: clamp(3.5rem, 7vw, 6rem); }

/* Sous 860px les deux colonnes s'empilent deja (regle d'origine). La
   vignette y reprend toute la largeur : la plafonner ici la laisserait
   flotter au milieu d'une colonne vide. */

/* -------------------------------------------------------------------------
   §3 — LE BLOC COMPARATIF : QUATRE LIGNES, JAMAIS DEUX

   A 2,125rem, « Sound that still feels like a demo » cassait en deux et la
   colonne de gauche comptait cinq lignes face aux quatre de droite. Les
   deux colonnes descendent a 1,75rem : la ligne la plus longue tient, et
   les huit lignes sont a la meme hauteur.

   Les titres TRADITIONAL WAY et READY RELEASE ne bougent pas.

   `nowrap` n'est pose qu'au-dessus de 900px, la ou la mesure est sure. En
   dessous, la reduction de taille suffit et un `nowrap` risquerait un
   debordement horizontal.
   ------------------------------------------------------------------------- */
.cmp__li {
  font-size: clamp(1rem, 1.85vw, 1.75rem);
  grid-template-columns: clamp(34px, 3vw, 46px) minmax(0, 1fr);
  gap: clamp(0.7rem, 1.1vw, 1rem);
}
.cmp__list { gap: clamp(0.85rem, 1.6vw, 1.25rem); }
.cmp__x     { width: clamp(26px, 2.2vw, 34px); height: clamp(26px, 2.2vw, 34px); }
.cmp__mark  { width: clamp(32px, 2.9vw, 46px); }
@media (min-width: 900px) {
  .cmp__li > span { white-space: nowrap; }
}

/* -------------------------------------------------------------------------
   §4 — LES TROIS TEMOIGNAGES VIDEO

   Trois cadres 9:16 de taille strictement identique, poses sur une grille
   a trois colonnes egales. La grille est plafonnee a 900px : a pleine
   largeur de conteneur, une colonne ferait 420px, donc 747px de haut, et
   le bloc mangerait un ecran entier a lui seul. A 900px chaque cadre fait
   ~285px de large et ~505px de haut, ce qui reste la proportion d'un
   telephone pose sur la page.

   Aucune marge haute ou basse supplementaire : le resserrage du §1 tient
   deja l'espacement avec la section du dessus et la grille de prix du
   dessous.
   ------------------------------------------------------------------------- */
.tvid { margin-top: clamp(2.25rem, 4.5vw, 3.5rem); }
.tvid__grid {
  list-style: none;
  margin: 0 auto;
  padding: 0;
  max-width: 900px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.75rem, 1.6vw, 1.25rem);
}
.tvid__i { min-width: 0; }
.tvid__frame {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: clamp(10px, 1.1vw, 18px);
  overflow: hidden;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line), 0 22px 52px rgba(0, 0, 0, 0.42);
}
.tvid__v {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* L'emplacement vide. Il se lit comme reserve, pas comme casse : filet
   pointille, pictogramme neutre, libelle. */
.tvid__ph {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.85rem;
  border: 1px dashed var(--line-strong);
  border-radius: inherit;
  background: linear-gradient(180deg, rgba(232, 197, 71, 0.05), transparent 60%);
}
.tvid__ph-ic {
  width: clamp(28px, 3vw, 40px);
  height: clamp(28px, 3vw, 40px);
  border: 1px solid var(--ash-dim);
  border-radius: 50%;
  position: relative;
}
/* Triangle de lecture, dessine en CSS : pas de fichier a charger pour un
   emplacement qui a vocation a disparaitre. */
.tvid__ph-ic::after {
  content: "";
  position: absolute;
  top: 50%; left: 54%;
  transform: translate(-50%, -50%);
  border-left: 10px solid var(--ash-dim);
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
}
.tvid__ph-l {
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash-dim);
}

/* Trois colonnes jusqu'au bout : empiler des 9:16 les uns sous les autres
   ferait defiler trois ecrans. En mobile la grille se resserre, elle ne se
   casse pas. */
@media (max-width: 620px) {
  .tvid__grid { gap: 0.5rem; max-width: none; }
  .tvid__ph { gap: 0.5rem; }
  .tvid__ph-l { font-size: 0.5rem; letter-spacing: 0.1em; }
}

/* =========================================================================
   v77 — SECTION 01, VERSION COURTE (.conv--slim)
   Le bloc ne garde que l'argument : titre, promesse, trois lignes de contenu.
   Le cadre bleu part, et avec lui le prix, l'upload, la reassurance et le
   lien vers le pack. Objectif mesure : moitie de la hauteur precedente
   (~590px pleine largeur avant, ~290px apres).

   La photo n'est pas seulement retrecie, elle est recadree. Elle occupait
   66% de la largeur sur un bloc haut ; a hauteur divisee par deux, le meme
   object-position ne montrait plus qu'un torse coupe. Elle passe a 46% et
   remonte sur le visage et la console.
   ========================================================================= */
.conv--slim {
  border: 0;
  border-radius: var(--radius-m);
  padding: clamp(1.15rem, 2.4vw, 1.7rem) clamp(1.1rem, 2.6vw, 2rem);
  grid-template-columns: minmax(0, 1fr);
  row-gap: clamp(0.75rem, 1.8vw, 1.1rem);
  background:
    radial-gradient(90% 160% at 8% 0%, rgba(232, 197, 71, 0.07), transparent 62%),
    var(--surface);
}
/* plus de filet sous l'en-tete : a cette hauteur il decoupait le bloc en deux
   bandes de 120px et annulait le gain de compacite */
.conv--slim .conv__head {
  border-bottom: 0;
  padding-bottom: 0;
  max-width: min(52ch, 58%);
}
.conv--slim .conv__t { font-size: clamp(1.2rem, 2.05vw, 1.65rem); max-width: 26ch; }
.conv--slim .conv__sub { margin-top: 0.5rem; line-height: 1.55; }

/* les trois lignes passent sur deux colonnes : en une seule colonne elles
   rendaient au bloc la hauteur qu'on venait de lui retirer */
.conv--slim .conv__inc {
  max-width: min(60ch, 58%);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.45rem clamp(1rem, 2.5vw, 2rem);
}
.conv--slim .conv__inc li:first-child { grid-column: 1 / -1; }

.conv--slim .conv__photo { width: 46%; }
.conv--slim .conv__photo img {
  object-position: 56% 30%;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,0.5) 30%, #000 68%);
          mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,0.5) 30%, #000 68%);
}
.conv--slim .conv__veil {
  background:
    linear-gradient(100deg,
      var(--surface) 0%,
      rgba(15, 17, 21, 0.94) 40%,
      rgba(15, 17, 21, 0.55) 62%,
      rgba(15, 17, 21, 0.18) 100%);
}
@media (max-width: 859px) {
  .conv--slim .conv__head,
  .conv--slim .conv__inc { max-width: none; }
  .conv--slim .conv__inc { grid-template-columns: 1fr; }
  .conv--slim .conv__inc li:first-child { grid-column: auto; }
  .conv--slim .conv__photo { width: 100%; }
  .conv--slim .conv__photo img {
    object-position: 60% 28%;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 60%);
            mask-image: linear-gradient(to bottom, transparent 0%, #000 60%);
  }
  /* en une colonne le texte traverse toute la largeur : le voile diagonal
     du desktop laissait la sous-ligne passer sur le visage */
  .conv--slim .conv__veil {
    background:
      linear-gradient(to bottom, var(--surface) 0%, rgba(15, 17, 21, 0.93) 34%, rgba(15, 17, 21, 0.86) 100%);
  }
}

/* =========================================================================
   v77 — LIGNE DE FORMATS SANS BOUTON
   Cover Art et YouTube Thumbnail n'ont plus de bouton d'ajout. La ligne qui
   vivait sous lui remonte a sa place : centree, un cran plus grande, et sur
   la couleur de texte courante plutot que sur le gris de note de bas de page,
   puisqu'elle est maintenant le dernier mot du bloc et non une legende.
   ========================================================================= */
.sec-cta__formats--solo {
  margin-top: clamp(1.1rem, 2.4vw, 1.6rem);
  margin-inline: auto;
  max-width: 68ch;
  text-align: center;
  font-size: clamp(0.86rem, 1.05vw, 0.95rem);
  line-height: 1.55;
  color: var(--ash);
  text-wrap: pretty;
}

/* =========================================================================
   v77 — SOCIAL MEDIA KIT + MOCKUPS
   Rubrique de presentation : meme geometrie que prod--thumb, soulignement
   statique comme prod--cover (l'animation au mot-cle reste l'effet propre du
   bloc thumbnail, la dupliquer une troisieme fois en ferait un tic de page).
   ========================================================================= */
.prod--social { margin-bottom: clamp(2.25rem, 5vw, 3.75rem); }

/* bandeau en attente d'images : cadre pointille + numero, meme geometrie
   carree que le bandeau Cover Art pour que les deux bandes se repondent */
.cmq__tile--ph {
  border: 1px dashed var(--line-strong);
  background:
    repeating-linear-gradient(135deg,
      rgba(242, 240, 235, 0.022) 0 8px,
      transparent 8px 16px),
    var(--surface);
  display: grid;
  place-items: center;
}
.cmq__item:hover .cmq__tile--ph { transform: none; }
.cmq__phn {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  color: var(--ash-dim);
}

/* =========================================================================
   v78 — CHAPITRE 04 RECONSTRUIT + FIN DE CHAPITRE 03
   Une seule regle de composition pour tout le chapitre : le texte porte, les
   cadres disparaissent. Pas de carte fermee, pas de tableau de prix, pas de
   deuxieme systeme typographique — tout est bati sur --display / --mono, les
   tokens de couleur existants et la primitive .reveal deja pilotee par
   main.js. Aucun JS n'a ete ajoute.
   ========================================================================= */

/* ---------- 03 · la phrase de fin, seule ----------
   Elle remplace le bloc tarifaire. Centree, large, sans cadre : c'est la
   respiration entre deux chapitres, pas un encart. */
.endline {
  margin: clamp(2.5rem, 6vw, 4.5rem) auto 0;
  max-width: 24ch;
  text-align: center;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.9rem, 5vw, 3.6rem);
  line-height: 1.04;
  letter-spacing: -0.03em;
  color: var(--bone);
  text-wrap: balance;
}
.endline__kw { color: var(--signal); font-weight: 700; }

/* Le vide noir entre 03 et 04 venait du bas de section calibre pour un bloc
   de ~600px. Sans lui, la marge basse standard laissait un ecran presque
   vide avant l'ouverture du chapitre 04. */
#shorts.section { padding-bottom: clamp(3rem, 7vw, 5.5rem); }
/* =====================================================================
   CHAPITRE 04 · FULL VIDEO CLIP — refonte v79
   Contraintes du brief : aucune card, aucune tile, aucune grille de
   blocs, aucun container repetitif. Filets fins, asymetrie, vide.
   Echelle typographique alignee sur le reste du site : plus aucun
   titre de ce chapitre ne depasse --fs-h2.
   ===================================================================== */

.vblock { margin-top: clamp(4.5rem, 11vw, 9rem); }

.vw__t {
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h2);
  line-height: 1.03;
  letter-spacing: -0.035em;
  max-width: 20ch;
  text-wrap: balance;
}
/* v79 — l'ancien --big montait a 5rem et cassait l'echelle de la page. */
.vw__t--lead { max-width: 22ch; }
.vw__t--mid { font-size: var(--fs-h3); max-width: 26ch; margin-top: clamp(2.5rem, 6vw, 4rem); }

.vw__lead {
  margin-top: 1.15rem;
  font-size: var(--fs-lead);
  line-height: 1.55;
  color: var(--ash);
  max-width: 56ch;
}
.vw__sub { margin-top: 1rem; font-size: 0.9375rem; line-height: 1.6; color: var(--ash-dim); max-width: 54ch; }

/* Un seul index CSS pour toutes les cascades du chapitre. */
.vbeat__i, .vdep__i, .varc__i, .vget__i, .vlev__i, .vsteps .vstep {
  transition-delay: calc(var(--i, 0) * 80ms);
}

/* ---------- 01 · these ---------- */
.vhero { margin-top: clamp(1.5rem, 4vw, 3rem); max-width: 62ch; }
.vhero__eyebrow {
  color: var(--ash-dim);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  font-size: 0.7rem;
}
.vhero__t {
  margin-top: 1.4rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h2);
  line-height: 1.02;
  letter-spacing: -0.04em;
}
.vhero__t2 { color: var(--signal); }
.vhero__lead {
  margin-top: 1.4rem;
  font-size: var(--fs-lead);
  line-height: 1.6;
  color: var(--ash);
  max-width: 52ch;
}

/* ---------- 02 · trois temps ----------
   Lignes continues separees par un filet, pas trois colonnes. */
.vbeat { margin-top: clamp(2.25rem, 5vw, 3.25rem); max-width: 62ch; }
.vbeat__i {
  display: grid;
  grid-template-columns: 8rem 1fr;
  gap: 1.5rem;
  align-items: baseline;
  padding: 1.1rem 0;
  border-top: 1px solid var(--line);
}
.vbeat__i:last-child { border-bottom: 1px solid var(--line); }
.vbeat__k {
  color: var(--ash-dim);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.vbeat__i:nth-child(2) .vbeat__k { color: var(--signal); }
.vbeat__p { font-size: var(--fs-body); line-height: 1.5; color: var(--bone); }

/* ---------- 03 · LE DEPLOIEMENT · element signature ----------
   Une tige verticale, cinq filets horizontaux de longueurs inegales.
   Aucune boite : le dessin EST l'argument. --w decale chaque libelle,
   ce qui produit l'asymetrie demandee au brief. */
.vdep__kicker {
  color: var(--ash-dim);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin-bottom: 1rem;
}

.vdep {
  position: relative;
  margin-top: clamp(2.75rem, 6vw, 4.5rem);
  padding-left: clamp(1.5rem, 4vw, 3rem);
}
/* la tige */
.vdep::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.6em;
  bottom: 2.2rem;
  width: 1px;
  background: linear-gradient(180deg,
              var(--signal) 0%,
              var(--line-strong) 22%,
              var(--line) 100%);
}

.vdep__src {
  position: relative;
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h3);
  letter-spacing: -0.025em;
  color: var(--bone);
  line-height: 1;
}
.vdep__dot {
  position: absolute;
  left: calc(-1 * clamp(1.5rem, 4vw, 3rem) - 3px);
  top: 0.42em;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--signal);
  box-shadow: 0 0 0 4px rgba(232, 197, 71, 0.14);
}

.vdep__list { margin-top: clamp(2rem, 5vw, 3rem); }

.vdep__i {
  position: relative;
  padding: 1.35rem 0 1.35rem calc(var(--w, 20%) * 0.42 + 2.5rem);
  display: block;
}
/* le filet qui part de la tige jusqu'au libelle */
.vdep__i::before {
  content: '';
  position: absolute;
  left: calc(-1 * clamp(1.5rem, 4vw, 3rem));
  top: 2.05rem;
  width: calc(var(--w, 20%) * 0.42 + clamp(1.5rem, 4vw, 3rem) + 1.6rem);
  height: 1px;
  background: linear-gradient(90deg, var(--line-strong), var(--line));
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform 1s var(--ease) calc(var(--i, 0) * 110ms + 120ms);
}
.vdep__i.is-in::before { transform: scaleX(1); }

.vdep__t {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.15rem, 1.9vw, 1.6rem);
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--bone);
}
.vdep__p {
  display: block;
  margin-top: 0.5rem;
  color: var(--ash-dim);
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.vdep__i:first-child .vdep__t { color: var(--signal); }

.vdep__foot {
  margin-top: clamp(2rem, 5vw, 3rem);
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--fs-h3);
  letter-spacing: -0.02em;
  color: var(--bone);
  max-width: 24ch;
}

/* ---------- 04 · l'arc ----------
   Escalier vertical plutot que course horizontale : quatre temps sur une
   seule ligne se cassaient au retour a la ligne, laissant un filet
   orphelin en debut de rang. L'indentation croissante dit la meme chose
   et porte l'asymetrie demandee au brief. */
.varc { margin-left: clamp(0rem, 6vw, 7rem); }
.varc__run { display: grid; gap: clamp(0.6rem, 1.5vw, 1rem); }
.varc__i {
  display: flex;
  align-items: baseline;
  gap: clamp(0.9rem, 2vw, 1.5rem);
  padding-left: calc(var(--i, 0) * clamp(0.75rem, 2.5vw, 2.75rem));
}
.varc__i::before {
  content: '';
  flex: 0 0 auto;
  width: clamp(1.75rem, 5vw, 4.5rem);
  height: 1px;
  background: var(--line-strong);
  transform: translateY(-0.35em);
}
.varc__i--end::before { background: var(--signal); }
.varc__l {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.05rem, 2.1vw, 1.7rem);
  letter-spacing: -0.025em;
  color: var(--ash);
}
.varc__i--end .varc__l { color: var(--signal); }
.varc .vw__sub { margin-top: clamp(1.5rem, 3vw, 2rem); }

/* ---------- 05 · seconde piece · emplacement video ----------
   Compact et decale : il enrichit sans dominer. Le placeholder a la
   meme empreinte que la vraie video, donc la substituer ne deplace
   rien dans la page. */
.vfilm {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
  margin-top: clamp(1.5rem, 4vw, 2.5rem);
}
.vfilm__fig { margin: 0; max-width: 560px; }
.vfilm__ph,
.vfilm__v {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-s);
  overflow: hidden;
}
.vfilm__v { object-fit: cover; background: var(--void-2); }
.vfilm__ph {
  background:
    radial-gradient(120% 90% at 20% 0%, rgba(232, 197, 71, 0.10), transparent 60%),
    var(--void-2);
  box-shadow: inset 0 0 0 1px var(--line);
}
.vfilm__sheen {
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg,
              transparent 38%,
              rgba(242, 240, 235, 0.055) 50%,
              transparent 62%);
  transform: translateX(-100%);
  animation: vfilmSheen 6.5s var(--ease) infinite;
}
@keyframes vfilmSheen {
  0%, 62% { transform: translateX(-100%); }
  100%    { transform: translateX(100%); }
}
/* Repere de lecture : l'encadre doit se lire comme un emplacement video,
   pas comme un bloc vide. Trace fin, aucun aplat. */
.vfilm__ph::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  width: clamp(38px, 5vw, 52px);
  height: clamp(38px, 5vw, 52px);
  transform: translate(-50%, -50%);
  border: 1px solid var(--line-strong);
  border-radius: 50%;
}
.vfilm__play {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-42%, -50%);
  width: 0; height: 0;
  border-left: clamp(9px, 1.2vw, 12px) solid var(--ash);
  border-top: clamp(6px, 0.8vw, 8px) solid transparent;
  border-bottom: clamp(6px, 0.8vw, 8px) solid transparent;
}
.vfilm__badge {
  position: absolute;
  left: clamp(0.9rem, 2vw, 1.4rem);
  bottom: clamp(0.9rem, 2vw, 1.4rem);
  color: var(--ash);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.vfilm__cap {
  margin-top: 0.85rem;
  color: var(--ash);
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
/* v85 — la legende porte desormais deux informations d'importance inegale :
   l'interprete et le titre (ce qu'on regarde), puis la nature du fichier (un
   extrait). Un seul niveau de gris les separe — pas de seconde taille, pas de
   seconde famille : la legende reste une ligne, pas un bloc. */
.vfilm__cap-x { color: var(--ash-dim); }
.vfilm__t {
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--fs-h3);
  line-height: 1.15;
  letter-spacing: -0.025em;
  color: var(--bone);
  max-width: 24ch;
}

/* ---------- 06 · monde d'artiste ---------- */
.vstmt {
  margin-top: clamp(2rem, 5vw, 3rem);
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--fs-h3);
  line-height: 1.2;
  letter-spacing: -0.025em;
  color: var(--bone);
  max-width: 34ch;
}
.vstmt__b { color: var(--signal); }

.vvs {
  margin-top: clamp(2.25rem, 5vw, 3.25rem);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
  max-width: 76ch;
}
.vvs__side { padding-top: 1.2rem; border-top: 1px solid var(--line-strong); }
.vvs__side--b { border-top-color: var(--signal); }
.vvs__k { color: var(--ash-dim); font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase; }
.vvs__t {
  margin-top: 0.8rem;
  font-size: var(--fs-body);
  line-height: 1.5;
  color: var(--ash);
  max-width: 30ch;
}
.vvs__side--b .vvs__t { color: var(--bone); }
.vvs__x { align-self: center; color: var(--ash-dim); font-size: 0.7rem; letter-spacing: 0.2em; text-transform: uppercase; }

/* ---------- 07 · du morceau a l'ecran ----------
   Lignes filees, plus de cartes. Le numero vit dans la marge. */
.vsteps { margin-top: clamp(2rem, 5vw, 3rem); max-width: 70ch; }
.vstep {
  display: grid;
  grid-template-columns: 3.5rem 1fr;
  gap: 0 1.5rem;
  padding: 1.35rem 0;
  border-top: 1px solid var(--line);
}
.vsteps .vstep:last-child { border-bottom: 1px solid var(--line); }
.vstep__n { color: var(--ash-dim); font-size: 0.7rem; letter-spacing: 0.14em; padding-top: 0.3em; }
.vstep__name {
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--fs-body);
  letter-spacing: -0.01em;
  color: var(--bone);
}
.vstep__do { grid-column: 2; margin-top: 0.35rem; font-size: 0.9375rem; line-height: 1.55; color: var(--ash); }
.vstep__why { grid-column: 2; margin-top: 0.4rem; font-size: 0.875rem; line-height: 1.5; color: var(--signal); opacity: 0.85; }

.vdet { margin-top: 1.75rem; border-top: 1px solid var(--line); max-width: 70ch; }
.vdet__sum {
  list-style: none;
  cursor: pointer;
  padding: 1.1rem 0;
  font-family: var(--caps);
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ash);
  display: flex;
  align-items: center;
  gap: 0.75rem;
  transition: color 0.25s var(--ease);
}
.vdet__sum::-webkit-details-marker { display: none; }
.vdet__sum::before {
  content: '+';
  display: inline-block;
  width: 1em;
  color: var(--signal);
  font-size: 1.1rem;
  line-height: 1;
}
.vdet[open] .vdet__sum::before { content: '\2212'; }
.vdet__sum:hover { color: var(--bone); }
.vdet__in { padding-bottom: 1.25rem; }
.vsteps--det { margin-top: 0; }

.vhyb { margin-top: clamp(3rem, 7vw, 5rem); }

.clip-pos {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  padding-left: clamp(1rem, 3vw, 2rem);
  border-left: 1px solid var(--signal);
  font-family: var(--display);
  font-weight: 500;
  font-size: var(--fs-lead);
  line-height: 1.45;
  color: var(--ash);
  max-width: 44ch;
}

/* ---------- 08 · ce que vous repartez avec ---------- */
.vget { margin-top: clamp(2rem, 5vw, 3rem); max-width: 70ch; }
.vget__i {
  display: grid;
  grid-template-columns: 11rem 1fr;
  gap: 1.5rem;
  align-items: baseline;
  padding: 1.15rem 0;
  border-top: 1px solid var(--line);
}
.vget__i:last-child { border-bottom: 1px solid var(--line); }
.vget__k { color: var(--signal); font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase; }
.vget__t { font-size: var(--fs-body); line-height: 1.45; color: var(--bone); }

.vlev { margin-top: clamp(3.5rem, 8vw, 6rem); }
.vlev__grid {
  margin-top: clamp(2rem, 5vw, 3rem);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.75rem, 4vw, 3.5rem);
}
.vlev__i { padding-top: 1.2rem; border-top: 1px solid var(--line-strong); }
.vlev__i:nth-child(2) { border-top-color: var(--signal); }
.vlev__n {
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h3);
  letter-spacing: -0.025em;
  color: var(--bone);
}
.vlev__who { margin-top: 0.7rem; font-size: 0.9375rem; line-height: 1.5; color: var(--ash); }
.vlev__get { margin-top: 1.1rem; display: grid; gap: 0.55rem; }
.vlev__get li {
  position: relative;
  padding-left: 1rem;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--bone);
}
.vlev__get li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.62em;
  width: 5px; height: 1px;
  background: var(--signal);
}
.vlev__rev { margin-top: 1rem; color: var(--ash-dim); font-size: 0.7rem; letter-spacing: 0.14em; text-transform: uppercase; }
.vlev__specs { margin-top: clamp(1.75rem, 4vw, 2.5rem); color: var(--ash); font-size: 0.7rem; letter-spacing: 0.14em; text-transform: uppercase; }
.vlev__seal { margin-top: 0.6rem; }
.vlev__live {
  margin-top: 1.5rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--line);
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ash);
  max-width: 56ch;
}
.vlev__live-k { color: var(--bone); font-weight: 600; }

/* ---------- 09 · sortie de chapitre ---------- */
.vend { text-align: left; }
/* v79 — descendu de 4.6rem a l'echelle h2 du site. */
.vend__t {
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h2);
  line-height: 1.02;
  letter-spacing: -0.04em;
  color: var(--bone);
  max-width: 16ch;
}
.vend__act { margin-top: 2rem; }

/* ---------- respirations ---------- */
@media (max-width: 1080px) {
  .vfilm { grid-template-columns: 1fr; gap: 2rem; }
  .vfilm__fig { max-width: 100%; }
  .vlev__grid { grid-template-columns: 1fr; gap: 2rem; }
}
@media (max-width: 860px) {
  .vvs { grid-template-columns: 1fr; gap: 1.5rem; }
  .vvs__x { justify-self: start; }
  .vdep__i { padding-left: 2rem; }
  .vdep__i::before { width: calc(clamp(1.5rem, 4vw, 3rem) + 1.4rem); }
  .varc__i + .varc__i::before { width: 1.25rem; margin: 0 0.75rem; }
}
@media (max-width: 640px) {
  .vbeat__i { grid-template-columns: 1fr; gap: 0.4rem; }
  .vget__i { grid-template-columns: 1fr; gap: 0.4rem; }
  .vstep { grid-template-columns: 2.5rem 1fr; gap: 0 1rem; }
  .vhero__t, .vw__t { max-width: 100%; }
  /* L'escalier se resserre mais garde ses filets : les masquer ne laissait
     un tiret qu'au premier rang, ce qui se lisait comme un bug. */
  .varc__i { gap: 0.75rem; padding-left: calc(var(--i, 0) * 0.5rem); }
  .varc__i::before { width: 1.25rem; }
}

@media (prefers-reduced-motion: reduce) {
  .vbeat__i, .vdep__i, .varc__i, .vget__i, .vlev__i, .vsteps .vstep {
    transition-delay: 0s !important;
  }
  .vdep__i::before { transform: scaleX(1); transition: none; }
  .vfilm__sheen { animation: none; }
}

/* =========================================================================
   =========================================================================
   V82 — BRIEF WORD DU 25/08 (six chantiers)

   Ce bloc est volontairement en fin de feuille : il surcharge des regles
   ecrites plus haut (v39, v40, v53, v81) sans les supprimer, ce qui rend
   chaque changement lisible et reversible d'un seul tenant.
   =========================================================================
   ========================================================================= */

/* -------------------------------------------------------------------------
   1 — INDUSTRY-STANDARD SOUND : une composition, deux recits
   Le brief interdit nommement : cards, grand rectangle bleu, bordures a
   repetition, surcharge d'elements d'interface, degrades, langage visuel
   "AI startup". Ce qui suit retire tout cela et laisse la typographie, la
   photographie et l'espace faire le travail.
   ------------------------------------------------------------------------- */
.vsblk--v82 {
  --vs-left:  #08090b;          /* charbon presque noir : l'impasse */
  --vs-right: #101216;          /* a peine plus clair : la sortie   */
  border: 0;                    /* c'etait le cadre qui en faisait une carte */
  background: linear-gradient(90deg,
    var(--vs-left) 0%, var(--vs-left) 50%,
    var(--vs-right) 50%, var(--vs-right) 100%);
  padding: clamp(2.5rem, 6.5vw, 5.5rem) clamp(1.75rem, 5vw, 4.5rem);
  margin-top: clamp(4rem, 9vw, 7rem);
}

/* le subgrid de la v39 alignait trois rangees fixes : la composition n'en a
   plus, il faut le neutraliser explicitement */
.vsblk--v82 .vsblk__cols {
  grid-template-columns: minmax(0, 0.78fr) minmax(0, 1.22fr);
  grid-template-rows: auto;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.vsblk--v82 .vsblk__c { display: block; grid-row: auto; grid-template-rows: none; }

/* la photographie ne vit plus qu'a droite : le brief demande un charbon nu
   a gauche, et une texture photographique discrete a droite seulement */
.vsblk--v82 .vsblk__bg { inset: 0 0 0 50%; grid-template-columns: 1fr; }
.vsblk--v82 .vsblk__half--us .vsblk__img { opacity: 0.15; filter: saturate(0.9); }
.vsblk--v82 .vsblk__half--us::after {
  left: 0; width: 22%;
  background: linear-gradient(270deg, transparent, var(--vs-right));
}
.vsblk--v82::before {
  background: linear-gradient(180deg,
    rgba(8, 9, 11, 0.62) 0%, rgba(8, 9, 11, 0.76) 55%, rgba(8, 9, 11, 0.90) 100%);
}

/* ---- gauche : l'alternative automatique, volontairement en retrait ---- */
.vsblk--v82 .vsblk__lbl {
  color: var(--ash-dim);
  font-size: 0.6875rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}
.vsblk--v82 .vsblk__c--them .vsblk__t {
  margin-top: 1.5rem;
  font-size: clamp(1.05rem, 1.75vw, 1.4rem);
  font-weight: 500;
  line-height: 1.32;
  letter-spacing: -0.012em;
  color: var(--ash);
  max-width: 22ch;
}
.vsblk--v82 .vsblk__names {
  margin-top: 1.9rem;
  color: var(--ash-dim);
  font-size: 0.625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  line-height: 1.7;
}
.vsblk--v82 .vsblk__c--them .vsblk__body { margin-top: 1.5rem; }
.vsblk--v82 .vsblk__c--them .vsblk__body p {
  margin: 0 0 0.75rem;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ash-dim);
  max-width: 30ch;
}
.vsblk--v82 .vsblk__dead {
  margin-top: 2.25rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.1rem, 1.8vw, 1.4rem);
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--ash);
}

/* ---- le filet : un seul trait vertical, pas un cadre ---- */
.vsblk--v82 .vsblk__c--us {
  border-left: 1px solid rgba(232, 197, 71, 0.42);
  background: none;                     /* le "large blue rectangle" part ici */
  padding-left: clamp(1.5rem, 3.2vw, 3rem);
}

/* ---- droite : sceau, titre, preuve, benefices, cloture ---- */
.vsblk--v82 .vsblk__mark--rr {
  min-height: 0;
  justify-content: flex-start;          /* le sceau s'aligne sur la colonne */
  margin-bottom: clamp(1.75rem, 3.5vw, 2.75rem);
}
.vsblk--v82 .vsblk__logo { width: 116px; height: 116px; }

.vsblk--v82 .vsblk__t--lead {
  font-family: var(--display);
  font-weight: 700;
  /* 2 lignes sur desktop, comme demande au brief : le <br> force la coupe,
     le corps est cale pour que la premiere ligne tienne dans la colonne. */
  font-size: clamp(1.7rem, 2.8vw, 2.35rem);
  line-height: 1.06;
  letter-spacing: -0.035em;
  color: var(--bone);
  max-width: none;
}

.vsblk--v82 .vsblk__proof {
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  display: grid;
  gap: 0.4rem;
}
.vsblk--v82 .vsblk__proof-k {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.1rem, 1.85vw, 1.45rem);
  letter-spacing: -0.02em;
  color: var(--bone);
}
.vsblk--v82 .vsblk__proof-s {
  font-size: var(--fs-body);
  line-height: 1.5;
  color: var(--ash);
}

/* trois lignes scannables, pas trois cartes : un filet fin, rien d'autre */
.vsblk--v82 .vsblk__ben {
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  list-style: none;
  padding: 0;
  border-top: 1px solid var(--line);
  max-width: 34ch;
}
.vsblk--v82 .vsblk__ben-i {
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-body);
  line-height: 1.35;
  color: var(--bone);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.6s var(--ease) calc(var(--i, 0) * 110ms + 260ms),
              transform 0.6s var(--ease) calc(var(--i, 0) * 110ms + 260ms);
}
.vsblk.is-in .vsblk__ben-i { opacity: 1; transform: none; }

.vsblk--v82 .vsblk__close {
  margin-top: clamp(2rem, 4vw, 3rem);
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.25rem, 2.1vw, 1.85rem);   /* jamais au-dessus du titre */
  line-height: 1.16;
  letter-spacing: -0.028em;
  color: var(--bone);
}
.vsblk--v82 .vsblk__close-b { color: var(--ash); }

@media (max-width: 860px) {
  .vsblk--v82 {
    background: linear-gradient(180deg,
      var(--vs-left) 0%, var(--vs-left) 46%, var(--vs-right) 46%, var(--vs-right) 100%);
  }
  /* pas de photo sous 860px : elle passerait sous le texte au lieu de rester
     derriere lui, ce que le brief interdit explicitement */
  .vsblk--v82 .vsblk__bg { display: none; }
  .vsblk--v82 .vsblk__cols { grid-template-columns: 1fr; gap: 2.5rem; }
  .vsblk--v82 .vsblk__c--us {
    border-left: 0;
    border-top: 1px solid rgba(232, 197, 71, 0.42);   /* le filet bascule */
    padding-left: 0;
    padding-top: 2.25rem;
  }
  .vsblk--v82 .vsblk__t--lead { font-size: clamp(1.75rem, 8vw, 2.4rem); max-width: none; }
  .vsblk--v82 .vsblk__logo { width: 92px; height: 92px; }
}

@media (prefers-reduced-motion: reduce) {
  .vsblk--v82 .vsblk__ben-i { opacity: 1; transform: none; transition: none; }
}

/* -------------------------------------------------------------------------
   2 — "What branding actually buys you" : les lignes se rapprochent
   ------------------------------------------------------------------------- */
.wbrand .vdep--brand .vdep__i { padding-top: 1.15rem; padding-bottom: 1.15rem; }
.wbrand .vdep--brand .vdep__i::before { top: 1.85rem; }
.wbrand .vdep__d { margin-top: 0.35rem; line-height: 1.45; }
.wbrand .vdep--brand { margin-top: clamp(1.75rem, 4vw, 2.75rem); }
.wbrand .vdep__list { margin-top: clamp(1.4rem, 3vw, 2rem); }

/* -------------------------------------------------------------------------
   3 — "The goal isn't more content." sur UNE ligne
   85 caracteres dans un conteneur de 1238px : la seule facon de tenir en
   une ligne est de descendre le corps. C'est un arbitrage assume, pas un
   oubli — le bloc perd un peu de poids typographique.
   ------------------------------------------------------------------------- */
.vdep__foot--one {
  max-width: none;
  font-size: clamp(1.05rem, 1.72vw, 1.75rem);
  line-height: 1.25;
  text-wrap: nowrap;
}
.vdep__foot-b { color: var(--signal); font-weight: 700; }
@media (max-width: 1100px) {
  .vdep__foot--one { text-wrap: balance; max-width: 34ch; }
}

/* -------------------------------------------------------------------------
   4 + 5 — UN SEUL FILM, ET LES SPECS EN DEUX LIGNES
   Les trois colonnes de paliers deviennent quatre cellules en largeur ;
   les quatre lignes de specs deviennent deux bandeaux horizontaux.
   ------------------------------------------------------------------------- */
.vlev--one { margin-top: clamp(3rem, 7vw, 5rem); }
.vlev__lead {
  margin-top: 1.1rem;
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--ash);
  max-width: 62ch;
}
.vlev__row {
  margin-top: clamp(1.75rem, 4vw, 2.75rem);
  list-style: none;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0 clamp(1.25rem, 3vw, 2.5rem);
}
.vlev__cell {
  padding-top: 1rem;
  border-top: 1px solid var(--line-strong);
  transition-delay: calc(var(--i, 0) * 90ms);
}
.vlev__cell:first-child { border-top-color: var(--signal); }
.vlev__k {
  display: block;
  color: var(--signal);
  font-size: 0.65rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.vlev__v {
  display: block;
  margin-top: 0.6rem;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--bone);
}

/* ligne 1 : toutes les specs, y compris le sceau, sur un seul rang */
.vlev__strip {
  margin-top: clamp(2rem, 4.5vw, 3rem);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem clamp(0.9rem, 2vw, 1.6rem);
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
}
.vlev__spec {
  position: relative;
  color: var(--ash);
  font-size: 0.6875rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}
.vlev__spec + .vlev__spec::before {
  content: '';
  position: absolute;
  left: calc(clamp(0.9rem, 2vw, 1.6rem) / -2);
  top: 0.42em;
  width: 3px; height: 3px;
  background: var(--line-strong);
}
.vlev__spec--seal { color: var(--signal); }

/* ligne 2 : le live action, en pleine largeur, sans retour a la ligne */
.vlev--one .vlev__live {
  margin-top: 0.9rem;
  padding-top: 0;
  border-top: 0;
  max-width: none;
}
@media (max-width: 1080px) {
  .vlev__row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem clamp(1.25rem, 3vw, 2.5rem); }
}
@media (max-width: 620px) {
  .vlev__row { grid-template-columns: 1fr; gap: 1.25rem; }
}

/* -------------------------------------------------------------------------
   6 — LE CHAPITRE 05 GAGNE EN LARGEUR, PERD EN HAUTEUR
   Resserrage mesure : rythme vertical entre blocs, interlignes des titres,
   et mesures de ligne elargies pour occuper la surface horizontale libre.
   ------------------------------------------------------------------------- */
.section--why { padding-block: clamp(3.5rem, 8vw, 6.5rem); }
.section--why .wblock { margin-top: clamp(2.75rem, 6.5vw, 5rem); }

.wpain { max-width: 76ch; }
.wpain__t { margin-top: 1.1rem; }
.wpain__lead { margin-top: 1.15rem; max-width: 68ch; line-height: 1.55; }

.wans { max-width: 66ch; }
.wans__lead { margin-top: 1rem; max-width: 62ch; line-height: 1.55; }

.wsec__t { max-width: 38ch; }
.wpil { gap: clamp(2rem, 4.5vw, 3.75rem); }
.wpil__i { padding: 1.05rem 0; }
.wpil__lead .wpil__t { margin-top: 0.8rem; max-width: 24ch; }
.wpil__lead .wpil__b { margin-top: 0.9rem; max-width: 46ch; }
.wpil__b { line-height: 1.5; }
.wcmp__lead { margin-top: 0.95rem; max-width: 66ch; line-height: 1.55; }
.wtrack { margin-top: clamp(1.75rem, 4.5vw, 3rem); }

/* -------------------------------------------------------------------------
   7 — LE RAIL FIXE DU CHAPITRE 05
   Copie deliberee de la grammaire de .chprog : meme coin, meme largeur,
   meme bascule a 1500px. Un visiteur qui a appris a lire le premier rail
   n'a rien a reapprendre.
   ------------------------------------------------------------------------- */
/* le rail des chapitres cede la place des que celui-ci s'allume */
.chprog.is-relayed { opacity: 0 !important; visibility: hidden !important; pointer-events: none !important; }

/* CORRECTIF v82.1 — le rail etait pose au mauvais endroit.
   La v82 avait copie les regles de BASE de .chprog (coin bas-gauche). Ces
   regles sont mortes : elles sont surchargees a tous les paliers. Le rail
   des chapitres a en realite DEUX formes, et aucune n'est un bloc flottant :

     >= 1500px : une gouttiere de gauche, centree verticalement, large de
                 --lrail-w, avec un filet a droite. La page reserve cette
                 gouttiere (.page--panel main > *).
     <= 1499px : une bande pleine largeur ancree au bas de la fenetre, haute
                 de --lrail-h, opaque, avec un filet en haut.

   .wrail reprend desormais les deux formes a l'identique, y compris les
   deux bornes de la bande (lisiere du panneau entre 1280 et 1499, barre de
   release sous 1280). Mesure de controle en fin de fichier v82.1. */
.wrail {
  position: fixed;
  z-index: 60;
  display: flex;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
  pointer-events: none;
}
.wrail.is-on { opacity: 1; visibility: visible; pointer-events: auto; }

.wrail__ttl { color: var(--bone); font-size: 0.625rem; letter-spacing: 0.09em; line-height: 1.25; }
.wrail__pos { color: var(--ash-dim); font-size: 0.625rem; letter-spacing: 0.12em; }

.wrail__idx { display: flex; gap: 0.3rem; list-style: none; margin: 0; padding: 0; }
.wrail__step { display: block; }

.wrail__dot {
  display: block;
  width: 1.2rem;
  height: 2px;
  background: var(--line-strong);
  cursor: pointer;
  transition: background 0.35s var(--ease);
}
.wrail__dot.is-on { background: var(--signal); }
.wrail__dot:hover { background: var(--bone); }
.wrail__dot:focus-visible { outline: 1px solid var(--signal); outline-offset: 3px; }
.wrail__n, .wrail__lbl {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---- forme gouttiere (1500px et plus) : exactement celle de .chprog ---- */
@media (min-width: 1500px) {
  .wrail {
    left: 0;
    bottom: auto;
    top: 50%;
    transform: translateY(-50%);
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
    width: var(--lrail-w);
    padding: 1rem 0.6rem 1rem 1rem;
    border-right: 1px solid var(--line);
    background: none;
    transition: opacity 0.5s var(--ease);
  }
  /* sans ceci le rail descendrait d'une demi-hauteur a l'instant ou il
     apparait : la regle de base annule transform sur .is-on */
  .wrail.is-on { transform: translateY(-50%); }
  .wrail__pos { display: none; }        /* l'index dit deja ou on en est */

  .wrail__idx {
    position: relative;
    flex-direction: column;
    gap: 0;
    width: 100%;
    padding-left: 0.75rem;
  }
  .wrail__idx::before,
  .wrail__idx::after {
    content: '';
    position: absolute;
    left: 0;
    top: 0.5rem;
    width: 1px;
  }
  .wrail__idx::before { bottom: 0.5rem; background: var(--line-strong); }
  .wrail__idx::after {
    height: calc(var(--wp, 0) * (100% - 1rem));
    background: var(--signal);
    transition: height 0.5s var(--ease);
  }

  .wrail__dot {
    position: relative;
    display: block;
    width: 100%;
    height: auto;
    background: none;
    padding: 0.42rem 0 0.42rem 0.55rem;
    transition: none;
  }
  .wrail__dot:hover, .wrail__dot.is-on { background: none; }
  .wrail__dot::before {
    content: '';
    position: absolute;
    left: -1px;
    top: 0.72rem;
    width: 3px; height: 3px;
    background: var(--line-strong);
    transition: background 0.3s var(--ease), height 0.3s var(--ease), top 0.3s var(--ease);
  }
  .wrail__dot.is-on::before {
    background: var(--signal);
    height: 1rem;
    top: 0.32rem;
    left: -1px;
    width: 2px;
  }
  .wrail__n, .wrail__lbl {
    position: static;
    width: auto; height: auto;
    overflow: visible;
    clip-path: none;
    white-space: normal;
    display: block;
  }
  .wrail__n {
    font-size: 0.5625rem;
    letter-spacing: 0.14em;
    color: var(--ash-dim);
    transition: color 0.3s var(--ease);
  }
  .wrail__lbl {
    font-size: 0.625rem;
    letter-spacing: 0.06em;
    line-height: 1.35;
    color: var(--ash-dim);
    transition: color 0.3s var(--ease);
  }
  .wrail__dot:hover .wrail__n,
  .wrail__dot:hover .wrail__lbl { color: var(--ash); }
  .wrail__dot.is-on .wrail__n { color: var(--signal); }
  .wrail__dot.is-on .wrail__lbl { color: var(--bone); font-weight: 500; }
}

/* ---- forme bande de pied (sous 1500px) : exactement celle de .chprog ---- */
@media (max-width: 1499px) {
  .wrail {
    left: 0; right: 0;
    bottom: 0;
    height: var(--lrail-h);
    flex-direction: row;
    align-items: center;
    gap: 0.9rem;
    padding-inline: var(--gutter);
    background: var(--void);
    border-top: 1px solid var(--line);
    transform: none;
  }
  .wrail.is-on { transform: none; }
  .wrail__pos { margin-left: auto; }
}
/* la bande s'arrete sur la lisiere du panneau de commande, sinon elle passe
   dessous : meme z-index, et le panneau vient apres dans le DOM

   v87 — conditionnee a .page--panel. Sur blueprint.html il n'y a pas de
   panneau : la regle amputait la bande de 14vw a droite et laissait un vide
   inexplicable au bord de l'ecran, entre 1280 et 1499px. */
@media (min-width: 1280px) and (max-width: 1499px) {
  .page--panel .wrail { right: var(--rpan-w); }
}
/* sous 1280px la barre de release reprend le bas de la fenetre */
@media (max-width: 1279px) {
  body.has-rbar .wrail { bottom: var(--rbar-h); }
}
@media (max-width: 720px) {
  .wrail { gap: 0.6rem; }
}

@media (prefers-reduced-motion: reduce) {
  .wrail, .wrail__idx::after, .wrail__dot::before, .wrail__n, .wrail__lbl { transition: none; }
}

/* -------------------------------------------------------------------------
   8 — "WHAT HAPPENS AFTER I PAY?" : aucune case
   La grille de six cellules a bordures est remplacee par une colonne
   editoriale posee sur un filet continu. Le brief demandait de rassurer ;
   une grille de cases ressemble a un tableau de bord, pas a quelqu'un qui
   s'occupe de vous.
   ------------------------------------------------------------------------- */
.aftx { margin-top: clamp(3rem, 6vw, 4.5rem); }
.aftx__eyebrow {
  color: var(--ash-dim);
  font-size: 0.6875rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.aftx__title {
  margin-top: 0.9rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h3);
  line-height: 1.12;
  letter-spacing: -0.03em;
  color: var(--bone);
  max-width: 24ch;
}
.aftx__list {
  position: relative;
  margin-top: clamp(2rem, 4vw, 2.75rem);
  padding: 0 0 0 clamp(1.75rem, 3.5vw, 2.75rem);
  list-style: none;
  display: grid;
  gap: clamp(1.05rem, 2.4vw, 1.55rem);
}
/* le filet continu : une seule ligne pour les six temps, pas six cadres */
.aftx__list::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.5rem;
  bottom: 0.5rem;
  width: 1px;
  background: linear-gradient(180deg, var(--signal), var(--line-strong) 22%, var(--line));
}
.aftx__i {
  position: relative;
  display: grid;
  grid-template-columns: 2.5rem minmax(0, 1fr);
  gap: 0 1.1rem;
  align-items: baseline;
  transition-delay: calc(var(--i, 0) * 70ms);
}
.aftx__i::before {
  content: '';
  position: absolute;
  left: calc(clamp(1.75rem, 3.5vw, 2.75rem) * -1 - 2px);
  top: 0.55em;
  width: 5px; height: 5px;
  background: var(--void);
  box-shadow: 0 0 0 1px var(--line-strong);
}
.aftx__i:first-child::before { background: var(--signal); box-shadow: none; }
.aftx__n {
  color: var(--signal);
  font-size: 0.6875rem;
  letter-spacing: 0.18em;
}
.aftx__i:not(:first-child) .aftx__n { color: var(--ash-dim); }
.aftx__body { display: block; }
.aftx__t {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--fs-body);
  letter-spacing: -0.012em;
  color: var(--bone);
}
.aftx__d {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--ash);
  max-width: 62ch;
}
.aftx__proof {
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  padding-left: clamp(1.75rem, 3.5vw, 2.75rem);
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ash-dim);
}
@media (max-width: 620px) {
  .aftx__i { grid-template-columns: 1fr; gap: 0.35rem; }
  .aftx__list { padding-left: 1.5rem; }
  .aftx__i::before { left: -1.5rem; }
  .aftx__proof { padding-left: 1.5rem; }
}

/* =========================================================================
   V83 — CHAPITRE 04 RESSERRE, VENTE A L'UNITE SUPPRIMEE (brief du 25/08)
   ========================================================================= */

/* ---- rythme du chapitre 04 : les respirations etaient calibrees pour neuf
   blocs, il en reste six. A 9rem entre chacun, le chapitre se lisait comme
   une succession d'ecrans vides. ---- */
#ch-04 .vblock { margin-top: clamp(2.75rem, 6vw, 5rem); }
/* La ligne 1 fait 37 caracteres ("You have an international blockbuster") :
   a l'echelle --fs-h2 dans 52ch elle cassait en trois. Mesure elargie et
   corps plafonne pour tenir en DEUX lignes, comme le reste du site. */
#ch-04 .vhero { margin-top: clamp(1rem, 3vw, 2rem); max-width: none; }
#ch-04 .vhero__t {
  margin-top: 1rem;
  font-size: clamp(1.85rem, 3.6vw, 3.1rem);
  max-width: 21ch;
}
#ch-04 .vhero__lead { margin-top: 1.1rem; }

/* ---- les trois temps passent en rang : trois lignes empilees pour trois
   propositions de dix mots etaient la definition du scroll inutile ---- */
.vbeat--row {
  margin-top: clamp(1.75rem, 4vw, 2.5rem);
  max-width: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0 clamp(1.25rem, 3vw, 2.5rem);
  border-bottom: 0;
}
.vbeat--row .vbeat__i {
  display: block;
  padding: 1rem 0 0;
  border-top: 1px solid var(--line);
  border-bottom: 0;
  transition-delay: calc(var(--i, 0) * 90ms);
}
.vbeat--row .vbeat__i:nth-child(2) { border-top-color: var(--signal); }
.vbeat--row .vbeat__k { display: block; }
.vbeat--row .vbeat__p { display: block; margin-top: 0.5rem; font-size: 0.9375rem; line-height: 1.45; }
@media (max-width: 720px) {
  .vbeat--row { grid-template-columns: 1fr; gap: 0; }
  .vbeat--row .vbeat__i:nth-child(n+2) { margin-top: 0.9rem; }
}

/* ---- le pied de la tige recupere les deux idees des blocs supprimes ---- */
.vdep__tail {
  margin-top: 1rem;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ash);
  max-width: 62ch;
}
.vdep__tail-b { color: var(--bone); font-weight: 600; }

/* ---- "From song to screen" : cinq etapes en rang au lieu de cinq lignes.
   Gain mesure : ~675px de haut deviennent ~200. Le detail complet reste
   dans le <details>, mot pour mot. ---- */
@media (min-width: 900px) {
  #ch-04 .vsteps:not(.vsteps--det) {
    max-width: none;
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0 clamp(1rem, 2.4vw, 2rem);
  }
  #ch-04 .vsteps:not(.vsteps--det) .vstep {
    display: block;
    padding: 1rem 0 0;
    border-top: 1px solid var(--line);
    border-bottom: 0;
  }
  #ch-04 .vsteps:not(.vsteps--det) .vstep:first-child { border-top-color: var(--signal); }
  #ch-04 .vsteps:not(.vsteps--det) .vstep__n { display: block; padding-top: 0; }
  #ch-04 .vsteps:not(.vsteps--det) .vstep__name { margin-top: 0.45rem; }
  #ch-04 .vsteps:not(.vsteps--det) .vstep__do { margin-top: 0.45rem; font-size: 0.875rem; line-height: 1.5; }
}
#ch-04 .vhyb { margin-top: clamp(2rem, 4.5vw, 3.25rem); }
#ch-04 .vdet { max-width: none; }

/* le conteneur du bloc 08 ne porte plus que la specification du film :
   sans son titre ni sa liste, il n'a plus besoin de sa propre respiration */
#ch-04 .vout { margin-top: 0; }
#ch-04 .vlev--one { margin-top: clamp(2.75rem, 6vw, 5rem); }

/* =========================================================================
   v84 — BRIEF WORD DU 25/08 (sept consignes, une capture chacune)

   Tout est en fin de fichier, apres les blocs v79 a v83 du meme chapitre :
   ces regles surchargent volontairement les leurs, et les lire dans l'ordre
   du fichier revient a lire l'historique des decisions.
   ========================================================================= */

/* -------------------------------------------------------------------------
   1 · CAPTURE 2 — LE DEPLOIEMENT PASSE EN RANG

   « Arrange la section, ca doit etre horizontal pas vertical, on perd trop
   d'espace, ca oblige a scroller en bas. Objectif reduire de 60%
   verticalite. » Le texte n'est pas touche : c'est une regle de mise en
   page, rien d'autre.

   La tige verticale part avec le mode rang. Elle etait le dispositif :
   cinq filets de longueurs inegales suspendus a un axe. En rang, ce role
   passe au filet superieur de chaque colonne, qui se dessine de la gauche
   vers la droite exactement comme les cinq etapes deux blocs plus bas
   (regle #ch-04 .vsteps de la v83). Meme grammaire, une seule a apprendre.

   MESURE : cinq items a 1,35rem de padding haut et bas plus deux lignes de
   texte occupaient ~560px, marges de liste comprises. Le rang tient dans
   ~150px. Reduction ~73%, au-dela des 60% demandes.

   Sous 900px la tige verticale d'origine reprend la main sans surcharge :
   cinq colonnes sur un telephone donneraient cinq colonnes de deux
   caracteres.
   ------------------------------------------------------------------------- */
@media (min-width: 900px) {
  #ch-04 .vdep--row { margin-top: clamp(1.75rem, 4vw, 2.75rem); padding-left: 0; }
  /* la tige : elle n'a plus d'objet une fois les filets mis en rang */
  #ch-04 .vdep--row::before { display: none; }
  /* le point bleu vivait dans le padding gauche, qui vient d'etre annule */
  #ch-04 .vdep--row .vdep__src { padding-left: 1.15rem; }
  #ch-04 .vdep--row .vdep__dot { left: 0; }

  #ch-04 .vdep--row .vdep__list {
    margin-top: clamp(1.5rem, 3vw, 2.25rem);
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0 clamp(1rem, 2.4vw, 2rem);
    /* stretch, pas start : "Chorus & performance moments" tient sur deux
       lignes quand les quatre autres en tiennent une. Sans etirement son
       eyebrow descendait d'une ligne et cassait le rang. */
    align-items: stretch;
  }
  /* --w pilotait la longueur du filet ET l'indentation du libelle. En rang
     la largeur vient de la grille : on annule le padding calcule, sinon
     chaque colonne se decale d'une valeur qui n'a plus de sens. */
  #ch-04 .vdep--row .vdep__i {
    padding: 1rem 0 0;
    display: flex;
    flex-direction: column;
  }
  /* l'eyebrow est pousse en pied de colonne : les cinq s'alignent sur la
     meme ligne de base quel que soit le nombre de lignes du libelle */
  #ch-04 .vdep--row .vdep__p { margin-top: auto; padding-top: 0.5rem; }
  #ch-04 .vdep--row .vdep__i::before {
    left: 0;
    top: 0;
    width: 100%;
    background: linear-gradient(90deg, var(--line-strong), var(--line));
  }
  #ch-04 .vdep--row .vdep__i:first-child::before { background: var(--signal); }
  #ch-04 .vdep--row .vdep__t {
    margin-top: 0.45rem;
    font-size: clamp(1rem, 1.35vw, 1.22rem);
    line-height: 1.2;
  }
  #ch-04 .vdep--row .vdep__p { font-size: 0.65rem; letter-spacing: 0.13em; }
  #ch-04 .vdep--row + .vdep__foot { margin-top: clamp(1.75rem, 3.5vw, 2.5rem); max-width: 34ch; }
}

/* -------------------------------------------------------------------------
   2 · CAPTURE 3 — LES DEUX COMPARATIFS REMONTENT ET PERDENT LEURS FILETS

   « Pas de trait noir et bleu horizontal » : ce sont les deux `border-top`
   de .vvs__side, l'un en --line-strong (le gris qui lit noir sur ce fond),
   l'autre en --signal. Ils partent tous les deux.

   « On met en avant les deux comparatifs » : sans filet il faut autre chose
   pour tenir les deux colonnes. Le libelle du cote droit passe en --signal,
   le texte monte d'un cran typographique, et l'axe VERSUS gagne de l'air.
   La hierarchie est portee par le texte, plus par un cadre.
   ------------------------------------------------------------------------- */
#ch-04 .vbrand .vvs { margin-top: clamp(1.75rem, 4vw, 2.75rem); }
#ch-04 .vbrand .vvs__side { padding-top: 0; border-top: 0; }
#ch-04 .vbrand .vvs__side--b { border-top: 0; }
#ch-04 .vbrand .vvs__side--b .vvs__k { color: var(--signal); }
#ch-04 .vbrand .vvs__t {
  margin-top: 0.75rem;
  font-size: clamp(1.05rem, 1.7vw, 1.35rem);
  line-height: 1.4;
}
#ch-04 .vbrand .vvs__side--b .vvs__t { font-weight: 600; }
#ch-04 .vbrand .vstmt { margin-top: clamp(2rem, 4.5vw, 3rem); }

/* -------------------------------------------------------------------------
   3 · CAPTURE 4 — PAS D'ESPACE NOIR VIDE APRES LA SUPPRESSION

   .vw__t--mid porte `margin-top: clamp(2.5rem, 6vw, 4rem)` pour se detacher
   du texte qui le precedait. Ce texte n'existe plus : le titre est
   desormais le PREMIER element du bloc, et cette marge s'ajoutait a celle
   de .vblock. C'est exactement le vide noir que le brief interdit.
   ------------------------------------------------------------------------- */
#ch-04 .vproc { margin-top: clamp(2.5rem, 5.5vw, 4rem); }
#ch-04 .vproc > .vw__t--mid:first-of-type { margin-top: 0; }

/* -------------------------------------------------------------------------
   4 · CAPTURES 5 ET 6 — LA CASCADE A 0,5 S

   « Chaque 0.5 sec se revele de la gauche a la droite les etapes, de
   maniere animee. Objectif faire comprendre au visiteur le deroule de
   maniere captivante. »

   Aucun JS nouveau. Les deux rangs portent deja `.reveal` et `--i` : quand
   le rang entre dans le champ, l'observateur de main.js pose `.is-in` sur
   les cinq (resp. quatre) elements dans la meme frame, et c'est le
   `transition-delay` indexe sur --i qui produit le deroule. Le delai
   generique du chapitre (80 ms / 90 ms) est surcharge a 500 ms ici, et
   seulement ici.

   Le filet superieur ne peut pas s'animer en `border-top` : une bordure ne
   se met pas a l'echelle. Il devient un ::after en `scaleX(0)` d'origine
   gauche, ce qui donne litteralement le balayage gauche -> droite demande.

   DUREE TOTALE : 4 x 500 ms = 2 s avant la cinquieme etape. C'est long pour
   un visiteur qui scrolle vite ; c'est la valeur du brief, elle se change
   ici et nulle part ailleurs (--seq-step).

   reduced-motion : plus bas dans ce bloc, tout est pose a l'etat final,
   sans delai ni transition. Une cascade de 2 s est exactement ce que ce
   reglage demande d'eviter.
   ------------------------------------------------------------------------- */
#ch-04 .vsteps:not(.vsteps--det),
#ch-04 .vlev__row { --seq-step: 500ms; }

@media (min-width: 900px) {
  #ch-04 .vsteps:not(.vsteps--det) .vstep {
    position: relative;
    border-top: 0;
    transition-delay: calc(var(--i, 0) * var(--seq-step));
  }
  #ch-04 .vsteps:not(.vsteps--det) .vstep::after {
    content: '';
    position: absolute;
    left: 0; right: 0; top: 0;
    height: 1px;
    background: var(--line);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 0.5s var(--ease) calc(var(--i, 0) * var(--seq-step));
  }
  #ch-04 .vsteps:not(.vsteps--det) .vstep.is-in::after { transform: scaleX(1); }
  #ch-04 .vsteps:not(.vsteps--det) .vstep:first-child::after { background: var(--signal); }
}

@media (min-width: 620px) {
  #ch-04 .vlev__row .vlev__cell {
    position: relative;
    border-top: 0;
    transition-delay: calc(var(--i, 0) * var(--seq-step));
  }
  #ch-04 .vlev__row .vlev__cell::after {
    content: '';
    position: absolute;
    left: 0; right: 0; top: 0;
    height: 1px;
    background: var(--line-strong);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 0.5s var(--ease) calc(var(--i, 0) * var(--seq-step));
  }
  #ch-04 .vlev__row .vlev__cell.is-in::after { transform: scaleX(1); }
  #ch-04 .vlev__row .vlev__cell:first-child::after { background: var(--signal); }
}

@media (prefers-reduced-motion: reduce) {
  #ch-04 .vsteps:not(.vsteps--det) .vstep,
  #ch-04 .vlev__row .vlev__cell { transition-delay: 0s; }
  #ch-04 .vsteps:not(.vsteps--det) .vstep::after,
  #ch-04 .vlev__row .vlev__cell::after { transform: scaleX(1); transition: none; }
}

/* -------------------------------------------------------------------------
   5 · LE SECOND FILM — LA VIDEO REMPLACE LE PLACEHOLDER

   .vfilm__ph et .vfilm__v partageaient deja l'aspect-ratio et le rayon :
   la substitution ne deplace rien. Ce qui s'ajoute est le conteneur qui
   permet au bouton Sound de se positionner (.rail__sound est en absolu, il
   lui faut un parent positionne, et <figure> porte aussi la legende).
   ------------------------------------------------------------------------- */
.vfilm__box {
  position: relative;
  border-radius: var(--radius-s);
  overflow: hidden;
}
.vfilm__box .vfilm__v { border-radius: 0; }
.vfilm__sound { right: 0.75rem; bottom: 0.75rem; }
/* lecture refusee par le navigateur : les controles natifs occupent le bas
   du cadre, le bouton s'efface plutot que de se superposer a eux */
.vfilm__fig.is-fallback .vfilm__sound { display: none; }

/* -------------------------------------------------------------------------
   6 · CAPTURE 7 — LA PHOTO DANS LE VIDE DE DROITE

   « La photo doit etre parfaitement integre a cote dans cet espace vide.
   Interdiction absolu de rallonger verticalement la section. »

   La garantie est structurelle : les deux colonnes de .wbrand__cols sont
   etirees a la meme hauteur (comportement par defaut de `align-items:
   stretch`), la figure ne porte aucune hauteur propre, et l'image est
   detachee du flux en `position:absolute; inset:0`. La colonne photo ne
   peut donc pas depasser la colonne de gauche, quel que soit le nombre de
   piliers. Aucune valeur en pixels a maintenir.

   `min-height: 0` sur la figure : sans lui, un enfant de grille prend pour
   plancher la hauteur de son contenu, et l'image de 1500px de haut
   rallongerait la ligne — precisement l'interdit du brief.
   ------------------------------------------------------------------------- */
.wbrand__fig { display: none; }

@media (min-width: 1024px) {
  .wbrand__cols {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.42fr);
    gap: clamp(2rem, 4.5vw, 4rem);
    align-items: stretch;
    /* la respiration que portait .vdep--brand remonte sur la grille : les
       deux colonnes doivent partir de la meme ligne, sinon la photo demarre
       plus haut que la tige et pointe dans le vide au-dessus. */
    margin-top: clamp(2.5rem, 6vw, 4rem);
  }
  .wbrand__cols > .vdep--brand { margin-top: 0; }
  .wbrand__fig {
    display: block;
    position: relative;
    min-height: 0;
    margin: 0;
    border-radius: var(--radius-m);
    overflow: hidden;
  }
  .wbrand__fig picture,
  .wbrand__fig img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
  }
  /* la fente est bien plus etroite que le 2:3 du fichier : on cadre haut,
     sur le moniteur et le plan de travail, pas sur le milieu du bureau */
  .wbrand__fig img { object-fit: cover; object-position: 50% 24%; }
  /* le fond de page est presque noir : sans ce voile le bord de la photo
     tranche comme une vignette collee. Il la fait appartenir a la page. */
  .wbrand__fig::after {
    content: '';
    position: absolute;
    inset: 0;
    background:
      linear-gradient(90deg, var(--void) 0%, rgba(10, 11, 13, 0) 26%),
      linear-gradient(180deg, rgba(10, 11, 13, 0.34) 0%, rgba(10, 11, 13, 0) 26%, rgba(10, 11, 13, 0.55) 78%, var(--void) 100%);
    pointer-events: none;
  }
}

/* =========================================================================
   v86 — DUREE DE CAMPAGNE, CALENDRIERS, GARDE-FOU DE VOCABULAIRE

   Le brief du 25/08 change la nature des trois offres : elles ne se
   distinguent plus par un empilement de livrables mais par la DUREE DE
   PUBLICATION qu'elles couvrent. Trois ajouts, tous prefixes, aucune regle
   anterieure modifiee.

   /!\ Le risque n° 1 de cette version est une confusion de lecture : « 3
   Days » lu comme un delai de livraison. Le site publie par ailleurs un
   engagement a 48 heures sur le socle. C'est pour cela que la ligne
   `--camp` / `--pcamp` est collee au nom, dans la meme foulee visuelle :
   le nom seul ne doit jamais circuler sans son unite.
   ========================================================================= */

/* ---- la ligne de duree, sous le nom de l'offre ---- */
.pack__campaign,
.rrp__camp,
.rpan__pcamp {
  display: block;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--signal);
  margin-top: 0.2rem;
}
.rrp__camp { margin: 0.35rem 0 0.6rem; font-size: 0.6875rem; }
.rpan__pcamp { font-size: 0.5625rem; letter-spacing: 0.1em; color: var(--ash); margin-top: 0.15rem; }

/* ---- le garde-fou, sous les trois packs du panneau ----
   Volontairement en gris faible et non en accent : ce n'est pas un argument
   de vente, c'est une precision qui evite un litige. La mettre en avant
   ferait douter ; la cacher ferait mentir. */
.rpan__note {
  margin: 0.6rem 0 0;
  font-size: 0.5625rem;
  line-height: 1.45;
  color: var(--ash-dim);
}

/* ---- les calendriers, dans les cartes de la home ----
   Le brief (§22) demande un PLAN, pas une quantite. Le calendrier est donc
   pose AVANT la liste des livrables : on lit d'abord ce qui va se passer,
   ensuite ce qu'on recoit. L'ordre inverse redonnerait un catalogue. */
.rrp__cal {
  margin: 0 0 1.35rem;
  padding: 0.9rem 0 0;
  border-top: 1px solid var(--rrp-line);
}
.rrp__cal-h {
  margin: 0 0 0.65rem;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--rrp-faint);
}
.rrp__cal-l { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; }
.rrp__cal-i {
  display: grid;
  grid-template-columns: 5.25rem minmax(0, 1fr);
  gap: 0.15rem 0.6rem;
  align-items: baseline;
}
.rrp__cal-d {
  font-family: var(--mono);
  font-size: 0.5625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--rrp-faint);
  white-space: nowrap;
}
.rrp__cal-t { font-size: 0.8125rem; font-weight: 600; color: var(--rrp-ink); }
/* La glose passe sous les deux colonnes : sur 30 jours en quatre phases,
   elle est longue, et la contraindre a la colonne de droite fabriquerait
   une colonne de six lignes a cote d'un titre d'une seule. */
.rrp__cal-w {
  grid-column: 2;
  font-size: 0.75rem;
  line-height: 1.45;
  color: var(--rrp-dim);
}

@media (max-width: 560px) {
  .rrp__cal-i { grid-template-columns: 1fr; }
  .rrp__cal-w { grid-column: 1; }
}

/* =========================================================================
   v89 — BRIEF WORD DU 26/08
   Ce bloc est en fin de feuille : chaque regle ci-dessous doit l'emporter
   sur une regle de meme specificite ecrite plus haut (les sections v70 a
   v79 redefinissent plusieurs fois les memes selecteurs). Rien n'est
   supprime en amont — les valeurs d'origine restent lisibles la ou elles
   ont ete decidees, avec leur justification d'epoque.
   ========================================================================= */

/* -------------------------------------------------------------------------
   §1 — BANDEAU DE TEMOIGNAGES : REMONTE, ET UN CRAN PLUS GRAND

   « Remonte tres legerement, environ 7 a 8mm au-dessus. »
   7,5 mm = 28 px a 96 ppp (1 mm = 3,7795 px). La remontee est un
   margin-top negatif et NON une reduction du padding : le padding tient la
   respiration interne du bandeau, le reduire aurait colle les vignettes a
   leur filet. La marge negative deplace le bloc entier, filet compris.

   Sur mobile la valeur est ramenee a 16 px : 28 px representent la moitie
   d'un interstice a cette largeur, et le bandeau serait venu mordre la
   declaration de marque juste au-dessus.

   Corps +1 cran des deux textes : le nom passe de 0,625 a 0,75rem, la
   citation de 0,875 a 1rem. Le nom garde son `white-space: nowrap` — les
   pseudonymes ne se coupent pas — mais gagne donc en largeur : la vignette
   la plus longue (« Nathan CiusAKAMakai Capernium ») s'elargit d'environ
   14 px, ce qui reste dans la largeur fixe de .tst__i.
   ------------------------------------------------------------------------- */
.tst { margin-top: -28px; }
@media (max-width: 700px) {
  .tst { margin-top: -16px; }
}
.tst__name  { font-size: 0.75rem; }
.tst__quote { font-size: 1rem; }

/* -------------------------------------------------------------------------
   §2 — COMPARATIF : LA LIGNE DE REVENDICATION

   « Meme taille, texte centre. » Le corps n'est donc pas touche : la regle
   v79 (clamp 1.5 -> 2.5rem) reste en vigueur. Deux choses seulement :

   - le centrage. .cmp__head est deja `text-align: center`, mais .cmp__sub
     portait `max-width: 26ch` SANS marge automatique : le bloc restait cale
     a gauche et seul son texte etait centre, a l'interieur d'une boite
     decalee. Le defaut ne se voyait pas sur l'ancienne phrase, qui
     remplissait ses 26ch ; il se serait vu immediatement sur celle-ci.

   - la mesure. 26ch coupait « 3, 10 or 30 days of ready-to-post content. »
     en deux lignes des le milieu. 34ch la laisse tenir sur une ligne
     au-dessus de 900px, et casser proprement en dessous.
   ------------------------------------------------------------------------- */
.cmp__sub--claim {
  max-width: 34ch;
  margin-inline: auto;
  text-align: center;
}

/* -------------------------------------------------------------------------
   §3 — COMPARATIF : CINQ LIGNES, DEUX CRANS PLUS PETIT

   Le corps passe de clamp(1rem, 1.85vw, 1.75rem) a
   clamp(0.875rem, 1.45vw, 1.375rem) : deux crans, des deux cotes, comme
   demande. Les pastilles et les croix suivent, sinon un glyphe de 46 px se
   retrouve en face d'un texte de 22 px et le rapport se casse.

   /!\ LE PIEGE ETAIT ICI : la regle v79 pose `white-space: nowrap` sur
   `.cmp__li > span` au-dessus de 900px, pour empecher « Sound that still
   feels like a demo » de casser en deux. Appliquee telle quelle a la
   cinquieme ligne — 59 caracteres, contre 32 pour la plus longue des
   quatre autres — elle aurait produit un DEBORDEMENT HORIZONTAL de la
   page entiere, pas un simple depassement de colonne.

   La cinquieme ligne est donc explicitement autorisee a casser.

   v90 — LE CIBLAGE A CHANGE. Ces regles visaient `[style*="--s:4"]`, donc
   la POSITION dans la liste. La permutation demandee le 26/08 a deplace la
   ligne longue en --s:3 et le prix en --s:4 : le ciblage par position
   aurait silencieusement autorise le PRIX a casser sur deux lignes et
   remis le `nowrap` sur la ligne longue — c'est-a-dire exactement le
   debordement horizontal decrit ci-dessus, reintroduit par un simple
   changement d'ordre. La ligne longue porte desormais une classe,
   `.cmp__li--long`, qui la suit ou qu'elle aille.
   ------------------------------------------------------------------------- */
.cmp__li {
  font-size: clamp(0.875rem, 1.45vw, 1.375rem);
  grid-template-columns: clamp(30px, 2.4vw, 38px) minmax(0, 1fr);
}
.cmp__x    { width: clamp(22px, 1.8vw, 28px); height: clamp(22px, 1.8vw, 28px); }
.cmp__mark { width: clamp(28px, 2.3vw, 38px); }

@media (min-width: 900px) {
  .cmp__li--long > span { white-space: normal; }
}
/* La ligne longue tient sur deux lignes de texte la ou les autres en
   occupent une : `align-items: center` (regle v72) la centrerait sur sa
   pastille et desalignerait la base des cinq entrees. */
.cmp__li--long { align-items: start; }
.cmp__li--long .cmp__x,
.cmp__li--long .cmp__mark { margin-top: 0.15em; }

/* -------------------------------------------------------------------------
   §4 — LA LIGNE NEUVE SOUS LE TITRE DES CARTES

   Elle dit le contenu du pack, la ligne au-dessus dit ce qu'on emporte.
   Plus petite et plus grise : c'est une precision, pas une seconde
   accroche. Le .rrp__lead portait toute la marge basse du bloc ; elle
   descend ici, sinon les deux lignes se retrouvaient separees par un
   interstice de 2,5rem au milieu d'une meme idee.
   ------------------------------------------------------------------------- */
.rrp__lead { margin-bottom: 0.35rem; }
.rrp__sublead {
  margin: 0 auto clamp(1.75rem, 3vw, 2.5rem);
  text-align: center;
  color: var(--rrp-dim);
  font-size: 0.8125rem;
  opacity: 0.8;
  max-width: 46ch;
}

/* =========================================================================
   v90 — BRIEF WORD DU 26/08, DEUXIEME ENVOI (avec les captures)
   ========================================================================= */

/* -------------------------------------------------------------------------
   §5 — v92 : LE BLOC EST CENTRE, ET LA REVENDICATION EST RESTYLEE

   Points 1, 2 et 3 du brief du 26/08.

   CENTRAGE. Le montage en deux colonnes (declaration a gauche, rail a
   droite) disparait : les trois rangs sont empiles et centres sur un meme
   axe. Rien d'autre ne change dans la declaration — meme police, meme
   corps, meme graisse, memes couleurs, meme coupe en deux lignes. Seul
   l'axe bouge, comme demande.

   Effet de bord traite : .coh__l1 et .coh__l2 sont en `display: block` et
   .coh__line--stmt est borne a 20ch. Un bloc de 20ch dans un conteneur
   centre reste cale a GAUCHE tant qu'il n'a pas de marge automatique — le
   texte aurait ete centre a l'interieur d'une boite decalee. C'est
   exactement le defaut corrige sur .cmp__sub en v89. `margin-inline: auto`
   est donc pose ici aussi.

   Le rail garde `margin-left: auto` dans la regle v70 ; il faut l'annuler,
   sinon le centrage du conteneur est neutralise par la marge.
   ------------------------------------------------------------------------- */
.coh__inner--stmt {
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.coh__line--stmt { margin-inline: auto; }
.coh__inner--stmt .coh__chain {
  margin-left: 0;
  margin-inline: auto;
  justify-content: center;
}

/* -------------------------------------------------------------------------
   §5b — LA REVENDICATION

   ENCRE. Permanent Marker, auto-hebergee dans /assets/fonts. C'est la
   police de la phrase de reference (« WE TURN FACELESS UPLOADS INTO
   UNAVOIDABLE NAMES. ») : marqueur gras, arrondi, legerement irregulier.

   /!\ SI ELLE NE S'AFFICHE PAS EN LIGNE, VERIFIER LE CACHE AVANT LE CODE.
   Le rendu du 26/08 montrait cette ligne dans la police courante du site :
   ce n'etait pas la declaration @font-face, c'etait une feuille de style
   servie depuis le cache navigateur (voir netlify.toml, bloc CACHE).

   CORPS. Le brief demande ×2 pour le texte et ×4 pour le chiffre, par
   rapport au corps courant de la ligne. Le corps de reference etant celui
   du texte de page (1rem), cela donne 2rem et 4rem. Les valeurs sont
   exprimees en clamp pour suivre la largeur, avec 2rem et 4rem comme
   valeurs pivots au format de reference :

     texte    clamp(1.4rem, 2.6vw, 2rem)      -> ×2
     chiffre  2em du texte                    -> ×4

   Le rapport 2:1 entre le chiffre et le texte est porte par `em` et non
   par une seconde valeur en rem : il ne peut donc pas se desynchroniser
   quand le clamp se resserre sur petit ecran.

   COULEURS. Les six valeurs sont celles du brief, echantillonnees sur
   l'image de reference. Ce ne sont PAS celles de .rpan__w--1..7 : elles
   sont plus saturees. Aucune n'est le jaune du site, aucune n'est reprise
   deux fois — c'etait une contrainte explicite.

   /!\ CONTRASTE. Verifie sur #0A0B0D : les six passent AA pour du grand
   texte (>= 3:1). #3B7CFF (TO) est la plus basse a 3,4:1 — elle tient
   parce que cette ligne est enorme, elle ne tiendrait pas en corps de
   texte courant. Ne pas reutiliser cette palette ailleurs sans remesurer.
   ------------------------------------------------------------------------- */
.coh__claim {
  margin: clamp(1.25rem, 2.6vw, 2.25rem) auto 0;
  font-family: 'Permanent Marker', 'Bradley Hand', 'Segoe Script',
               'Brush Script MT', cursive;
  font-weight: 400;
  font-size: clamp(1.4rem, 2.6vw, 2rem);
  line-height: 1.05;
  letter-spacing: 0.005em;
  text-transform: uppercase;
  text-align: center;
}

/* Le chiffre reste sur le premier rang et domine, comme demande. En
   `inline` il se serait glisse en tete de la premiere ligne de texte,
   deux fois plus haut que ses voisins, ecartant cette ligne de tout son
   corps. En bloc il devient le rang 1 et le texte occupe le rang 2.

   line-height 0.85 : a 2em, l'interligne normal ouvrait un demi-cadratin
   sous le chiffre et cassait le bloc en deux. */
.coh__cn {
  display: block;
  font-size: 2em;
  line-height: 0.85;
  color: #FF6A3D;
}
.coh__ct {
  display: block;
  margin-top: 0.1em;
  text-wrap: balance;
}
.coh__cw { display: inline; }
.coh__cw--2 { color: #FFE14A; }   /* ARTISTS. — jaune de FACELESS   */
.coh__cw--3 { color: #4BD16A; }   /* MADE     — vert de UPLOADS     */
.coh__cw--4 { color: #3B7CFF; }   /* TO       — bleu de INTO        */
.coh__cw--5 { color: #9B7CFF; }   /* STAND    — violet de UNAVOIDABLE */
.coh__cw--6 { color: #FF7AD9; }   /* OUT.     — rose de NAMES.      */

/* La revendication entre entre la declaration et le rail : la lecture
   reste phrase -> chiffre -> signature. Meme keyframe, meme courbe. */
.coh__inner--stmt .coh__claim { opacity: 0; transform: translateY(10px); }
.coh__inner--stmt.is-in .coh__claim {
  animation: coh-rise 0.85s var(--ease) 0.52s both;
}

@media (forced-colors: active) {
  .coh__cw, .coh__cn { color: CanvasText; }
}
@media (prefers-reduced-motion: reduce) {
  .coh__inner--stmt .coh__claim { opacity: 1; transform: none; animation: none; }
}

/* -------------------------------------------------------------------------
   §6 — LES TROIS CONTENEURS `reveal` DE LA v70 NE BOUGENT PAS EUX-MEMES
   `.reveal` fait deux choses : il declenche l'observateur de main.js ET il
   fait monter l'element de 28px. Ici on ne veut que la premiere. Sans ca,
   le conteneur monte de 28px pendant que ses enfants montent de 10 a 12px
   chacun avec leur propre retard : deux mouvements simultanes sur le meme
   contenu, et l'echelonnement ne se lit plus. La classe reste, l'observateur
   reste, seul le deplacement du parent est neutralise.
   ------------------------------------------------------------------------- */
.coh__inner--stmt.reveal,
.cmp__cols--rank.reveal,
.ben--flat .ben__grid.reveal {
  opacity: 1;
  transform: none;
  transition: none;
}

/* La coupe du titre est explicite au-dessus de 720px. Laissee a
   `text-wrap: balance`, elle tombait a l'interieur de « world-class, » : le
   navigateur coupait sur le trait d'union et affichait « to world- / class, ».
   Le <br> ne change aucun mot ; sous 720px il est neutralise et la coupe
   redevient automatique, la ligne complete n'y tenant de toute facon pas. */
@media (max-width: 720px) {
  .cmp__t-br { display: none; }
}

/* Sous 720px le <br> est neutralise et la coupe redevient automatique — et
   le navigateur reprend son mauvais reflexe : il coupe SUR le trait d'union
   de « world-class, » et affiche « to world- / class, ». Le mot compose est
   donc rendu insecable. Aucun caractere n'est ajoute ni retire : le <span>
   n'entoure que du texte existant. */
.cmp__t .nowrap { white-space: nowrap; }


/* =========================================================================
   v71 — LA COMPARAISON SOUS LE STATEMENT : SIX LIGNES DEVIENNENT
         TROIS TRANSFORMATIONS
   Aucun mot, aucun ordre, aucune police, aucune couleur de palette ne
   change. Tout est ajoute en fin de fichier et gagne par la cascade ; les
   regles v65 de `.swr__grid` et `.swr__i` restent en place.

   Le mecanisme : le remplissage `grid-auto-flow: column` sur trois rangees
   fait deja que les elements 1-3 sont la colonne gauche et 4-6 la droite,
   et que 1/4, 2/5, 3/6 partagent une rangee. Toute la hierarchie se deduit
   donc du rang en :nth-child — pas une classe de plus dans le HTML.
   ========================================================================= */

/* ---------- §1 Respiration : trois blocs, pas six lignes ----------
   Le regroupement en paires demande par le brief se fait UNIQUEMENT par
   l'espacement et l'alignement. Aucun numero, aucun label, aucune icone
   n'est ajoute : la rangee devient assez haute et assez espacee de sa
   voisine pour se lire comme une unite. */
.swr__grid--rank {
  position: relative;
  margin-top: clamp(3.25rem, 6.5vw, 5.25rem);   /* etait clamp(2.5, 5vw, 4) */
  row-gap: clamp(0.9rem, 1.8vw, 1.6rem);
  column-gap: clamp(2.25rem, 5vw, 4.5rem);      /* etait clamp(1.5, 3.5vw, 3.25) */
}
.swr__grid--rank .swr__i {
  position: relative;
  padding-block: clamp(1.05rem, 1.9vw, 1.5rem);
  transition: color 0.4s var(--ease), opacity 0.4s var(--ease);
}

/* ---------- §2 Les separateurs deviennent des lignes de rythme ----------
   Le filet plein de bord a bord se lit comme une bordure de tableau. Il est
   remplace par un degrade qui s'eteint du cote de l'axe central : la ligne
   part du bord exterieur, la ou commence le regard, et disparait avant de
   toucher la separation. Elle rythme, elle n'encadre pas.

   `border-bottom-color: transparent` plutot qu'une suppression : la ligne
   garde son 1px d'epaisseur dans le calcul de hauteur, donc aucun decalage
   de mise en page par rapport a la v70. */
.swr__grid--rank .swr__i { border-bottom-color: transparent; }
.swr__grid--rank .swr__i::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  transition: opacity 0.4s var(--ease);
}
/* Colonne gauche : la ligne s'eteint vers la droite, donc vers l'axe. */
.swr__grid--rank .swr__i:nth-child(-n+3)::after {
  background: linear-gradient(90deg,
    rgba(242, 240, 235, 0.13) 0%,
    rgba(242, 240, 235, 0.05) 62%,
    rgba(242, 240, 235, 0) 92%);
}
/* Colonne droite : la ligne s'allume depuis l'axe et se prolonge plus loin.
   Meme geste, sens inverse — c'est ce qui fait lire la traversee. */
.swr__grid--rank .swr__i:nth-child(n+4)::after {
  background: linear-gradient(90deg,
    rgba(232, 197, 71, 0.28) 0%,
    rgba(242, 240, 235, 0.22) 26%,
    rgba(242, 240, 235, 0.10) 100%);
}

/* ---------- §3 La hierarchie gauche / droite ----------
   Le brief demande une difference RESSENTIE, pas criee : la taille ne bouge
   pas, la police non plus. Seuls la luminosite, la graisse et
   l'interlettrage travaillent. */
.swr__grid--rank .swr__i:nth-child(-n+3) {
  color: #A8ADB6;          /* entre --ash et --bone : recule sans devenir gris */
  font-weight: 400;
}
.swr__grid--rank .swr__i:nth-child(n+4) {
  color: #FFFFFF;
  font-weight: 600;
  letter-spacing: -0.006em;
}

/* ---------- §4 L'axe central ----------
   Une ligne de transition, pas une bordure de tableau : elle est plus
   claire au milieu, s'eteint a ses deux extremites, et se DESSINE de haut
   en bas a l'entree dans le viewport. `transform: scaleY` et non `height` :
   aucun recalcul de mise en page pendant l'animation.

   Elle est posee au centre de la gouttiere (`left: 50%` sur une grille de
   deux colonnes egales), donc elle ne touche jamais le texte. */
.swr__grid--rank::before {
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: 50%;
  width: 1px;
  transform: translateX(-50%) scaleY(0);
  transform-origin: 50% 0;
  background: linear-gradient(180deg,
    rgba(232, 197, 71, 0) 0%,
    rgba(232, 197, 71, 0.30) 26%,
    rgba(232, 197, 71, 0.42) 50%,
    rgba(232, 197, 71, 0.30) 74%,
    rgba(232, 197, 71, 0) 100%);
  pointer-events: none;
  transition: transform 0.75s var(--ease) 0.42s, opacity 0.4s var(--ease);
}
.swr__grid--rank.is-in::before { transform: translateX(-50%) scaleY(1); }

/* ---------- §5 La sequence d'entree ----------
   gauche (3 lignes) -> l'axe se dessine -> droite (3 lignes, revelation
   plus marquee). Total 1,35 s, dans la fourchette demandee.

   La colonne droite part de plus bas (14px contre 8px) et d'un contraste
   plus faible : c'est elle qui « arrive », la gauche est deja la. */
.swr__grid--rank .swr__i { opacity: 0; }
.swr__grid--rank.is-in .swr__i:nth-child(1) { animation: swr-l 0.6s var(--ease) 0.10s both; }
.swr__grid--rank.is-in .swr__i:nth-child(2) { animation: swr-l 0.6s var(--ease) 0.19s both; }
.swr__grid--rank.is-in .swr__i:nth-child(3) { animation: swr-l 0.6s var(--ease) 0.28s both; }
.swr__grid--rank.is-in .swr__i:nth-child(4) { animation: swr-r 0.7s var(--ease) 0.66s both; }
.swr__grid--rank.is-in .swr__i:nth-child(5) { animation: swr-r 0.7s var(--ease) 0.75s both; }
.swr__grid--rank.is-in .swr__i:nth-child(6) { animation: swr-r 0.7s var(--ease) 0.84s both; }

@keyframes swr-l {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
/* La montee de contraste de la phase 4 : la ligne arrive volontairement
   sous-exposee et gagne sa luminosite finale en fin de course. */
@keyframes swr-r {
  0%   { opacity: 0;    transform: translateY(14px); filter: brightness(0.62); }
  70%  { opacity: 1;    transform: none;             filter: brightness(0.88); }
  100% { opacity: 1;    transform: none;             filter: none; }
}

/* ---------- §6 Le survol : du focus, pas du mouvement ----------
   Souris fine uniquement. Au survol d'une ligne Ready Release, cette ligne
   et son separateur montent en luminosite, l'axe reagit legerement, et la
   colonne gauche recule d'un cran de plus. Aucun deplacement, aucun zoom,
   aucune bordure. */
@media (hover: hover) and (pointer: fine) {
  .swr__grid--rank .swr__i:nth-child(n+4):hover { color: #FFFFFF; }
  .swr__grid--rank .swr__i:nth-child(n+4):hover::after { opacity: 1; }
  .swr__grid--rank .swr__i:nth-child(n+4)::after { opacity: 0.8; }

  /* :has() sert ici a faire reagir des ELEMENTS VOISINS au survol d'un
     enfant, ce qu'aucun autre selecteur ne permet. Sans support, la ligne
     survolee s'eclaire quand meme (regles ci-dessus) : seul l'effet de
     recul de la colonne opposee est perdu. Degradation propre. */
  .swr__grid--rank:has(.swr__i:nth-child(n+4):hover) .swr__i:nth-child(-n+3) {
    opacity: 0.55;
  }
  .swr__grid--rank:has(.swr__i:nth-child(n+4):hover)::before {
    opacity: 1;
    filter: brightness(1.4);
  }
}

/* ---------- §7 Mobile : la paire reste la paire ----------
   Sous 720px la v65 repasse en une colonne, ce qui donne les trois lignes
   de gauche puis les trois de droite : la paire est cassee, et avec elle
   l'idee de transformation. `order` retablit l'alternance 1-4-2-5-3-6.

   A NOTER : l'ordre du DOM reste 1..6, l'ordre affiche devient 1-4-2-5-3-6.
   Un lecteur d'ecran annonce donc les trois lignes de gauche puis les trois
   de droite. Les six enonces sont autonomes et la liste reste intelligible
   dans les deux ordres, mais la divergence est reelle et assumee ici.

   L'axe vertical n'a plus de sens en une colonne : il devient un trait
   horizontal court entre les deux moitiees de chaque paire. */
@media (max-width: 720px) {
  .swr__grid--rank::before { display: none; }

  .swr__grid--rank .swr__i:nth-child(1) { order: 1; }
  .swr__grid--rank .swr__i:nth-child(4) { order: 2; }
  .swr__grid--rank .swr__i:nth-child(2) { order: 3; }
  .swr__grid--rank .swr__i:nth-child(5) { order: 4; }
  .swr__grid--rank .swr__i:nth-child(3) { order: 5; }
  .swr__grid--rank .swr__i:nth-child(6) { order: 6; }

  /* La ligne de gauche ne ferme plus rien : elle introduit celle de droite.
     Son filet devient donc un trait court, decale, qui se lit comme un
     « puis » et non comme une fin de rangee. */
  .swr__grid--rank .swr__i:nth-child(-n+3) {
    padding-bottom: clamp(0.55rem, 1.6vw, 0.75rem);
  }
  .swr__grid--rank .swr__i:nth-child(-n+3)::after {
    left: 0; right: auto; width: 1.75rem;
    background: rgba(232, 197, 71, 0.45);
  }
  .swr__grid--rank .swr__i:nth-child(n+4) {
    padding-top: clamp(0.55rem, 1.6vw, 0.75rem);
    padding-bottom: clamp(1.6rem, 4vw, 2.25rem);   /* le vide entre paires */
  }
  .swr__grid--rank .swr__i:nth-child(n+4)::after {
    background: linear-gradient(90deg,
      rgba(242, 240, 235, 0.13) 0%,
      rgba(242, 240, 235, 0) 88%);
  }
  .swr__grid--rank .swr__i:nth-child(6)::after { display: none; }
}

/* ---------- §8 Le conteneur ne bouge pas lui-meme ----------
   Meme raison qu'au §6 de la v70 : `.reveal` sert ici d'INTERRUPTEUR, pas
   d'animation. Son propre deplacement de 28px se superposerait aux six
   deplacements echelonnes des enfants. */
.swr__grid--rank.reveal { opacity: 1; transform: none; transition: none; }

/* ---------- §9 Mouvement reduit ----------
   Etat final pose directement : couleurs, graisses et axe sont conserves,
   seules les animations disparaissent. La hierarchie ne depend d'aucune
   animation — elle tient au contraste seul. */
@media (prefers-reduced-motion: reduce) {
  .swr__grid--rank .swr__i {
    opacity: 1; transform: none; filter: none; animation: none !important;
    transition: none;
  }
  .swr__grid--rank::before {
    transform: translateX(-50%) scaleY(1); transition: none;
  }
}


/* =========================================================================
   v72 — LES SIX LIGNES GRANDISSENT, LES SEPT CADRES SE REMPLISSENT
   Ajoute en fin de fichier : aucune regle anterieure n'est reecrite ni
   supprimee, ce bloc gagne par l'ordre de la cascade.
   ========================================================================= */

/* -------------------------------------------------------------------------
   §1 — LA TAILLE DES SIX LIGNES « We believe… »

   Constat de depart : ces six lignes et les quatre lignes du bloc de
   comparaison etaient DEJA dans la meme police (Manrope, var(--body)). Ce
   que l'oeil lisait comme « une autre police » etait un ecart de taille :
   15 px ici contre 34 px la-bas. C'est donc la taille qui bouge, et elle
   seule — pas la famille, pas les mots, pas l'ordre.

   Pourquoi pas 34 px exactement : le bloc de comparaison dispose d'une
   demi-page (~600 px par colonne). Ces six lignes vivent dans la colonne de
   texte de la section, elle-meme divisee en deux — soit ~300 px par
   colonne. A 34 px, « Sound industry-standard » mesure ~400 px : les cinq
   lignes les plus longues passeraient sur deux lignes chacune, et la
   grille de trois rangees deviendrait un pave. 24 px au plafond est la
   plus grande valeur qui tient chaque enonce sur UNE ligne, et l'ecart
   avec le statement au-dessus (34,4 px) reste lisible comme une
   hierarchie. Le gain reel est de +59 % sur la taille du glyphe.

   La gouttiere se resserre de 4,5 a 3,5rem : a 24 px, deux colonnes de
   texte separees par 72 px se lisaient comme deux listes independantes. */
.swr__grid--rank {
  column-gap: clamp(1.75rem, 3.6vw, 3.5rem);
  row-gap: clamp(1.1rem, 2.1vw, 1.9rem);
}
.swr__grid--rank .swr__i {
  font-size: clamp(1.125rem, 1.7vw, 1.5rem);
  line-height: 1.3;
  padding-block: clamp(1.15rem, 2.1vw, 1.7rem);
}
/* A cette taille, -0.006em ne se voit plus : le meme resserrement optique
   demande 2,5 fois plus. La colonne droite garde son avance de graisse. */
.swr__grid--rank .swr__i:nth-child(n+4) { letter-spacing: -0.015em; }
.swr__grid--rank .swr__i:nth-child(-n+3) { letter-spacing: -0.008em; }

/* Le statement au-dessus n'a pas change de taille, mais la liste s'est
   rapprochee de lui : l'ecart qui les separait a ete calcule pour un corps
   de 15 px. */
.swr__grid--rank { margin-top: clamp(2.75rem, 5.5vw, 4.5rem); }

/* Sous 980 px la colonne de texte prend toute la largeur : les deux
   colonnes de lignes passent a ~430 px chacune et peuvent donc porter le
   corps du bloc de comparaison sans casser. */
@media (max-width: 980px) and (min-width: 721px) {
  .swr__grid--rank .swr__i { font-size: clamp(1.25rem, 3vw, 1.75rem); }
}
/* En une colonne, plus rien ne contraint la longueur de ligne. */
@media (max-width: 720px) {
  .swr__grid--rank .swr__i { font-size: clamp(1.15rem, 5vw, 1.6rem); }
}


/* -------------------------------------------------------------------------
   §2 — LE CADRE COMMUN DES SEPT LIVRABLES

   `.dlv__ph` etait le cadre d'attente : fond, halo, filet interieur, rayon.
   `.dlv__frame` reprend exactement ces valeurs et devient le cadre qui
   CONTIENT un media. Les deux coexistent : `.dlv__ph` reste en place pour
   toute case qui redeviendrait vide.

   `overflow: hidden` est la seule addition de fond : sans lui, une video en
   `object-fit: cover` deborderait des coins arrondis. */
.dlv__frame {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: clamp(200px, 21vw, 360px);
  border-radius: clamp(10px, 1.1vw, 18px);
  overflow: hidden;
  background:
    radial-gradient(120% 90% at 50% 0%,
      rgba(232, 197, 71, 0.10) 0%,
      rgba(232, 197, 71, 0) 62%),
    linear-gradient(180deg, var(--surface-2) 0%, var(--surface) 100%);
  box-shadow: inset 0 0 0 1px var(--line),
              0 18px 44px rgba(0, 0, 0, 0.45);
}

/* Le numero de place reste ce qu'il etait, mais il passe maintenant AU
   DESSUS d'un media. Un voile local sous le chiffre plutot qu'un scrim sur
   toute l'image : le sujet reste a pleine luminosite. */
.dlv__frame .dlv__ph-n {
  z-index: 2;
  color: rgba(242, 240, 235, 0.92);
  padding: 0.15rem 0.45rem;
  border-radius: 4px;
  background: rgba(10, 11, 13, 0.55);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
}

/* <picture> est inline par defaut : sans ce display:block il ne prend pas
   la hauteur du cadre et l'image se cale sur sa ligne de base. */
.dlv__pic { display: block; width: 100%; height: 100%; }

.dlv__frame .dlv__img {
  width: 100%;
  height: 100%;
  border-radius: 0;      /* le rayon est porte par le cadre, pas par le media */
  object-fit: cover;
}

/* ---------- Le regime FIT : la case 04 ----------
   Le media est contenu, pas recadre. Une marge interieure evite que le
   mockup ne touche le filet du cadre — colle au bord, un rendu d'interface
   se lit comme une capture ratee plutot que comme un ecran presente. */
.dlv__frame--fit .dlv__pic { padding: clamp(0.5rem, 1vw, 0.9rem); }
.dlv__frame--fit .dlv__img { object-fit: contain; }


/* -------------------------------------------------------------------------
   §3 — LA CASE 03 : DEUX VIDEOS QUI ALTERNENT

   C'est le seul endroit de la page ou une case alterne. 5 000 ms par video,
   fondu croise de 500 ms — la meme duree de fondu que les cartes
   `data-seq` de la section 04, pour que les deux mecanismes ne se lisent
   pas comme deux systemes differents.

   Les deux plans sont ramenes au CARRE a l'encodage. C'est le point qui
   rend l'alternance possible : les fichiers livres etaient tous deux en
   1080x1080, mais l'un portait une image 16:9 letterboxee et l'autre une
   image 9:16 pillarboxee. Recadrer chacun sur son contenu reel puis les
   ramener a une meme forme est la seule facon d'eviter que la case ne
   change de proportion toutes les cinq secondes. */
.dlv__sq {
  position: relative;
  display: block;
  height: 100%;
  aspect-ratio: 1 / 1;
  max-width: 100%;
  border-radius: clamp(6px, 0.8vw, 12px);
  overflow: hidden;
  background: #000;
}
.dlv__v {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.5s var(--ease);
}
.dlv__v.is-on { opacity: 1; }

/* La case 07 : une seule video, qui remplit le cadre entier. */
.dlv__v--fill { position: absolute; inset: 0; border-radius: 0; }

/* Sans JS, la case doit montrer quelque chose : la premiere video est donc
   visible PAR DEFAUT, poster compris. Le JS ne prend la main qu'apres avoir
   pose `is-live` sur le cadre — c'est a partir de la seulement que
   l'opacite est pilotee par `is-on`. Un cadre vide n'est ainsi jamais
   possible, quel que soit l'etat du navigateur. */
.dlv__frame--seq .dlv__v:first-child { opacity: 1; }
.dlv__frame--seq.is-live .dlv__v { opacity: 0; }
.dlv__frame--seq.is-live .dlv__v.is-on { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .dlv__v { transition: none; }
}


/* -------------------------------------------------------------------------
   §4 — LES DEUX RUPTURES DEJA EN PLACE S'APPLIQUENT AU NOUVEAU CADRE
   Les media queries de la v68 ne connaissaient que `.dlv__img` et
   `.dlv__ph`. Elles sont reprises ici pour `.dlv__frame`, aux memes
   valeurs et aux memes seuils. */
@media (max-width: 620px) {
  .dlv__frame { height: clamp(190px, 52vw, 260px); }
}


/* =========================================================================
   v73 — LA SECTION PROCESS
   Ajoute en fin de fichier : aucune regle anterieure n'est reecrite ni
   supprimee. Toutes les regles sont prefixees `.hproc` — aucune ne peut
   atteindre un autre bloc de la page.
   ========================================================================= */

/* La section vit A L'INTERIEUR de `.dlv` (voir le commentaire dans
   index.html). Elle doit donc fabriquer elle-meme sa respiration haute,
   sinon elle se colle a la derniere rangee de livrables. La respiration
   basse est laissee au `margin-top` du CTA, deja en place. */
.hproc {
  margin-top: clamp(5.5rem, 11vw, 10rem);
}

.hproc__head {
  text-align: center;
  margin-bottom: clamp(3.5rem, 7vw, 6rem);
}
/* Meme corps que le titre de la section hote : les deux titres se suivent a
   quelques centaines de pixels, un ecart de taille se lirait comme une
   hierarchie qui n'existe pas. */
.hproc__ht {
  font-size: var(--fs-h2);
  max-width: 20ch;
  margin-inline: auto;
  text-wrap: balance;
}
.hproc__hs {
  margin: clamp(1rem, 1.8vw, 1.5rem) auto 0;
  max-width: 46ch;
  font-size: var(--fs-lead);
  color: var(--ash);
  line-height: 1.55;
}

.hproc__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  row-gap: clamp(3rem, 6vw, 5.5rem);
}

/* ---------- Un bloc : illustration a gauche, texte a droite ----------
   Les trois blocs sont identiques, sans alternance. C'est ce que fait la
   reference, et c'est ce qui tient la colonne de lecture : le regard
   descend tout droit sur les titres, sans traverser la page a chaque
   etape.

   1.15fr / 1fr : l'illustration est l'element important de la section,
   mais la colonne de texte doit rester au-dessus de 40ch pour que les
   paragraphes gardent des lignes lisibles. */
.hproc__step {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}
/* Le filet ferme l'etape et annonce la suivante. Il n'existe pas sous la
   troisieme : c'est le CTA qui suit, et deux separations empilees a cet
   endroit feraient lire une fin de page. */
.hproc__step:not(:last-child) {
  padding-bottom: clamp(3rem, 6vw, 5.5rem);
  border-bottom: 1px solid var(--line);
}

/* ---------- Le cadre de l'illustration ----------
   Meme grammaire que `.dlv__frame` de la v72 : rayon, filet interieur,
   ombre portee. Le fond n'est PAS repris : chaque SVG porte deja son
   propre fond sombre et sa trame, de facon a rester lisible meme ouvert
   seul dans un onglet. */
.hproc__fig {
  margin: 0;
  border-radius: clamp(10px, 1.1vw, 18px);
  overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--line),
              0 22px 52px rgba(0, 0, 0, 0.42);
}
.hproc__img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}

/* ---------- La colonne de texte ---------- */
.hproc__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin: 0;
  padding: 0.4rem 0.9rem 0.4rem 0.75rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-family: var(--display);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--bone);
}
.hproc__dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--signal);
  flex: none;
}
.hproc__st {
  margin-top: clamp(1.1rem, 2vw, 1.6rem);
  font-size: var(--fs-h3);
  letter-spacing: -0.02em;
  line-height: 1.15;
}
/* 46ch et non la largeur de la colonne : la consigne demande des lignes
   courtes et beaucoup d'espace negatif. Sur grand ecran la colonne fait
   plus de 60ch, ce qui donnerait un pave de documentation. */
.hproc__d {
  margin-top: clamp(0.85rem, 1.5vw, 1.25rem);
  max-width: 46ch;
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--ash);
}

/* ---------- Rupture ----------
   Sous 900 px les deux colonnes passent l'une sous l'autre, illustration
   en premier : c'est deja l'ordre du DOM, aucun `order` n'est necessaire
   et l'ordre annonce reste l'ordre affiche. */
@media (max-width: 900px) {
  .hproc__step {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(1.5rem, 4vw, 2.25rem);
  }
  .hproc__d { max-width: none; }
}

/* L'animation est celle qui existe deja : `.reveal` et son observateur.
   Rien n'a ete ajoute — pas de rotation, pas de parallaxe, pas de
   flottement. Le bloc monte de 28 px une fois et ne rejoue jamais. Sous
   `prefers-reduced-motion`, la regle de la ligne 524 pose l'etat final
   sans transition ; elle couvre `.hproc__step` sans modification. */

/* La consigne demande explicitement que le CTA qui suit ne semble pas
   colle. Son propre `margin-top` (3,5rem au plancher) suffisait a peine
   sur petit ecran : la troisieme etape ajoute donc sa propre respiration
   basse, sans toucher au CTA lui-meme. */
.hproc__step:last-child {
  padding-bottom: clamp(1.75rem, 3.5vw, 3rem);
}


/* =========================================================================
   v74 — TROIS AJOUTS, AUCUNE REECRITURE

   1. `.fsig`  — la signature du fondateur, entre la carte du release et
                 « Everything your artist brand needs… ».
   2. `.pkbtn` — le bouton blanc « Check out our packages ».
   3. `.hpk`   — les trois packs, en bas de la home.

   Tout est prefixe. Aucune regle anterieure n'est modifiee ni supprimee.
   Le renommage `.proc` -> `.hproc` de cette version est traite plus haut,
   dans le bloc v73 lui-meme : c'etait une collision de noms avec le bloc
   des 13 etapes de release.html, pas un ajout.
   ========================================================================= */

/* -------------------------------------------------------------------------
   §1 — LA CITATION MANUSCRITE

   Le brief demande une manuscrite « fine, elegante, contemporaine, tres
   lisible » et exclut explicitement le feutre decoratif. Permanent Marker,
   la seule manuscrite deja embarquee (bloc des plateformes, v35), est
   precisement ce qui est exclu : elle n'est pas reutilisee.

   Caveat (SIL Open Font License) est chargee depuis Google Fonts, faute de
   fichier local. C'est LE point a reprendre avant mise en ligne : c'est la
   seule dependance a un tiers de tout le site, et elle transmet l'IP du
   visiteur a Google. Voir MISSING-CONTENT.md §v74 — le passage en
   auto-heberge est un @font-face de quatre lignes et un woff2 depose dans
   /assets/fonts/, rien de plus.

   La pile de repli n'est pas decorative : si Caveat ne charge pas, la
   citation reste manuscrite sur macOS/iOS et sur Windows, et retombe sur
   l'italique du corps ailleurs — jamais sur une cursive de mariage. */
:root {
  --hand: 'Caveat', 'Segoe Script', 'Bradley Hand', 'Noteworthy', cursive;
}

.fsig {
  /* Aucun cadre, aucune carte, aucun fond : le bandeau est POSE dans le
     flux. Le seul marqueur de separation est un filet haut a 5,5 %
     d'opacite, plus clair que `--line` : il se lit comme un changement de
     respiration, pas comme une bordure.

     Une insertion, pas une section : la respiration est celle d'un
     paragraphe long, pas celle d'un chapitre. `--section-y` vaut le double
     et aurait fabrique exactement la grande section que le brief refuse. */
  border-top: 1px solid rgba(255, 255, 255, 0.055);
  padding-block: clamp(2.25rem, 4.5vw, 3.75rem);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: clamp(1.25rem, 3vw, 2.5rem);
  align-items: center;
}

/* Aucun cadre, aucune carte, aucun fond : le bandeau est POSE dans le flux.
   Le seul marqueur de separation est un filet haut a 6 % d'opacite, plus
   clair que `--line`, qui se lit comme un changement de respiration et non
   comme une bordure. */

/* ---------- La photo ----------
   Portrait editorial compact, jamais dominant : sa largeur est plafonnee a
   120 px, soit environ 9 % de la colonne utile. Pas de cercle, pas d'avatar,
   pas de bordure — un rayon de 10 px, celui des cadres du site. */
.fsig__ph {
  display: block;
  width: clamp(80px, 8.5vw, 120px);
  border-radius: 10px;
  overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--line);
}
.fsig__ph img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
}

.fsig__body { min-width: 0; }

/* ---------- La citation ----------
   Assez grande pour se lire comme une pensee, pas assez pour devenir un
   titre : elle plafonne a 1,85rem quand `--fs-h3` du site est au-dessus.
   La mesure est bornee a 54ch pour qu'elle tienne en trois ou quatre
   lignes courtes, comme une note ecrite a la main. */
.fsig__q {
  margin: 0;
  max-width: 54ch;
  font-family: var(--hand);
  font-weight: 500;
  font-size: clamp(1.3rem, 2.1vw, 1.85rem);
  line-height: 1.35;
  letter-spacing: 0.005em;
  color: var(--bone);
}
.fsig__q p { margin: 0; }

/* ---------- La signature ----------
   Typographie Ready Release, et volontairement plus discrete que la
   citation : c'est la citation qui porte le bandeau, pas la fonction. */
.fsig__by {
  margin: clamp(0.7rem, 1.4vw, 1rem) 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.45rem 0.7rem;
}
.fsig__name {
  font-family: var(--display);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--bone);
}
.fsig__role {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash-dim);
}

/* ---------- Rupture ----------
   La photo RESTE a gauche sous 720 px : la consigne l'autorise tant que la
   largeur suit, et a 80 px elle suit. Le bandeau ne devient donc jamais une
   pile verticale — c'est la contrainte n°6 du brief. */
@media (max-width: 720px) {
  .fsig { gap: 1rem; align-items: start; }
  .fsig__q { font-size: clamp(1.15rem, 4.6vw, 1.45rem); }
}

/* -------------------------------------------------------------------------
   §2 — LE BOUTON BLANC « CHECK OUT OUR PACKAGES »

   Forme de la reference : pilule pleine, libelle a gauche, chevron dans un
   disque a droite. Couleur imposee : blanc plein.

   A NOTER — ce bouton leve la regle posee en v66/v67 (« le blanc plein est
   reserve au parcours de commande »). C'est une decision explicite, pas un
   oubli : consignee dans MISSING-CONTENT.md §v74. Aucun autre CTA de la
   page n'a ete repeint. */
.pkbtn-wrap {
  /* La consigne demande de ne pas fabriquer d'espace noir inutile : la
     marge haute est courte, et c'est `.hproc` qui suit qui porte deja sa
     propre respiration. */
  margin: clamp(2.25rem, 4vw, 3.25rem) 0 0;
  text-align: center;
}
.pkbtn {
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.95rem 0.95rem 0.95rem 1.85rem;
  border-radius: 999px;
  background: #fff;
  color: #0A0B0D;
  font-family: var(--caps);
  font-size: clamp(0.95rem, 1.15vw, 1.0625rem);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1;
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.pkbtn:hover {
  transform: translateY(-2px);
  box-shadow: 0 14px 34px rgba(255, 255, 255, 0.14);
}
.pkbtn:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
.pkbtn__ic {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  /* Le disque du chevron est le meme blanc, assombri : sur la reference il
     se detache du bouton sans introduire de seconde couleur. */
  background: rgba(10, 11, 13, 0.09);
}
.pkbtn__ic svg { width: 0.7rem; height: 0.7rem; display: block; }
@media (prefers-reduced-motion: reduce) {
  .pkbtn { transition: none; }
  .pkbtn:hover { transform: none; }
}

/* « Ne pas creer d'espace noir inutile entre les sections. » Le bouton
   s'intercale entre la grille et le Process : sans cette regle, sa hauteur
   et sa marge s'ADDITIONNENT aux 10rem que `.hproc` se donnait quand elle
   suivait directement la grille. La respiration haute du Process est donc
   reduite de moitie lorsqu'il est precede du bouton — et seulement dans ce
   cas, le selecteur adjacent ne peut pas atteindre une autre page. Solde
   reel ajoute a la page : environ 36 px au lieu de 114. */
.pkbtn-wrap + .hproc { margin-top: clamp(3rem, 6vw, 5rem); }

/* -------------------------------------------------------------------------
   v75 — SECTION PRICING DE LA HOME

   Remplace integralement le bloc `.hpk` de la v74. Plus aucune regle `.hpk`
   n'est conservee : les classes ne sont plus utilisees dans aucune page.

   FOND SOMBRE, PAS BLANC. Le document de cadrage demandait un fond blanc.
   Le site entier tourne sur --void (#0A0B0D) et --bone : une section blanche
   au milieu aurait lu comme un bloc colle, pas comme une section premium.
   L'intention du brief — respiration, bleu profond, bordures fines, aucune
   couleur parasite — est tenue dans la palette du site.

   POUR PASSER EN BLANC malgre tout : ajouter la classe `rrp--light` sur la
   <section>. Tout le bloc bascule, aucun autre fichier a toucher. La regle
   est ecrite plus bas et volontairement gardee courte pour rester lisible.
   ------------------------------------------------------------------------- */
.rrp {
  --rrp-bg: transparent;
  --rrp-card: var(--surface);
  --rrp-ink: var(--bone);
  --rrp-dim: var(--ash);
  --rrp-faint: var(--ash-dim);
  --rrp-line: var(--line);
  --rrp-line-2: var(--line-strong);
  --rrp-blue: var(--signal);
  --rrp-blue-deep: var(--signal-fill);
  background: var(--rrp-bg);
}

/* ---------------------------------------------------------------- en-tete */
.rrp__head { max-width: 68ch; margin: 0 auto clamp(2rem, 4vw, 3.25rem); text-align: center; }
.rrp__kicker {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--rrp-blue);
  margin: 0 0 1rem;
}
.rrp__t {
  font-family: var(--display);
  font-size: var(--fs-h2);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.06;
  color: var(--rrp-ink);
  margin: 0;
  text-wrap: balance;
}
.rrp__sub {
  margin: 1.1rem auto 0;
  /* v76 — la mesure passe de 62ch a 860px. En `ch`, la largeur se calculait
     sur la police de l'element : le paragraphe tombait a ~560px et se lisait
     comme un pave de quatre lignes courtes centrees. En pixels, il tient sur
     deux a trois lignes larges. */
  max-width: min(100%, 860px);
  text-wrap: pretty;
  color: var(--rrp-dim);
  font-size: var(--fs-body);
  line-height: 1.6;
}
.rrp__pos {
  margin: 1.6rem auto 0;
  max-width: min(100%, 720px);
  text-wrap: balance;
  font-family: var(--display);
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.35;
  color: var(--rrp-ink);
}
/* v76 — une seule ligne, tenue sur une seule ligne tant que la place le
   permet. Le paragraphe de quatre lignes qui occupait cette place est
   supprime : il redisait ce que les cartes disent en detail. */
.rrp__pos--2 {
  margin-top: 0.85rem;
  font-family: var(--body);
  font-size: 1rem;
  font-weight: 400;
  color: var(--rrp-dim);
  line-height: 1.5;
  max-width: min(100%, 780px);
}

/* ----------------------------------------------------------------- toggle */
.rrp__toggle {
  display: flex;
  width: max-content;
  gap: 2px;
  padding: 3px;
  margin: 0 auto;
  border: 1px solid var(--rrp-line);
  border-radius: 999px;
  background: var(--rrp-card);
}
.rrp__tbtn {
  appearance: none;
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 0.55rem 1.35rem;
  border-radius: 999px;
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--rrp-dim);
  transition: color 0.25s var(--ease), background 0.25s var(--ease);
}
.rrp__tbtn:hover { color: var(--rrp-ink); }
.rrp__tbtn.is-on { color: var(--void); background: var(--rrp-blue-deep); }
.rrp__tbtn:focus-visible { outline: 2px solid var(--rrp-blue); outline-offset: 2px; }

.rrp__lead {
  margin: 1.25rem auto clamp(1.75rem, 3vw, 2.5rem);
  text-align: center;
  color: var(--rrp-dim);
  font-size: 0.9375rem;
}

/* ------------------------------------------------------------------ grille
   Trois colonnes egales. La carte du milieu ne prend pas plus de place :
   elle est surelevee et bordee de bleu. Elargir une colonne casserait
   l'alignement des lignes de livrables entre les trois cartes, qui est
   precisement ce qui rend la comparaison lisible. */
.rrp__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 1.8vw, 1.6rem);
  align-items: center;
}

.rrp__card {
  position: relative;
  border: 1px solid var(--rrp-line);
  border-radius: var(--radius-m);
  background: var(--rrp-card);
  transition: border-color 0.3s var(--ease), transform 0.3s var(--ease);
}
.rrp__card:hover { border-color: var(--rrp-line-2); }
.rrp__body {
  display: flex;
  flex-direction: column;
  padding: clamp(1.5rem, 2.4vw, 2.25rem) clamp(1.35rem, 2vw, 1.9rem) clamp(1.4rem, 2vw, 1.85rem);
  transition: opacity 0.22s var(--ease);
}
.rrp__card.is-swapping .rrp__body { opacity: 0; }

.rrp__card--star {
  border-color: rgba(232, 197, 71, 0.45);
  background: linear-gradient(180deg, rgba(232, 197, 71, 0.09), rgba(232, 197, 71, 0.02) 55%, transparent), var(--rrp-card);
  box-shadow: 0 24px 60px -32px rgba(232, 197, 71, 0.75);
  transform: translateY(-10px);
}
.rrp__flag {
  position: absolute;
  top: 0; left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--void);
  background: var(--rrp-blue-deep);
  border-radius: 999px;
  padding: 0.28rem 0.85rem;
  white-space: nowrap;
}

/* --------------------------------------------------------- corps de carte
   Ordre impose par le brief : nom, promesse, prix, valeur, livrables, CTA,
   garantie, rarete. Le prix n'est jamais le seul element dominant. */
.rrp__name {
  font-family: var(--display);
  font-size: clamp(1.15rem, 1.7vw, 1.4rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--rrp-ink);
  margin: 0;
}
.rrp__promise {
  margin: 0.45rem 0 0;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--rrp-dim);
  min-height: 2.9em;
}
.rrp__price { margin: 1.1rem 0 0; display: flex; align-items: baseline; gap: 0.5rem; }
.rrp__amount {
  font-family: var(--display);
  font-size: clamp(2.1rem, 3.2vw, 2.85rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1;
  color: var(--rrp-ink);
  font-variant-numeric: tabular-nums;
}
.rrp__save {
  margin: 0.7rem 0 0;
  align-self: flex-start;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--rrp-blue);
  border: 1px solid rgba(232, 197, 71, 0.45);
  border-radius: 999px;
  padding: 0.28rem 0.7rem;
  line-height: 1.3;
}
.rrp__under {
  margin: 0.75rem 0 0;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--rrp-faint);
}

.rrp__group {
  margin: clamp(1.35rem, 2.2vw, 1.75rem) 0 0;
  padding-top: clamp(1.1rem, 1.8vw, 1.4rem);
  border-top: 1px solid var(--rrp-line);
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--rrp-faint);
}
.rrp__group--opt { color: var(--rrp-blue); }

.rrp__feats { list-style: none; margin: 0.95rem 0 0; padding: 0; display: grid; gap: 0.95rem; }
.rrp__feat { position: relative; padding-left: 1.4rem; }
.rrp__feat::before {
  content: '';
  position: absolute;
  left: 0; top: 0.42em;
  width: 7px; height: 7px;
  border-left: 1.5px solid var(--rrp-blue);
  border-bottom: 1.5px solid var(--rrp-blue);
  transform: rotate(-45deg);
}
.rrp__feat-t {
  display: block;
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--rrp-ink);
  line-height: 1.35;
}
.rrp__feat-d {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--rrp-dim);
}
.rrp__opt {
  margin: 0.7rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--rrp-dim);
}
.rrp__opt span { color: var(--rrp-ink); font-weight: 700; }

.rrp__note {
  margin: clamp(1.1rem, 1.8vw, 1.5rem) 0 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--rrp-faint);
}

/* Le CTA est pousse en bas : les trois boutons s'alignent quel que soit le
   nombre de livrables au-dessus. */
.rrp__cta {
  appearance: none;
  cursor: pointer;
  display: block;
  width: 100%;
  margin-top: clamp(1.25rem, 2.2vw, 1.75rem);
  padding: 0.85rem 1rem;
  border: 1px solid var(--rrp-line-2);
  border-radius: var(--radius-s);
  background: transparent;
  font-family: var(--body);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--rrp-ink);
  transition: background 0.25s var(--ease), border-color 0.25s var(--ease), opacity 0.25s var(--ease);
}
.rrp__cta::after { content: ' \2192'; }
.rrp__cta:hover { border-color: var(--rrp-ink); background: rgba(242, 240, 235, 0.06); }
.rrp__cta:focus-visible { outline: 2px solid var(--rrp-blue); outline-offset: 2px; }
.rrp__cta.is-busy { opacity: 0.55; cursor: progress; }
.rrp__card--star .rrp__cta {
  border-color: transparent;
  background: var(--rrp-blue-deep);
  color: var(--void);
}
.rrp__card--star .rrp__cta:hover { background: #F2D56D; }

.rrp__guarantee {
  margin: 0.8rem 0 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  font-size: 0.75rem;
  color: var(--rrp-dim);
}
/* Bouclier minimaliste, dessine en CSS : pas d'icone a charger pour une
   ligne de 12 px. */
.rrp__shield {
  width: 11px; height: 13px;
  flex: 0 0 auto;
  background: var(--rrp-blue);
  clip-path: polygon(50% 0%, 100% 22%, 100% 62%, 50% 100%, 0% 62%, 0% 22%);
  opacity: 0.85;
}
.rrp__scarce {
  margin: 0.55rem 0 0;
  text-align: center;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--rrp-faint);
}
.rrp__reco {
  margin: 1rem 0 0;
  padding-top: 0.9rem;
  border-top: 1px solid var(--rrp-line);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--rrp-dim);
  font-style: italic;
}

/* ------------------------------------------------------------ aide au choix */
.rrp__guide {
  margin: clamp(2.5rem, 5vw, 4rem) auto 0;
  max-width: var(--container-narrow);
  padding: clamp(1.5rem, 2.6vw, 2.25rem);
  border: 1px solid var(--rrp-line);
  border-radius: var(--radius-m);
  text-align: center;
}
.rrp__guide-t {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--rrp-faint);
}
.rrp__guide-l {
  list-style: none;
  margin: 1.35rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}
.rrp__guide-l li { display: grid; gap: 0.2rem; }
.rrp__guide-n { font-family: var(--display); font-weight: 700; color: var(--rrp-ink); font-size: 1rem; }
.rrp__guide-d { font-size: 0.8125rem; color: var(--rrp-dim); }
.rrp__guide-p {
  margin: 1.5rem auto 0;
  max-width: 58ch;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--rrp-dim);
}

/* ------------------------------------------------------- pourquoi ce prix */
.rrp__why {
  margin: clamp(2.5rem, 5vw, 4rem) auto 0;
  max-width: 68ch;
  text-align: center;
}
.rrp__why-k {
  margin: 0 0 1.1rem;
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--rrp-blue);
}
.rrp__why-p {
  margin: 0 0 0.85rem;
  font-size: var(--fs-body);
  line-height: 1.65;
  color: var(--rrp-dim);
}
.rrp__why-s {
  margin: 1.2rem 0 0;
  font-family: var(--display);
  font-size: clamp(1.05rem, 1.7vw, 1.35rem);
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--rrp-ink);
}

/* -------------------------------------------------------------- conclusion */
.rrp__end {
  margin: clamp(2.5rem, 5vw, 4rem) auto 0;
  max-width: 62ch;
  text-align: center;
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid var(--rrp-line);
}
.rrp__end-t {
  margin: 0;
  font-family: var(--display);
  font-size: var(--fs-h3);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.15;
  color: var(--rrp-ink);
}
.rrp__end-p {
  margin: 0.9rem 0 0;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--rrp-dim);
}
.rrp__end-cta {
  display: inline-block;
  margin-top: 1.35rem;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--rrp-blue);
  border-bottom: 1px solid rgba(232, 197, 71, 0.4);
  padding-bottom: 2px;
}
.rrp__end-cta:hover { border-bottom-color: var(--rrp-blue); }

.rrp__foot {
  margin: clamp(1.6rem, 3vw, 2.5rem) 0 0;
  text-align: center;
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.1em;
  color: var(--rrp-faint);
}

#packages { scroll-margin-top: 6.5rem; }

/* ------------------------------------------------------------- responsive
   Pas de trois colonnes ecrasees. Sous 1080 px les cartes s'empilent, dans
   l'ordre Release / Launch / Complete, et Launch garde son badge et sa
   bordure bleue : c'est la seule hierarchie a preserver en mobile. */
@media (max-width: 1080px) {
  .rrp__grid { grid-template-columns: minmax(0, 1fr); max-width: 560px; margin-inline: auto; gap: 1.75rem; }
  .rrp__card--star { transform: none; }
  .rrp__promise { min-height: 0; }
  .rrp__guide-l { grid-template-columns: minmax(0, 1fr); gap: 0.9rem; }
  .rrp__guide-l li { display: flex; gap: 0.5rem; justify-content: center; align-items: baseline; }
}
@media (max-width: 640px) {
  .rrp__head { text-align: left; }
  .rrp__lead { text-align: left; }
  .rrp__toggle { width: 100%; }
  .rrp__tbtn { flex: 1; text-align: center; }
  #packages { scroll-margin-top: 5rem; }
}
@media (prefers-reduced-motion: reduce) {
  .rrp__card, .rrp__body, .rrp__cta { transition: none; }
}

/* -------------------------------------------------------------------------
   VARIANTE CLAIRE — ajouter `rrp--light` sur la <section> pour l'activer.
   Elle ne redefinit que les jetons du bloc : aucune regle ci-dessus n'est
   dupliquee. Livree non activee : a comparer en situation avant de trancher.
   ------------------------------------------------------------------------- */
.rrp--light {
  --rrp-bg: #FFFFFF;
  --rrp-card: #FFFFFF;
  --rrp-ink: #0A0B0D;
  --rrp-dim: #4A505B;
  --rrp-faint: #7A828F;
  --rrp-line: rgba(10, 11, 13, 0.10);
  --rrp-line-2: rgba(10, 11, 13, 0.22);
  --rrp-blue: #E8C547;
  --rrp-blue-deep: #BCA047;
  padding-inline: var(--gutter);
}
.rrp--light .rrp__card { box-shadow: 0 1px 2px rgba(10, 11, 13, 0.04); }
.rrp--light .rrp__card--star {
  background: #FFFFFF;
  border-color: rgba(232, 197, 71, 0.35);
  box-shadow: 0 24px 60px -34px rgba(232, 197, 71, 0.45);
}
.rrp--light .rrp__cta:hover { background: rgba(10, 11, 13, 0.04); }
.rrp--light .rrp__card--star .rrp__cta:hover { background: #F2D56D; }

/* =========================================================================
   v76 — RESSERRAGE VERTICAL, VIGNETTES DU PROCESS, BLOC COMPARATIF,
         TEMOIGNAGES VIDEO

   Cinq corrections issues des captures. Chacune est ecrite ici, en fin de
   feuille, et surcharge la regle d'origine sans la modifier : les blocs
   v72 / v73 / v74 restent lisibles tels qu'ils ont ete ecrits.
   ========================================================================= */

/* -------------------------------------------------------------------------
   §1 — L'ESPACE NOIR ENTRE LE TEMOIGNAGE DU FONDATEUR ET « EVERYTHING YOUR
        ARTIST BRAND NEEDS »

   `.fsig` fermait sur 3,75rem, puis `.section` rouvrait sur `--section-y`,
   soit jusqu'a 11rem. Les deux s'additionnaient : pres de 15rem de noir
   pour un simple changement de sujet. Le bas de la section est reduit dans
   le meme mouvement, parce que le bloc video qui s'y trouve maintenant est
   suivi immediatement de la grille de prix.
   ------------------------------------------------------------------------- */
.dlv {
  padding-top: clamp(2.5rem, 5vw, 4.5rem);
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
}
.dlv__head { margin-bottom: clamp(2.25rem, 4.5vw, 3.75rem); }
/* La section de prix rouvrait elle aussi sur `--section-y` juste apres. */
.rrp { padding-top: clamp(3rem, 6vw, 5rem); }

/* -------------------------------------------------------------------------
   §2 — LES TROIS VIGNETTES DU PROCESS

   Elles occupaient plus de la moitie de la largeur utile, donc environ
   360px de haut chacune en 3:2, face a une colonne de texte qui en fait
   210. La liste est ramenee a 1000px et les deux colonnes deviennent
   egales : l'illustration tombe a ~470px de large, soit ~313px de haut.
   Elle depasse encore le texte en haut et en bas, mais de peu — ce qui
   etait la demande, et ce qui garde l'image comme element principal.

   Les gouttieres verticales suivent : une etape ne peut pas etre plus
   espacee de la suivante qu'elle n'est haute.
   ------------------------------------------------------------------------- */
.hproc__list {
  max-width: 920px;
  margin-inline: auto;
  row-gap: clamp(2rem, 4vw, 3.25rem);
}
/* Sous 901px la regle d'origine empile les deux colonnes. Elle est ecrite
   PLUS HAUT dans cette feuille : une declaration sans media query ici la
   ecraserait et ramenerait deux colonnes sur telephone. D'ou le
   `min-width`. */
@media (min-width: 901px) {
  .hproc__step {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(1.5rem, 3.5vw, 3.5rem);
  }
}
.hproc__step:not(:last-child) { padding-bottom: clamp(2rem, 4vw, 3.25rem); }
.hproc__head { margin-bottom: clamp(2.25rem, 4.5vw, 3.75rem); }
.hproc { margin-top: clamp(3.5rem, 7vw, 6rem); }

/* Sous 860px les deux colonnes s'empilent deja (regle d'origine). La
   vignette y reprend toute la largeur : la plafonner ici la laisserait
   flotter au milieu d'une colonne vide. */

/* -------------------------------------------------------------------------
   §3 — LE BLOC COMPARATIF : QUATRE LIGNES, JAMAIS DEUX

   A 2,125rem, « Sound that still feels like a demo » cassait en deux et la
   colonne de gauche comptait cinq lignes face aux quatre de droite. Les
   deux colonnes descendent a 1,75rem : la ligne la plus longue tient, et
   les huit lignes sont a la meme hauteur.

   Les titres TRADITIONAL WAY et READY RELEASE ne bougent pas.

   `nowrap` n'est pose qu'au-dessus de 900px, la ou la mesure est sure. En
   dessous, la reduction de taille suffit et un `nowrap` risquerait un
   debordement horizontal.
   ------------------------------------------------------------------------- */
.cmp__li {
  font-size: clamp(1rem, 1.85vw, 1.75rem);
  grid-template-columns: clamp(34px, 3vw, 46px) minmax(0, 1fr);
  gap: clamp(0.7rem, 1.1vw, 1rem);
}
.cmp__list { gap: clamp(0.85rem, 1.6vw, 1.25rem); }
.cmp__x     { width: clamp(26px, 2.2vw, 34px); height: clamp(26px, 2.2vw, 34px); }
.cmp__mark  { width: clamp(32px, 2.9vw, 46px); }
@media (min-width: 900px) {
  .cmp__li > span { white-space: nowrap; }
}

/* -------------------------------------------------------------------------
   §4 — LES TROIS TEMOIGNAGES VIDEO

   Trois cadres 9:16 de taille strictement identique, poses sur une grille
   a trois colonnes egales. La grille est plafonnee a 900px : a pleine
   largeur de conteneur, une colonne ferait 420px, donc 747px de haut, et
   le bloc mangerait un ecran entier a lui seul. A 900px chaque cadre fait
   ~285px de large et ~505px de haut, ce qui reste la proportion d'un
   telephone pose sur la page.

   Aucune marge haute ou basse supplementaire : le resserrage du §1 tient
   deja l'espacement avec la section du dessus et la grille de prix du
   dessous.
   ------------------------------------------------------------------------- */
.tvid { margin-top: clamp(2.25rem, 4.5vw, 3.5rem); }
.tvid__grid {
  list-style: none;
  margin: 0 auto;
  padding: 0;
  max-width: 900px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.75rem, 1.6vw, 1.25rem);
}
.tvid__i { min-width: 0; }
.tvid__frame {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: clamp(10px, 1.1vw, 18px);
  overflow: hidden;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line), 0 22px 52px rgba(0, 0, 0, 0.42);
}
.tvid__v {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* L'emplacement vide. Il se lit comme reserve, pas comme casse : filet
   pointille, pictogramme neutre, libelle. */
.tvid__ph {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.85rem;
  border: 1px dashed var(--line-strong);
  border-radius: inherit;
  background: linear-gradient(180deg, rgba(232, 197, 71, 0.05), transparent 60%);
}
.tvid__ph-ic {
  width: clamp(28px, 3vw, 40px);
  height: clamp(28px, 3vw, 40px);
  border: 1px solid var(--ash-dim);
  border-radius: 50%;
  position: relative;
}
/* Triangle de lecture, dessine en CSS : pas de fichier a charger pour un
   emplacement qui a vocation a disparaitre. */
.tvid__ph-ic::after {
  content: "";
  position: absolute;
  top: 50%; left: 54%;
  transform: translate(-50%, -50%);
  border-left: 10px solid var(--ash-dim);
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
}
.tvid__ph-l {
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash-dim);
}

/* Trois colonnes jusqu'au bout : empiler des 9:16 les uns sous les autres
   ferait defiler trois ecrans. En mobile la grille se resserre, elle ne se
   casse pas. */
@media (max-width: 620px) {
  .tvid__grid { gap: 0.5rem; max-width: none; }
  .tvid__ph { gap: 0.5rem; }
  .tvid__ph-l { font-size: 0.5rem; letter-spacing: 0.1em; }
}

/* =========================================================================
   v77 — SECTION 01, VERSION COURTE (.conv--slim)
   Le bloc ne garde que l'argument : titre, promesse, trois lignes de contenu.
   Le cadre bleu part, et avec lui le prix, l'upload, la reassurance et le
   lien vers le pack. Objectif mesure : moitie de la hauteur precedente
   (~590px pleine largeur avant, ~290px apres).

   La photo n'est pas seulement retrecie, elle est recadree. Elle occupait
   66% de la largeur sur un bloc haut ; a hauteur divisee par deux, le meme
   object-position ne montrait plus qu'un torse coupe. Elle passe a 46% et
   remonte sur le visage et la console.
   ========================================================================= */
.conv--slim {
  border: 0;
  border-radius: var(--radius-m);
  padding: clamp(1.15rem, 2.4vw, 1.7rem) clamp(1.1rem, 2.6vw, 2rem);
  grid-template-columns: minmax(0, 1fr);
  row-gap: clamp(0.75rem, 1.8vw, 1.1rem);
  background:
    radial-gradient(90% 160% at 8% 0%, rgba(232, 197, 71, 0.07), transparent 62%),
    var(--surface);
}
/* plus de filet sous l'en-tete : a cette hauteur il decoupait le bloc en deux
   bandes de 120px et annulait le gain de compacite */
.conv--slim .conv__head {
  border-bottom: 0;
  padding-bottom: 0;
  max-width: min(52ch, 58%);
}
.conv--slim .conv__t { font-size: clamp(1.2rem, 2.05vw, 1.65rem); max-width: 26ch; }
.conv--slim .conv__sub { margin-top: 0.5rem; line-height: 1.55; }

/* les trois lignes passent sur deux colonnes : en une seule colonne elles
   rendaient au bloc la hauteur qu'on venait de lui retirer */
.conv--slim .conv__inc {
  max-width: min(60ch, 58%);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.45rem clamp(1rem, 2.5vw, 2rem);
}
.conv--slim .conv__inc li:first-child { grid-column: 1 / -1; }

.conv--slim .conv__photo { width: 46%; }
.conv--slim .conv__photo img {
  object-position: 56% 30%;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,0.5) 30%, #000 68%);
          mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,0.5) 30%, #000 68%);
}
.conv--slim .conv__veil {
  background:
    linear-gradient(100deg,
      var(--surface) 0%,
      rgba(15, 17, 21, 0.94) 40%,
      rgba(15, 17, 21, 0.55) 62%,
      rgba(15, 17, 21, 0.18) 100%);
}
@media (max-width: 859px) {
  .conv--slim .conv__head,
  .conv--slim .conv__inc { max-width: none; }
  .conv--slim .conv__inc { grid-template-columns: 1fr; }
  .conv--slim .conv__inc li:first-child { grid-column: auto; }
  .conv--slim .conv__photo { width: 100%; }
  .conv--slim .conv__photo img {
    object-position: 60% 28%;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 60%);
            mask-image: linear-gradient(to bottom, transparent 0%, #000 60%);
  }
  /* en une colonne le texte traverse toute la largeur : le voile diagonal
     du desktop laissait la sous-ligne passer sur le visage */
  .conv--slim .conv__veil {
    background:
      linear-gradient(to bottom, var(--surface) 0%, rgba(15, 17, 21, 0.93) 34%, rgba(15, 17, 21, 0.86) 100%);
  }
}

/* =========================================================================
   v77 — LIGNE DE FORMATS SANS BOUTON
   Cover Art et YouTube Thumbnail n'ont plus de bouton d'ajout. La ligne qui
   vivait sous lui remonte a sa place : centree, un cran plus grande, et sur
   la couleur de texte courante plutot que sur le gris de note de bas de page,
   puisqu'elle est maintenant le dernier mot du bloc et non une legende.
   ========================================================================= */
.sec-cta__formats--solo {
  margin-top: clamp(1.1rem, 2.4vw, 1.6rem);
  margin-inline: auto;
  max-width: 68ch;
  text-align: center;
  font-size: clamp(0.86rem, 1.05vw, 0.95rem);
  line-height: 1.55;
  color: var(--ash);
  text-wrap: pretty;
}

/* =========================================================================
   v77 — SOCIAL MEDIA KIT + MOCKUPS
   Rubrique de presentation : meme geometrie que prod--thumb, soulignement
   statique comme prod--cover (l'animation au mot-cle reste l'effet propre du
   bloc thumbnail, la dupliquer une troisieme fois en ferait un tic de page).
   ========================================================================= */
.prod--social { margin-bottom: clamp(2.25rem, 5vw, 3.75rem); }

/* bandeau en attente d'images : cadre pointille + numero, meme geometrie
   carree que le bandeau Cover Art pour que les deux bandes se repondent */
.cmq__tile--ph {
  border: 1px dashed var(--line-strong);
  background:
    repeating-linear-gradient(135deg,
      rgba(242, 240, 235, 0.022) 0 8px,
      transparent 8px 16px),
    var(--surface);
  display: grid;
  place-items: center;
}
.cmq__item:hover .cmq__tile--ph { transform: none; }
.cmq__phn {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  color: var(--ash-dim);
}

/* =========================================================================
   v78 — CHAPITRE 04 RECONSTRUIT + FIN DE CHAPITRE 03
   Une seule regle de composition pour tout le chapitre : le texte porte, les
   cadres disparaissent. Pas de carte fermee, pas de tableau de prix, pas de
   deuxieme systeme typographique — tout est bati sur --display / --mono, les
   tokens de couleur existants et la primitive .reveal deja pilotee par
   main.js. Aucun JS n'a ete ajoute.
   ========================================================================= */

/* ---------- 03 · la phrase de fin, seule ----------
   Elle remplace le bloc tarifaire. Centree, large, sans cadre : c'est la
   respiration entre deux chapitres, pas un encart. */
.endline {
  margin: clamp(2.5rem, 6vw, 4.5rem) auto 0;
  max-width: 24ch;
  text-align: center;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.9rem, 5vw, 3.6rem);
  line-height: 1.04;
  letter-spacing: -0.03em;
  color: var(--bone);
  text-wrap: balance;
}
.endline__kw { color: var(--signal); font-weight: 700; }

/* Le vide noir entre 03 et 04 venait du bas de section calibre pour un bloc
   de ~600px. Sans lui, la marge basse standard laissait un ecran presque
   vide avant l'ouverture du chapitre 04. */
#shorts.section { padding-bottom: clamp(3rem, 7vw, 5.5rem); }
/* =====================================================================
   CHAPITRE 04 · FULL VIDEO CLIP — refonte v79
   Contraintes du brief : aucune card, aucune tile, aucune grille de
   blocs, aucun container repetitif. Filets fins, asymetrie, vide.
   Echelle typographique alignee sur le reste du site : plus aucun
   titre de ce chapitre ne depasse --fs-h2.
   ===================================================================== */

.vblock { margin-top: clamp(4.5rem, 11vw, 9rem); }

.vw__t {
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h2);
  line-height: 1.03;
  letter-spacing: -0.035em;
  max-width: 20ch;
  text-wrap: balance;
}
/* v79 — l'ancien --big montait a 5rem et cassait l'echelle de la page. */
.vw__t--lead { max-width: 22ch; }
.vw__t--mid { font-size: var(--fs-h3); max-width: 26ch; margin-top: clamp(2.5rem, 6vw, 4rem); }

.vw__lead {
  margin-top: 1.15rem;
  font-size: var(--fs-lead);
  line-height: 1.55;
  color: var(--ash);
  max-width: 56ch;
}
.vw__sub { margin-top: 1rem; font-size: 0.9375rem; line-height: 1.6; color: var(--ash-dim); max-width: 54ch; }

/* Un seul index CSS pour toutes les cascades du chapitre. */
.vbeat__i, .vdep__i, .varc__i, .vget__i, .vlev__i, .vsteps .vstep {
  transition-delay: calc(var(--i, 0) * 80ms);
}

/* ---------- 01 · these ---------- */
.vhero { margin-top: clamp(1.5rem, 4vw, 3rem); max-width: 62ch; }
.vhero__eyebrow {
  color: var(--ash-dim);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  font-size: 0.7rem;
}
.vhero__t {
  margin-top: 1.4rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h2);
  line-height: 1.02;
  letter-spacing: -0.04em;
}
.vhero__t2 { color: var(--signal); }
.vhero__lead {
  margin-top: 1.4rem;
  font-size: var(--fs-lead);
  line-height: 1.6;
  color: var(--ash);
  max-width: 52ch;
}

/* ---------- 02 · trois temps ----------
   Lignes continues separees par un filet, pas trois colonnes. */
.vbeat { margin-top: clamp(2.25rem, 5vw, 3.25rem); max-width: 62ch; }
.vbeat__i {
  display: grid;
  grid-template-columns: 8rem 1fr;
  gap: 1.5rem;
  align-items: baseline;
  padding: 1.1rem 0;
  border-top: 1px solid var(--line);
}
.vbeat__i:last-child { border-bottom: 1px solid var(--line); }
.vbeat__k {
  color: var(--ash-dim);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.vbeat__i:nth-child(2) .vbeat__k { color: var(--signal); }
.vbeat__p { font-size: var(--fs-body); line-height: 1.5; color: var(--bone); }

/* ---------- 03 · LE DEPLOIEMENT · element signature ----------
   Une tige verticale, cinq filets horizontaux de longueurs inegales.
   Aucune boite : le dessin EST l'argument. --w decale chaque libelle,
   ce qui produit l'asymetrie demandee au brief. */
.vdep__kicker {
  color: var(--ash-dim);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin-bottom: 1rem;
}

.vdep {
  position: relative;
  margin-top: clamp(2.75rem, 6vw, 4.5rem);
  padding-left: clamp(1.5rem, 4vw, 3rem);
}
/* la tige */
.vdep::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.6em;
  bottom: 2.2rem;
  width: 1px;
  background: linear-gradient(180deg,
              var(--signal) 0%,
              var(--line-strong) 22%,
              var(--line) 100%);
}

.vdep__src {
  position: relative;
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h3);
  letter-spacing: -0.025em;
  color: var(--bone);
  line-height: 1;
}
.vdep__dot {
  position: absolute;
  left: calc(-1 * clamp(1.5rem, 4vw, 3rem) - 3px);
  top: 0.42em;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--signal);
  box-shadow: 0 0 0 4px rgba(232, 197, 71, 0.14);
}

.vdep__list { margin-top: clamp(2rem, 5vw, 3rem); }

.vdep__i {
  position: relative;
  padding: 1.35rem 0 1.35rem calc(var(--w, 20%) * 0.42 + 2.5rem);
  display: block;
}
/* le filet qui part de la tige jusqu'au libelle */
.vdep__i::before {
  content: '';
  position: absolute;
  left: calc(-1 * clamp(1.5rem, 4vw, 3rem));
  top: 2.05rem;
  width: calc(var(--w, 20%) * 0.42 + clamp(1.5rem, 4vw, 3rem) + 1.6rem);
  height: 1px;
  background: linear-gradient(90deg, var(--line-strong), var(--line));
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform 1s var(--ease) calc(var(--i, 0) * 110ms + 120ms);
}
.vdep__i.is-in::before { transform: scaleX(1); }

.vdep__t {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.15rem, 1.9vw, 1.6rem);
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--bone);
}
.vdep__p {
  display: block;
  margin-top: 0.5rem;
  color: var(--ash-dim);
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.vdep__i:first-child .vdep__t { color: var(--signal); }

.vdep__foot {
  margin-top: clamp(2rem, 5vw, 3rem);
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--fs-h3);
  letter-spacing: -0.02em;
  color: var(--bone);
  max-width: 24ch;
}

/* ---------- 04 · l'arc ----------
   Escalier vertical plutot que course horizontale : quatre temps sur une
   seule ligne se cassaient au retour a la ligne, laissant un filet
   orphelin en debut de rang. L'indentation croissante dit la meme chose
   et porte l'asymetrie demandee au brief. */
.varc { margin-left: clamp(0rem, 6vw, 7rem); }
.varc__run { display: grid; gap: clamp(0.6rem, 1.5vw, 1rem); }
.varc__i {
  display: flex;
  align-items: baseline;
  gap: clamp(0.9rem, 2vw, 1.5rem);
  padding-left: calc(var(--i, 0) * clamp(0.75rem, 2.5vw, 2.75rem));
}
.varc__i::before {
  content: '';
  flex: 0 0 auto;
  width: clamp(1.75rem, 5vw, 4.5rem);
  height: 1px;
  background: var(--line-strong);
  transform: translateY(-0.35em);
}
.varc__i--end::before { background: var(--signal); }
.varc__l {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.05rem, 2.1vw, 1.7rem);
  letter-spacing: -0.025em;
  color: var(--ash);
}
.varc__i--end .varc__l { color: var(--signal); }
.varc .vw__sub { margin-top: clamp(1.5rem, 3vw, 2rem); }

/* ---------- 05 · seconde piece · emplacement video ----------
   Compact et decale : il enrichit sans dominer. Le placeholder a la
   meme empreinte que la vraie video, donc la substituer ne deplace
   rien dans la page. */
.vfilm {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
  margin-top: clamp(1.5rem, 4vw, 2.5rem);
}
.vfilm__fig { margin: 0; max-width: 560px; }
.vfilm__ph,
.vfilm__v {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-s);
  overflow: hidden;
}
.vfilm__v { object-fit: cover; background: var(--void-2); }
.vfilm__ph {
  background:
    radial-gradient(120% 90% at 20% 0%, rgba(232, 197, 71, 0.10), transparent 60%),
    var(--void-2);
  box-shadow: inset 0 0 0 1px var(--line);
}
.vfilm__sheen {
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg,
              transparent 38%,
              rgba(242, 240, 235, 0.055) 50%,
              transparent 62%);
  transform: translateX(-100%);
  animation: vfilmSheen 6.5s var(--ease) infinite;
}
@keyframes vfilmSheen {
  0%, 62% { transform: translateX(-100%); }
  100%    { transform: translateX(100%); }
}
/* Repere de lecture : l'encadre doit se lire comme un emplacement video,
   pas comme un bloc vide. Trace fin, aucun aplat. */
.vfilm__ph::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  width: clamp(38px, 5vw, 52px);
  height: clamp(38px, 5vw, 52px);
  transform: translate(-50%, -50%);
  border: 1px solid var(--line-strong);
  border-radius: 50%;
}
.vfilm__play {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-42%, -50%);
  width: 0; height: 0;
  border-left: clamp(9px, 1.2vw, 12px) solid var(--ash);
  border-top: clamp(6px, 0.8vw, 8px) solid transparent;
  border-bottom: clamp(6px, 0.8vw, 8px) solid transparent;
}
.vfilm__badge {
  position: absolute;
  left: clamp(0.9rem, 2vw, 1.4rem);
  bottom: clamp(0.9rem, 2vw, 1.4rem);
  color: var(--ash);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.vfilm__cap {
  margin-top: 0.85rem;
  color: var(--ash);
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
/* v85 — la legende porte desormais deux informations d'importance inegale :
   l'interprete et le titre (ce qu'on regarde), puis la nature du fichier (un
   extrait). Un seul niveau de gris les separe — pas de seconde taille, pas de
   seconde famille : la legende reste une ligne, pas un bloc. */
.vfilm__cap-x { color: var(--ash-dim); }
.vfilm__t {
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--fs-h3);
  line-height: 1.15;
  letter-spacing: -0.025em;
  color: var(--bone);
  max-width: 24ch;
}

/* ---------- 06 · monde d'artiste ---------- */
.vstmt {
  margin-top: clamp(2rem, 5vw, 3rem);
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--fs-h3);
  line-height: 1.2;
  letter-spacing: -0.025em;
  color: var(--bone);
  max-width: 34ch;
}
.vstmt__b { color: var(--signal); }

.vvs {
  margin-top: clamp(2.25rem, 5vw, 3.25rem);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
  max-width: 76ch;
}
.vvs__side { padding-top: 1.2rem; border-top: 1px solid var(--line-strong); }
.vvs__side--b { border-top-color: var(--signal); }
.vvs__k { color: var(--ash-dim); font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase; }
.vvs__t {
  margin-top: 0.8rem;
  font-size: var(--fs-body);
  line-height: 1.5;
  color: var(--ash);
  max-width: 30ch;
}
.vvs__side--b .vvs__t { color: var(--bone); }
.vvs__x { align-self: center; color: var(--ash-dim); font-size: 0.7rem; letter-spacing: 0.2em; text-transform: uppercase; }

/* ---------- 07 · du morceau a l'ecran ----------
   Lignes filees, plus de cartes. Le numero vit dans la marge. */
.vsteps { margin-top: clamp(2rem, 5vw, 3rem); max-width: 70ch; }
.vstep {
  display: grid;
  grid-template-columns: 3.5rem 1fr;
  gap: 0 1.5rem;
  padding: 1.35rem 0;
  border-top: 1px solid var(--line);
}
.vsteps .vstep:last-child { border-bottom: 1px solid var(--line); }
.vstep__n { color: var(--ash-dim); font-size: 0.7rem; letter-spacing: 0.14em; padding-top: 0.3em; }
.vstep__name {
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--fs-body);
  letter-spacing: -0.01em;
  color: var(--bone);
}
.vstep__do { grid-column: 2; margin-top: 0.35rem; font-size: 0.9375rem; line-height: 1.55; color: var(--ash); }
.vstep__why { grid-column: 2; margin-top: 0.4rem; font-size: 0.875rem; line-height: 1.5; color: var(--signal); opacity: 0.85; }

.vdet { margin-top: 1.75rem; border-top: 1px solid var(--line); max-width: 70ch; }
.vdet__sum {
  list-style: none;
  cursor: pointer;
  padding: 1.1rem 0;
  font-family: var(--caps);
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ash);
  display: flex;
  align-items: center;
  gap: 0.75rem;
  transition: color 0.25s var(--ease);
}
.vdet__sum::-webkit-details-marker { display: none; }
.vdet__sum::before {
  content: '+';
  display: inline-block;
  width: 1em;
  color: var(--signal);
  font-size: 1.1rem;
  line-height: 1;
}
.vdet[open] .vdet__sum::before { content: '\2212'; }
.vdet__sum:hover { color: var(--bone); }
.vdet__in { padding-bottom: 1.25rem; }
.vsteps--det { margin-top: 0; }

.vhyb { margin-top: clamp(3rem, 7vw, 5rem); }

.clip-pos {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  padding-left: clamp(1rem, 3vw, 2rem);
  border-left: 1px solid var(--signal);
  font-family: var(--display);
  font-weight: 500;
  font-size: var(--fs-lead);
  line-height: 1.45;
  color: var(--ash);
  max-width: 44ch;
}

/* ---------- 08 · ce que vous repartez avec ---------- */
.vget { margin-top: clamp(2rem, 5vw, 3rem); max-width: 70ch; }
.vget__i {
  display: grid;
  grid-template-columns: 11rem 1fr;
  gap: 1.5rem;
  align-items: baseline;
  padding: 1.15rem 0;
  border-top: 1px solid var(--line);
}
.vget__i:last-child { border-bottom: 1px solid var(--line); }
.vget__k { color: var(--signal); font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase; }
.vget__t { font-size: var(--fs-body); line-height: 1.45; color: var(--bone); }

.vlev { margin-top: clamp(3.5rem, 8vw, 6rem); }
.vlev__grid {
  margin-top: clamp(2rem, 5vw, 3rem);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.75rem, 4vw, 3.5rem);
}
.vlev__i { padding-top: 1.2rem; border-top: 1px solid var(--line-strong); }
.vlev__i:nth-child(2) { border-top-color: var(--signal); }
.vlev__n {
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h3);
  letter-spacing: -0.025em;
  color: var(--bone);
}
.vlev__who { margin-top: 0.7rem; font-size: 0.9375rem; line-height: 1.5; color: var(--ash); }
.vlev__get { margin-top: 1.1rem; display: grid; gap: 0.55rem; }
.vlev__get li {
  position: relative;
  padding-left: 1rem;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--bone);
}
.vlev__get li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.62em;
  width: 5px; height: 1px;
  background: var(--signal);
}
.vlev__rev { margin-top: 1rem; color: var(--ash-dim); font-size: 0.7rem; letter-spacing: 0.14em; text-transform: uppercase; }
.vlev__specs { margin-top: clamp(1.75rem, 4vw, 2.5rem); color: var(--ash); font-size: 0.7rem; letter-spacing: 0.14em; text-transform: uppercase; }
.vlev__seal { margin-top: 0.6rem; }
.vlev__live {
  margin-top: 1.5rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--line);
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ash);
  max-width: 56ch;
}
.vlev__live-k { color: var(--bone); font-weight: 600; }

/* ---------- 09 · sortie de chapitre ---------- */
.vend { text-align: left; }
/* v79 — descendu de 4.6rem a l'echelle h2 du site. */
.vend__t {
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h2);
  line-height: 1.02;
  letter-spacing: -0.04em;
  color: var(--bone);
  max-width: 16ch;
}
.vend__act { margin-top: 2rem; }

/* ---------- respirations ---------- */
@media (max-width: 1080px) {
  .vfilm { grid-template-columns: 1fr; gap: 2rem; }
  .vfilm__fig { max-width: 100%; }
  .vlev__grid { grid-template-columns: 1fr; gap: 2rem; }
}
@media (max-width: 860px) {
  .vvs { grid-template-columns: 1fr; gap: 1.5rem; }
  .vvs__x { justify-self: start; }
  .vdep__i { padding-left: 2rem; }
  .vdep__i::before { width: calc(clamp(1.5rem, 4vw, 3rem) + 1.4rem); }
  .varc__i + .varc__i::before { width: 1.25rem; margin: 0 0.75rem; }
}
@media (max-width: 640px) {
  .vbeat__i { grid-template-columns: 1fr; gap: 0.4rem; }
  .vget__i { grid-template-columns: 1fr; gap: 0.4rem; }
  .vstep { grid-template-columns: 2.5rem 1fr; gap: 0 1rem; }
  .vhero__t, .vw__t { max-width: 100%; }
  /* L'escalier se resserre mais garde ses filets : les masquer ne laissait
     un tiret qu'au premier rang, ce qui se lisait comme un bug. */
  .varc__i { gap: 0.75rem; padding-left: calc(var(--i, 0) * 0.5rem); }
  .varc__i::before { width: 1.25rem; }
}

@media (prefers-reduced-motion: reduce) {
  .vbeat__i, .vdep__i, .varc__i, .vget__i, .vlev__i, .vsteps .vstep {
    transition-delay: 0s !important;
  }
  .vdep__i::before { transform: scaleX(1); transition: none; }
  .vfilm__sheen { animation: none; }
}

/* =========================================================================
   =========================================================================
   V82 — BRIEF WORD DU 25/08 (six chantiers)

   Ce bloc est volontairement en fin de feuille : il surcharge des regles
   ecrites plus haut (v39, v40, v53, v81) sans les supprimer, ce qui rend
   chaque changement lisible et reversible d'un seul tenant.
   =========================================================================
   ========================================================================= */

/* -------------------------------------------------------------------------
   1 — INDUSTRY-STANDARD SOUND : une composition, deux recits
   Le brief interdit nommement : cards, grand rectangle bleu, bordures a
   repetition, surcharge d'elements d'interface, degrades, langage visuel
   "AI startup". Ce qui suit retire tout cela et laisse la typographie, la
   photographie et l'espace faire le travail.
   ------------------------------------------------------------------------- */
.vsblk--v82 {
  --vs-left:  #08090b;          /* charbon presque noir : l'impasse */
  --vs-right: #101216;          /* a peine plus clair : la sortie   */
  border: 0;                    /* c'etait le cadre qui en faisait une carte */
  background: linear-gradient(90deg,
    var(--vs-left) 0%, var(--vs-left) 50%,
    var(--vs-right) 50%, var(--vs-right) 100%);
  padding: clamp(2.5rem, 6.5vw, 5.5rem) clamp(1.75rem, 5vw, 4.5rem);
  margin-top: clamp(4rem, 9vw, 7rem);
}

/* le subgrid de la v39 alignait trois rangees fixes : la composition n'en a
   plus, il faut le neutraliser explicitement */
.vsblk--v82 .vsblk__cols {
  grid-template-columns: minmax(0, 0.78fr) minmax(0, 1.22fr);
  grid-template-rows: auto;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.vsblk--v82 .vsblk__c { display: block; grid-row: auto; grid-template-rows: none; }

/* la photographie ne vit plus qu'a droite : le brief demande un charbon nu
   a gauche, et une texture photographique discrete a droite seulement */
.vsblk--v82 .vsblk__bg { inset: 0 0 0 50%; grid-template-columns: 1fr; }
.vsblk--v82 .vsblk__half--us .vsblk__img { opacity: 0.15; filter: saturate(0.9); }
.vsblk--v82 .vsblk__half--us::after {
  left: 0; width: 22%;
  background: linear-gradient(270deg, transparent, var(--vs-right));
}
.vsblk--v82::before {
  background: linear-gradient(180deg,
    rgba(8, 9, 11, 0.62) 0%, rgba(8, 9, 11, 0.76) 55%, rgba(8, 9, 11, 0.90) 100%);
}

/* ---- gauche : l'alternative automatique, volontairement en retrait ---- */
.vsblk--v82 .vsblk__lbl {
  color: var(--ash-dim);
  font-size: 0.6875rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}
.vsblk--v82 .vsblk__c--them .vsblk__t {
  margin-top: 1.5rem;
  font-size: clamp(1.05rem, 1.75vw, 1.4rem);
  font-weight: 500;
  line-height: 1.32;
  letter-spacing: -0.012em;
  color: var(--ash);
  max-width: 22ch;
}
.vsblk--v82 .vsblk__names {
  margin-top: 1.9rem;
  color: var(--ash-dim);
  font-size: 0.625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  line-height: 1.7;
}
.vsblk--v82 .vsblk__c--them .vsblk__body { margin-top: 1.5rem; }
.vsblk--v82 .vsblk__c--them .vsblk__body p {
  margin: 0 0 0.75rem;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ash-dim);
  max-width: 30ch;
}
.vsblk--v82 .vsblk__dead {
  margin-top: 2.25rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.1rem, 1.8vw, 1.4rem);
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--ash);
}

/* ---- le filet : un seul trait vertical, pas un cadre ---- */
.vsblk--v82 .vsblk__c--us {
  border-left: 1px solid rgba(232, 197, 71, 0.42);
  background: none;                     /* le "large blue rectangle" part ici */
  padding-left: clamp(1.5rem, 3.2vw, 3rem);
}

/* ---- droite : sceau, titre, preuve, benefices, cloture ---- */
.vsblk--v82 .vsblk__mark--rr {
  min-height: 0;
  justify-content: flex-start;          /* le sceau s'aligne sur la colonne */
  margin-bottom: clamp(1.75rem, 3.5vw, 2.75rem);
}
.vsblk--v82 .vsblk__logo { width: 116px; height: 116px; }

.vsblk--v82 .vsblk__t--lead {
  font-family: var(--display);
  font-weight: 700;
  /* 2 lignes sur desktop, comme demande au brief : le <br> force la coupe,
     le corps est cale pour que la premiere ligne tienne dans la colonne. */
  font-size: clamp(1.7rem, 2.8vw, 2.35rem);
  line-height: 1.06;
  letter-spacing: -0.035em;
  color: var(--bone);
  max-width: none;
}

.vsblk--v82 .vsblk__proof {
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  display: grid;
  gap: 0.4rem;
}
.vsblk--v82 .vsblk__proof-k {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.1rem, 1.85vw, 1.45rem);
  letter-spacing: -0.02em;
  color: var(--bone);
}
.vsblk--v82 .vsblk__proof-s {
  font-size: var(--fs-body);
  line-height: 1.5;
  color: var(--ash);
}

/* trois lignes scannables, pas trois cartes : un filet fin, rien d'autre */
.vsblk--v82 .vsblk__ben {
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  list-style: none;
  padding: 0;
  border-top: 1px solid var(--line);
  max-width: 34ch;
}
.vsblk--v82 .vsblk__ben-i {
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-body);
  line-height: 1.35;
  color: var(--bone);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.6s var(--ease) calc(var(--i, 0) * 110ms + 260ms),
              transform 0.6s var(--ease) calc(var(--i, 0) * 110ms + 260ms);
}
.vsblk.is-in .vsblk__ben-i { opacity: 1; transform: none; }

.vsblk--v82 .vsblk__close {
  margin-top: clamp(2rem, 4vw, 3rem);
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.25rem, 2.1vw, 1.85rem);   /* jamais au-dessus du titre */
  line-height: 1.16;
  letter-spacing: -0.028em;
  color: var(--bone);
}
.vsblk--v82 .vsblk__close-b { color: var(--ash); }

@media (max-width: 860px) {
  .vsblk--v82 {
    background: linear-gradient(180deg,
      var(--vs-left) 0%, var(--vs-left) 46%, var(--vs-right) 46%, var(--vs-right) 100%);
  }
  /* pas de photo sous 860px : elle passerait sous le texte au lieu de rester
     derriere lui, ce que le brief interdit explicitement */
  .vsblk--v82 .vsblk__bg { display: none; }
  .vsblk--v82 .vsblk__cols { grid-template-columns: 1fr; gap: 2.5rem; }
  .vsblk--v82 .vsblk__c--us {
    border-left: 0;
    border-top: 1px solid rgba(232, 197, 71, 0.42);   /* le filet bascule */
    padding-left: 0;
    padding-top: 2.25rem;
  }
  .vsblk--v82 .vsblk__t--lead { font-size: clamp(1.75rem, 8vw, 2.4rem); max-width: none; }
  .vsblk--v82 .vsblk__logo { width: 92px; height: 92px; }
}

@media (prefers-reduced-motion: reduce) {
  .vsblk--v82 .vsblk__ben-i { opacity: 1; transform: none; transition: none; }
}

/* -------------------------------------------------------------------------
   2 — "What branding actually buys you" : les lignes se rapprochent
   ------------------------------------------------------------------------- */
.wbrand .vdep--brand .vdep__i { padding-top: 1.15rem; padding-bottom: 1.15rem; }
.wbrand .vdep--brand .vdep__i::before { top: 1.85rem; }
.wbrand .vdep__d { margin-top: 0.35rem; line-height: 1.45; }
.wbrand .vdep--brand { margin-top: clamp(1.75rem, 4vw, 2.75rem); }
.wbrand .vdep__list { margin-top: clamp(1.4rem, 3vw, 2rem); }

/* -------------------------------------------------------------------------
   3 — "The goal isn't more content." sur UNE ligne
   85 caracteres dans un conteneur de 1238px : la seule facon de tenir en
   une ligne est de descendre le corps. C'est un arbitrage assume, pas un
   oubli — le bloc perd un peu de poids typographique.
   ------------------------------------------------------------------------- */
.vdep__foot--one {
  max-width: none;
  font-size: clamp(1.05rem, 1.72vw, 1.75rem);
  line-height: 1.25;
  text-wrap: nowrap;
}
.vdep__foot-b { color: var(--signal); font-weight: 700; }
@media (max-width: 1100px) {
  .vdep__foot--one { text-wrap: balance; max-width: 34ch; }
}

/* -------------------------------------------------------------------------
   4 + 5 — UN SEUL FILM, ET LES SPECS EN DEUX LIGNES
   Les trois colonnes de paliers deviennent quatre cellules en largeur ;
   les quatre lignes de specs deviennent deux bandeaux horizontaux.
   ------------------------------------------------------------------------- */
.vlev--one { margin-top: clamp(3rem, 7vw, 5rem); }
.vlev__lead {
  margin-top: 1.1rem;
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--ash);
  max-width: 62ch;
}
.vlev__row {
  margin-top: clamp(1.75rem, 4vw, 2.75rem);
  list-style: none;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0 clamp(1.25rem, 3vw, 2.5rem);
}
.vlev__cell {
  padding-top: 1rem;
  border-top: 1px solid var(--line-strong);
  transition-delay: calc(var(--i, 0) * 90ms);
}
.vlev__cell:first-child { border-top-color: var(--signal); }
.vlev__k {
  display: block;
  color: var(--signal);
  font-size: 0.65rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.vlev__v {
  display: block;
  margin-top: 0.6rem;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--bone);
}

/* ligne 1 : toutes les specs, y compris le sceau, sur un seul rang */
.vlev__strip {
  margin-top: clamp(2rem, 4.5vw, 3rem);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem clamp(0.9rem, 2vw, 1.6rem);
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
}
.vlev__spec {
  position: relative;
  color: var(--ash);
  font-size: 0.6875rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}
.vlev__spec + .vlev__spec::before {
  content: '';
  position: absolute;
  left: calc(clamp(0.9rem, 2vw, 1.6rem) / -2);
  top: 0.42em;
  width: 3px; height: 3px;
  background: var(--line-strong);
}
.vlev__spec--seal { color: var(--signal); }

/* ligne 2 : le live action, en pleine largeur, sans retour a la ligne */
.vlev--one .vlev__live {
  margin-top: 0.9rem;
  padding-top: 0;
  border-top: 0;
  max-width: none;
}
@media (max-width: 1080px) {
  .vlev__row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem clamp(1.25rem, 3vw, 2.5rem); }
}
@media (max-width: 620px) {
  .vlev__row { grid-template-columns: 1fr; gap: 1.25rem; }
}

/* -------------------------------------------------------------------------
   6 — LE CHAPITRE 05 GAGNE EN LARGEUR, PERD EN HAUTEUR
   Resserrage mesure : rythme vertical entre blocs, interlignes des titres,
   et mesures de ligne elargies pour occuper la surface horizontale libre.
   ------------------------------------------------------------------------- */
.section--why { padding-block: clamp(3.5rem, 8vw, 6.5rem); }
.section--why .wblock { margin-top: clamp(2.75rem, 6.5vw, 5rem); }

.wpain { max-width: 76ch; }
.wpain__t { margin-top: 1.1rem; }
.wpain__lead { margin-top: 1.15rem; max-width: 68ch; line-height: 1.55; }

.wans { max-width: 66ch; }
.wans__lead { margin-top: 1rem; max-width: 62ch; line-height: 1.55; }

.wsec__t { max-width: 38ch; }
.wpil { gap: clamp(2rem, 4.5vw, 3.75rem); }
.wpil__i { padding: 1.05rem 0; }
.wpil__lead .wpil__t { margin-top: 0.8rem; max-width: 24ch; }
.wpil__lead .wpil__b { margin-top: 0.9rem; max-width: 46ch; }
.wpil__b { line-height: 1.5; }
.wcmp__lead { margin-top: 0.95rem; max-width: 66ch; line-height: 1.55; }
.wtrack { margin-top: clamp(1.75rem, 4.5vw, 3rem); }

/* -------------------------------------------------------------------------
   7 — LE RAIL FIXE DU CHAPITRE 05
   Copie deliberee de la grammaire de .chprog : meme coin, meme largeur,
   meme bascule a 1500px. Un visiteur qui a appris a lire le premier rail
   n'a rien a reapprendre.
   ------------------------------------------------------------------------- */
/* le rail des chapitres cede la place des que celui-ci s'allume */
.chprog.is-relayed { opacity: 0 !important; visibility: hidden !important; pointer-events: none !important; }

/* CORRECTIF v82.1 — le rail etait pose au mauvais endroit.
   La v82 avait copie les regles de BASE de .chprog (coin bas-gauche). Ces
   regles sont mortes : elles sont surchargees a tous les paliers. Le rail
   des chapitres a en realite DEUX formes, et aucune n'est un bloc flottant :

     >= 1500px : une gouttiere de gauche, centree verticalement, large de
                 --lrail-w, avec un filet a droite. La page reserve cette
                 gouttiere (.page--panel main > *).
     <= 1499px : une bande pleine largeur ancree au bas de la fenetre, haute
                 de --lrail-h, opaque, avec un filet en haut.

   .wrail reprend desormais les deux formes a l'identique, y compris les
   deux bornes de la bande (lisiere du panneau entre 1280 et 1499, barre de
   release sous 1280). Mesure de controle en fin de fichier v82.1. */
.wrail {
  position: fixed;
  z-index: 60;
  display: flex;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
  pointer-events: none;
}
.wrail.is-on { opacity: 1; visibility: visible; pointer-events: auto; }

.wrail__ttl { color: var(--bone); font-size: 0.625rem; letter-spacing: 0.09em; line-height: 1.25; }
.wrail__pos { color: var(--ash-dim); font-size: 0.625rem; letter-spacing: 0.12em; }

.wrail__idx { display: flex; gap: 0.3rem; list-style: none; margin: 0; padding: 0; }
.wrail__step { display: block; }

.wrail__dot {
  display: block;
  width: 1.2rem;
  height: 2px;
  background: var(--line-strong);
  cursor: pointer;
  transition: background 0.35s var(--ease);
}
.wrail__dot.is-on { background: var(--signal); }
.wrail__dot:hover { background: var(--bone); }
.wrail__dot:focus-visible { outline: 1px solid var(--signal); outline-offset: 3px; }
.wrail__n, .wrail__lbl {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---- forme gouttiere (1500px et plus) : exactement celle de .chprog ---- */
@media (min-width: 1500px) {
  .wrail {
    left: 0;
    bottom: auto;
    top: 50%;
    transform: translateY(-50%);
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
    width: var(--lrail-w);
    padding: 1rem 0.6rem 1rem 1rem;
    border-right: 1px solid var(--line);
    background: none;
    transition: opacity 0.5s var(--ease);
  }
  /* sans ceci le rail descendrait d'une demi-hauteur a l'instant ou il
     apparait : la regle de base annule transform sur .is-on */
  .wrail.is-on { transform: translateY(-50%); }
  .wrail__pos { display: none; }        /* l'index dit deja ou on en est */

  .wrail__idx {
    position: relative;
    flex-direction: column;
    gap: 0;
    width: 100%;
    padding-left: 0.75rem;
  }
  .wrail__idx::before,
  .wrail__idx::after {
    content: '';
    position: absolute;
    left: 0;
    top: 0.5rem;
    width: 1px;
  }
  .wrail__idx::before { bottom: 0.5rem; background: var(--line-strong); }
  .wrail__idx::after {
    height: calc(var(--wp, 0) * (100% - 1rem));
    background: var(--signal);
    transition: height 0.5s var(--ease);
  }

  .wrail__dot {
    position: relative;
    display: block;
    width: 100%;
    height: auto;
    background: none;
    padding: 0.42rem 0 0.42rem 0.55rem;
    transition: none;
  }
  .wrail__dot:hover, .wrail__dot.is-on { background: none; }
  .wrail__dot::before {
    content: '';
    position: absolute;
    left: -1px;
    top: 0.72rem;
    width: 3px; height: 3px;
    background: var(--line-strong);
    transition: background 0.3s var(--ease), height 0.3s var(--ease), top 0.3s var(--ease);
  }
  .wrail__dot.is-on::before {
    background: var(--signal);
    height: 1rem;
    top: 0.32rem;
    left: -1px;
    width: 2px;
  }
  .wrail__n, .wrail__lbl {
    position: static;
    width: auto; height: auto;
    overflow: visible;
    clip-path: none;
    white-space: normal;
    display: block;
  }
  .wrail__n {
    font-size: 0.5625rem;
    letter-spacing: 0.14em;
    color: var(--ash-dim);
    transition: color 0.3s var(--ease);
  }
  .wrail__lbl {
    font-size: 0.625rem;
    letter-spacing: 0.06em;
    line-height: 1.35;
    color: var(--ash-dim);
    transition: color 0.3s var(--ease);
  }
  .wrail__dot:hover .wrail__n,
  .wrail__dot:hover .wrail__lbl { color: var(--ash); }
  .wrail__dot.is-on .wrail__n { color: var(--signal); }
  .wrail__dot.is-on .wrail__lbl { color: var(--bone); font-weight: 500; }
}

/* ---- forme bande de pied (sous 1500px) : exactement celle de .chprog ---- */
@media (max-width: 1499px) {
  .wrail {
    left: 0; right: 0;
    bottom: 0;
    height: var(--lrail-h);
    flex-direction: row;
    align-items: center;
    gap: 0.9rem;
    padding-inline: var(--gutter);
    background: var(--void);
    border-top: 1px solid var(--line);
    transform: none;
  }
  .wrail.is-on { transform: none; }
  .wrail__pos { margin-left: auto; }
}
/* la bande s'arrete sur la lisiere du panneau de commande, sinon elle passe
   dessous : meme z-index, et le panneau vient apres dans le DOM

   v87 — conditionnee a .page--panel. Sur blueprint.html il n'y a pas de
   panneau : la regle amputait la bande de 14vw a droite et laissait un vide
   inexplicable au bord de l'ecran, entre 1280 et 1499px. */
@media (min-width: 1280px) and (max-width: 1499px) {
  .page--panel .wrail { right: var(--rpan-w); }
}
/* sous 1280px la barre de release reprend le bas de la fenetre */
@media (max-width: 1279px) {
  body.has-rbar .wrail { bottom: var(--rbar-h); }
}
@media (max-width: 720px) {
  .wrail { gap: 0.6rem; }
}

@media (prefers-reduced-motion: reduce) {
  .wrail, .wrail__idx::after, .wrail__dot::before, .wrail__n, .wrail__lbl { transition: none; }
}

/* -------------------------------------------------------------------------
   8 — "WHAT HAPPENS AFTER I PAY?" : aucune case
   La grille de six cellules a bordures est remplacee par une colonne
   editoriale posee sur un filet continu. Le brief demandait de rassurer ;
   une grille de cases ressemble a un tableau de bord, pas a quelqu'un qui
   s'occupe de vous.
   ------------------------------------------------------------------------- */
.aftx { margin-top: clamp(3rem, 6vw, 4.5rem); }
.aftx__eyebrow {
  color: var(--ash-dim);
  font-size: 0.6875rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.aftx__title {
  margin-top: 0.9rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h3);
  line-height: 1.12;
  letter-spacing: -0.03em;
  color: var(--bone);
  max-width: 24ch;
}
.aftx__list {
  position: relative;
  margin-top: clamp(2rem, 4vw, 2.75rem);
  padding: 0 0 0 clamp(1.75rem, 3.5vw, 2.75rem);
  list-style: none;
  display: grid;
  gap: clamp(1.05rem, 2.4vw, 1.55rem);
}
/* le filet continu : une seule ligne pour les six temps, pas six cadres */
.aftx__list::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.5rem;
  bottom: 0.5rem;
  width: 1px;
  background: linear-gradient(180deg, var(--signal), var(--line-strong) 22%, var(--line));
}
.aftx__i {
  position: relative;
  display: grid;
  grid-template-columns: 2.5rem minmax(0, 1fr);
  gap: 0 1.1rem;
  align-items: baseline;
  transition-delay: calc(var(--i, 0) * 70ms);
}
.aftx__i::before {
  content: '';
  position: absolute;
  left: calc(clamp(1.75rem, 3.5vw, 2.75rem) * -1 - 2px);
  top: 0.55em;
  width: 5px; height: 5px;
  background: var(--void);
  box-shadow: 0 0 0 1px var(--line-strong);
}
.aftx__i:first-child::before { background: var(--signal); box-shadow: none; }
.aftx__n {
  color: var(--signal);
  font-size: 0.6875rem;
  letter-spacing: 0.18em;
}
.aftx__i:not(:first-child) .aftx__n { color: var(--ash-dim); }
.aftx__body { display: block; }
.aftx__t {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--fs-body);
  letter-spacing: -0.012em;
  color: var(--bone);
}
.aftx__d {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--ash);
  max-width: 62ch;
}
.aftx__proof {
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  padding-left: clamp(1.75rem, 3.5vw, 2.75rem);
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ash-dim);
}
@media (max-width: 620px) {
  .aftx__i { grid-template-columns: 1fr; gap: 0.35rem; }
  .aftx__list { padding-left: 1.5rem; }
  .aftx__i::before { left: -1.5rem; }
  .aftx__proof { padding-left: 1.5rem; }
}

/* =========================================================================
   V83 — CHAPITRE 04 RESSERRE, VENTE A L'UNITE SUPPRIMEE (brief du 25/08)
   ========================================================================= */

/* ---- rythme du chapitre 04 : les respirations etaient calibrees pour neuf
   blocs, il en reste six. A 9rem entre chacun, le chapitre se lisait comme
   une succession d'ecrans vides. ---- */
#ch-04 .vblock { margin-top: clamp(2.75rem, 6vw, 5rem); }
/* La ligne 1 fait 37 caracteres ("You have an international blockbuster") :
   a l'echelle --fs-h2 dans 52ch elle cassait en trois. Mesure elargie et
   corps plafonne pour tenir en DEUX lignes, comme le reste du site. */
#ch-04 .vhero { margin-top: clamp(1rem, 3vw, 2rem); max-width: none; }
#ch-04 .vhero__t {
  margin-top: 1rem;
  font-size: clamp(1.85rem, 3.6vw, 3.1rem);
  max-width: 21ch;
}
#ch-04 .vhero__lead { margin-top: 1.1rem; }

/* ---- les trois temps passent en rang : trois lignes empilees pour trois
   propositions de dix mots etaient la definition du scroll inutile ---- */
.vbeat--row {
  margin-top: clamp(1.75rem, 4vw, 2.5rem);
  max-width: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0 clamp(1.25rem, 3vw, 2.5rem);
  border-bottom: 0;
}
.vbeat--row .vbeat__i {
  display: block;
  padding: 1rem 0 0;
  border-top: 1px solid var(--line);
  border-bottom: 0;
  transition-delay: calc(var(--i, 0) * 90ms);
}
.vbeat--row .vbeat__i:nth-child(2) { border-top-color: var(--signal); }
.vbeat--row .vbeat__k { display: block; }
.vbeat--row .vbeat__p { display: block; margin-top: 0.5rem; font-size: 0.9375rem; line-height: 1.45; }
@media (max-width: 720px) {
  .vbeat--row { grid-template-columns: 1fr; gap: 0; }
  .vbeat--row .vbeat__i:nth-child(n+2) { margin-top: 0.9rem; }
}

/* ---- le pied de la tige recupere les deux idees des blocs supprimes ---- */
.vdep__tail {
  margin-top: 1rem;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ash);
  max-width: 62ch;
}
.vdep__tail-b { color: var(--bone); font-weight: 600; }

/* ---- "From song to screen" : cinq etapes en rang au lieu de cinq lignes.
   Gain mesure : ~675px de haut deviennent ~200. Le detail complet reste
   dans le <details>, mot pour mot. ---- */
@media (min-width: 900px) {
  #ch-04 .vsteps:not(.vsteps--det) {
    max-width: none;
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0 clamp(1rem, 2.4vw, 2rem);
  }
  #ch-04 .vsteps:not(.vsteps--det) .vstep {
    display: block;
    padding: 1rem 0 0;
    border-top: 1px solid var(--line);
    border-bottom: 0;
  }
  #ch-04 .vsteps:not(.vsteps--det) .vstep:first-child { border-top-color: var(--signal); }
  #ch-04 .vsteps:not(.vsteps--det) .vstep__n { display: block; padding-top: 0; }
  #ch-04 .vsteps:not(.vsteps--det) .vstep__name { margin-top: 0.45rem; }
  #ch-04 .vsteps:not(.vsteps--det) .vstep__do { margin-top: 0.45rem; font-size: 0.875rem; line-height: 1.5; }
}
#ch-04 .vhyb { margin-top: clamp(2rem, 4.5vw, 3.25rem); }
#ch-04 .vdet { max-width: none; }

/* le conteneur du bloc 08 ne porte plus que la specification du film :
   sans son titre ni sa liste, il n'a plus besoin de sa propre respiration */
#ch-04 .vout { margin-top: 0; }
#ch-04 .vlev--one { margin-top: clamp(2.75rem, 6vw, 5rem); }

/* =========================================================================
   v84 — BRIEF WORD DU 25/08 (sept consignes, une capture chacune)

   Tout est en fin de fichier, apres les blocs v79 a v83 du meme chapitre :
   ces regles surchargent volontairement les leurs, et les lire dans l'ordre
   du fichier revient a lire l'historique des decisions.
   ========================================================================= */

/* -------------------------------------------------------------------------
   1 · CAPTURE 2 — LE DEPLOIEMENT PASSE EN RANG

   « Arrange la section, ca doit etre horizontal pas vertical, on perd trop
   d'espace, ca oblige a scroller en bas. Objectif reduire de 60%
   verticalite. » Le texte n'est pas touche : c'est une regle de mise en
   page, rien d'autre.

   La tige verticale part avec le mode rang. Elle etait le dispositif :
   cinq filets de longueurs inegales suspendus a un axe. En rang, ce role
   passe au filet superieur de chaque colonne, qui se dessine de la gauche
   vers la droite exactement comme les cinq etapes deux blocs plus bas
   (regle #ch-04 .vsteps de la v83). Meme grammaire, une seule a apprendre.

   MESURE : cinq items a 1,35rem de padding haut et bas plus deux lignes de
   texte occupaient ~560px, marges de liste comprises. Le rang tient dans
   ~150px. Reduction ~73%, au-dela des 60% demandes.

   Sous 900px la tige verticale d'origine reprend la main sans surcharge :
   cinq colonnes sur un telephone donneraient cinq colonnes de deux
   caracteres.
   ------------------------------------------------------------------------- */
@media (min-width: 900px) {
  #ch-04 .vdep--row { margin-top: clamp(1.75rem, 4vw, 2.75rem); padding-left: 0; }
  /* la tige : elle n'a plus d'objet une fois les filets mis en rang */
  #ch-04 .vdep--row::before { display: none; }
  /* le point bleu vivait dans le padding gauche, qui vient d'etre annule */
  #ch-04 .vdep--row .vdep__src { padding-left: 1.15rem; }
  #ch-04 .vdep--row .vdep__dot { left: 0; }

  #ch-04 .vdep--row .vdep__list {
    margin-top: clamp(1.5rem, 3vw, 2.25rem);
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0 clamp(1rem, 2.4vw, 2rem);
    /* stretch, pas start : "Chorus & performance moments" tient sur deux
       lignes quand les quatre autres en tiennent une. Sans etirement son
       eyebrow descendait d'une ligne et cassait le rang. */
    align-items: stretch;
  }
  /* --w pilotait la longueur du filet ET l'indentation du libelle. En rang
     la largeur vient de la grille : on annule le padding calcule, sinon
     chaque colonne se decale d'une valeur qui n'a plus de sens. */
  #ch-04 .vdep--row .vdep__i {
    padding: 1rem 0 0;
    display: flex;
    flex-direction: column;
  }
  /* l'eyebrow est pousse en pied de colonne : les cinq s'alignent sur la
     meme ligne de base quel que soit le nombre de lignes du libelle */
  #ch-04 .vdep--row .vdep__p { margin-top: auto; padding-top: 0.5rem; }
  #ch-04 .vdep--row .vdep__i::before {
    left: 0;
    top: 0;
    width: 100%;
    background: linear-gradient(90deg, var(--line-strong), var(--line));
  }
  #ch-04 .vdep--row .vdep__i:first-child::before { background: var(--signal); }
  #ch-04 .vdep--row .vdep__t {
    margin-top: 0.45rem;
    font-size: clamp(1rem, 1.35vw, 1.22rem);
    line-height: 1.2;
  }
  #ch-04 .vdep--row .vdep__p { font-size: 0.65rem; letter-spacing: 0.13em; }
  #ch-04 .vdep--row + .vdep__foot { margin-top: clamp(1.75rem, 3.5vw, 2.5rem); max-width: 34ch; }
}

/* -------------------------------------------------------------------------
   2 · CAPTURE 3 — LES DEUX COMPARATIFS REMONTENT ET PERDENT LEURS FILETS

   « Pas de trait noir et bleu horizontal » : ce sont les deux `border-top`
   de .vvs__side, l'un en --line-strong (le gris qui lit noir sur ce fond),
   l'autre en --signal. Ils partent tous les deux.

   « On met en avant les deux comparatifs » : sans filet il faut autre chose
   pour tenir les deux colonnes. Le libelle du cote droit passe en --signal,
   le texte monte d'un cran typographique, et l'axe VERSUS gagne de l'air.
   La hierarchie est portee par le texte, plus par un cadre.
   ------------------------------------------------------------------------- */
#ch-04 .vbrand .vvs { margin-top: clamp(1.75rem, 4vw, 2.75rem); }
#ch-04 .vbrand .vvs__side { padding-top: 0; border-top: 0; }
#ch-04 .vbrand .vvs__side--b { border-top: 0; }
#ch-04 .vbrand .vvs__side--b .vvs__k { color: var(--signal); }
#ch-04 .vbrand .vvs__t {
  margin-top: 0.75rem;
  font-size: clamp(1.05rem, 1.7vw, 1.35rem);
  line-height: 1.4;
}
#ch-04 .vbrand .vvs__side--b .vvs__t { font-weight: 600; }
#ch-04 .vbrand .vstmt { margin-top: clamp(2rem, 4.5vw, 3rem); }

/* -------------------------------------------------------------------------
   3 · CAPTURE 4 — PAS D'ESPACE NOIR VIDE APRES LA SUPPRESSION

   .vw__t--mid porte `margin-top: clamp(2.5rem, 6vw, 4rem)` pour se detacher
   du texte qui le precedait. Ce texte n'existe plus : le titre est
   desormais le PREMIER element du bloc, et cette marge s'ajoutait a celle
   de .vblock. C'est exactement le vide noir que le brief interdit.
   ------------------------------------------------------------------------- */
#ch-04 .vproc { margin-top: clamp(2.5rem, 5.5vw, 4rem); }
#ch-04 .vproc > .vw__t--mid:first-of-type { margin-top: 0; }

/* -------------------------------------------------------------------------
   4 · CAPTURES 5 ET 6 — LA CASCADE A 0,5 S

   « Chaque 0.5 sec se revele de la gauche a la droite les etapes, de
   maniere animee. Objectif faire comprendre au visiteur le deroule de
   maniere captivante. »

   Aucun JS nouveau. Les deux rangs portent deja `.reveal` et `--i` : quand
   le rang entre dans le champ, l'observateur de main.js pose `.is-in` sur
   les cinq (resp. quatre) elements dans la meme frame, et c'est le
   `transition-delay` indexe sur --i qui produit le deroule. Le delai
   generique du chapitre (80 ms / 90 ms) est surcharge a 500 ms ici, et
   seulement ici.

   Le filet superieur ne peut pas s'animer en `border-top` : une bordure ne
   se met pas a l'echelle. Il devient un ::after en `scaleX(0)` d'origine
   gauche, ce qui donne litteralement le balayage gauche -> droite demande.

   DUREE TOTALE : 4 x 500 ms = 2 s avant la cinquieme etape. C'est long pour
   un visiteur qui scrolle vite ; c'est la valeur du brief, elle se change
   ici et nulle part ailleurs (--seq-step).

   reduced-motion : plus bas dans ce bloc, tout est pose a l'etat final,
   sans delai ni transition. Une cascade de 2 s est exactement ce que ce
   reglage demande d'eviter.
   ------------------------------------------------------------------------- */
#ch-04 .vsteps:not(.vsteps--det),
#ch-04 .vlev__row { --seq-step: 500ms; }

@media (min-width: 900px) {
  #ch-04 .vsteps:not(.vsteps--det) .vstep {
    position: relative;
    border-top: 0;
    transition-delay: calc(var(--i, 0) * var(--seq-step));
  }
  #ch-04 .vsteps:not(.vsteps--det) .vstep::after {
    content: '';
    position: absolute;
    left: 0; right: 0; top: 0;
    height: 1px;
    background: var(--line);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 0.5s var(--ease) calc(var(--i, 0) * var(--seq-step));
  }
  #ch-04 .vsteps:not(.vsteps--det) .vstep.is-in::after { transform: scaleX(1); }
  #ch-04 .vsteps:not(.vsteps--det) .vstep:first-child::after { background: var(--signal); }
}

@media (min-width: 620px) {
  #ch-04 .vlev__row .vlev__cell {
    position: relative;
    border-top: 0;
    transition-delay: calc(var(--i, 0) * var(--seq-step));
  }
  #ch-04 .vlev__row .vlev__cell::after {
    content: '';
    position: absolute;
    left: 0; right: 0; top: 0;
    height: 1px;
    background: var(--line-strong);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 0.5s var(--ease) calc(var(--i, 0) * var(--seq-step));
  }
  #ch-04 .vlev__row .vlev__cell.is-in::after { transform: scaleX(1); }
  #ch-04 .vlev__row .vlev__cell:first-child::after { background: var(--signal); }
}

@media (prefers-reduced-motion: reduce) {
  #ch-04 .vsteps:not(.vsteps--det) .vstep,
  #ch-04 .vlev__row .vlev__cell { transition-delay: 0s; }
  #ch-04 .vsteps:not(.vsteps--det) .vstep::after,
  #ch-04 .vlev__row .vlev__cell::after { transform: scaleX(1); transition: none; }
}

/* -------------------------------------------------------------------------
   5 · LE SECOND FILM — LA VIDEO REMPLACE LE PLACEHOLDER

   .vfilm__ph et .vfilm__v partageaient deja l'aspect-ratio et le rayon :
   la substitution ne deplace rien. Ce qui s'ajoute est le conteneur qui
   permet au bouton Sound de se positionner (.rail__sound est en absolu, il
   lui faut un parent positionne, et <figure> porte aussi la legende).
   ------------------------------------------------------------------------- */
.vfilm__box {
  position: relative;
  border-radius: var(--radius-s);
  overflow: hidden;
}
.vfilm__box .vfilm__v { border-radius: 0; }
.vfilm__sound { right: 0.75rem; bottom: 0.75rem; }
/* lecture refusee par le navigateur : les controles natifs occupent le bas
   du cadre, le bouton s'efface plutot que de se superposer a eux */
.vfilm__fig.is-fallback .vfilm__sound { display: none; }

/* -------------------------------------------------------------------------
   6 · CAPTURE 7 — LA PHOTO DANS LE VIDE DE DROITE

   « La photo doit etre parfaitement integre a cote dans cet espace vide.
   Interdiction absolu de rallonger verticalement la section. »

   La garantie est structurelle : les deux colonnes de .wbrand__cols sont
   etirees a la meme hauteur (comportement par defaut de `align-items:
   stretch`), la figure ne porte aucune hauteur propre, et l'image est
   detachee du flux en `position:absolute; inset:0`. La colonne photo ne
   peut donc pas depasser la colonne de gauche, quel que soit le nombre de
   piliers. Aucune valeur en pixels a maintenir.

   `min-height: 0` sur la figure : sans lui, un enfant de grille prend pour
   plancher la hauteur de son contenu, et l'image de 1500px de haut
   rallongerait la ligne — precisement l'interdit du brief.
   ------------------------------------------------------------------------- */
.wbrand__fig { display: none; }

@media (min-width: 1024px) {
  .wbrand__cols {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.42fr);
    gap: clamp(2rem, 4.5vw, 4rem);
    align-items: stretch;
    /* la respiration que portait .vdep--brand remonte sur la grille : les
       deux colonnes doivent partir de la meme ligne, sinon la photo demarre
       plus haut que la tige et pointe dans le vide au-dessus. */
    margin-top: clamp(2.5rem, 6vw, 4rem);
  }
  .wbrand__cols > .vdep--brand { margin-top: 0; }
  .wbrand__fig {
    display: block;
    position: relative;
    min-height: 0;
    margin: 0;
    border-radius: var(--radius-m);
    overflow: hidden;
  }
  .wbrand__fig picture,
  .wbrand__fig img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
  }
  /* la fente est bien plus etroite que le 2:3 du fichier : on cadre haut,
     sur le moniteur et le plan de travail, pas sur le milieu du bureau */
  .wbrand__fig img { object-fit: cover; object-position: 50% 24%; }
  /* le fond de page est presque noir : sans ce voile le bord de la photo
     tranche comme une vignette collee. Il la fait appartenir a la page. */
  .wbrand__fig::after {
    content: '';
    position: absolute;
    inset: 0;
    background:
      linear-gradient(90deg, var(--void) 0%, rgba(10, 11, 13, 0) 26%),
      linear-gradient(180deg, rgba(10, 11, 13, 0.34) 0%, rgba(10, 11, 13, 0) 26%, rgba(10, 11, 13, 0.55) 78%, var(--void) 100%);
    pointer-events: none;
  }
}

/* =========================================================================
   v86 — DUREE DE CAMPAGNE, CALENDRIERS, GARDE-FOU DE VOCABULAIRE

   Le brief du 25/08 change la nature des trois offres : elles ne se
   distinguent plus par un empilement de livrables mais par la DUREE DE
   PUBLICATION qu'elles couvrent. Trois ajouts, tous prefixes, aucune regle
   anterieure modifiee.

   /!\ Le risque n° 1 de cette version est une confusion de lecture : « 3
   Days » lu comme un delai de livraison. Le site publie par ailleurs un
   engagement a 48 heures sur le socle. C'est pour cela que la ligne
   `--camp` / `--pcamp` est collee au nom, dans la meme foulee visuelle :
   le nom seul ne doit jamais circuler sans son unite.
   ========================================================================= */

/* ---- la ligne de duree, sous le nom de l'offre ---- */
.pack__campaign,
.rrp__camp,
.rpan__pcamp {
  display: block;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--signal);
  margin-top: 0.2rem;
}
.rrp__camp { margin: 0.35rem 0 0.6rem; font-size: 0.6875rem; }
.rpan__pcamp { font-size: 0.5625rem; letter-spacing: 0.1em; color: var(--ash); margin-top: 0.15rem; }

/* ---- le garde-fou, sous les trois packs du panneau ----
   Volontairement en gris faible et non en accent : ce n'est pas un argument
   de vente, c'est une precision qui evite un litige. La mettre en avant
   ferait douter ; la cacher ferait mentir. */
.rpan__note {
  margin: 0.6rem 0 0;
  font-size: 0.5625rem;
  line-height: 1.45;
  color: var(--ash-dim);
}

/* ---- les calendriers, dans les cartes de la home ----
   Le brief (§22) demande un PLAN, pas une quantite. Le calendrier est donc
   pose AVANT la liste des livrables : on lit d'abord ce qui va se passer,
   ensuite ce qu'on recoit. L'ordre inverse redonnerait un catalogue. */
.rrp__cal {
  margin: 0 0 1.35rem;
  padding: 0.9rem 0 0;
  border-top: 1px solid var(--rrp-line);
}
.rrp__cal-h {
  margin: 0 0 0.65rem;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--rrp-faint);
}
.rrp__cal-l { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; }
.rrp__cal-i {
  display: grid;
  grid-template-columns: 5.25rem minmax(0, 1fr);
  gap: 0.15rem 0.6rem;
  align-items: baseline;
}
.rrp__cal-d {
  font-family: var(--mono);
  font-size: 0.5625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--rrp-faint);
  white-space: nowrap;
}
.rrp__cal-t { font-size: 0.8125rem; font-weight: 600; color: var(--rrp-ink); }
/* La glose passe sous les deux colonnes : sur 30 jours en quatre phases,
   elle est longue, et la contraindre a la colonne de droite fabriquerait
   une colonne de six lignes a cote d'un titre d'une seule. */
.rrp__cal-w {
  grid-column: 2;
  font-size: 0.75rem;
  line-height: 1.45;
  color: var(--rrp-dim);
}

@media (max-width: 560px) {
  .rrp__cal-i { grid-template-columns: 1fr; }
  .rrp__cal-w { grid-column: 1; }
}

/* =========================================================================
   v89 — BRIEF WORD DU 26/08
   Ce bloc est en fin de feuille : chaque regle ci-dessous doit l'emporter
   sur une regle de meme specificite ecrite plus haut (les sections v70 a
   v79 redefinissent plusieurs fois les memes selecteurs). Rien n'est
   supprime en amont — les valeurs d'origine restent lisibles la ou elles
   ont ete decidees, avec leur justification d'epoque.
   ========================================================================= */

/* -------------------------------------------------------------------------
   §1 — BANDEAU DE TEMOIGNAGES : REMONTE, ET UN CRAN PLUS GRAND

   « Remonte tres legerement, environ 7 a 8mm au-dessus. »
   7,5 mm = 28 px a 96 ppp (1 mm = 3,7795 px). La remontee est un
   margin-top negatif et NON une reduction du padding : le padding tient la
   respiration interne du bandeau, le reduire aurait colle les vignettes a
   leur filet. La marge negative deplace le bloc entier, filet compris.

   Sur mobile la valeur est ramenee a 16 px : 28 px representent la moitie
   d'un interstice a cette largeur, et le bandeau serait venu mordre la
   declaration de marque juste au-dessus.

   Corps +1 cran des deux textes : le nom passe de 0,625 a 0,75rem, la
   citation de 0,875 a 1rem. Le nom garde son `white-space: nowrap` — les
   pseudonymes ne se coupent pas — mais gagne donc en largeur : la vignette
   la plus longue (« Nathan CiusAKAMakai Capernium ») s'elargit d'environ
   14 px, ce qui reste dans la largeur fixe de .tst__i.
   ------------------------------------------------------------------------- */
.tst { margin-top: -28px; }
@media (max-width: 700px) {
  .tst { margin-top: -16px; }
}
.tst__name  { font-size: 0.75rem; }
.tst__quote { font-size: 1rem; }

/* -------------------------------------------------------------------------
   §2 — COMPARATIF : LA LIGNE DE REVENDICATION

   « Meme taille, texte centre. » Le corps n'est donc pas touche : la regle
   v79 (clamp 1.5 -> 2.5rem) reste en vigueur. Deux choses seulement :

   - le centrage. .cmp__head est deja `text-align: center`, mais .cmp__sub
     portait `max-width: 26ch` SANS marge automatique : le bloc restait cale
     a gauche et seul son texte etait centre, a l'interieur d'une boite
     decalee. Le defaut ne se voyait pas sur l'ancienne phrase, qui
     remplissait ses 26ch ; il se serait vu immediatement sur celle-ci.

   - la mesure. 26ch coupait « 3, 10 or 30 days of ready-to-post content. »
     en deux lignes des le milieu. 34ch la laisse tenir sur une ligne
     au-dessus de 900px, et casser proprement en dessous.
   ------------------------------------------------------------------------- */
.cmp__sub--claim {
  max-width: 34ch;
  margin-inline: auto;
  text-align: center;
}

/* -------------------------------------------------------------------------
   §3 — COMPARATIF : CINQ LIGNES, DEUX CRANS PLUS PETIT

   Le corps passe de clamp(1rem, 1.85vw, 1.75rem) a
   clamp(0.875rem, 1.45vw, 1.375rem) : deux crans, des deux cotes, comme
   demande. Les pastilles et les croix suivent, sinon un glyphe de 46 px se
   retrouve en face d'un texte de 22 px et le rapport se casse.

   /!\ LE PIEGE ETAIT ICI : la regle v79 pose `white-space: nowrap` sur
   `.cmp__li > span` au-dessus de 900px, pour empecher « Sound that still
   feels like a demo » de casser en deux. Appliquee telle quelle a la
   cinquieme ligne — 59 caracteres, contre 32 pour la plus longue des
   quatre autres — elle aurait produit un DEBORDEMENT HORIZONTAL de la
   page entiere, pas un simple depassement de colonne.

   La cinquieme ligne est donc explicitement autorisee a casser.

   v90 — LE CIBLAGE A CHANGE. Ces regles visaient `[style*="--s:4"]`, donc
   la POSITION dans la liste. La permutation demandee le 26/08 a deplace la
   ligne longue en --s:3 et le prix en --s:4 : le ciblage par position
   aurait silencieusement autorise le PRIX a casser sur deux lignes et
   remis le `nowrap` sur la ligne longue — c'est-a-dire exactement le
   debordement horizontal decrit ci-dessus, reintroduit par un simple
   changement d'ordre. La ligne longue porte desormais une classe,
   `.cmp__li--long`, qui la suit ou qu'elle aille.
   ------------------------------------------------------------------------- */
.cmp__li {
  font-size: clamp(0.875rem, 1.45vw, 1.375rem);
  grid-template-columns: clamp(30px, 2.4vw, 38px) minmax(0, 1fr);
}
.cmp__x    { width: clamp(22px, 1.8vw, 28px); height: clamp(22px, 1.8vw, 28px); }
.cmp__mark { width: clamp(28px, 2.3vw, 38px); }

@media (min-width: 900px) {
  .cmp__li--long > span { white-space: normal; }
}
/* La ligne longue tient sur deux lignes de texte la ou les autres en
   occupent une : `align-items: center` (regle v72) la centrerait sur sa
   pastille et desalignerait la base des cinq entrees. */
.cmp__li--long { align-items: start; }
.cmp__li--long .cmp__x,
.cmp__li--long .cmp__mark { margin-top: 0.15em; }

/* -------------------------------------------------------------------------
   §4 — LA LIGNE NEUVE SOUS LE TITRE DES CARTES

   Elle dit le contenu du pack, la ligne au-dessus dit ce qu'on emporte.
   Plus petite et plus grise : c'est une precision, pas une seconde
   accroche. Le .rrp__lead portait toute la marge basse du bloc ; elle
   descend ici, sinon les deux lignes se retrouvaient separees par un
   interstice de 2,5rem au milieu d'une meme idee.
   ------------------------------------------------------------------------- */
.rrp__lead { margin-bottom: 0.35rem; }
.rrp__sublead {
  margin: 0 auto clamp(1.75rem, 3vw, 2.5rem);
  text-align: center;
  color: var(--rrp-dim);
  font-size: 0.8125rem;
  opacity: 0.8;
  max-width: 46ch;
}

/* =========================================================================
   v90 — BRIEF WORD DU 26/08, DEUXIEME ENVOI (avec les captures)
   ========================================================================= */

/* -------------------------------------------------------------------------
   §5 (v90/v91) — SUPPRIME EN v92

   Ce bloc portait le montage « declaration a gauche, rail a droite » et la
   premiere palette de la revendication. Il a ete retire en entier, et non
   simplement neutralise : ecrit APRES le bloc v92, il l'emportait dans la
   cascade et reimposait l'ancienne palette (#FF5A5A, #FF9E2C…) ainsi que
   l'ancien corps. Constate au rendu — les couleurs mesurees etaient celles
   d'avant alors que la nouvelle regle etait bien presente plus haut.

   Le montage centre et la palette du brief sont en §5 / §5b, au-dessus.
   ------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------
   §6 — « ready-to-post content » en JAUNE STUDIO 54 et en gras

   La valeur est #E8C547 — celle du document du 26/08, « Color lock
   (mandatory) » — ecrite ici EN DUR et non via var(--signal).
   var(--signal) porte exactement cette valeur (voir le bloc de tokens en
   tete de feuille), donc le rendu est identique —
   mais la valeur litterale rend la regle verifiable a l'oeil nu dans le
   fichier, sans avoir a remonter la chaine des variables. C'est une
   demande qui est revenue trois fois : elle merite de ne plus dependre
   d'une indirection.

   Le selecteur est double (.cmp__sub .cmp__hi) plutot que simple. Ce n'est
   pas de la superstition : .cmp__sub est redefini a QUATRE endroits de
   cette feuille (lignes 1244, 7443, 7707, 11491), dont deux posent
   `color: var(--ash)`. Un simple .cmp__hi passait, mais une cinquieme
   redefinition de .cmp__sub ecrite plus bas un jour, ou un
   `.cmp__sub *`, l'aurait emporte en silence. La specificite superieure
   met la regle a l'abri.

   <b> et non <strong> : la mise en avant est visuelle, elle ne change pas
   le sens de la phrase. <strong> ferait insister les lecteurs d'ecran sur
   trois mots au milieu d'une phrase qui n'en a pas besoin. Le point final
   reste hors du <b> : il appartient a la phrase.
   ------------------------------------------------------------------------- */
.cmp__sub .cmp__hi,
.cmp__hi {
  color: #E8C547;
  font-weight: 800;
}

/* -------------------------------------------------------------------------
   §7 — LE VIDE NOIR AU-DESSUS DES CARTES

   « On resserre pour ne pas avoir d'espace vide noir inutile. »
   La marge basse du bloc d'introduction passe de clamp(1.75, 3vw, 2.5rem)
   a clamp(0.9, 1.6vw, 1.3rem) : environ la moitie. Le haut de la premiere
   carte remonte d'autant.

   La marge HAUTE de .rrp__lead (1.25rem) est conservee : elle separe
   l'introduction du selecteur 1 Song / 3 Songs, qui est un controle. La
   reduire aurait colle du texte a des boutons.
   ------------------------------------------------------------------------- */
.rrp__sublead { margin-bottom: clamp(0.9rem, 1.6vw, 1.3rem); }

/* -------------------------------------------------------------------------
   §8 — v91 : LE DEBORDEMENT HORIZONTAL — TENTATIVE ECHOUEE, NON LIVREE

   Le defaut de MISSING-CONTENT §0.10 a enfin pu etre MESURE, un moteur de
   rendu etant disponible pour la premiere fois :

     viewport 1280 -> scrollWidth 1299  (19px de trop)
     viewport 1024 -> scrollWidth 1040  (16px)
     viewport  768 -> scrollWidth  780  (12px)
     viewport 1440 et 1897 -> aucun debordement

   Deux elements sortent du cadre, tous deux anterieurs a cette version :
   .hero__video-bg (1382px de large dans une fenetre de 1280, a cause du
   transform: scale(var(--hero-crop))) et .bnd__track (4991px, ce qui est
   le principe meme d'une piste de defilement continu).

   `overflow-x: clip` pose sur .hero, .bnd et .bnd__rail a ete essaye puis
   RETIRE : mesure apres correction, le debordement etait toujours de 19px
   a 1280. La coupe n'a donc pas lieu au niveau teste, et la cause reelle
   est ailleurs — probablement un ancetre commun qui retablit un contexte
   de defilement.

   La regle n'est pas livree. Une declaration qui ne corrige rien mais qui
   PARAIT corriger quelque chose est pire que son absence : elle ferme le
   dossier sans le resoudre. §0.10 reste ouverte, avec desormais des
   mesures chiffrees pour la prochaine tentative.
   ------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------
   §9 — v92 : LES CINQ TEXTES DE LA SECTION PRIX

   Brief du 26/08. Consigne stricte : ne toucher QUE ces cinq textes. Pas
   d'icone, pas de bouton, pas de bloc neuf, pas de changement de taille de
   carte, pas de reecriture du corps sous les prix. Ce bloc ne contient donc
   que des regles de corps, de graisse et de couleur.

   LE JAUNE. #E8C547, la valeur EXACTE du document du 26/08, repetee neuf
   fois et assortie de « Color lock (mandatory) ».

   /!\ La v92 avait pose #F5C400 a la place, au motif que #E8C547 etait
   echantillonne sur une capture compressee et que le token du site devait
   faire foi. Cet arbitrage n'avait pas ete valide par le client, qui a
   tranche le 26/08 : c'est le document qui fait foi. Le token du site a
   donc ete aligne sur #E8C547, et non l'inverse — pour que ces cinq textes
   soient du meme or que le badge et les boutons, comme le brief le demande
   explicitement (« the same yellow already used on the badge »).

   La valeur est ecrite en dur et non via var(--signal), pour la meme
   raison qu'en §6 : une regle de couleur demandee plusieurs fois doit etre
   verifiable a l'oeil nu dans le fichier.

   /!\ .rrp__camp et .rrp__cal-h sont DUPLIQUES dans cette feuille (lignes
   11368/14779 et 11401/14812). Ce bloc est en fin de fichier : il l'emporte
   sur les deux copies. Ne pas modifier les copies amont en croyant agir —
   c'est ici que la valeur finale est decidee.
   ------------------------------------------------------------------------- */

/* TEXTE 1 — le titre au-dessus des trois cartes. Il portait le corps du
   texte courant (0,9375rem) et le gris de fond. Il devient la promesse
   principale de la section : il monte d'un rang typographique et passe en
   or. La ligne grise qui le suivait a ete fusionnee dedans, il n'y a plus
   de deuxieme ligne a menager sous lui. */
.rrp__lead {
  color: #E8C547;
  font-weight: 700;
  font-size: clamp(1.05rem, 1.9vw, 1.5rem);
  line-height: 1.25;
  max-width: 30ch;
  margin: 1.25rem auto clamp(1.75rem, 3vw, 2.5rem);
}

/* TEXTES 2, 3, 4 — la ligne sous le nom de chaque pack.
   0,6875rem -> 0,875rem. Le `letter-spacing` de 0,14em est conserve : c'est
   lui qui donne son rang de capitale espacee a la ligne, et le retirer
   l'aurait fait ressembler a du texte courant en majuscules. */
.rrp__camp {
  color: #E8C547;
  font-weight: 800;
  font-size: 0.875rem;
}

/* TEXTE 5 — les trois titres de section dans les cartes, traites comme un
   systeme unique : meme corps, meme graisse, meme or, aux trois endroits.
   0,625rem -> 0,8125rem. Ils passent de gris tres faible a l'or : ils
   annoncent desormais le contenu livre et non une etape de production. */
.rrp__cal-h {
  color: #E8C547;
  font-weight: 800;
  font-size: 0.8125rem;
}

/* -------------------------------------------------------------------------
   §10 — v92 : LA GARANTIE, A LA PLACE DE « WHY THE PRICE IS DIFFERENT »

   Disposition de l'exemple Softriver, habillage Ready Release. Aucune
   couleur neuve : l'or est #E8C547, le blanc var(--bone), le gris
   var(--rrp-dim) — les memes que le reste de la section prix.

   Les regles .rrp__why-* restent dans la feuille, plus haut : elles ne sont
   plus referencees par aucune page, mais les retirer est un nettoyage a
   faire en une passe dediee, pas au detour de celle-ci.
   ------------------------------------------------------------------------- */
.rrp__gtee {
  margin-top: clamp(3rem, 6vw, 5rem);
  text-align: center;
}

/* Le bouton est une PILULE PLEINE LARGEUR, comme dans l'exemple : c'est ce
   qui lui donne son poids sans le remplir de couleur. `display: block` et
   non inline-flex, sinon il se contracte a la largeur de son texte et le
   rang visuel s'effondre.

   Contour or fin, fond transparent : le blanc plein et l'or plein restent
   reserves au parcours de commande (regle de la v66). Ce bouton mene a un
   appel, pas a un paiement — il ne doit pas se disputer l'attention avec
   les trois cartes situees juste au-dessus. */
.rrp__gtee-btn {
  display: block;
  width: 100%;
  padding: clamp(0.9rem, 1.8vw, 1.15rem) 1.5rem;
  border: 1px solid rgba(232, 197, 71, 0.55);
  border-radius: 999px;
  background: transparent;
  color: #E8C547;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(0.95rem, 1.5vw, 1.0625rem);
  text-decoration: none;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.rrp__gtee-btn:hover {
  border-color: #E8C547;
  background: rgba(232, 197, 71, 0.07);
}
/* La fleche avance de 3px au survol : le meme geste que les autres liens
   flechees du site, pas une animation propre a ce bouton. */
.rrp__gtee-arw {
  display: inline-block;
  transition: transform 0.3s var(--ease);
}
.rrp__gtee-btn:hover .rrp__gtee-arw { transform: translateX(3px); }

.rrp__gtee-t {
  margin: clamp(2.25rem, 4.5vw, 3.5rem) auto 0;
  max-width: 24ch;
  color: var(--bone);
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(1.35rem, 3vw, 2.25rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
/* 58ch : la mesure de l'exemple, qui casse le paragraphe en deux lignes
   sur grand ecran. Au-dela, la ligne devient trop longue pour un texte
   centre — c'est la limite de lisibilite du centrage, pas une preference. */
.rrp__gtee-p {
  margin: clamp(0.9rem, 1.8vw, 1.25rem) auto 0;
  max-width: 58ch;
  color: var(--rrp-dim);
  font-size: 0.9375rem;
  line-height: 1.6;
  text-wrap: balance;
}
.rrp__gtee-l {
  margin: clamp(1rem, 2vw, 1.5rem) 0 0;
  color: var(--rrp-faint, var(--ash-dim));
  font-size: 0.8125rem;
}
/* Souligne EXPLICITEMENT et non par defaut : sur fond noir, un lien or de
   0,8125rem au milieu d'une ligne grise ne se distingue pas assez par la
   seule couleur. `underline-offset` evite que le trait vienne couper les
   jambages du y de « Policy ». */
.rrp__gtee-lk {
  color: #E8C547;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.rrp__gtee-lk:hover { text-decoration-thickness: 2px; }

@media (prefers-reduced-motion: reduce) {
  .rrp__gtee-btn, .rrp__gtee-arw { transition: none; }
  .rrp__gtee-btn:hover .rrp__gtee-arw { transform: none; }
}

/* =========================================================================
   §11 — v93 : LE BAS DES TROIS CARTES ET LES TITRES DE CAMPAGNE
   Briefs 5 et 6 du document Word du 26/08.

   Ce bloc est en FIN DE FEUILLE, comme les §6 a §10. La raison est la meme
   qu'en §9 : .rrp__grid, .rrp__card--star, .rrp__cta, .rrp__reco et
   .rrp__cal-h sont tous DUPLIQUES plus haut dans ce fichier (autour des
   lignes 9172 / 9195 / 9319 / 9373 / 11401 et de leurs copies 12583 /
   12606 / 12744 / 14812). Ne pas modifier les copies amont en croyant
   agir : c'est ici que la valeur finale est decidee.
   ========================================================================= */

/* -------------------------------------------------------------------------
   11.1 — HAUTEUR COMMUNE, ET UN SEUL CARTE QUI GRANDIT A L'OUVERTURE

   Le brief demande deux choses qui se contredisent dans une grille CSS :
   les trois cartes doivent finir sur la meme ligne en etat FERME, mais
   quand l'accordeon s'ouvre, SEULE la carte du milieu doit s'allonger.

   `align-items: stretch` donne la premiere et interdit la seconde : dans
   une meme rangee de grille, si une carte grandit, les deux autres
   s'etirent avec elle. On garde donc `align-items: start` et la hauteur
   commune est posee en `min-height` par le script, mesuree sur l'etat
   ferme. Ouvrir l'accordeon fait alors depasser la seule carte du milieu.

   Sous 1080 px les cartes s'empilent : la question ne se pose plus, le
   script retire le min-height (voir home-pricing.js).

   La surelevation de 10 px de la carte « Most chosen » est SUPPRIMEE.
   C'etait le dernier ecart : a hauteur egale, un translateY laissait les
   trois bords bas decales de 10 px. Arbitrage du 26/08 : alignement exact
   des bas, conformement au document. Le halo dore et la bordure or, eux,
   sont conserves — c'est eux qui portent la hierarchie « Most chosen ».
   ------------------------------------------------------------------------- */
.rrp__grid { align-items: start; }
.rrp__card--star { transform: none; }

.rrp__card { display: flex; flex-direction: column; }
.rrp__body { flex: 1 1 auto; }

/* Le pied se colle en bas de la carte. Comme les cartes ont la meme
   hauteur et que les quatre rangs du pied ont la meme hauteur d'une carte
   a l'autre (cales invisibles comprises), les rangs tombent a la meme
   ordonnee sans une seule marge arbitraire.

   /!\ LA CLASSE EST .rrp__tail, PAS .rrp__foot.
   .rrp__foot existe deja dans cette feuille (lignes 9482 et 12893) : c'est
   la ligne « Prices follow the currency selector » posee SOUS la grille.
   Elle porte text-align:center, la police mono, un interlettrage de 0,1em
   et une marge haute. Reutiliser ce nom pour le bas des cartes centrait le
   paragraphe de l'accordeon et le passait en mono — et surtout, toute
   retouche future de l'une des deux aurait casse l'autre en silence. */
.rrp__tail { margin-top: auto; }

/* -------------------------------------------------------------------------
   11.2 — L'ACCORDEON « AVAILABLE SEPARATELY »

   Ferme par defaut. Le contenu est retire du flux par l'attribut [hidden]
   et non par une hauteur nulle : une hauteur nulle laisse l'element dans
   l'ordre de tabulation et le fait lire par les lecteurs d'ecran.

   Il s'ouvre vers le BAS par construction : le panneau est le frere suivant
   du declencheur, il n'y a pas de positionnement absolu qui pourrait le
   faire remonter.
   ------------------------------------------------------------------------- */
.rrp__acc {
  margin: clamp(1.1rem, 1.8vw, 1.5rem) 0 0;
  padding-top: 0.9rem;
  border-top: 1px solid var(--rrp-line);
}
.rrp__acc-tr {
  appearance: none;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
}
.rrp__acc--ghost { visibility: hidden; }
.rrp__acc--ghost .rrp__acc-tr { cursor: default; }
/* Empilees, les cartes ne sont plus cote a cote : il n'y a plus de rang a
   tenir. Les cales passent de `visibility: hidden` a `display: none`, sinon
   elles laissent un trou vertical de 54 px au milieu de la carte — visible
   sur telephone, ou il n'aligne plus rien. */
@media (max-width: 1080px) {
  .rrp__acc--ghost,
  .rrp__reco--ghost { display: none; }
}

.rrp__acc-k {
  display: block;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #E8C547;
}
.rrp__acc-h {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--rrp-dim);
}
.rrp__acc-tr:hover .rrp__acc-h { color: var(--rrp-ink); }
.rrp__acc-tr:focus-visible { outline: 2px solid #E8C547; outline-offset: 3px; }
.rrp__acc-chev {
  display: inline-block;
  transition: transform 0.25s var(--ease);
}
.rrp__acc.is-open .rrp__acc-chev { transform: rotate(180deg); }

.rrp__acc-p { margin-top: 0.7rem; }
.rrp__acc-p .rrp__opt { margin-top: 0; }

/* Le supplement +140 EUR : un lien, pas un bouton plein. Il ne doit pas
   entrer en concurrence avec le CTA de paiement situe juste dessous. */
.rrp__addon {
  display: inline-block;
  margin-top: 0.6rem;
  font-size: 0.8125rem;
  font-weight: 700;
  color: #E8C547;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.rrp__addon::after { content: ' \2192'; }
.rrp__addon:hover { text-decoration-thickness: 2px; }

/* -------------------------------------------------------------------------
   11.3 — LE CTA DE PAIEMENT

   Or plein, texte noir, pas de contour, pleine largeur, meme geometrie sur
   les trois cartes. La carte du milieu perd donc son CTA distinctif :
   c'etait le seul bouton plein, il le sont maintenant tous les trois, comme
   le brief le demande. Sa hierarchie tient a la bordure or, au halo et au
   badge.

   Le libelle reste long a dessein (« release pack — content + master ») :
   il porte le message commercial. `text-wrap: balance` repartit les deux
   lignes plutot que de laisser un mot seul au second rang, et
   `min-height` garantit que les trois boutons ont exactement la meme
   hauteur meme si l'un d'eux tombait sur une ligne de plus.
   ------------------------------------------------------------------------- */
.rrp__cta,
.rrp__card--star .rrp__cta {
  border: 0;
  border-radius: 999px;
  background: #E8C547;
  color: var(--void);
  font-weight: 700;
  font-size: 0.875rem;
  line-height: 1.3;
  padding: 0.9rem 1.15rem;
  min-height: 3.4rem;
  text-wrap: balance;
}
.rrp__cta:hover,
.rrp__card--star .rrp__cta:hover { background: #F2D56D; border: 0; }
.rrp__cta:focus-visible { outline: 2px solid var(--bone); outline-offset: 3px; }

/* -------------------------------------------------------------------------
   11.4 — LA TAGLINE ITALIQUE, DERNIER RANG

   C'est le seul rang du pied dont la hauteur varie d'une carte a l'autre :
   les deux phrases n'ont pas la meme longueur, et la carte 3 Days n'en a
   pas du tout (sa phrase de positionnement est .rrp__note, plus haut, et
   elle n'a PAS ete deplacee). Sans normalisation, un rang de plus sur une
   carte remonterait son CTA d'une ligne.

   `min-height` fixe le rang a deux lignes de texte + le filet superieur.
   La valeur n'est pas choisie a vue : elle a ete mesuree au navigateur a
   1440, 1280 et 1120 px, ou les deux phrases reelles tiennent en deux
   lignes. Sous 1081 px les cartes s'empilent et la contrainte tombe.
   ------------------------------------------------------------------------- */
@media (min-width: 1081px) {
  /* Repli sans JavaScript : deux lignes. Le script, lui, egalise les trois
     taglines a la hauteur reelle de la plus haute — c'est lui qui fait foi,
     parce que la phrase de la carte 10 Days et celle de la carte 30 Days
     passent de deux a trois lignes entre 1180 px et 1150 px. Une valeur
     ecrite en dur ici serait juste d'un cote de ce seuil et fausse de
     l'autre. */
  .rrp__reco { min-height: calc(0.9rem + 2 * 1.5 * 0.8125rem); }
}
.rrp__reco--ghost { visibility: hidden; }

/* -------------------------------------------------------------------------
   11.5 — LES TITRES DE CAMPAGNE (brief 6)

   Deux lignes a la place de « Your 3 days of posts ». Le conteneur garde
   .rrp__cal-h — donc son `text-transform: uppercase` — et perd ses regles
   de corps, qui passent aux deux lignes filles.

   PREMIERE LIGNE, or #E8C547, gras, au moins deux fois le corps precedent
   (0,8125rem -> 1,625rem, soit exactement x2, atteint des 1334 px).
   Au-dela, la borne haute du clamp NE MONTE PLUS : a 27 px et plus, le
   titre le plus long deborde la largeur utile de la carte et retombe sur
   deux lignes — et il le fait sur les cartes 10 et 30 Days avant la carte
   3 Days, ce qui desynchroniserait les trois calendriers. Mesure faite au
   navigateur a 1081 / 1120 / 1180 / 1240 / 1280 / 1440 px.
   L'interlettrage de 0,14em
   herite de .rrp__cal-h est ANNULE : a 26 px, une capitale espacee de
   0,14em depasse la largeur utile de la carte et le titre tombe sur trois
   lignes. Le grand corps porte deja l'emphase que l'espacement portait a
   10 px.

   DEUXIEME LIGNE, blanc casse, semi-gras, plus petite. Elle porte
   « READY TO POST », qui est la promesse commerciale : elle reste lisible
   et ne redescend pas au niveau du gris de fond.

   Le calendrier en dessous n'est pas touche — mais il descend
   mecaniquement, puisque le titre au-dessus de lui occupe plus de place.
   Aucun autre moyen de rendre ces titres « visuellement dominants ».
   ------------------------------------------------------------------------- */
.rrp__cal-h {
  margin: 0 0 0.75rem;
  font-size: inherit;
  letter-spacing: normal;
}
.rrp__cal-h1 {
  display: block;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(1.3rem, 1.95vw, 1.625rem);
  line-height: 1.05;
  letter-spacing: -0.015em;
  color: #E8C547;
}
/* Empilees, les cartes font 515 px : le titre peut monter au maximum du
   clamp bien plus tot. Le plancher descend en revanche pour le telephone,
   ou la carte ne fait plus que 305 px. */
@media (max-width: 1080px) {
  .rrp__cal-h1 { font-size: clamp(1.15rem, 3.4vw, 1.625rem); }
}
.rrp__cal-h2 {
  display: block;
  margin-top: 0.3rem;
  font-family: var(--body);
  font-weight: 600;
  font-size: clamp(0.6875rem, 0.95vw, 0.8125rem);
  line-height: 1.3;
  letter-spacing: 0.05em;
  color: var(--bone);
}

@media (prefers-reduced-motion: reduce) {
  .rrp__acc-chev { transition: none; }
}

/* =========================================================================
   v94 — SECTION TARIFAIRE : LE VOLUME DEVIENT L'INFORMATION DOMINANTE
   Brief du 26/08, « MODIFICATION CHIRURGICALE — PRICING SECTION UNIQUEMENT ».

   Rien ici ne touche la police, la palette, les cartes elles-memes, ni
   aucune autre section. Ce bloc est ajoute EN FIN DE FEUILLE : il gagne la
   cascade sans qu'aucune regle anterieure ait a etre supprimee, ce qui
   evite de casser les surcharges v89-v93 en amont.

   Contrainte du brief : « ne pas agrandir massivement la hauteur des
   cartes ». Le volume et les trois rangs de valeur remplacent les six
   blocs .rrp__feat et leurs descriptions longues — le bilan de hauteur est
   negatif, pas positif.
   ========================================================================= */

/* ------------------------------------------------------------ LE VOLUME
   « 5 POSTS · 3 DAYS ». Le chiffre est l'element le plus grand de la carte
   apres le prix. Il repond a HOW MANY? avant toute lecture. */
.rrp__vol {
  margin: 0.5rem 0 0;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.3em;
  font-family: var(--display);
  line-height: 1;
  color: var(--rrp-ink);
}
.rrp__vol-n {
  font-size: clamp(2.5rem, 4.4vw, 3.5rem);
  font-weight: 800;
  letter-spacing: -0.04em;
  color: #E8C547;
}
.rrp__vol-u {
  font-size: clamp(1.05rem, 1.6vw, 1.35rem);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.rrp__vol-s {
  font-size: clamp(0.95rem, 1.4vw, 1.15rem);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ash);
}

/* Le rythme repond a HOW OFTEN?. Une seule ligne, jamais deux idees. */
.rrp__rhythm {
  margin: 0.55rem 0 0;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--ash);
}

/* ------------------------------------------------- LES RANGS DE VALEUR
   CONTENT / RELEASE ASSETS / STRATEGY / SUPPORT. La hierarchie doit etre
   « tres facile a scanner » : cle en capitales or, chiffre en blanc gras,
   detail en gris. Trois niveaux de gris, pas de puces, pas de tableau —
   les tableaux sont explicitement exclus par le brief. */
.rrp__val {
  margin: clamp(1.1rem, 2vw, 1.5rem) 0 0;
  display: grid;
  gap: clamp(0.7rem, 1.2vw, 0.95rem);
  padding-top: clamp(1rem, 1.8vw, 1.35rem);
  border-top: 1px solid rgba(255, 255, 255, 0.09);
}
.rrp__val-k {
  margin: 0;
  font-family: var(--caps);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #E8C547;
}
.rrp__val-h {
  margin: 0.28rem 0 0;
  font-family: var(--display);
  font-size: clamp(1rem, 1.5vw, 1.1875rem);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--rrp-ink);
}
.rrp__val-d {
  margin: 0.22rem 0 0;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--ash);
}

/* v95 — LE RANG STORIES.
   Arbitrage du 26/08 : 2 Stories par jour, tous les packs, par chanson, et
   les Stories ne sont PLUS comptees dans les publications. Le rang doit
   donc se lire comme une COUCHE EN PLUS, pas comme une quatrieme categorie
   de la meme liste — sinon on retombe exactement dans la confusion que
   l'arbitrage vient de trancher.
   Le liere or a gauche est le seul marqueur : pas de fond, pas de cadre,
   rien qui ajoute du poids visuel a une carte deja dense. */
.rrp__val-b--story {
  padding-left: clamp(0.7rem, 1.2vw, 0.9rem);
  border-left: 2px solid rgba(232, 197, 71, 0.55);
}
.rrp__val-b--story .rrp__val-d { color: var(--ash-dim); }

/* --------------------------------------------------------- PLATEFORMES
   Repond a WHERE?. La note qui suit desamorce le contresens que le brief
   signale : le plan dit ou va chaque piece, il ne demande pas de tout
   publier partout. */
.rrp__plat {
  margin: clamp(1rem, 1.8vw, 1.35rem) 0 0;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--rrp-ink);
}
.rrp__plat-k {
  display: block;
  margin-bottom: 0.2rem;
  font-family: var(--caps);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #E8C547;
}
.rrp__plat-n {
  margin: 0.3rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--ash-dim);
}

/* ------------------------------------------------- LA LIGNE DE CAMPAGNE
   Le calendrier existant est conserve — « c'est une force », dit le brief.
   Un quatrieme rang est ajoute a chaque etape : le CONTENU de cette
   journee. C'est lui qui rend le plan concret. */
.rrp__cal-c {
  display: block;
  margin-top: 0.2rem;
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.03em;
  color: var(--ash-dim);
}

/* -------------------------------------------------------------- RESULT
   Repond a WHY?. Encadre discretement pour se detacher sans devenir une
   section nouvelle : le brief interdit d'en ajouter une. */
.rrp__res {
  margin: clamp(1.1rem, 2vw, 1.5rem) 0 0;
  padding: clamp(0.85rem, 1.5vw, 1.1rem) clamp(0.9rem, 1.6vw, 1.15rem);
  border-left: 2px solid rgba(232, 197, 71, 0.5);
  background: rgba(232, 197, 71, 0.045);
  border-radius: 0 8px 8px 0;
}
.rrp__res-k {
  margin: 0;
  font-family: var(--caps);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #E8C547;
}
.rrp__res-p {
  margin: 0.3rem 0 0;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--rrp-ink);
}

/* ------------------------------------------------------------ LES CTA
   « Boutons pleins et beaucoup plus forts visuellement que les liens
   secondaires. » Les trois cartes ont deja .rrp__cta--pay en or plein
   depuis la v93 ; ce qui change est le libelle, qui porte maintenant le
   montant. Le montant ne doit pas passer a la ligne seul. */
.rrp__cta--pay [data-rrp-amount] {
  white-space: nowrap;
  font-weight: 800;
}

/* =========================================================================
   v94 — BOUTON « BOOK A CALL »
   Brief : « trop large, reduis-le en le maintenant en position centrale,
   augmente legerement la taille de la police ».

   Il etait en display:block + width:100%, donc aussi large que la grille
   des trois cartes. Il passe en largeur de contenu, borne par une largeur
   maximale, et centre par margin-inline:auto — et non par text-align, qui
   n'aurait centre que le texte a l'interieur d'une boite restee large.

   `width: fit-content` a besoin de `max-width: 100%` : sans lui, un
   libelle long deborderait le conteneur sur petit ecran. C'est exactement
   le defaut de .cmp__list corrige en v90.
   ========================================================================= */
.rrp__gtee-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  width: -moz-fit-content;
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
  padding: clamp(0.8rem, 1.5vw, 1rem) clamp(1.75rem, 3vw, 2.5rem);
  font-size: clamp(1.05rem, 1.7vw, 1.1875rem);
}

/* =========================================================================
   v94 — PAGES LEGALES
   Brief : « les liens correspondants aux sections seront ecrits en petit en
   bas de page avec bouton de retour ». Les quatre documents partagent donc
   un pied commun : la liste des documents en petit, puis un bouton de
   retour a l'accueil.

   Ces regles ne s'appliquent qu'aux classes doc-*, presentes uniquement sur
   legal / privacy / terms / refund. Aucune page du site n'est touchee.
   ========================================================================= */
.doc-date {
  margin-bottom: 2rem;
  font-size: 0.875rem;
  color: var(--ash-dim);
}

/* Le tableau des finalites et bases legales. Le brief tarifaire interdit
   les tableaux DANS LES CARTES ; il ne dit rien des documents juridiques,
   ou un tableau est la forme attendue par la CNIL. */
.doc-table {
  width: 100%;
  margin: 1.25rem 0;
  border-collapse: collapse;
  font-size: 0.875rem;
}
.doc-table th,
.doc-table td {
  padding: 0.65rem 0.85rem;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.doc-table th {
  font-family: var(--caps);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #E8C547;
}
@media (max-width: 620px) {
  .doc-table, .doc-table tbody, .doc-table tr, .doc-table td { display: block; width: 100%; }
  .doc-table thead { display: none; }
  .doc-table tr { padding: 0.6rem 0; border-bottom: 1px solid rgba(255,255,255,0.1); }
  .doc-table td { border: 0; padding: 0.15rem 0; }
  .doc-table td:first-child { font-weight: 700; }
}

.doc-links {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: 1.5rem;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
}
.doc-links a { color: var(--ash); text-decoration: none; }
.doc-links a:hover { color: #E8C547; text-decoration: underline; }
.doc-links span { color: var(--ash-dim); }

.doc-back { margin-top: 1.5rem; }
.doc-back-btn {
  display: inline-block;
  padding: 0.7rem 1.5rem;
  border: 1px solid rgba(232, 197, 71, 0.55);
  border-radius: 999px;
  color: #E8C547;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.9375rem;
  text-decoration: none;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.doc-back-btn:hover {
  border-color: #E8C547;
  background: rgba(232, 197, 71, 0.07);
}
@media (prefers-reduced-motion: reduce) {
  .doc-back-btn { transition: none; }
}

/* =========================================================================
   READY RELEASE — PAGE START (contact.html)                          (v95)

   Refonte complete demandee par le brief du 26/08. Contraintes explicites :
   meme direction artistique, meme typographie, meme univers sombre, meme
   sobriete ; pas de design generique de formulaire SaaS, pas de couleurs
   criardes, pas de surcharge visuelle.

   Rien n'est invente ici : les couleurs viennent des tokens (--void,
   --bone, --ash, --signal a #E8C547), les familles des trois roles deja
   definis (--display / --body / --caps), les espacements de l'echelle
   fluide. Le seul element neuf est le fond onde du §4.
   ========================================================================= */

.rs { position: relative; isolation: isolate; }

/* ------------------------------------------------------------- LE FOND §4 */
.rs-bg {
  position: absolute;
  inset: 0 0 auto;
  height: min(1100px, 100%);
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}
.rs-bg__glow {
  position: absolute;
  left: 50%;
  top: -18%;
  width: min(1500px, 150%);
  aspect-ratio: 2 / 1;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at 50% 40%,
              rgba(232, 197, 71, 0.055) 0%,
              rgba(232, 197, 71, 0.018) 38%,
              transparent 68%);
}
/* La forme d'onde est ancree EN BAS de sa zone et fondue vers le haut :
   posee telle quelle, elle serait un bandeau qui coupe la page en deux.
   Le masque la fait naitre du noir. */
.rs-bg__wave {
  position: absolute;
  left: 0;
  right: 0;
  top: 34%;
  width: 100%;
  height: min(420px, 42vh);
  color: var(--signal);
  opacity: 0.085;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 42%, #000 62%, transparent);
          mask-image: linear-gradient(to bottom, transparent, #000 42%, #000 62%, transparent);
}
.rs-bg__grain {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0.035;
  mix-blend-mode: overlay;
}

/* ------------------------------------------------------------------ HERO */
.rs-hero {
  padding: clamp(2.5rem, 7vw, 5.5rem) 0 clamp(1.5rem, 3vw, 2.5rem);
}
.rs-hero__t {
  margin: 0.9rem 0 0;
  font-family: var(--display);
  font-size: var(--fs-h1);
  font-weight: 800;
  line-height: 0.95;
  letter-spacing: -0.035em;
  color: var(--bone);
}
.rs-hero__sub {
  margin: clamp(1rem, 2vw, 1.5rem) 0 0;
  max-width: 34ch;
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--ash);
}
.rs-hero__assure {
  margin: clamp(1.1rem, 2vw, 1.6rem) 0 0;
  font-family: var(--caps);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--signal-dim);
}

/* -------------------------------------------------------- LE PARCOURS §2 */
.rs-path {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: clamp(0.5rem, 1.4vw, 1.1rem);
  margin: 0 0 clamp(2.5rem, 6vw, 4.5rem);
  padding: 0;
  list-style: none;
  counter-reset: none;
}
.rs-path__i {
  padding-top: 0.85rem;
  border-top: 2px solid var(--line);
  transition: border-color 0.4s var(--ease), color 0.4s var(--ease);
}
.rs-path__i.is-done { border-top-color: rgba(232, 197, 71, 0.4); }
.rs-path__i.is-now  { border-top-color: var(--signal); }
.rs-path__n {
  display: block;
  font-family: var(--caps);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--ash-dim);
}
.rs-path__i.is-now .rs-path__n { color: var(--signal); }
.rs-path__l {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.8125rem;
  line-height: 1.35;
  color: var(--ash-dim);
}
.rs-path__i.is-now .rs-path__l { color: var(--bone); }
.rs-path__i.is-done .rs-path__l { color: var(--ash); }

/* --------------------------------------------------------------- PANNEAUX */
.rs-panel { padding: 0 0 clamp(4rem, 10vw, 7rem); }
.rs-panel[hidden] { display: none; }

.rs-sec { margin: 0 0 clamp(1.8rem, 4vw, 2.8rem); }
.rs-sec__t {
  margin: 0;
  font-family: var(--display);
  font-size: var(--fs-h3);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--bone);
}
.rs-sec__s {
  margin: 0.6rem 0 0;
  max-width: 52ch;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ash);
}

/* ---------------------------------------------------------- CHARGEMENT */
.rs-load { display: flex; align-items: center; gap: 0.45rem; padding: 3rem 0; }
.rs-load__dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--signal);
  opacity: 0.35;
  animation: rsPulse 1.2s var(--ease) infinite;
}
.rs-load__dot:nth-child(2) { animation-delay: 0.15s; }
.rs-load__dot:nth-child(3) { animation-delay: 0.3s; }
.rs-load__t {
  margin: 0 0 0 0.7rem;
  font-size: 0.9375rem;
  color: var(--ash);
}
@keyframes rsPulse {
  0%, 100% { opacity: 0.25; transform: scale(0.85); }
  50%      { opacity: 1;    transform: scale(1); }
}

/* -------------------------------------------------------- LES PACKS §5 */
.rs-packs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(0.9rem, 1.8vw, 1.4rem);
  align-items: stretch;
}
.rs-pack {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: clamp(1.5rem, 2.6vw, 2.1rem) clamp(1.3rem, 2.2vw, 1.8rem) clamp(1.4rem, 2.4vw, 1.8rem);
  background: linear-gradient(180deg, rgba(23, 25, 29, 0.85), rgba(18, 19, 22, 0.85));
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  backdrop-filter: blur(2px);
  transition: border-color 0.35s var(--ease), transform 0.35s var(--ease);
}
.rs-pack:hover { border-color: var(--line-strong); }
.rs-pack--star { border-color: rgba(232, 197, 71, 0.34); }
.rs-pack__flag {
  position: absolute;
  top: 0; left: 50%;
  transform: translate(-50%, -50%);
  padding: 0.32rem 0.75rem;
  background: var(--signal-fill);
  border-radius: 999px;
  font-family: var(--caps);
  font-size: 0.5625rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--void);
  white-space: nowrap;
}
.rs-pack__n {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(1.35rem, 2.2vw, 1.7rem);
  font-weight: 800;
  letter-spacing: -0.025em;
  color: var(--bone);
}
.rs-pack__p {
  margin: 0.5rem 0 0;
  font-family: var(--heavy);
  font-size: clamp(1.9rem, 3.4vw, 2.6rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--signal);
}
.rs-pack__v {
  margin: 0.9rem 0 0;
  font-size: 1rem;
  color: var(--bone);
}
.rs-pack__v b { font-family: var(--display); font-weight: 800; }
.rs-pack__r {
  margin: 0.2rem 0 0;
  font-size: 0.8125rem;
  color: var(--ash-dim);
}
.rs-pack__d {
  margin: 0.9rem 0 0;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ash);
}
.rs-pack__inc {
  margin: clamp(1rem, 1.8vw, 1.35rem) 0 0;
  padding-top: clamp(0.9rem, 1.6vw, 1.15rem);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.rs-pack__ih {
  margin: 0;
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 700;
  color: var(--bone);
}
.rs-pack__id {
  margin: 0.28rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--ash);
}
/* Le rang Stories, meme traitement que sur la home : un liere or, parce
   que les Stories sont une couche EN PLUS et non une categorie de plus. */
.rs-pack__st {
  margin: clamp(0.9rem, 1.5vw, 1.15rem) 0 0;
  padding-left: 0.8rem;
  border-left: 2px solid rgba(232, 197, 71, 0.55);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ash-dim);
}
.rs-pack__st b { color: var(--bone); font-weight: 700; }
.rs-pack__cta {
  margin-top: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.7rem;
  width: 100%;
  margin-block-start: clamp(1.4rem, 2.4vw, 1.9rem);
  padding: 1rem 1.15rem;
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-s);
  font-family: var(--caps);
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  text-align: left;
  color: var(--bone);
  cursor: pointer;
  transition: background 0.3s var(--ease), color 0.3s var(--ease),
              border-color 0.3s var(--ease);
}
.rs-pack--star .rs-pack__cta {
  background: var(--signal-fill);
  border-color: var(--signal-fill);
  color: var(--void);
}
.rs-pack__cta:hover {
  background: var(--signal-fill);
  border-color: var(--signal-fill);
  color: var(--void);
}
.rs-pack__cta:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 3px;
}
.rs-pack__cta.is-busy { opacity: 0.55; cursor: progress; }
.rs-pack__cta-a { transition: transform 0.3s var(--ease); }
.rs-pack__cta:hover .rs-pack__cta-a { transform: translateX(3px); }

/* ---------------------------------------------------------- CONFIANCE §18 */
.rs-trust {
  margin: clamp(2rem, 4vw, 3rem) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.6rem;
}
.rs-trust__i {
  position: relative;
  padding-left: 1.35rem;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--ash);
}
.rs-trust__i::before {
  content: "";
  position: absolute;
  left: 0; top: 0.55em;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--signal);
  opacity: 0.7;
}
.rs-help {
  margin: clamp(1.6rem, 3vw, 2.2rem) 0 0;
  font-size: 0.875rem;
  color: var(--ash-dim);
}
.rs-help a { color: var(--signal); text-decoration: none; }
.rs-help a:hover { text-decoration: underline; }

.rs-note {
  margin: 0 0 clamp(1.6rem, 3vw, 2.2rem);
  padding: 0.95rem 1.15rem;
  background: rgba(232, 197, 71, 0.06);
  border: 1px solid rgba(232, 197, 71, 0.22);
  border-radius: var(--radius-s);
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--bone);
}
.rs-err {
  margin: clamp(1.2rem, 2.4vw, 1.8rem) 0 0;
  padding: 0.95rem 1.15rem;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--signal);
  border-radius: var(--radius-s);
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--bone);
}

/* --------------------------------------------------- CONFIRMATION §8/§15 */
.rs-conf {
  max-width: 46rem;
  padding: clamp(1.8rem, 4vw, 3rem);
  background: linear-gradient(180deg, rgba(23, 25, 29, 0.9), rgba(18, 19, 22, 0.9));
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
}
.rs-conf__k {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin: 0;
  font-family: var(--caps);
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--signal);
}
.rs-conf__tick {
  width: 15px; height: 15px;
  border-radius: 50%;
  background: var(--signal-fill);
  position: relative;
  flex: none;
}
.rs-conf__tick::after {
  content: "";
  position: absolute;
  left: 4.5px; top: 3px;
  width: 4px; height: 7px;
  border: solid var(--void);
  border-width: 0 2px 2px 0;
  transform: rotate(42deg);
}
.rs-conf__t {
  margin: clamp(0.9rem, 1.8vw, 1.3rem) 0 0;
  font-family: var(--display);
  font-size: var(--fs-h2);
  font-weight: 800;
  line-height: 0.98;
  letter-spacing: -0.035em;
  color: var(--bone);
}
.rs-conf__s {
  margin: clamp(0.8rem, 1.6vw, 1.15rem) 0 0;
  max-width: 40ch;
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--ash);
}
.rs-conf__s b { color: var(--bone); font-weight: 700; }
.rs-conf__meta,
.rs-done__meta {
  margin: clamp(1.5rem, 3vw, 2.2rem) 0 0;
  display: grid;
  gap: 0.9rem;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
}
.rs-conf__meta dt,
.rs-done__meta dt {
  font-family: var(--caps);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash-dim);
}
.rs-conf__meta dd,
.rs-done__meta dd {
  margin: 0.28rem 0 0;
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 600;
  color: var(--bone);
  overflow-wrap: anywhere;
}
.rs-conf__n {
  margin: 1rem 0 0;
  font-size: 0.8125rem;
  color: var(--ash-dim);
}

/* ------------------------------------------------------------- BOUTONS */
.rs-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: clamp(1.5rem, 3vw, 2.1rem);
  padding: 1.05rem 1.6rem;
  border-radius: var(--radius-s);
  border: 1px solid transparent;
  font-family: var(--caps);
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.3s var(--ease), border-color 0.3s var(--ease),
              color 0.3s var(--ease), opacity 0.3s var(--ease);
}
.rs-btn--primary {
  background: var(--signal-fill);
  border-color: var(--signal-fill);
  color: var(--void);
}
.rs-btn--primary:hover { background: #F2D56D; border-color: #F2D56D; }
.rs-btn--ghost {
  background: transparent;
  border-color: var(--line-strong);
  color: var(--bone);
}
.rs-btn--ghost:hover { border-color: var(--signal); color: var(--signal); }
.rs-btn--wide { margin-top: clamp(1.8rem, 3.5vw, 2.6rem); }
.rs-btn:focus-visible { outline: 2px solid var(--signal); outline-offset: 3px; }
.rs-btn.is-busy { opacity: 0.55; cursor: progress; }
.rs-btn__a { transition: transform 0.3s var(--ease); }
.rs-btn:hover .rs-btn__a { transform: translateX(3px); }
.rs-btn:hover .rs-btn__a--l { transform: translateX(-3px); }

/* --------------------------------------------------------- PROGRESSION §20 */
.rs-prog { margin: 0 0 clamp(2rem, 4vw, 3rem); }
.rs-prog__bar {
  height: 2px;
  background: var(--line);
  border-radius: 2px;
  overflow: hidden;
}
.rs-prog__fill {
  display: block;
  height: 100%;
  width: 0;
  background: var(--signal);
  transition: width 0.5s var(--ease);
}
.rs-prog__l {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(0.8rem, 2.2vw, 2rem);
  margin: 0.9rem 0 0;
  padding: 0;
  list-style: none;
}
.rs-prog__i { display: flex; align-items: baseline; gap: 0.4rem; }
.rs-prog__n {
  font-family: var(--caps);
  font-size: 0.5625rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  color: var(--ash-dim);
}
.rs-prog__t {
  font-size: 0.8125rem;
  color: var(--ash-dim);
  transition: color 0.35s var(--ease);
}
.rs-prog__i.is-done .rs-prog__t { color: var(--ash); }
.rs-prog__i.is-done .rs-prog__n { color: rgba(232, 197, 71, 0.6); }
.rs-prog__i.is-now .rs-prog__t { color: var(--bone); font-weight: 600; }
.rs-prog__i.is-now .rs-prog__n { color: var(--signal); }

/* ------------------------------------------------------- LE FORMULAIRE §20
   « grands champs, beaucoup d'espace, labels clairs ». Aucun champ ne
   descend sous 3,1 rem de haut, aucun label sous 0,75 rem : le brief §22
   interdit explicitement le texte minuscule sur mobile. */
.rs-form { max-width: 44rem; }
.rs-step {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;                /* sans ca, un fieldset refuse de retrecir */
}
.rs-step[hidden] { display: none; }
.rs-step__t {
  padding: 0;
  font-family: var(--display);
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--bone);
}
.rs-step__s {
  margin: 0.55rem 0 clamp(1.8rem, 3.5vw, 2.6rem);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ash);
}
.rs-f { margin: 0 0 clamp(1.4rem, 2.6vw, 2rem); }
.rs-f__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(0.9rem, 2vw, 1.6rem);
}
.rs-f__row .rs-f { margin-bottom: clamp(1.4rem, 2.6vw, 2rem); }
.rs-f__l {
  display: block;
  margin: 0 0 0.55rem;
  font-family: var(--caps);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ash);
}
.rs-f__req { color: var(--signal); }
.rs-f__i,
.rs-f__t {
  display: block;
  width: 100%;
  padding: 1rem 1.1rem;
  background: rgba(10, 11, 13, 0.7);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-s);
  font-family: var(--body);
  font-size: 1rem;              /* 16px : en dessous, iOS zoome au focus */
  line-height: 1.45;
  color: var(--bone);
  transition: border-color 0.25s var(--ease), background 0.25s var(--ease);
}
.rs-f__t { resize: vertical; min-height: 6.5rem; }
.rs-f__i::placeholder,
.rs-f__t::placeholder { color: var(--ash-dim); }
.rs-f__i:focus,
.rs-f__t:focus {
  outline: none;
  border-color: var(--signal);
  background: rgba(10, 11, 13, 0.95);
}
.rs-f__i.is-bad,
.rs-f__t.is-bad { border-color: #C96A4A; }
/* Le champ date natif rend son icone en noir sur fond sombre : invisible. */
.rs-f__i--date::-webkit-calendar-picker-indicator { filter: invert(0.7); cursor: pointer; }
.rs-f__h {
  margin: 0.5rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ash-dim);
}
.rs-f__e {
  margin: 0.5rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: #E39A7E;
}

/* Chips de direction artistique et Oui/Non. Des boutons, pas des cases a
   cocher : le brief §20 refuse explicitement l'empilement de checkboxes. */
.rs-moods, .rs-yn { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.rs-mood, .rs-yn__b {
  padding: 0.75rem 1.1rem;
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-family: var(--body);
  font-size: 0.9375rem;
  color: var(--ash);
  cursor: pointer;
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease),
              background 0.25s var(--ease);
}
.rs-yn__b { min-width: 5.5rem; text-align: center; }
.rs-mood:hover, .rs-yn__b:hover { border-color: var(--ash); color: var(--bone); }
.rs-mood.is-on, .rs-yn__b.is-on {
  background: rgba(232, 197, 71, 0.12);
  border-color: var(--signal);
  color: var(--bone);
}
.rs-mood:focus-visible, .rs-yn__b:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

/* ------------------------------------------------------ RECAPITULATIF §9 */
.rs-sum {
  margin: 0 0 clamp(1.8rem, 3.5vw, 2.6rem);
  padding: clamp(1.3rem, 2.6vw, 1.9rem);
  background: rgba(23, 25, 29, 0.7);
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
}
.rs-sum__r {
  display: grid;
  grid-template-columns: minmax(8rem, 32%) 1fr;
  gap: 0.9rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.rs-sum__r:last-of-type { border-bottom: 0; }
.rs-sum dt {
  font-family: var(--caps);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash-dim);
  align-self: center;
}
.rs-sum dd {
  margin: 0;
  font-size: 0.9375rem;
  color: var(--bone);
  overflow-wrap: anywhere;
}
.rs-sum__ok {
  margin: 1.1rem 0 0;
  font-family: var(--display);
  font-size: 1.0625rem;
  font-weight: 700;
  color: var(--signal);
}

/* ----------------------------------------------------------- ACTIONS */
.rs-act {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.8rem;
  margin-top: clamp(1.5rem, 3vw, 2.2rem);
}
.rs-act .rs-btn { margin-top: 0; }
.rs-act--end { margin-top: clamp(2rem, 4vw, 3rem); }
.rs-save {
  margin: 1.1rem 0 0;
  font-size: 0.8125rem;
  color: var(--ash-dim);
  transition: color 0.3s var(--ease);
}
.rs-save.is-flash { color: var(--signal); }

/* ------------------------------------------------------- APRES ENVOI §12 */
.rs-done {
  max-width: 46rem;
  padding: clamp(1.8rem, 4vw, 3rem);
  background: linear-gradient(180deg, rgba(23, 25, 29, 0.9), rgba(18, 19, 22, 0.9));
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
}
.rs-done__t {
  margin: 0;
  font-family: var(--display);
  font-size: var(--fs-h2);
  font-weight: 800;
  line-height: 0.98;
  letter-spacing: -0.035em;
  color: var(--bone);
}
.rs-done__s {
  margin: clamp(0.8rem, 1.6vw, 1.15rem) 0 0;
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--ash);
}
.rs-done__next {
  margin: clamp(1.5rem, 3vw, 2.2rem) 0 0;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--bone);
}
.rs-done__nk {
  display: block;
  margin-bottom: 0.25rem;
  font-family: var(--caps);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash-dim);
}
.rs-done__mail { margin: clamp(1.4rem, 2.8vw, 2rem) 0 0; font-size: 0.9375rem; color: var(--ash); }
.rs-done__mail b { color: var(--bone); font-weight: 600; }

/* La timeline est numerotee parce que l'ordre PORTE une information : le
   client veut savoir ou en est sa commande dans une suite d'etapes. */
.rs-tl {
  margin: clamp(1.6rem, 3vw, 2.4rem) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0;
}
.rs-tl__i {
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  padding: 0.75rem 0 0.75rem 0.9rem;
  border-left: 2px solid var(--line);
}
.rs-tl__i.is-done { border-left-color: rgba(232, 197, 71, 0.45); }
.rs-tl__i.is-now  { border-left-color: var(--signal); }
.rs-tl__n {
  font-family: var(--caps);
  font-size: 0.625rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  color: var(--ash-dim);
  flex: none;
}
.rs-tl__i.is-done .rs-tl__n { color: rgba(232, 197, 71, 0.7); }
.rs-tl__i.is-now .rs-tl__n { color: var(--signal); }
.rs-tl__l { font-size: 0.9375rem; color: var(--ash-dim); }
.rs-tl__i.is-done .rs-tl__l { color: var(--ash); }
.rs-tl__i.is-now .rs-tl__l { color: var(--bone); font-weight: 600; }

/* ====================================================== RESPONSIVE §22
   « une carte pack a la fois ; CTA full width ; formulaire une colonne ;
   aucun texte minuscule ». */
@media (max-width: 1080px) {
  .rs-packs { grid-template-columns: 1fr; }
  .rs-pack--star { order: -1; }        /* le pack recommande passe en tete */
  .rs-pack__flag { left: clamp(1.3rem, 2.2vw, 1.8rem); transform: translate(0, -50%); }
}
@media (max-width: 780px) {
  .rs-path {
    grid-template-columns: 1fr;
    gap: 0;
  }
  .rs-path__i {
    display: flex;
    align-items: baseline;
    gap: 0.7rem;
    padding: 0.7rem 0 0.7rem 0.9rem;
    border-top: 0;
    border-left: 2px solid var(--line);
  }
  .rs-path__i.is-done { border-left-color: rgba(232, 197, 71, 0.4); }
  .rs-path__i.is-now  { border-left-color: var(--signal); }
  .rs-path__n { flex: none; }
  .rs-path__l { margin-top: 0; font-size: 0.875rem; }

  .rs-f__row { grid-template-columns: 1fr; gap: 0; }
  .rs-hero__sub { max-width: none; }
  .rs-conf__s { max-width: none; }

  .rs-sum__r { grid-template-columns: 1fr; gap: 0.25rem; }

  .rs-act { flex-direction: column-reverse; align-items: stretch; }
  .rs-act .rs-btn { justify-content: center; width: 100%; }
  .rs-btn--wide { width: 100%; justify-content: center; }

  .rs-prog__l { gap: 0.6rem 1.1rem; }
  .rs-prog__t { font-size: 0.75rem; }

  /* Rien ne descend sous 0,8125 rem (13 px) sur mobile. */
  .rs-pack__r, .rs-pack__id, .rs-pack__st,
  .rs-f__h, .rs-f__e, .rs-conf__n, .rs-save { font-size: 0.8125rem; }
}

/* Le fond ne doit pas peser sur les petits ecrans : la forme d'onde y est
   presque invisible et le filtre de grain est couteux a composer. */
@media (max-width: 640px) {
  .rs-bg__grain { display: none; }
  .rs-bg__wave { opacity: 0.06; }
}

@media (prefers-reduced-motion: reduce) {
  .rs-load__dot { animation: none; opacity: 0.6; }
  .rs-prog__fill { transition: none; }
  .rs-btn__a, .rs-pack__cta-a { transition: none; }
}

/* =============================================================================
   v96 — SECTION PREUVE : AIDE AU CHOIX (GAUCHE) + RESULTAT CLIENT (DROITE)

   Regle du fichier : le bloc .rrp de la §9 est duplique plus bas dans la
   feuille, et c'est la SECONDE occurrence qui gagne. Tout ce qui suit est
   donc ecrit ici, en fin de fichier, pour ne dependre d'aucune des deux.

   .rrp__guide n'est pas restyle. Les deux seules declarations qui le visent
   annulent le centrage horizontal qu'il tenait quand il etait seul et pleine
   largeur : sa bordure, ses polices, ses couleurs et ses espacements
   internes restent ceux de la v95.
   ============================================================================= */

.rrp__proof {
  margin: clamp(2.5rem, 5vw, 4rem) auto 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.58fr);
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: center;
}

/* L'encadre etait centre sur --container-narrow quand il occupait toute la
   largeur. En colonne, il prend la sienne. Rien d'autre ne change. */
.rrp__proof .rrp__guide {
  margin: 0;
  max-width: none;
}

/* ------------------------------------------------------------ colonne droite */
.rrp__proof-col {
  margin: 0;
  display: grid;
  justify-items: center;
  gap: 0;
  text-align: center;
}

.rrp__proof-h {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.35rem, 2.1vw, 1.75rem);
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--bone);
  text-wrap: balance;
}

/* Seul accent de la section. Feutre + #FFE14A, et nulle part ailleurs. */
.rrp__proof-mark {
  font-family: 'Permanent Marker', 'Bradley Hand', 'Segoe Script', cursive;
  font-weight: 400;
  color: #FFE14A;
  /* Permanent Marker porte haut et serre : sans ces deux corrections la
     capitale depasse la ligne de l'Inter Tight qui la precede. */
  font-size: 1.28em;
  line-height: 1;
  letter-spacing: 0.012em;
  white-space: nowrap;
}

.rrp__proof-sub {
  margin: 0.85rem 0 0;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--bone);
  opacity: 0.72;
}

/* Pas de cadre, pas de carte, pas de halo : l'image se pose sur le noir. */
.rrp__proof-img {
  display: block;
  width: clamp(228px, 22vw, 325px);
  height: auto;
  margin: clamp(1.25rem, 2.4vw, 1.9rem) 0 0;
}

.rrp__proof-cap {
  margin: clamp(1.1rem, 2vw, 1.5rem) 0 0;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--ash);
}

/* ------------------------------------------------------------------- tablette */
@media (max-width: 1040px) {
  .rrp__proof { grid-template-columns: minmax(0, 1fr); gap: clamp(2.5rem, 6vw, 3.5rem); }
  .rrp__proof .rrp__guide { max-width: var(--container-narrow); margin-inline: auto; }
  .rrp__proof-img { width: clamp(240px, 46vw, 340px); }
}

/* -------------------------------------------------------------------- mobile */
@media (max-width: 640px) {
  .rrp__proof { margin-top: clamp(2rem, 8vw, 2.75rem); }
  .rrp__proof-h { font-size: clamp(1.25rem, 6.2vw, 1.5rem); }
  .rrp__proof-img { width: min(78vw, 300px); }
}

/* Le titre vise par /terms.html#refunds arrivait sous la barre collante.
   Meme valeur que les ancres deja traitees (#packages, #release-map). */
#refunds { scroll-margin-top: 6.5rem; }
@media (max-width: 720px) { #refunds { scroll-margin-top: 5rem; } }

/* =============================================================================
   v97 — TROIS CORRECTIONS, ECRITES EN FIN DE FEUILLE

   Rappel de la regle du fichier : le bloc .rrp et le bloc .tst sont chacun
   dupliques plus haut, et c'est la SECONDE occurrence qui gagne. Tout ce qui
   suit est donc pose ici pour ne dependre d'aucune des deux.
   ============================================================================= */

/* ---------------------------------------------------- 1. HIERARCHIE DE VALEUR

   « Professional WAV Mastering » et « 1 Full Music Video · 3–4 min » passent
   en or. Ils reutilisent .rrp__val-h, le rang typographique qui portait deja
   « 4 ready-to-post pieces » : aucun corps nouveau, aucune police nouvelle,
   aucune couleur nouvelle — #E8C547 est l'or deja pose sur .rrp__val-k. */
.rrp__val-h--key { color: #E8C547; }

/* Le clip est un SECOND rang sous « 17 ready-to-post pieces » : il doit
   dominer la ligne grise qui le suit sans concurrencer le compte de pieces
   qui le precede. */
.rrp__val-h--sub {
  margin-top: 0.34rem;
  font-size: clamp(0.9375rem, 1.35vw, 1.0625rem);
}

/* Micro-copie de tete. Discrete par construction : corps du texte courant,
   italique, gris — elle situe l'offre, elle ne crie pas. */
.rrp__micro {
  margin: 0.5rem 0 0;
  font-size: 0.875rem;
  line-height: 1.45;
  font-style: italic;
  color: var(--ash);
}

/* ------------------------------------------- 2. GARANTIE REMONTEE SOUS LES CARTES

   Marge haute reduite : sous les cartes, l'ecart de 5 rem prevu pour une fin
   de section laissait un trou. En dessous, .rrp__proof porte deja sa propre
   marge haute, donc rien n'est ajoute entre les deux. */
.rrp__gtee--top { margin-top: clamp(2rem, 3.6vw, 3rem); }

/* ----------------------------------------------- 3. TEMOIGNAGES : GRILLE 5 x 2

   Le marquee est retire cote balisage (plus de piste, plus de doublons). Il
   reste a neutraliser ce que la §3 avait pose sur .tst__track et a poser la
   grille. Les selecteurs ci-dessous ne suppriment aucune regle existante :
   ils la remplacent en fin de feuille, ce qui laisse la §3 lisible comme
   trace de ce que faisait l'ancien montage. */
.tst__viewport {
  overflow: visible;
  /* Le masque en degrade annoncait un contenu qui continuait hors cadre.
     Plus rien ne defile : il n'a plus d'objet et il mangeait les colonnes
     1 et 5. */
  -webkit-mask-image: none;
          mask-image: none;
  /* Pleine largeur, comme le bandeau qu'elle remplace : chaque pixel gagne
     en largeur est une ligne de citation en moins, donc de la hauteur en
     moins. Un cadrage sur --container coutait 120 px de large pour rien. */
  max-width: none;
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 2.5vw, 2.25rem);
}

.tst__track {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  column-gap: clamp(0.85rem, 1.25vw, 1.25rem);
  row-gap: clamp(0.5rem, 0.8vw, 0.75rem);
  width: auto;
  align-items: start;
  /* Le marquee vivait ici. */
  animation: none;
  will-change: auto;
}

.tst__i {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  margin-right: 0;
}

/* Rythme editorial : trois positions verticales seulement, assez pour casser
   la grille, trop peu pour ajouter un pixel de hauteur a la bande — les
   translations ne participent pas au flux. Les colonnes 2 et 4 montent, la
   3 descend, les 1 et 5 tiennent la ligne. */
.tst__i:nth-child(5n + 2) { transform: translateY(-5px); }
.tst__i:nth-child(5n + 3) { transform: translateY(4px); }
.tst__i:nth-child(5n + 4) { transform: translateY(-3px); }

/* Portrait un cran plus substantiel que l'ancienne pastille, sans devenir
   un portrait. */
.tst__av {
  width: clamp(34px, 2.6vw, 38px);
  height: clamp(34px, 2.6vw, 38px);
  margin-top: 0.08rem;
}

/* Le nom devient scannable : capitales, plus dense, couleur remontee d'un
   cran par rapport au gris de fond de l'ancien bandeau. */
.tst__name {
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ash);
  white-space: normal;
}

.tst__body { max-width: none; min-width: 0; }

.tst__quote {
  margin: 0.2rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.38;
  text-wrap: pretty;
}

/* Plus de piste a mettre en pause : le survol ne garde que le gain de
   contraste sur la vignette visee. */
@media (hover: hover) and (pointer: fine) {
  .tst__i:hover .tst__name { color: var(--bone); }
}

/* Mouvement reduit : il n'y a plus de mouvement. Les regles de secours de la
   §3 (defilement manuel, masque de droite, doublons masques) n'ont plus
   d'objet et sont annulees ici. */
@media (prefers-reduced-motion: reduce) {
  .tst__track { animation: none; width: auto; }
  .tst__viewport {
    overflow-x: visible;
    -webkit-mask-image: none;
            mask-image: none;
  }
}

/* -------------------------------------------------------------------- tablette */
@media (max-width: 1080px) {
  .tst__track { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .tst__i:nth-child(5n + 2),
  .tst__i:nth-child(5n + 3),
  .tst__i:nth-child(5n + 4) { transform: none; }
}

@media (max-width: 780px) {
  .tst__track { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------------------------------------------------------------------- mobile */
@media (max-width: 560px) {
  .tst__track { grid-template-columns: minmax(0, 1fr); row-gap: 0.55rem; }
  .tst__quote { font-size: 0.8125rem; }
  .tst__av { width: 34px; height: 34px; }
}


/* La bande etait calee sur une SEULE rangee. Deux rangees ne peuvent pas
   tenir dans la meme hauteur ; le padding est donc ramene au minimum
   lisible pour limiter l'ecart. Mesure et arbitrage : MISSING-CONTENT §0.19. */
.tst { padding-block: clamp(0.7rem, 1.2vw, 0.95rem); }

/* =============================================================================
   v98 — LA MATRICE DE LIVRABLES REMPLACE LES TROIS CARTES

   Brief du 26/08 : « une seule grille de livrables, identique pour les trois
   offres, et on montre visuellement ce qui est inclus ou non ». Trois regles
   de forme en decoulent, et elles expliquent tout ce qui suit.

   1. PAS DE VERT NI DE ROUGE. Demande explicite : « pas necessairement des
      gros coches verts et croix rouges partout ». L'inclus est en os (--bone),
      le non-inclus est un tiret en --ash-dim. La couleur ne porte donc aucune
      information : un daltonien lit la meme chose, et les lecteurs d'ecran
      lisent « Included » / « Not included » en sr-only.

   2. UNE SEULE COLONNE MISE EN AVANT. Launch garde son liseré or et son
      bandeau « Most chosen », comme la carte du milieu en v97. C'est le seul
      accent de couleur de la matrice.

   3. LE BLANC PLEIN RESTE RESERVE AU PARCOURS DE COMMANDE (regle v66). Les
      trois CTA de colonne mènent au paiement : Launch en or plein, les deux
      autres en contour. Rien d'autre dans la matrice n'est plein.

   Les anciennes regles .rrp__card / .rrp__grid / .rrp__val / .rrp__acc restent
   dans la feuille : elles ne sont plus referencees par la home, mais
   release.html et le mode x3 s'en servent encore. Les retirer est un nettoyage
   a faire en une passe dediee.
   ============================================================================= */

.rrpm {
  --rrpm-line: rgba(242, 240, 235, 0.10);
  --rrpm-line-2: rgba(242, 240, 235, 0.20);
  --rrpm-star: rgba(232, 197, 71, 0.45);
  margin-top: clamp(2rem, 4vw, 3.25rem);
}

/* Le selecteur de formule n'existe que sous 720px (voir plus bas). */
.rrpm__pick { display: none; }

.rrpm__t {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  text-align: left;
}

/* ------------------------------------------------------------- en-tetes
   `position: sticky` sur les <th> et non sur <thead> : Safari ne rend pas
   un thead colle, alors qu'il rend des cellules collees.

   `top: 5.5rem` et non `var(--rbar-h)` : --rbar-h est la hauteur de la barre
   de commande BASSE de release.html, pas celle de l'en-tete. L'en-tete du
   site est en position: fixed en haut, et 5.5rem est deja la valeur utilisee
   par .builder__summary pour se caler dessous. Une seule convention. */
.rrpm__corner,
.rrpm__h {
  position: sticky;
  top: 5.5rem;
  z-index: 3;
  background: var(--void);
  vertical-align: bottom;
  padding: 0 0 clamp(0.9rem, 1.6vw, 1.25rem);
}
.rrpm__corner { width: 34%; }
.rrpm__h { width: 22%; }

.rrpm__hd {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.35rem;
  height: 100%;
  padding: clamp(1.1rem, 2vw, 1.6rem) clamp(0.9rem, 1.4vw, 1.25rem) clamp(1rem, 1.6vw, 1.25rem);
  border: 1px solid var(--rrpm-line);
  border-radius: var(--radius-m) var(--radius-m) 0 0;
  border-bottom: 0;
  background: var(--surface);
}
.rrpm__h--star .rrpm__hd {
  border-color: var(--rrpm-star);
  background: linear-gradient(180deg, rgba(232, 197, 71, 0.10), rgba(232, 197, 71, 0.02) 60%, transparent), var(--surface);
}

.rrpm__flag {
  position: absolute;
  top: 0; left: clamp(0.9rem, 1.4vw, 1.25rem);
  transform: translateY(-50%);
  font-family: var(--caps);
  font-size: 0.5625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--void);
  background: #E8C547;
  border-radius: 999px;
  padding: 0.26rem 0.7rem;
  white-space: nowrap;
}

.rrpm__name {
  font-family: var(--display);
  font-size: clamp(1.05rem, 1.6vw, 1.35rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--bone);
}
.rrpm__sub {
  font-family: var(--caps);
  font-size: 0.625rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ash-dim);
}
/* Le benefice avant le prix : c'est l'ordre demande — le client comprend
   d'abord POURQUOI il choisirait cette formule, puis combien elle coute. */
.rrpm__ben {
  margin-top: 0.15rem;
  font-size: 0.875rem;
  line-height: 1.4;
  color: var(--ash);
  min-height: 2.8em;
  text-wrap: balance;
}
.rrpm__price {
  margin-top: 0.35rem;
  font-family: var(--display);
  font-size: clamp(1.6rem, 2.6vw, 2.25rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1;
  color: var(--bone);
  font-variant-numeric: tabular-nums;
}

.rrpm__cta {
  width: 100%;
  margin-top: 0.75rem;
  border: 1px solid var(--rrpm-line-2);
  border-radius: 999px;
  background: transparent;
  color: var(--bone);
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.875rem;
  padding: 0.75rem 1rem;
  cursor: pointer;
  transition: background 0.3s var(--ease), border-color 0.3s var(--ease), color 0.3s var(--ease);
}
.rrpm__cta:hover { border-color: var(--bone); background: rgba(242, 240, 235, 0.06); }
.rrpm__h--star .rrpm__cta { border-color: transparent; background: #E8C547; color: var(--void); }
.rrpm__h--star .rrpm__cta:hover { background: #F2D56D; }
.rrpm__cta:focus-visible { outline: 2px solid var(--bone); outline-offset: 3px; }
.rrpm__cta.is-busy { opacity: 0.6; pointer-events: none; }

/* ------------------------------------------------------------- rangees */
.rrpm__g th {
  padding: clamp(1.6rem, 2.6vw, 2.25rem) 0 0.6rem;
  font-family: var(--caps);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--signal);
  border-bottom: 1px solid var(--rrpm-line-2);
}

.rrpm__r > * {
  padding: clamp(0.7rem, 1.1vw, 0.95rem) 0;
  border-bottom: 1px solid var(--rrpm-line);
  vertical-align: top;
}
.rrpm__r:hover > * { background: rgba(242, 240, 235, 0.025); }

.rrpm__rl { padding-right: 1.5rem; font-weight: 400; }
.rrpm__rt {
  display: block;
  font-family: var(--display);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--bone);
  line-height: 1.3;
}
.rrpm__rd {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--ash-dim);
}

/* Les cellules des colonnes gardent le fond de leur colonne pour que le
   liseré de Launch descende sur toute la hauteur du tableau. */
.rrpm__c {
  text-align: center;
  border-left: 1px solid transparent;
  border-right: 1px solid transparent;
}
.rrpm__c--launch { border-left-color: var(--rrpm-star); border-right-color: var(--rrpm-star); background: rgba(232, 197, 71, 0.03); }
.rrpm__r:last-child .rrpm__c--launch { border-bottom-color: var(--rrpm-star); }

.rrpm__tick {
  display: inline-block;
  font-size: 1.05rem;
  line-height: 1;
  color: var(--bone);
}
.rrpm__q {
  display: inline-block;
  font-family: var(--display);
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--bone);
  font-variant-numeric: tabular-nums;
}
/* Non inclus : attenue, jamais barre en rouge. Le tiret suffit, et la ligne
   entiere s'attenue pour que le trou se lise d'un coup d'oeil vertical. */
.rrpm__dash {
  display: inline-block;
  font-size: 1rem;
  line-height: 1;
  color: var(--ash-dim);
  opacity: 0.65;
}
.rrpm__up {
  font-family: var(--display);
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--signal);
  white-space: nowrap;
}

/* ------------------------------------------------- pied commun a la matrice */
.rrpm__guarantee {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin: clamp(1.5rem, 2.6vw, 2.25rem) 0 0;
  font-size: 0.8125rem;
  color: var(--ash);
  text-align: center;
}
.rrpm__scarce {
  margin: 0.45rem 0 0;
  font-size: 0.8125rem;
  color: var(--ash-dim);
  text-align: center;
}
.rrpm__plat {
  margin: 1rem auto 0;
  max-width: 62ch;
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--ash-dim);
  text-align: center;
}
.rrpm__plat-k {
  font-family: var(--caps);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash);
  margin-right: 0.5rem;
}

/* ------------------------------------------------------- plans de campagne */
.rrpm__cals {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 1.8vw, 1.75rem);
  margin-top: clamp(2.5rem, 4.5vw, 3.75rem);
}
.rrpm__cal {
  border: 1px solid var(--rrpm-line);
  border-radius: var(--radius-m);
  padding: clamp(1.1rem, 1.8vw, 1.5rem);
  background: var(--surface);
}

/* ================================================================= tablette */
@media (max-width: 1040px) {
  .rrpm__corner { width: 30%; }
  .rrpm__ben { font-size: 0.8125rem; min-height: 3.6em; }
  .rrpm__cta { font-size: 0.8125rem; padding: 0.65rem 0.75rem; }
}

/* =================================================================== mobile
   Sous 720px, trois colonnes de comparaison ne tiennent pas : les libelles
   passent sur quatre lignes et la coche se retrouve a 40px de son intitule.
   On affiche donc UNE formule a la fois, choisie par [data-rrpm-pick]. Le
   tableau reste entier dans le DOM — rien n'est retire pour les lecteurs
   d'ecran ni pour les moteurs, les colonnes inactives sont seulement
   masquees. */
@media (max-width: 720px) {
  .rrpm__pick {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.4rem;
    margin-bottom: 1.25rem;
  }
  .rrpm__pbtn {
    border: 1px solid var(--rrpm-line-2);
    border-radius: 999px;
    background: transparent;
    color: var(--ash);
    font-family: var(--display);
    font-weight: 600;
    font-size: 0.8125rem;
    padding: 0.6rem 0.5rem;
    cursor: pointer;
  }
  .rrpm__pbtn.is-on { color: var(--void); background: var(--bone); border-color: var(--bone); }

  .rrpm__corner { width: 62%; }
  .rrpm__h { width: 38%; }

  .rrpm[data-pack="release"]  .rrpm__c--launch,
  .rrpm[data-pack="release"]  .rrpm__c--complete,
  .rrpm[data-pack="launch"]   .rrpm__c--release,
  .rrpm[data-pack="launch"]   .rrpm__c--complete,
  .rrpm[data-pack="complete"] .rrpm__c--release,
  .rrpm[data-pack="complete"] .rrpm__c--launch { display: none; }

  /* En une colonne, un en-tete colle de ~200px mangerait le quart de
     l'ecran : le collant est desactive. Les boutons de selection, eux,
     restent visibles au-dessus du tableau. */
  .rrpm__corner, .rrpm__h { position: static; }

  .rrpm__c--launch { border-left: 0; border-right: 0; background: transparent; }
  .rrpm__flag { left: auto; right: clamp(0.9rem, 1.4vw, 1.25rem); }
  .rrpm__rt { font-size: 0.875rem; }
  .rrpm__rd { font-size: 0.75rem; }

  .rrpm__cals { grid-template-columns: minmax(0, 1fr); }
  .rrpm[data-pack="release"]  ~ .rrpm__cals .rrpm__cal:not(.rrpm__cal--release),
  .rrpm[data-pack="launch"]   ~ .rrpm__cals .rrpm__cal:not(.rrpm__cal--launch),
  .rrpm[data-pack="complete"] ~ .rrpm__cals .rrpm__cal:not(.rrpm__cal--complete) { display: none; }
}

/* =============================================================================
   v98 — GARANTIE ET AIDE AU CHOIX SUR LA MEME RANGEE, PREUVE CENTREE

   Trois demandes du brief Word, dans l'ordre ou elles y sont ecrites. Aucun
   texte n'est modifie : seules la position et l'alignement changent.
   ============================================================================= */
.rrp__two {
  margin-top: clamp(3rem, 6vw, 5rem);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: start;
}

/* Le bloc garantie perd son centrage : il devient une colonne de gauche.
   `margin-inline: 0` sur le titre et le paragraphe est necessaire — ils
   etaient centres par `margin: ... auto`, pas par text-align seul. */
.rrp__gtee--left { margin-top: 0; text-align: left; }
.rrp__gtee--left .rrp__gtee-btn { margin-inline: 0; }
.rrp__gtee--left .rrp__gtee-t { margin-left: 0; margin-right: 0; max-width: 20ch; }
.rrp__gtee--left .rrp__gtee-p { margin-left: 0; margin-right: 0; max-width: 46ch; }
.rrp__gtee--left .rrp__gtee-t,
.rrp__gtee--left .rrp__gtee-p { text-wrap: pretty; }

/* Le bouton passe AVANT le titre dans le flux : dans une demi-colonne, il
   prendrait tout l'espace visuel s'il gardait sa taille de v94. */
.rrp__gtee--left .rrp__gtee-btn {
  padding: clamp(0.7rem, 1.3vw, 0.9rem) clamp(1.35rem, 2.2vw, 1.9rem);
  font-size: clamp(0.95rem, 1.4vw, 1.0625rem);
}

/* L'aide au choix reprend la largeur de sa colonne, comme en v96. */
.rrp__two .rrp__guide { margin: 0; max-width: none; }

/* Le telephone et son titre : centres sur la largeur de page. Ils n'ont plus
   de colonne — c'est ce que demande le brief (« au centre de la page, donc
   decale le legerement sur la gauche »). */
.rrp__proof-col--center {
  margin: clamp(3rem, 6vw, 5rem) auto 0;
  max-width: 640px;
}

@media (max-width: 1040px) {
  .rrp__two { grid-template-columns: minmax(0, 1fr); gap: clamp(2.5rem, 6vw, 3.5rem); }
  .rrp__two .rrp__guide { max-width: var(--container-narrow); }
}

.rrpm__q { white-space: nowrap; }

/* =============================================================================
   v99 — CHECKOUT READY RELEASE

   Une page de tunnel, pas une page de site : en-tete nu, pas de navigation,
   deux colonnes sur desktop (contenu / recapitulatif colle), une seule
   colonne en dessous de 900px.

   Le blanc plein reste reserve au parcours de commande (regle v66) : ici,
   c'est le bouton de paiement qui le porte, et lui seul.
   ============================================================================= */

.cko-body { background: var(--void); color: var(--bone); }

.cko-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem var(--gutter);
  border-bottom: 1px solid var(--line);
}
.cko-head__secure {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-family: var(--caps);
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash);
}
/* Le cadenas est dessine en CSS : pas de police d'icones a charger pour
   deux glyphes, et il suit la couleur du texte. */
.cko-lock {
  width: 11px; height: 13px;
  flex: none;
  border: 1.5px solid currentColor;
  border-radius: 2px;
  position: relative;
}
.cko-lock::before {
  content: '';
  position: absolute;
  left: 50%; top: -6px;
  transform: translateX(-50%);
  width: 7px; height: 7px;
  border: 1.5px solid currentColor;
  border-bottom: 0;
  border-radius: 4px 4px 0 0;
}

.cko {
  max-width: var(--container);
  margin-inline: auto;
  padding: clamp(2rem, 5vw, 3.5rem) var(--gutter) clamp(3rem, 6vw, 5rem);
}
.cko-noscript {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-m);
  padding: 1.25rem;
  background: var(--surface);
}

.cko__hero { text-align: center; margin-bottom: clamp(2rem, 4vw, 3rem); }
.cko__h1 {
  font-family: var(--display);
  font-size: clamp(1.9rem, 4vw, 3rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.05;
  margin: 0;
  text-wrap: balance;
}
.cko__sub {
  margin: 0.75rem auto 0;
  max-width: 52ch;
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--ash);
}

/* ------------------------------------------------------------ progression */
.cko-prog {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(0.75rem, 2vw, 2rem);
  list-style: none;
  margin: clamp(1.5rem, 3vw, 2.25rem) 0 0;
  padding: 0;
}
.cko-prog__i {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.8125rem;
  color: var(--ash-dim);
}
.cko-prog__n {
  display: grid;
  place-items: center;
  width: 26px; height: 26px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 700;
}
.cko-prog__i.is-on { color: var(--bone); }
.cko-prog__i.is-on .cko-prog__n {
  border-color: transparent;
  background: var(--signal);
  color: var(--void);
}

/* ---------------------------------------------------------------- colonnes */
.cko__cols {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 3vw, 2.75rem);
  align-items: start;
}
.cko__main { display: grid; gap: clamp(1rem, 2vw, 1.5rem); }

.cko-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  background: var(--surface);
  padding: clamp(1.25rem, 2.4vw, 2rem);
}
.cko-card--up {
  border-color: rgba(232, 197, 71, 0.35);
  background: linear-gradient(180deg, rgba(232, 197, 71, 0.07), rgba(232, 197, 71, 0.01) 60%, transparent), var(--surface);
}
.cko-card__t {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 0;
  font-family: var(--display);
  font-size: clamp(1.05rem, 1.8vw, 1.3rem);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.cko-card__n {
  display: grid;
  place-items: center;
  flex: none;
  width: 26px; height: 26px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  font-size: 0.75rem;
  color: var(--ash);
}
.cko-card__st {
  margin: 1.25rem 0 0;
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 700;
}
.cko-card__p {
  margin: 0.6rem 0 0;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ash);
}
.cko-card__p--dim { color: var(--ash-dim); font-size: 0.875rem; }

/* --------------------------------------------------------------- upload */
.cko-drop {
  display: grid;
  justify-items: center;
  gap: 0.3rem;
  margin-top: 1.1rem;
  padding: clamp(1.75rem, 4vw, 2.75rem) 1rem;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-m);
  background: rgba(242, 240, 235, 0.02);
  cursor: pointer;
  text-align: center;
  transition: border-color 0.25s var(--ease), background 0.25s var(--ease);
}
.cko-drop:hover, .cko-drop.is-over, .cko-drop:focus-visible {
  border-color: var(--signal);
  background: rgba(232, 197, 71, 0.05);
  outline: none;
}
.cko-drop--sm { padding: clamp(1.25rem, 3vw, 1.75rem) 1rem; }
.cko-drop__t { font-family: var(--display); font-weight: 700; font-size: 1rem; }
.cko-drop__s { font-size: 0.875rem; color: var(--ash); }
.cko-drop__f {
  margin-top: 0.35rem;
  font-family: var(--caps);
  font-size: 0.625rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ash-dim);
}

.cko-prog-bar {
  margin-top: 0.9rem;
  height: 4px;
  border-radius: 999px;
  background: rgba(242, 240, 235, 0.08);
  overflow: hidden;
}
.cko-prog-bar__fill {
  height: 100%;
  width: 0;
  background: var(--signal);
  transition: width 0.2s linear;
}

.cko-state {
  margin: 0.7rem 0 0;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--ash);
  min-height: 1.3em;
}
.cko-state--ok { color: var(--bone); }
.cko-state--err { color: #E5766B; }

.cko-note {
  margin: 0.55rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ash-dim);
}
.cko-note--c {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  text-align: center;
}
.cko-link { color: var(--signal); text-decoration: underline; }
.cko-link:hover { text-decoration-thickness: 2px; }

/* ---------------------------------------------------------------- champs */
.cko-fields {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.9rem;
  margin-top: 1.1rem;
}
.cko-f { display: grid; gap: 0.35rem; }
.cko-f--wide { grid-column: 1 / -1; }
.cko-f__l {
  font-family: var(--caps);
  font-size: 0.625rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ash);
}
.cko-f__opt { color: var(--ash-dim); letter-spacing: 0.08em; }
.cko-f__i {
  width: 100%;
  padding: 0.8rem 0.9rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-s);
  background: var(--void-2);
  color: var(--bone);
  font-family: var(--body);
  font-size: 0.9375rem;
}
.cko-f__i::placeholder { color: var(--ash-dim); }
.cko-f__i:focus { outline: none; border-color: var(--signal); }

/* ---------------------------------------------------------------- upsell */
.cko-up__picks {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.6rem;
  margin: 1.1rem 0;
}
.cko-up__pick {
  display: grid;
  gap: 0.2rem;
  padding: 0.9rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-m);
  background: transparent;
  color: var(--bone);
  text-align: left;
  cursor: pointer;
}
.cko-up__pick:hover { border-color: var(--bone); }
.cko-up__pick.is-on { border-color: var(--signal); background: rgba(232, 197, 71, 0.07); }
.cko-up__pn { font-family: var(--display); font-weight: 700; }
.cko-up__pc { font-size: 0.75rem; color: var(--ash-dim); }
.cko-up__pp { font-size: 0.875rem; margin-top: 0.25rem; }
.cko-up__pp s { color: var(--ash-dim); margin-right: 0.3rem; }
.cko-up__pp b { color: var(--signal); }

.cko-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 1.1rem;
  padding: 0.9rem 1.5rem;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--bone);
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.9375rem;
  cursor: pointer;
  transition: background 0.25s var(--ease), border-color 0.25s var(--ease);
}
.cko-btn--ghost:hover { border-color: var(--bone); background: rgba(242, 240, 235, 0.06); }
.cko-btn--pay {
  width: 100%;
  border-color: transparent;
  background: var(--bone);
  color: var(--void);
  font-size: 1rem;
  padding: 1.05rem 1.5rem;
}
.cko-btn--pay:hover:not(:disabled) { background: #FFFFFF; }
.cko-btn--pay:disabled { opacity: 0.45; cursor: not-allowed; }
.cko-btn:focus-visible { outline: 2px solid var(--signal); outline-offset: 3px; }

.cko-textlink {
  display: block;
  margin-top: 0.8rem;
  border: 0;
  background: none;
  padding: 0;
  color: var(--ash);
  font-family: var(--body);
  font-size: 0.875rem;
  text-decoration: underline;
  cursor: pointer;
}
.cko-textlink:hover { color: var(--bone); }

.cko-gate {
  margin: 1rem 0 0;
  font-size: 0.875rem;
  color: var(--ash-dim);
}
.cko-stripe { margin-top: 1.25rem; }

/* -------------------------------------------------------- recapitulatif */
.cko__side { display: grid; gap: 1rem; position: sticky; top: 5.5rem; }
.cko-sum {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-m);
  background: var(--surface);
  padding: clamp(1.25rem, 2.2vw, 1.6rem);
}
.cko-sum__t {
  margin: 0 0 1rem;
  font-family: var(--caps);
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash);
}
.cko-sum__line {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.15rem 0.75rem;
  padding-bottom: 0.9rem;
  margin-bottom: 0.9rem;
  border-bottom: 1px solid var(--line);
}
.cko-sum__n { font-family: var(--display); font-weight: 700; font-size: 1rem; }
.cko-sum__c { grid-column: 1; font-size: 0.8125rem; color: var(--ash-dim); }
.cko-sum__p {
  grid-column: 2; grid-row: 1;
  font-family: var(--display);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.cko-sum__rm {
  grid-column: 2;
  justify-self: end;
  border: 0; background: none; padding: 0;
  color: var(--ash);
  font-size: 0.75rem;
  text-decoration: underline;
  cursor: pointer;
}
.cko-sum__rm:hover { color: var(--bone); }
.cko-sum__rows { display: grid; gap: 0.4rem; }
.cko-sum__row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin: 0;
  font-size: 0.875rem;
  color: var(--ash);
}
.cko-sum__row--total {
  margin-top: 0.4rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--line);
  font-family: var(--display);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--bone);
  font-variant-numeric: tabular-nums;
}
.cko-sum__desc { margin: 1rem 0 0; font-size: 0.8125rem; color: var(--ash-dim); }

.cko-inc { margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--line); }
.cko-inc__h {
  margin: 0 0 0.6rem;
  font-family: var(--caps);
  font-size: 0.625rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ash);
}
.cko-inc__l { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4rem; }
.cko-inc__l li {
  position: relative;
  padding-left: 1.2rem;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--ash);
}
.cko-inc__l li::before {
  content: '\2713';
  position: absolute;
  left: 0;
  color: var(--bone);
}
.cko-inc__more { margin: 0.8rem 0 0; font-size: 0.75rem; }

.cko-why, .cko-next {
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  padding: clamp(1.1rem, 2vw, 1.4rem);
}
.cko-why__t {
  margin: 0 0 0.8rem;
  font-family: var(--display);
  font-size: 0.9375rem;
  font-weight: 700;
}
.cko-why__l, .cko-next__l {
  margin: 0; padding: 0;
  display: grid;
  gap: 0.75rem;
  list-style: none;
  counter-reset: ckon;
}
.cko-why__l li, .cko-next__l li { display: grid; gap: 0.15rem; }
.cko-why__l b, .cko-next__l b { font-size: 0.875rem; }
.cko-why__l span, .cko-next__l span { font-size: 0.8125rem; line-height: 1.45; color: var(--ash-dim); }
.cko-next__l li { counter-increment: ckon; padding-left: 1.6rem; position: relative; }
.cko-next__l li::before {
  content: counter(ckon);
  position: absolute;
  left: 0; top: 0.05rem;
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--signal);
}

/* --------------------------------------------------------- confirmation */
.cko__wrap--done { max-width: 620px; margin-inline: auto; }
.cko-done { text-align: center; }
.cko-done__k {
  margin: 0 0 0.75rem;
  font-family: var(--caps);
  font-size: 0.625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--signal);
}
.cko-sum--done { margin: clamp(1.75rem, 3vw, 2.5rem) 0; text-align: left; }
.cko__wrap--done .cko-why__t { margin-top: 2rem; text-align: left; }
.cko__wrap--done .cko-next__l { text-align: left; }
.cko-done__cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  margin-top: 2rem;
}

.cko-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 1.5rem var(--gutter);
  border-top: 1px solid var(--line);
  font-size: 0.8125rem;
  color: var(--ash-dim);
}
.cko-foot p { margin: 0; display: flex; gap: 1rem; }

/* =================================================================== mobile
   Ordre impose par le brief §39 : progression, pack, upload, informations,
   upsell, recapitulatif, paiement. Le recapitulatif passe donc APRES le
   contenu et cesse d'etre colle — un bloc colle sur un ecran de 640px de
   haut mangerait la moitie du formulaire. */
@media (max-width: 900px) {
  .cko__cols { grid-template-columns: minmax(0, 1fr); }
  .cko__side { position: static; }
  .cko-fields { grid-template-columns: minmax(0, 1fr); }
  .cko-up__picks { grid-template-columns: minmax(0, 1fr); }
  .cko-prog { gap: 0.6rem; }
  .cko-prog__l { display: none; }
  .cko-prog__i.is-on .cko-prog__l { display: inline; }
}

/* =======================================================================
   v100 — « million-dollar » : la couleur monte dans les lettres
   =======================================================================

   Brief du 27/08, MINUTAGE REVU (todo) : le mot reste BLANC pendant la
   premiere seconde. A 1 s la couleur part du bas et remonte dans les
   lettres ; le mot est totalement jaune a 3,5 s. Ensuite plus rien ne
   bouge. Le jaune reste #E8C547, le token --signal.

   Decoupage : montee de 1 s a 2 s, achevement de 2 s a 3,5 s. La forme des
   deux calques est celle de la v100 ; seuls les retards changent.

   LE MOT N'EXISTE QU'UNE FOIS DANS LE DOCUMENT.
   La premiere version de ce bloc empilait trois <span> portant le meme
   texte. Le rendu etait juste, mais `innerText` retournait le mot QUATRE
   fois : un copier-coller du titre collait « million-dollar
   million-dollar million-dollar million-dollar », et le texte rendu de la
   page d'accueil repetait le mot. Les deux calques colores sont donc des
   PSEUDO-ELEMENTS, remplis par `content: attr(data-word)`. Un
   pseudo-element n'est pas un noeud du document : il n'est ni selectionne,
   ni copie, ni lu deux fois, et aucun aria-hidden n'est necessaire.

   POURQUOI DEUX CALQUES ET NON UN
   Le masque a un bord FLOU — c'est ce qui fait MONTER la couleur au lieu
   de la devoiler sous une regle horizontale. Consequence : quand le masque
   arrive en haut, a 2 s, le sommet des lettres n'est encore qu'a moitie
   jaune. Un seul calque ne pourrait donc etre « totalement jaune » a 3,5 s
   qu'en repartant vers le bas, ce qui ramenerait le blanc. Le second
   calque acheve la couleur entre 2 s et 3,5 s. C'est le decoupage du brief.

   SI mask-image N'EST PAS SUPPORTE, la propriete est ignoree et le calque
   jaune s'affiche entier : le mot est jaune tout de suite. Le mot n'est
   jamais invisible, quoi qu'il arrive. */

.mdg {
  position: relative;
  display: inline-block;
  /* Le texte reel reste ici, en blanc, et c'est lui qui occupe la place :
     si un calque anime portait la mise en page, une police de repli
     chargee en retard decalerait la ligne entiere du hero. */
}

.mdg::before,
.mdg::after {
  content: attr(data-word);
  position: absolute;
  inset: 0;
  color: var(--signal);
  pointer-events: none;
  white-space: pre;
}

/* ---- calque 1 : la montee (1 s -> 2 s) -------------------------------
   Le masque fait DEUX fois la hauteur du mot. En position haute, le mot
   est couvert par la moitie transparente ; en position basse, par la
   moitie opaque. Deplacer la position de 0 % a 100 % fait donc balayer la
   frontiere douce vers le haut. */

.mdg::before {
  -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 46%, #000 64%, #000 100%);
          mask-image: linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 46%, #000 64%, #000 100%);
  -webkit-mask-size: 100% 200%;
          mask-size: 100% 200%;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: 0% 0%;
          mask-position: 0% 0%;
  animation: mdg-rise 1s cubic-bezier(0.33, 0, 0.2, 1) 1s 1 forwards;
}

@keyframes mdg-rise {
  from { -webkit-mask-position: 0% 0%;   mask-position: 0% 0%; }
  to   { -webkit-mask-position: 0% 100%; mask-position: 0% 100%; }
}

/* ---- calque 2 : la couleur s'acheve (2 s -> 3,5 s) -------------------- */

.mdg::after {
  opacity: 0;
  animation: mdg-settle 1.5s linear 2s 1 forwards;
}

@keyframes mdg-settle {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Mouvement reduit : le resultat, sans le trajet. Le brief demande une
   couleur, pas une animation ; la couleur est donc posee d'emblee. */
@media (prefers-reduced-motion: reduce) {
  .mdg::before { animation: none; -webkit-mask-image: none; mask-image: none; }
  .mdg::after  { animation: none; opacity: 1; }
}

/* =======================================================================
   v100 — CHECKOUT : PHOTOS & PROJECT BRIEF
   =======================================================================

   Brief du 27/08 §30 : « le nouveau bloc doit etre indistinguable du reste
   du checkout ». Aucune valeur nouvelle n'est introduite ici — ni couleur,
   ni rayon, ni graisse, ni espacement. Tout vient des tokens que les
   cards existantes utilisent deja : --surface, --line, --line-strong,
   --signal, --ash, --ash-dim, --radius-m, --radius-s, --void-2.

   La zone de depot des photos REUTILISE .cko-drop, celle de l'audio, avec
   un seul modificateur de hauteur. Deux zones de depot cote a cote qui ne
   se ressemblent pas se lisent comme deux fonctionnalites differentes. */

.cko-drop--photo { padding: clamp(1.5rem, 3.2vw, 2.25rem) 1rem; }

/* ---- la grille de vignettes ---- */

.cko-photos {
  display: grid;
  /* auto-fill et non auto-fit : avec trois images, les vignettes gardent
     leur taille au lieu de s'etirer sur toute la largeur. */
  grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
  gap: 0.6rem;
  margin: 0.9rem 0 0;
  padding: 0;
  list-style: none;
}

.cko-ph {
  position: relative;
  display: grid;
  gap: 0.4rem;
  padding: 0.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  background: var(--void-2);
  min-width: 0;
}
.cko-ph.is-err { border-color: #E5766B; }
.cko-ph.is-up { opacity: 0.72; }

.cko-ph__img {
  display: block;
  aspect-ratio: 1 / 1;
  border-radius: 2px;
  overflow: hidden;
  background: rgba(242, 240, 235, 0.04);
}
.cko-ph__img img { width: 100%; height: 100%; object-fit: cover; }

.cko-ph__meta { display: grid; gap: 0.1rem; min-width: 0; }
.cko-ph__n {
  font-size: 0.6875rem;
  font-weight: 600;
  /* Un nom de fichier long ne doit pas elargir sa colonne : la grille
     entiere se decalerait. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cko-ph__s { font-size: 0.625rem; color: var(--ash-dim); }
.cko-ph.is-err .cko-ph__s { color: #E5766B; white-space: normal; }

.cko-ph__retry {
  justify-self: start;
  padding: 0.2rem 0.45rem;
  border: 1px solid var(--line-strong);
  border-radius: 2px;
  font-size: 0.625rem;
  color: var(--bone);
}
.cko-ph__retry:hover { border-color: var(--signal); color: var(--signal); }

.cko-ph__x {
  position: absolute;
  top: 0.35rem; right: 0.35rem;
  display: grid;
  place-items: center;
  /* 26 px : la meme cible que .cko-card__n, et au-dessus du minimum
     confortable au doigt une fois la marge de la vignette comptee. */
  width: 26px; height: 26px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: var(--void);
  color: var(--bone);
  font-size: 0.875rem;
  line-height: 1;
}
.cko-ph__x:hover { border-color: #E5766B; color: #E5766B; }
.cko-ph__x:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

/* ---- champs longs du brief ---- */

.cko-f__i--area {
  min-height: 5.5rem;
  line-height: 1.55;
  resize: vertical;
}
.cko-f__i--sel {
  /* Le select herite de .cko-f__i ; seule la fleche native doit etre
     remplacee, sinon elle reste claire sur fond sombre sous Windows. */
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.2rem;
  /* Un chevron SVG plutot que deux triangles en degrades : les degrades
     produisaient deux petits carres mal joints, lisibles comme un defaut
     de rendu sur une page de paiement. La couleur est ecrite en dur dans
     le data-URI — une URL ne lit pas var(). C'est #8A8F98, la valeur de
     --ash ; les deux doivent bouger ensemble. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238A8F98' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-position: calc(100% - 0.9rem) center;
  background-size: 10px 6px;
  background-repeat: no-repeat;
}
.cko-f__i--sel option { background: var(--void-2); color: var(--bone); }

/* ---- les deux cases a cocher ---- */

.cko-check {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.6rem;
  align-items: start;
  margin-top: 1.1rem;
  padding: 0.8rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  background: var(--void-2);
  cursor: pointer;
}
.cko-check--legal { margin-bottom: 1.1rem; }

.cko-check__i {
  /* accent-color evite de redessiner la case : la coche native reste, avec
     son comportement clavier et son rendu de focus par le systeme. */
  accent-color: var(--signal);
  width: 16px; height: 16px;
  margin: 0.15rem 0 0;
  flex: none;
  cursor: pointer;
}
.cko-check__l {
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ash);
}
.cko-check:hover { border-color: var(--line-strong); }
.cko-check:focus-within { border-color: var(--signal); }

/* ---- mobile ---- */

@media (max-width: 640px) {
  /* Trois colonnes de vignettes tiennent sur un telephone ; en dessous de
     96 px le nom du fichier n'est plus lisible du tout. */
  .cko-photos { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
  .cko-f__i--area { min-height: 6.5rem; }
}

/* =======================================================================
   v103 — BANDEAU DE PRESSE « AS FEATURED IN »
   =======================================================================

   Consigne du todo : « inserer de maniere centrale (pas trop vertical) »,
   « parfaitement implante, lisible, mais pas ostentatoire », « s'integrer
   parfaitement au reste, etre sobre mais lisible ».

   Les quatre contraintes se traduisent en quatre decisions, pas en gout :

   1. CENTRAL, PAS VERTICAL. Une seule rangee, centree, hauteur totale
      contenue sous 5rem au plus large. Aucun logo ne descend a la ligne
      avant 780px.
   2. SOBRE. Aucune valeur nouvelle : --ash-dim pour le surtitre, --line
      pour les filets, --fs-micro pour le corps. Les logos sont blancs a
      0,74 d'opacite — lisibles sur #0A0B0D, jamais plus lumineux que le
      titre qu'ils accompagnent.
   3. PROPORTIONS D'ORIGINE CONSERVEES. Les six logos sont decoupes de la
      planche fournie, ou ils etaient deja mis au meme poids optique les uns
      par rapport aux autres. Les redimensionner tous a HAUTEUR egale
      casserait ce reglage : AP, dont les capitales sont larges et courtes,
      paraitrait 15 % plus gros que MarketWatch. C'est donc la LARGEUR
      native qui est multipliee par un facteur commun, --press-k. Le rapport
      entre les six est exactement celui de la planche.
   4. PAS DE LIEN. Les logos ne sont pas cliquables : aucun article ne m'a
      ete fourni, et un logo cliquable qui ne mene nulle part est pire que
      pas de lien du tout. Le jour ou les URLs existent, envelopper chaque
      <img> dans un <a> suffit.
   ======================================================================= */

.press {
  /* Facteur d'echelle commun aux six logos. Une valeur SANS UNITE : une
     clamp() melangeant un nombre nu et une longueur (0.62vw) est invalide
     et la declaration entiere serait ignoree — les logos repartiraient
     alors a leur taille native, soit 243px de large pour Google News.
     L'echelle est donc pilotee par paliers, plus bas. */
  --press-k: 0.46;
  padding-block: clamp(1.5rem, 3vw, 2.25rem);
  border-top: 1px solid var(--line);
  text-align: center;
}
.press__eyebrow {
  color: var(--ash-dim);
  font-size: var(--fs-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin: 0;
}
.press__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(1.5rem, 3.4vw, 3.25rem);
  margin: clamp(0.9rem, 2vw, 1.35rem) 0 0;
  padding: 0;
  list-style: none;
}
.press__logo {
  display: block;
  height: auto;
  opacity: 0.74;
  transition: opacity 0.3s var(--ease);
}
.press__list:hover .press__logo { opacity: 0.5; }
.press__list li:hover .press__logo { opacity: 1; }

/* Largeur native x facteur commun — voir la decision 3 ci-dessus. */
.press__logo--marketwatch      { width: calc(124px * var(--press-k)); }
.press__logo--google-news      { width: calc(243px * var(--press-k)); }
.press__logo--usa-today        { width: calc(158px * var(--press-k)); }
.press__logo--yahoo-finance    { width: calc(160px * var(--press-k)); }
.press__logo--business-insider { width: calc(182px * var(--press-k)); }
.press__logo--ap               { width: calc(109px * var(--press-k)); }

/* Sous 780px la rangee se replie sur deux lignes plutot que de reduire les
   logos jusqu'a l'illisible. « Lisible » passe avant « une seule ligne ».

   v104 — mais elle se replie en GRILLE 3 x 2, pas en flex libre. En flex,
   la coupure tombait ou les largeurs le voulaient : quatre logos en haut,
   deux en bas, centres — une rangee basse a moitie vide, qui se lit comme
   un debordement et non comme une mise en page. Trois colonnes egales
   donnent deux rangees pleines et un axe vertical net. Les logos gardent
   leurs largeurs relatives (--press-k), ils sont seulement centres dans
   leur cellule : le reglage optique de la planche est preserve. */
@media (max-width: 780px) {
  .press { --press-k: 0.38; }
  .press__list {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    justify-items: center;
    align-items: center;
    gap: 1.25rem 1.25rem;
  }
}
@media (max-width: 420px) {
  .press { --press-k: 0.32; }
  .press__list { gap: 1rem 0.85rem; }
}

/* v104 — Le bandeau est passe a la fin du hero. Le bloc suivant (.coh)
   porte deja `border-block`, donc un filet haut : lui laisser un filet bas
   ferait deux traits de 1px separes de 1px. Le filet bas est supprime, le
   filet haut suffit a fermer le hero. */
.press--hero { border-bottom: 0; }

.press--cko {
  border-top: 0;
  padding-block: clamp(1.25rem, 2.5vw, 1.75rem);
}

@media (prefers-reduced-motion: reduce) {
  .press__logo { transition: none; }
}

/* =======================================================================
   v103 — BANNIERE DE CONSENTEMENT COOKIES (.cc)
   =======================================================================

   Elle n'existe dans le DOM que si assets/js/consent.v106.js la construit,
   c'est-a-dire uniquement si un identifiant Google Analytics est renseigne.
   Tant qu'il ne l'est pas, ces regles ne s'appliquent a rien.

   « Refuser » et « Accepter » ont la MEME taille, le meme rayon, le meme
   padding et un contraste comparable. Le bouton d'acceptation est rempli
   parce qu'il est l'action par defaut du parcours, pas parce que le refus
   doit couter plus cher a trouver — un refus rendu plus difficile qu'une
   acceptation n'est pas un consentement libre.
   ======================================================================= */

.cc {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 95;                       /* au-dessus de .rbar (90), sous rien */
  background: rgba(10, 11, 13, 0.94);
  -webkit-backdrop-filter: blur(14px);
          backdrop-filter: blur(14px);
  border-top: 1px solid var(--line-strong);
  transform: translateY(100%);
  transition: transform 0.35s var(--ease);
}
.cc.is-on { transform: translateY(0); }

.cc__in {
  max-width: var(--container);
  margin-inline: auto;
  padding: 1rem var(--gutter);
  display: flex;
  align-items: center;
  gap: 1.5rem;
}
.cc__txt {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--ash);
}
.cc__link { color: var(--signal); text-decoration: underline; }
.cc__acts { display: flex; gap: 0.6rem; margin-left: auto; flex-shrink: 0; }
.cc__btn {
  font: inherit;
  font-size: 0.875rem;
  font-weight: 600;
  padding: 0.6rem 1.15rem;
  border-radius: var(--radius-s);
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--bone);
  cursor: pointer;
  white-space: nowrap;
}
.cc__btn:hover { border-color: var(--bone); }
.cc__btn--yes {
  background: var(--signal-fill);
  border-color: var(--signal-fill);
  color: var(--void);
}
.cc__btn:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

@media (max-width: 720px) {
  .cc__in { flex-direction: column; align-items: stretch; gap: 0.9rem; }
  .cc__acts { margin-left: 0; }
  .cc__btn { flex: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .cc { transition: none; }
}

/* =========================================================================
   v106 — CIBLES TACTILES (§ optimisation mobile)

   Mesure a 390px avant correction : 22 controles sous 44px de hauteur sur
   la home, 38 sur release.html. Tous ne sont pas des defauts — un lien
   dans un paragraphe n'est pas un bouton, et l'elargir casserait
   l'interligne. Ce bloc ne corrige que les CONTROLES, la ou une erreur de
   doigt coute quelque chose.
   ========================================================================= */

/* 1. LE BOUTON DE MENU — 30 x 22. C'est le controle le plus important du
   site sur mobile : sans lui, aucune navigation. Le padding elargit la
   zone cliquable a 44 x 44 sans changer d'un pixel l'aspect des trois
   barres. La marge negative compense le padding pour que la position
   visuelle dans l'en-tete reste identique. */
@media (max-width: 860px) {
  .nav-toggle {
    box-sizing: content-box;
    padding: 11px 7px;
    margin: -11px -7px;
  }
}

/* 2. LES BOUTONS DE CHOIX DE PACK — 112 x 42, deux pixels sous la cible.
   min-height plutot que height : le libelle le plus long ne doit pas etre
   coupe s'il passe sur deux lignes. */
.rrp__tbtn,
.rrpm__pbtn { min-height: 44px; }

/* 3. LES LIENS DU PIED DE PAGE — 20px de haut, empiles avec 0.7rem
   d'ecart. Sur mobile, trois colonnes de liens a cette taille sont une
   suite de cibles voisines : le padding vertical porte chaque ligne a
   44px de zone cliquable, et le gap est reduit d'autant pour que la
   hauteur totale du pied ne bouge pratiquement pas. */
@media (max-width: 860px) {
  .foot__col ul { gap: 0.1rem; }
  .foot__col a { display: block; padding-block: 0.65rem; }
}

/* 4. LES LIENS LEGAUX DU CHECKOUT — Terms, Privacy, Refund, Cookie
   settings, 21px de haut, cote a cote. Ce sont les seuls liens que le
   client peut vouloir ouvrir AVANT de payer : ils doivent etre atteignables
   du premier coup. */
@media (max-width: 860px) {
  .cko-link { display: inline-block; padding-block: 0.6rem; }
}
