@charset "utf-8";

/* ═══════════════════════════════════════════════════════════════════
   FIRDO — « L'AUBE »
   L'heure bleue avant le lever du jour. Un fond nuit profond, une
   seule source de lumière dorée, et des filets à 0,5 px pour toute
   structure.

   TROIS LOIS HÉRITÉES DU DESIGN SYSTEM DE L'APP :
   1. L'accent ne se DILUE pas. Baisser l'opacité d'un or sur un bleu
      nuit ne donne pas « un or discret », ça donne du brun. Les
      grandes surfaces se distinguent par la LUMIÈRE (surface montante
      + lévitation), jamais par la teinte. L'or teinté n'est admis que
      sur de très petites surfaces (halo, pastille).
   2. Un seul accent, et rare : la courbe, le bouton principal, la
      flamme. Nulle part ailleurs.
   3. Le vert et le rouge sont RÉSERVÉS aux montants.
   ═══════════════════════════════════════════════════════════════════ */

:root {
  /* Neutres nuit ─ le socle */
  --canvas: #080d1a;
  --surface: #0e1526;
  --raised: #172136;
  --hairline: #25304b;
  --ink: #f3f5fa;
  --soft: #9aa6c0;
  --faint: #7e8aa8;
  --dim: #5b6684;

  /* Montants, et rien d'autre */
  --pos: #4cc38a;
  --neg: #f27362;

  /* L'accent ─ or feutré */
  --or: #e7b252;
  --or-deep: #c9902f;
  --or-light: #f0c878;
  --on-or: #191002;

  /* Rythme */
  --gouttiere: clamp(1.25rem, 4vw, 2.5rem);
  --page: 84rem;
  --respire: clamp(4.5rem, 11vw, 9.5rem);

  /* Échelle typographique fluide */
  /* Plafonné à 5,25 rem : au-delà, le titre à lui seul occupait
     toute la hauteur d'écran et repoussait le bouton sous la ligne
     de flottaison. Un titre qu'on admire mais qui cache l'action
     n'est pas un bon titre. */
  --t-display: clamp(2.5rem, 1.1rem + 4.6vw, 4.75rem);
  --t-fort: clamp(1.65rem, 0.95rem + 3vw, 3.4rem);
  --t-lede: clamp(1.06rem, 0.95rem + 0.55vw, 1.4rem);
  --t-corps: clamp(0.98rem, 0.93rem + 0.22vw, 1.09rem);
  --t-petit: 0.83rem;
  --t-micro: 0.69rem;

  --sans:
    ui-sans-serif, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
    'Helvetica Neue', sans-serif;
  --mono:
    ui-monospace, 'SF Mono', SFMono-Regular, Menlo, 'Roboto Mono',
    'Cascadia Mono', monospace;

  --pli: cubic-bezier(0.22, 0.61, 0.36, 1);
  --pli-doux: cubic-bezier(0.4, 0, 0.2, 1);

  color-scheme: dark;
}

/* ── Mode jour (palette v2.3 de l'app) ─────────────────────────── */
@media (prefers-color-scheme: light) {
  :root {
    --canvas: #f3f4f6;
    --surface: #ffffff;
    --raised: #ffffff;
    --hairline: #e4e6eb;
    --ink: #16181d;
    --soft: #4d535e;
    --faint: #6c7179;
    --dim: #9aa0aa;
    --or: #b97b10;
    --or-deep: #9a6408;
    --or-light: #d19a2e;
    --on-or: #ffffff;
    --pos: #1f8f5b;
    --neg: #c8402e;
    color-scheme: light;
  }
}

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

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

body {
  background: var(--canvas);
  color: var(--ink);
  font: 400 var(--t-corps) / 1.62 var(--sans);
  font-synthesis-weight: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  position: relative;
}

/* ── LE GRAIN ────────────────────────────────────────────────────
   Une pellicule fixe qui casse la platitude du dégradé. Sans elle,
   les grands aplats de nuit « bandent » sur les écrans 8 bits.       */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0.4;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='.36'/%3E%3C/svg%3E");
}

@media (prefers-color-scheme: light) {
  body::after {
    opacity: 0.18;
  }
}

/* ── L'AUBE ELLE-MÊME ────────────────────────────────────────────
   La lueur qui monte derrière le héros. Elle ne teinte aucune
   surface : c'est de la LUMIÈRE posée sur le fond, pas un aplat.    */
body::before {
  content: '';
  position: fixed;
  inset: -25% -10% auto -10%;
  height: 115vh;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(
      58% 42% at 50% 8%,
      rgba(231, 178, 82, 0.13),
      rgba(231, 178, 82, 0) 68%
    ),
    radial-gradient(
      90% 55% at 78% 0%,
      rgba(96, 128, 200, 0.11),
      rgba(96, 128, 200, 0) 62%
    );
  animation: aube 19s var(--pli-doux) infinite;
}

@keyframes aube {
  0%,
  100% {
    opacity: 0.78;
    transform: translate3d(0, 0, 0) scale(1);
  }
  50% {
    opacity: 1;
    transform: translate3d(0, 1.6%, 0) scale(1.045);
  }
}

@media (prefers-color-scheme: light) {
  body::before {
    background: radial-gradient(
      58% 42% at 50% 8%,
      rgba(185, 123, 16, 0.09),
      rgba(185, 123, 16, 0) 68%
    );
  }
}

/* ── Bases ───────────────────────────────────────────────────────── */
a {
  color: inherit;
  text-decoration: none;
}

b,
strong {
  font-weight: 700;
  color: var(--ink);
}

svg {
  display: block;
}

::selection {
  background: var(--or);
  color: var(--on-or);
}

.val-positive {
  color: var(--pos);
}

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

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.85rem 1.3rem;
  background: var(--or);
  color: var(--on-or);
  font-weight: 700;
  border-radius: 0 0 12px 0;
}
.skip:focus {
  left: 0;
}

/* ═══════════════ EN-TÊTE ═══════════════ */
header {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.05rem var(--gouttiere);
  border-bottom: 0.5px solid transparent;
  transition:
    background 0.4s var(--pli-doux),
    border-color 0.4s var(--pli-doux),
    backdrop-filter 0.4s var(--pli-doux);
}

header.pose {
  background: color-mix(in srgb, var(--canvas) 82%, transparent);
  backdrop-filter: blur(18px) saturate(1.3);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  border-bottom-color: var(--hairline);
}

header > a {
  display: flex;
  align-items: center;
  gap: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  font-size: 0.94rem;
}

/* La flamme du lockup respire — discrètement, elle est petite. */
header > a svg {
  animation: vacille 2.8s ease-in-out infinite;
  transform-origin: 50% 78%;
  filter: drop-shadow(0 0 7px rgba(231, 178, 82, 0.42));
}

@keyframes vacille {
  0%,
  100% {
    transform: rotate(-1.7deg) scaleY(1);
  }
  32% {
    transform: rotate(0.9deg) scaleY(1.055);
  }
  61% {
    transform: rotate(1.6deg) scaleY(0.97);
  }
}

header nav ul {
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 2vw, 1.9rem);
  list-style: none;
}

header nav a {
  font-size: var(--t-petit);
  color: var(--soft);
  transition: color 0.25s;
  position: relative;
}

header nav a:hover {
  color: var(--ink);
}

header nav a:not([data-cta])::after {
  content: '';
  position: absolute;
  left: 0;
  right: 100%;
  bottom: -5px;
  height: 1px;
  background: var(--or);
  transition: right 0.4s var(--pli);
}

header nav a:not([data-cta]):hover::after {
  right: 0;
}

header nav a[data-cta] {
  padding: 0.52rem 1.05rem;
  border-radius: 999px;
  background: var(--raised);
  color: var(--ink);
  font-weight: 600;
  border: 0.5px solid var(--hairline);
}

header nav a[data-cta]:hover {
  background: var(--or);
  color: var(--on-or);
  border-color: var(--or);
}

@media (max-width: 660px) {
  header nav li:not(:last-child) {
    display: none;
  }
}

/* ═══════════════ TRAME ═══════════════ */
main {
  display: block;
}

main > section {
  max-width: var(--page);
  margin-inline: auto;
  padding: var(--respire) var(--gouttiere);
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  column-gap: clamp(1rem, 2.4vw, 2rem);
  align-content: start;
}

main > section > * {
  grid-column: 1 / -1;
}

/* ── Sur-titre : l'interruption de motif ─────────────────────────
   Petit, capitales, très espacé, précédé d'un filet. C'est la
   signature typographique de l'app, reprise telle quelle.          */
.eyebrow {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-size: var(--t-micro);
  font-weight: 800;
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 1.5rem;
}

.eyebrow::before {
  content: '';
  width: clamp(1.5rem, 4vw, 3.25rem);
  height: 1px;
  background: linear-gradient(90deg, var(--or), transparent);
  flex: none;
}

/* ── Titres forts ────────────────────────────────────────────────── */
h1 {
  font-size: var(--t-display);
  font-weight: 800;
  line-height: 0.94;
  letter-spacing: -0.038em;
  text-wrap: balance;
}

h1 b {
  display: block;
  background: linear-gradient(
    100deg,
    var(--or-light) 8%,
    var(--or) 42%,
    var(--or-deep) 92%
  );
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.titre-fort {
  font-size: var(--t-fort);
  font-weight: 800;
  line-height: 1.06;
  letter-spacing: -0.024em;
  text-transform: uppercase;
  text-wrap: balance;
  margin-bottom: 1.6rem;
}

.titre-fort b {
  color: var(--or);
}

.lede {
  font-size: var(--t-lede);
  line-height: 1.5;
  color: var(--soft);
  margin-top: 1.65rem;
  max-width: 34ch;
  text-wrap: pretty;
}

.prose {
  color: var(--soft);
  max-width: 62ch;
  margin-bottom: 1.15rem;
  text-wrap: pretty;
}

.assist {
  font-size: var(--t-petit);
  color: var(--faint);
  line-height: 1.5;
}

/* ═══════════════ HÉROS ═══════════════ */
#hero {
  padding-top: clamp(1.75rem, 4vw, 3.25rem);
  padding-bottom: clamp(3rem, 8vw, 6rem);
  row-gap: 1.6rem;
  align-content: center;
  min-height: min(88vh, 52rem);
}

#hero hgroup {
  grid-column: 1 / span 6;
}

#hero > form {
  grid-column: 1 / span 5;
  margin-top: 0.6rem;
}

/* Les téléphones occupent la moitié droite et débordent
   volontairement de la colonne : c'est ce débord qui donne
   l'impression que le produit entre dans la page. */
#hero > figure {
  grid-column: 7 / -1;
  grid-row: 1 / span 2;
  align-self: center;
  margin-right: calc(var(--gouttiere) * -1);
}

@media (max-width: 1020px) {
  #hero hgroup,
  #hero > form,
  #hero > figure {
    grid-column: 1 / -1;
    grid-row: auto;
  }
  #hero > figure {
    margin: 2.5rem 0 0;
  }
}

/* ═══════════════ BANDEAU DE CONFIANCE ═══════════════
   La bande qui suit immédiatement le héros : trois réassurances,
   lues en deux secondes, avant que le doute ne s'installe. */
#bandeau {
  padding-block: 0;
  max-width: var(--page);
}

#bandeau ul {
  grid-column: 1 / -1;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  gap: 1px;
  background: var(--hairline);
  border-block: 0.5px solid var(--hairline);
}

#bandeau li {
  background: var(--canvas);
  padding: 1.15rem 1.4rem;
  font-size: var(--t-petit);
  color: var(--soft);
  display: flex;
  align-items: center;
  gap: 0.65rem;
}

#bandeau li::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--or);
  flex: none;
  margin-top: 0.42em;
  align-self: flex-start;
}

/* Libellé au-dessus, précision en dessous. En ligne, le gras se
   coupait en deux et la suite repartait à côté : on lisait deux
   colonnes là où il n'y a qu'une phrase. */
#bandeau li b {
  display: block;
}

#bandeau li {
  align-items: flex-start;
}

/* ═══════════════ SECTIONS PRODUIT ═══════════════
   Texte d'un côté, écran de l'autre, en alternance. */
.duo-section > hgroup {
  grid-column: 1 / span 6;
  align-self: center;
}

.duo-section > figure {
  grid-column: 8 / -1;
  align-self: center;
}

.duo-section.inverse > hgroup {
  grid-column: 7 / -1;
  order: 2;
}

.duo-section.inverse > figure {
  grid-column: 1 / span 5;
  order: 1;
}

.duo-section hgroup .titre-fort {
  margin-bottom: 1.9rem;
}

.duo-section .traits li a {
  color: var(--or);
  font-weight: 600;
  white-space: nowrap;
}

.duo-section .traits li a:hover {
  text-decoration: underline;
}

@media (max-width: 1020px) {
  .duo-section > hgroup,
  .duo-section > figure,
  .duo-section.inverse > hgroup,
  .duo-section.inverse > figure {
    grid-column: 1 / -1;
    order: 0;
  }
  .duo-section > figure {
    margin-top: 2.5rem;
  }
}

/* Dans « Les outils », la grille des dix labos passe SOUS le duo. */
#outils > fieldset,
#outils > .labos,
#outils > [data-compte-labos] {
  grid-column: 1 / -1;
}

#outils > fieldset {
  margin: 3.5rem 0 1.5rem;
}

/* ═══════════════ FORMULAIRES ═══════════════ */
form label {
  display: block;
  font-size: var(--t-micro);
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 0.55rem;
}

input[type='email'],
select {
  width: 100%;
  padding: 0.92rem 1.1rem;
  background: var(--surface);
  border: 0.5px solid var(--hairline);
  border-radius: 13px;
  color: var(--ink);
  font: inherit;
  transition:
    border-color 0.25s,
    background 0.25s,
    box-shadow 0.25s;
}

input[type='email']::placeholder {
  color: var(--dim);
}

input[type='email']:focus,
select:focus {
  outline: none;
  border-color: var(--or);
  background: var(--raised);
  box-shadow: 0 0 0 3px rgba(231, 178, 82, 0.14);
}

input[type='email'][aria-invalid='true'] {
  border-color: var(--neg);
}

button[type='submit'] {
  margin-top: 0.85rem;
  padding: 0.95rem 1.9rem;
  border: none;
  border-radius: 999px;
  background: linear-gradient(103deg, var(--or-light), var(--or-deep));
  color: var(--on-or);
  font: 700 var(--t-corps) / 1 var(--sans);
  cursor: pointer;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  transition:
    transform 0.3s var(--pli),
    box-shadow 0.3s var(--pli);
  box-shadow: 0 8px 26px -10px rgba(231, 178, 82, 0.6);
}

/* Le lustre qui balaie le bouton au survol. */
button[type='submit']::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    100deg,
    transparent 22%,
    rgba(255, 255, 255, 0.42) 50%,
    transparent 78%
  );
  transform: translateX(-105%);
  transition: transform 0.75s var(--pli);
}

button[type='submit']:hover {
  transform: translateY(-2px);
  box-shadow: 0 14px 34px -10px rgba(231, 178, 82, 0.72);
}

button[type='submit']:hover::before {
  transform: translateX(105%);
}

button[type='submit']:active {
  transform: translateY(0);
}

form .assist {
  margin-top: 0.9rem;
}

form .assist[data-etat='erreur'] {
  color: var(--neg);
}

form .assist[data-etat='ok'] {
  color: var(--pos);
}

/* ── Jeux de choix (radios en pastilles) ─────────────────────────── */
fieldset {
  border: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

fieldset legend {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

fieldset label {
  margin: 0;
  cursor: pointer;
  text-transform: none;
  letter-spacing: 0;
}

fieldset input[type='radio'] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

fieldset label span {
  display: block;
  padding: 0.5rem 0.95rem;
  border-radius: 999px;
  border: 0.5px solid var(--hairline);
  background: var(--surface);
  color: var(--soft);
  font-size: var(--t-petit);
  font-weight: 600;
  transition:
    background 0.28s var(--pli),
    color 0.28s,
    border-color 0.28s,
    transform 0.28s var(--pli);
}

fieldset label:hover span {
  color: var(--ink);
  border-color: var(--dim);
}

fieldset input:checked + span {
  background: var(--or);
  border-color: var(--or);
  color: var(--on-or);
  transform: translateY(-1px);
}

fieldset input:focus-visible + span {
  outline: 2px solid var(--or);
  outline-offset: 3px;
}

/* ═══════════════ FIGURES ═══════════════ */
figure {
  background: linear-gradient(163deg, var(--surface), var(--canvas) 92%);
  border: 0.5px solid var(--hairline);
  border-radius: 24px;
  padding: clamp(1.15rem, 2.6vw, 1.9rem);
  box-shadow:
    0 32px 68px -34px rgba(0, 0, 0, 0.86),
    inset 0 1px 0 rgba(255, 255, 255, 0.045);
  position: relative;
  overflow: hidden;
}

/* Le liseré de lumière en haut de carte — de la LUMIÈRE, pas une
   teinte : c'est ce qui remplace l'or dilué proscrit par la charte. */
figure::before {
  content: '';
  position: absolute;
  top: 0;
  left: 12%;
  right: 12%;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(231, 178, 82, 0.55),
    transparent
  );
}

figcaption {
  font-size: var(--t-petit);
  color: var(--faint);
  margin-bottom: 1.15rem;
  line-height: 1.5;
}

figcaption b {
  color: var(--ink);
}

/* ── La courbe ───────────────────────────────────────────────────── */
#preuve-vive fieldset {
  margin-bottom: 1.35rem;
}

#preuve-vive svg {
  width: 100%;
  height: auto;
  aspect-ratio: 640 / 200; /* réserve la place : zéro décalage */
  overflow: visible;
}

.grille line {
  stroke: var(--hairline);
  stroke-width: 1;
  stroke-dasharray: 2 7;
  opacity: 0.5;
}

#preuve-vive path {
  fill: none;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition:
    opacity 0.55s var(--pli),
    stroke 0.55s var(--pli);
}

.trace-ailleurs {
  stroke: var(--or);
  opacity: 0;
}

.trace-partielle {
  stroke: var(--dim);
}

.trace-fait {
  stroke: url(#or);
}

.bascule {
  stroke: var(--or);
  stroke-width: 1;
  stroke-dasharray: 3 5;
  opacity: 0.5;
  transition: opacity 0.55s var(--pli);
}

.point {
  fill: var(--or);
  filter: drop-shadow(0 0 8px rgba(231, 178, 82, 0.75));
}

/* Le point du jour pulse : lui est un FAIT. */
.point {
  animation: pouls 2.6s ease-in-out infinite;
  transform-box: fill-box;
  transform-origin: center;
}

@keyframes pouls {
  0%,
  100% {
    r: 4;
    opacity: 1;
  }
  50% {
    r: 5.2;
    opacity: 0.82;
  }
}

/* Mode « ailleurs » : la courbe lissée prend la main, la vérité s'efface. */
#preuve-vive[data-mode='ailleurs'] .trace-ailleurs {
  opacity: 1;
}
#preuve-vive[data-mode='ailleurs'] .trace-partielle,
#preuve-vive[data-mode='ailleurs'] .trace-fait {
  opacity: 0;
}
#preuve-vive[data-mode='ailleurs'] .bascule {
  opacity: 0;
}

/* Le tracé se dessine à l'apparition. */
#preuve-vive.entre .trace-partielle,
#preuve-vive.entre .trace-fait {
  animation: tracer 1.5s var(--pli) both;
}
#preuve-vive.entre .trace-fait {
  animation-delay: 0.72s;
}

@keyframes tracer {
  from {
    stroke-dasharray: 0 620;
  }
  to {
    stroke-dasharray: 620 0;
  }
}

.axe {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  list-style: none;
  margin-top: 0.5rem;
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
}

.axe li {
  text-align: center;
}
.axe li:first-child {
  text-align: left;
}
.axe li:last-child {
  text-align: right;
}

/* ── Lecture chiffrée ────────────────────────────────────────────── */
.lecture {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.55rem 1.1rem;
  align-items: baseline;
  margin-top: 1.5rem;
  padding-top: 1.3rem;
  border-top: 0.5px solid var(--hairline);
}

/* Sous 560 px, la colonne de valeurs devenait si étroite que la
   lecture longue tombait à trois mots par ligne. On empile. */
@media (max-width: 560px) {
  .lecture {
    grid-template-columns: 1fr;
    gap: 0.25rem;
  }
  .lecture dd {
    margin-bottom: 0.7rem;
  }
}

.lecture dt {
  font-size: var(--t-micro);
  font-weight: 800;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--faint);
}

.lecture dd output {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 1.12rem;
  color: var(--pos);
  transition: color 0.45s var(--pli);
}

/* L'effet de périmètre se dit SANS couleur. C'est la règle. */
.lecture .verdict output {
  font-family: var(--sans);
  font-size: var(--t-petit);
  font-weight: 400;
  color: var(--soft);
  line-height: 1.55;
}

.lecture .du output {
  color: var(--or);
}

#preuve-vive[data-mode='ailleurs'] [data-variation] {
  color: var(--pos);
}

/* ═══════════════ MATRICE DE PREUVE ═══════════════ */
/* Même principe que `.labos` : le filet appartient à la cellule, pour
   qu'une rangée incomplète ne laisse pas de bloc clair. */
.matrice {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  gap: 0.5px;
  background: var(--canvas);
  border: 0.5px solid var(--hairline);
  border-radius: 22px;
  overflow: hidden;
}

.matrice article {
  background: var(--canvas);
  box-shadow: 0 0 0 0.5px var(--hairline);
  padding: clamp(1.3rem, 2.6vw, 1.9rem);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  transition: background 0.4s var(--pli-doux);
}

.matrice article:hover {
  background: var(--surface);
}

.matrice dd {
  order: -1;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: clamp(2.1rem, 1.2rem + 2.6vw, 3.1rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.035em;
  background: linear-gradient(160deg, var(--ink), var(--soft));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.matrice dt {
  font-size: var(--t-petit);
  font-weight: 700;
  color: var(--ink);
  line-height: 1.35;
}

.matrice p {
  font-size: var(--t-petit);
  color: var(--faint);
  line-height: 1.52;
}

/* ═══════════════ TEXTE AU LARGE ═══════════════
   Les sections de récit gardent une colonne étroite : au-delà de
   ~70 caractères, l'œil perd la ligne suivante en revenant à gauche. */
#regle .titre-fort,
#regle .prose,
#apprendre .titre-fort,
#apprendre .prose,
#confiance .titre-fort,
#acces .titre-fort,
#acces .prose {
  grid-column: 1 / span 8;
}

@media (max-width: 900px) {
  #regle .titre-fort,
  #regle .prose,
  #apprendre .titre-fort,
  #apprendre .prose,
  #confiance .titre-fort,
  #acces .titre-fort,
  #acces .prose {
    grid-column: 1 / -1;
  }
}

/* ═══════════════ LE FILM ═══════════════ */
#film {
  grid-column: 1 / -1;
  margin-top: 2.5rem;
  padding: clamp(0.6rem, 1.4vw, 1rem);
}

#film video {
  display: block;
  width: 100%;
  height: auto;
  /* La proportion est déclarée : la place est réservée avant même que
     la vidéo soit chargée, donc rien ne saute quand elle arrive. */
  aspect-ratio: 16 / 9;
  border-radius: 16px;
  background: var(--canvas);
}

#film figcaption {
  margin: 0.95rem 0.35rem 0.15rem;
}

/* ═══════════════ LA RÈGLE ═══════════════
   La démonstration qu'on manipule (la courbe basculante) et celle
   qu'on regarde (le film) vivent côte à côte. */
#regle > #preuve-vive {
  grid-column: 1 / span 6;
  margin-top: 1.6rem;
}

#regle > #film {
  grid-column: 8 / -1;
  margin-top: 1.6rem;
  align-self: start;
}

@media (max-width: 1020px) {
  #regle > #preuve-vive,
  #regle > #film {
    grid-column: 1 / -1;
  }
}

/* La matrice de preuve ferme la section « confiance » : le chiffre
   et son libellé, sans commentaire. */
#confiance > .matrice {
  margin-top: 3rem;
}

#confiance .matrice article {
  gap: 0.35rem;
}

.ticket {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.9rem 1.05rem;
  background: var(--canvas);
  border: 0.5px solid var(--hairline);
  border-radius: 14px;
  margin-bottom: 1.3rem;
}

.ticket output {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--neg);
}

.curseur {
  display: block;
  font-size: var(--t-micro);
  font-weight: 800;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 1.35rem;
}

input[type='range'] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 26px;
  margin-top: 0.65rem;
  background: transparent;
  cursor: grab;
}

input[type='range']:active {
  cursor: grabbing;
}

input[type='range']::-webkit-slider-runnable-track {
  height: 5px;
  border-radius: 999px;
  background: linear-gradient(
    90deg,
    var(--or) 0 var(--part, 63%),
    var(--raised) var(--part, 63%) 100%
  );
}

input[type='range']::-moz-range-track {
  height: 5px;
  border-radius: 999px;
  background: linear-gradient(
    90deg,
    var(--or) 0 var(--part, 63%),
    var(--raised) var(--part, 63%) 100%
  );
}

input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 20px;
  height: 20px;
  margin-top: -7.5px;
  border-radius: 50%;
  background: var(--ink);
  border: 3px solid var(--or);
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.55);
  transition: transform 0.2s var(--pli);
}

input[type='range']::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--ink);
  border: 3px solid var(--or);
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.55);
}

input[type='range']:hover::-webkit-slider-thumb {
  transform: scale(1.16);
}

.enveloppes {
  list-style: none;
  display: grid;
  gap: 1rem;
}

.enveloppes li {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.4rem 1rem;
  align-items: center;
}

.enveloppes b {
  font-size: var(--t-petit);
}

.enveloppes output {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--t-petit);
  color: var(--soft);
  text-align: right;
}

meter {
  grid-column: 1 / -1;
  width: 100%;
  height: 6px;
  appearance: none;
  -webkit-appearance: none;
  background: var(--raised);
  border-radius: 999px;
  overflow: hidden;
  border: none;
}

meter::-webkit-meter-bar {
  background: var(--raised);
  border-radius: 999px;
  border: none;
  height: 6px;
}

meter::-webkit-meter-optimum-value,
meter::-webkit-meter-suboptimum-value,
meter::-webkit-meter-even-less-good-value {
  background: linear-gradient(90deg, var(--or-deep), var(--or));
  border-radius: 999px;
  transition: width 0.45s var(--pli);
}

meter::-moz-meter-bar {
  background: linear-gradient(90deg, var(--or-deep), var(--or));
  border-radius: 999px;
}

/* ── Traits (listes de bénéfices) ────────────────────────────────── */
.traits {
  list-style: none;
  display: grid;
  gap: 1.35rem;
}

.traits li {
  padding-left: 1.5rem;
  position: relative;
  color: var(--soft);
  max-width: 54ch;
  text-wrap: pretty;
}

.traits li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--or);
  box-shadow: 0 0 10px rgba(231, 178, 82, 0.5);
}

/* ═══════════════ OUTILS ═══════════════ */
#outils fieldset {
  margin: 0.5rem 0 2rem;
}

/* Les filets sont dessinés par les CELLULES (`box-shadow`), pas par le
   fond du conteneur. Avec l'ancienne astuce — fond couleur filet +
   `gap: 1px` — la dernière rangée incomplète laissait un grand
   rectangle clair là où il manquait des cartes, qui se lisait comme un
   défaut d'affichage. Ici, une case vide prend simplement la couleur du
   fond. */
.labos {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(17.5rem, 100%), 1fr));
  gap: 0.5px;
  background: var(--canvas);
  border: 0.5px solid var(--hairline);
  border-radius: 22px;
  overflow: hidden;
}

.labos li {
  background: var(--canvas);
  box-shadow: 0 0 0 0.5px var(--hairline);
  padding: 1.4rem 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.42rem;
  position: relative;
  transition:
    background 0.35s var(--pli-doux),
    opacity 0.35s,
    transform 0.35s var(--pli);
}

.labos li::after {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--or);
  transform: scaleY(0);
  transform-origin: 50% 0;
  transition: transform 0.4s var(--pli);
}

.labos li:hover {
  background: var(--surface);
}

.labos li:hover::after {
  transform: scaleY(1);
}

.labos li[hidden] {
  display: none;
}

.labos b {
  font-size: 1.02rem;
  letter-spacing: -0.012em;
}

.labos p {
  font-size: var(--t-petit);
  color: var(--soft);
  line-height: 1.5;
}

.labos small {
  font-size: var(--t-micro);
  font-weight: 800;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--faint);
  margin-top: auto;
  padding-top: 0.5rem;
}

[data-compte-labos] {
  margin-top: 1rem;
}

/* ═══════════════ ENGAGEMENTS ═══════════════ */
blockquote {
  grid-column: 1 / span 9;
  margin: 0.5rem 0 2.75rem;
  padding: clamp(1.5rem, 3vw, 2.4rem) clamp(1.5rem, 3vw, 2.6rem);
  background: linear-gradient(150deg, var(--surface), var(--canvas));
  border: 0.5px solid var(--hairline);
  border-left: 2px solid var(--or);
  border-radius: 6px 22px 22px 6px;
}

blockquote p {
  font-size: clamp(1.3rem, 0.9rem + 1.6vw, 2.05rem);
  font-weight: 700;
  line-height: 1.22;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

blockquote footer {
  margin-top: 1rem;
  font-size: var(--t-petit);
  color: var(--faint);
  line-height: 1.55;
  max-width: 56ch;
}

@media (max-width: 900px) {
  blockquote {
    grid-column: 1 / -1;
  }
}

/* Deux colonnes fermes plutôt qu'un `auto-fit` : à quatre
   engagements, l'ajustement automatique donnait 3 + 1, et l'orphelin
   de la seconde ligne se lisait comme un ajout de dernière minute. */
.engagements {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.9rem clamp(1.5rem, 4vw, 4rem);
}

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

.engagements article {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding-top: 1.15rem;
  border-top: 0.5px solid var(--hairline);
}

.engagements dt {
  font-weight: 700;
  font-size: 1.02rem;
  letter-spacing: -0.012em;
}

.engagements dd {
  color: var(--soft);
  font-size: var(--t-petit);
  line-height: 1.6;
}

/* ═══════════════ ACCÈS ═══════════════ */
#acces > form {
  grid-column: 1 / span 7;
}

#acces > .dispo {
  grid-column: 9 / -1;
  align-self: start;
  margin-top: 0.5rem;
}

@media (max-width: 940px) {
  #acces > form,
  #acces > .dispo {
    grid-column: 1 / -1;
  }
  #acces > .dispo {
    margin-top: 2.2rem;
  }
}

#acces form fieldset {
  display: block;
  margin-bottom: 1.3rem;
}

#acces form fieldset legend {
  position: static;
  width: auto;
  height: auto;
  clip-path: none;
  font-size: var(--t-micro);
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--or);
  margin-bottom: 0.75rem;
}

#acces form fieldset label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.dispo {
  padding: 1.5rem;
  background: var(--surface);
  border: 0.5px solid var(--hairline);
  border-radius: 20px;
}

.dispo .eyebrow {
  margin-bottom: 1rem;
}

.dispo b {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 1.02rem;
}

/* La pastille de disponibilité — le seul vert hors montants,
   parce qu'il dit un ÉTAT, pas une somme. */
.dispo b::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--pos);
  box-shadow: 0 0 0 0 rgba(76, 195, 138, 0.55);
  animation: souffle 2.4s ease-out infinite;
}

.dispo[data-etat='ferme'] b::before {
  background: var(--faint);
  animation: none;
}

@keyframes souffle {
  0% {
    box-shadow: 0 0 0 0 rgba(76, 195, 138, 0.5);
  }
  70% {
    box-shadow: 0 0 0 9px rgba(76, 195, 138, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(76, 195, 138, 0);
  }
}

.dispo small {
  display: block;
  margin-top: 0.5rem;
  font-size: var(--t-petit);
  color: var(--soft);
  line-height: 1.5;
}

.dispo .assist {
  margin-top: 1.1rem;
  padding-top: 1.1rem;
  border-top: 0.5px solid var(--hairline);
}

/* ═══════════════ PIED ═══════════════
   Sélecteur d'enfant direct À DESSEIN : sans lui, cette règle
   s'appliquait aussi au `<footer>` d'attribution DANS la citation,
   qui héritait alors de `max-width` + `margin-inline: auto` et se
   retrouvait centré au milieu du bloc. */
body > footer {
  max-width: var(--page);
  margin-inline: auto;
  padding: 3rem var(--gouttiere) 4rem;
  border-top: 0.5px solid var(--hairline);
  display: grid;
  gap: 1.3rem;
}

body > footer nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  list-style: none;
}

body > footer nav a {
  font-size: var(--t-petit);
  color: var(--soft);
  transition: color 0.25s;
}

body > footer nav a:hover {
  color: var(--or);
}

/* `--faint` et non `--dim` : sur le fond nuit, --dim tombe à 3,3:1,
   sous le seuil AA. La mention légale est justement le texte qu'il ne
   faut pas rendre pénible à lire. */
.mention {
  font-size: var(--t-micro);
  color: var(--faint);
  line-height: 1.65;
  max-width: 72ch;
}

/* ═══════════════ ENTRÉE EN SCÈNE ═══════════════
   Le rideau se lève une fois, par blocs décalés. Piloté par
   IntersectionObserver (classe .entre), jamais par le scroll brut.  */
[data-revele] {
  opacity: 0;
  transform: translate3d(0, 22px, 0);
  transition:
    opacity 0.85s var(--pli),
    transform 0.85s var(--pli);
  transition-delay: var(--retard, 0ms);
}

[data-revele].entre {
  opacity: 1;
  transform: none;
}

/* ═══════════════ « RÉDUIRE LES ANIMATIONS » ═══════════════
   Exigence du design system de l'app, reprise ici sans exception :
   tout s'arrête, rien ne disparaît.                                 */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  [data-revele] {
    opacity: 1;
    transform: none;
  }

  body::before {
    animation: none;
  }
}
