/* ==========================================================================
   SciRedPen, page de présentation

   Direction : la même surface que l'atelier, à l'échelle d'une page qui se
   lit d'un bout à l'autre. Plans unis, angles pleins, un seul crimson, celui
   de la correction, réservé aux marques. Rien n'est penché ni texturé, hors le
   manuscrit : une feuille porte sa fibre, et la main qui l'annote ne tient pas
   l'équerre. Ailleurs, ce qui se démarque le fait par le blanc autour de lui,
   par le corps ou par la couleur du texte.

   La page redéfinit ses couleurs sous `.landing-body`, et rien d'autre : les
   angles, les graisses et les fontes sont ceux de styles.css, chargée avant.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Jetons de la page
   -------------------------------------------------------------------------- */

.landing-body {
  /* Encre sur ardoise : la coque qui entoure le manuscrit. */
  --paper: #0f172a;
  --paper-deep: #020617;
  --card: #1e293b;
  --card-raised: #243244;

  --ink: #eaf1ff;
  --ink-soft: #94a3b8;
  --ink-faint: #7d8da3;

  --rule: rgba(203, 213, 225, 0.18);
  --rule-soft: rgba(203, 213, 225, 0.09);

  /* Le crimson du relecteur. Un seul, jamais décliné en dégradé. Sur ardoise
     il s'éclaircit pour rester lisible, et porte alors une encre sombre. */
  --red: #ffb4ac;
  --red-ink: #0f172a;
  --red-soft: rgba(255, 180, 172, 0.14);
  --red-line: rgba(255, 180, 172, 0.45);
  --blue-mark: #60a5fa;
  --green-mark: #4ade80;

  /* Fond de l'ouverture, pris dans la palette de la page : l'ardoise pour le
     fond, l'encre pour le maillage, le crimson de la correction pour les
     neurones actifs. Le script lit ces couleurs ici, il n'en écrit aucune. */
  --neural-from: var(--paper);
  --neural-to: var(--paper-deep);
  --neural-halo-a: rgba(96, 165, 250, 0.16);
  --neural-halo-b: rgba(255, 180, 172, 0.1);
  --neural-link: var(--ink-faint);
  --neural-node: var(--ink-soft);
  --neural-glow: var(--red);
  --neural-strength: 1;

  --page-shadow: 0 24px 60px rgba(2, 6, 23, 0.42);

  /* La famille et les graisses sont posées une seule fois, dans styles.css,
     chargée avant : la page de présentation redefinit ses couleurs, pas sa
     typographie. */
  --font-body: var(--font-text);

  --gutter: 26px;
  --content: 90%;

  /* Pas de la réglure. La trame peinte derrière l'ouverture a ce pas, et tout
     le rythme vertical de la page en est un multiple : les sections tombent
     donc sur les lignes du papier au lieu de flotter au-dessus. Changer cette
     seule valeur recompose la page entière. */
  --rule-pitch: 34px;
  --v-half: calc(var(--rule-pitch) / 2);
  --v-1: var(--rule-pitch);
  --v-2: calc(var(--rule-pitch) * 1.5);
  --v-3: calc(var(--rule-pitch) * 2);
  --v-4: calc(var(--rule-pitch) * 3);
  --v-5: calc(var(--rule-pitch) * 4);

  /* Approche des titres. Un grand corps se resserre : laissé à l'approche du
     corps de texte, il s'étale et perd son bloc. */
  --track-hero: -0.022em;
  --track-title: -0.015em;

  height: auto;
  min-height: 100%;
  /* `clip` et non `hidden` : la réglure et les blocs penchés débordent
     volontairement, sans ouvrir de défilement horizontal ni casser l'en-tête
     collant, ce que ferait un conteneur de défilement. */
  overflow-x: clip;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.6;
}

[data-theme="light"] .landing-body {
  /* Papier de manuscrit, encre d'archive : l'épreuve sortie de l'imprimante. */
  --paper: #f8fafc;
  --paper-deep: #f1f5f9;
  --card: #ffffff;
  --card-raised: #f8fafc;

  --ink: #0f172a;
  --ink-soft: #475569;
  --ink-faint: #64748b;

  --rule: #cbd5e1;
  --rule-soft: #e2e8f0;

  --red: #991b1b;
  --red-ink: #ffffff;
  --red-soft: rgba(153, 27, 27, 0.08);
  --red-line: rgba(153, 27, 27, 0.4);
  --blue-mark: #2563eb;
  --green-mark: #15803d;

  --neural-halo-a: rgba(37, 99, 235, 0.08);
  --neural-halo-b: rgba(153, 27, 27, 0.05);
  --neural-strength: 0.75;

  --page-shadow: 0 16px 40px rgba(15, 23, 42, 0.14);
}

.landing-body ::selection {
  background: var(--red-soft);
  color: inherit;
}

.landing-body :focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 3px;
}

.landing-body main {
  position: relative;
  z-index: 1;
  max-width: var(--content);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* `white-space: normal` explicite : la feuille de l'atelier fixe `nowrap` sur
   `h1`, pour le nom du document dans sa barre de titre. Un titre de une ligne
   là-bas, un titre de trois lignes ici. */
.landing-body h1,
.landing-body h2,
.landing-body h3 {
  font-family: var(--font-display);
  font-weight: var(--w-display);
  letter-spacing: var(--track-title);
  /* La hauteur d'x est grande : plus serre, les descendantes touchent les
     capitales de la ligne suivante. */
  line-height: 1.06;
  white-space: normal;
  text-wrap: balance;
}

.landing-body p {
  text-wrap: pretty;
}

/* Libellés techniques : le corps d'une note, une graisse au-dessus du texte
   courant, et leur casse d'origine. C'est le contraste de taille qui les
   détache, non la casse. */
.kicker,
.frame-file,
.frame-status,
.hero-note,
.plan-unit,
.plan-flag,
.section-footnote,
.footer-col h2 {
  font-family: var(--font-meta);
  font-size: 14px;
  font-weight: var(--w-strong);
}

.skip-link {
  position: absolute;
  top: -48px;
  left: 16px;
  z-index: 20;
  border-radius: var(--r-pill);
  background: var(--red);
  color: var(--red-ink);
  padding: var(--s-2) var(--s-4);
  font-family: var(--font-meta);
  font-size: 14px;
  font-weight: var(--w-strong);
  text-decoration: none;
  transition: top 120ms var(--ease-out);
}

.skip-link:focus {
  top: 12px;
}

/* --------------------------------------------------------------------------
   En-tête
   -------------------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  border-bottom: 1px solid var(--rule);
  /* Opaque et non translucide : un fond flouté laisserait passer le texte de
     l'article qui défile dessous, sur une page qui parle de lisibilité. */
  background: var(--paper);
}

.site-header-inner {
  max-width: var(--content);
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin: 0 auto;
  padding: var(--s-3) var(--gutter);
}

.site-menu {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  gap: var(--s-6);
  min-width: 0;
}

.site-header-inner > .btn-solid {
  flex: 0 0 auto;
  white-space: nowrap;
}

.menu-toggle {
  display: none;
}

.menu-icon-close,
.menu-toggle[aria-expanded="true"] .menu-icon-open {
  display: none;
}

.menu-toggle[aria-expanded="true"] .menu-icon-close {
  display: block;
}

.brand {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: var(--s-3);
  color: inherit;
  text-decoration: none;
}

.landing-body .brand-mark {
  display: grid;
  place-items: center;
  width: 160px;
  height: 42px;
  border: 0;
  background: transparent;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--s-6);
  margin-left: calc(var(--s-6) + var(--s-4));
  margin-right: auto;
}

.site-nav a {
  position: relative;
  color: var(--ink-soft);
  white-space: nowrap;
  font-family: var(--font-meta);
  font-size: 15px;
  text-decoration: none;
  transition: color 180ms var(--ease-hover);
}

@media (hover: hover) and (pointer: fine) {
  .site-nav a:hover {
    color: var(--ink);
  }

  .header-link:hover,
  .footer-col a:hover,
  .landing-body .icon-btn:hover:not(:disabled) {
    color: var(--red);
  }
}

.site-actions {
  display: flex;
  flex: 0 1 auto;
  align-items: center;
  gap: var(--s-3);
  min-width: 0;
}

.landing-body .lang-switch {
  border: 0;
  border-radius: var(--r-pill);
  background: var(--rule-soft);
}

.landing-body .lang-switch button,
.landing-body .lang-switch a {
  color: var(--ink-faint);
  font-family: var(--font-meta);
  font-size: 12px;
}

.landing-body .lang-switch button[aria-pressed="true"],
.landing-body .lang-switch button.active,
.landing-body .lang-switch a[aria-current="page"],
.landing-body .lang-switch a.active {
  background: var(--card);
  color: var(--ink);
}

.landing-body .icon-btn {
  border-color: transparent;
  color: var(--ink-soft);
}


.landing-body .divider {
  width: 1px;
  height: 20px;
  background: var(--rule);
}

.account-name {
  flex: 0 1 auto;
  min-width: 0;
  max-width: 20ch;
  overflow: hidden;
  color: var(--ink-soft);
  font-family: var(--font-meta);
  font-size: 14px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.header-link {
  color: var(--ink-soft);
  white-space: nowrap;
  font-family: var(--font-meta);
  font-size: 15px;
  text-decoration: none;
}


/* --------------------------------------------------------------------------
   Boutons
   Les mêmes pastilles que dans l'atelier : angle plein, libellé dans sa casse,
   et le crimson gardé pour le survol.
   -------------------------------------------------------------------------- */

.landing-body .btn-solid,
.landing-body .btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  height: 44px;
  border: 1px solid var(--ink);
  border-radius: var(--r-pill);
  background: var(--ink);
  color: var(--paper);
  padding: 0 var(--s-6);
  font-family: var(--font-meta);
  font-size: 15px;
  font-weight: var(--w-strong);
  text-decoration: none;
  cursor: pointer;
  transition: background 160ms var(--ease-hover), color 160ms var(--ease-hover),
    border-color 160ms var(--ease-hover), opacity 160ms var(--ease-hover);
}

/* La pastille s'atténue sous le doigt : la page répond avant le serveur. */
.landing-body .btn-solid:active:not(:disabled),
.landing-body .btn-ghost:active:not(:disabled) {
  opacity: 0.8;
}

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

@media (hover: hover) and (pointer: fine) {
  .landing-body .btn-solid:hover:not(:disabled) {
    border-color: var(--red);
    background: var(--red);
    color: var(--red-ink);
  }

  .landing-body .btn-ghost:hover:not(:disabled) {
    border-color: var(--red);
    background: transparent;
    color: var(--red);
  }
}

.landing-body .btn-lg {
  height: 52px;
  padding: 0 var(--s-7);
  font-size: 16px;
}

/* La flèche avance au survol : le seul mouvement du bouton, et il dit où il
   mène. */
.btn-arrow::after {
  content: "→";
  font-size: 14px;
  transition: transform 180ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .btn-arrow:hover::after {
    transform: translateX(4px);
  }
}

/* --------------------------------------------------------------------------
   Ouverture
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  min-height: calc(100dvh - 72px);
  display: grid;
  align-items: center;
  padding: var(--v-2) 0;
}

/* Le titre prend toute la mesure de la page, et la note de correction sort
   dans la marge de droite : c'est la place d'une annotation portee apres coup.
   Sous la largeur ou cette marge existe, la note revient simplement dans le
   flux, sous le titre. */
.hero-grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(380px, 0.92fr);
  align-items: center;
  gap: clamp(var(--s-7), 5vw, var(--v-3));
}

.hero-copy {
  min-width: 0;
}

/* Réseau de neurones : un dégradé d'ardoise et un maillage de points
   qui ondule, dessiné par landing.js dans le canvas. La couche couvre toute
   la largeur de la fenêtre, et son bord bas se fond dans le papier pour que
   l'ouverture ne se termine pas sur une arête. Sans script, le dégradé seul
   reste. */
.hero-network {
  position: absolute;
  inset: 0 calc(50% - 50vw);
  z-index: 0;
  overflow: clip;
  pointer-events: none;
  background:
    radial-gradient(42% 52% at 84% 22%, var(--neural-halo-a), transparent 72%),
    radial-gradient(36% 46% at 14% 82%, var(--neural-halo-b), transparent 72%),
    linear-gradient(160deg, var(--neural-from) 0%, var(--neural-to) 100%);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 78%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 78%, transparent 100%);
}

.neural-network {
  display: block;
  width: 100%;
  height: 100%;
}

.hero-title {
  max-width: 18ch;
  font-size: clamp(42px, 4.8vw, 68px);
  line-height: 1;
  letter-spacing: var(--track-hero);
}

html[lang="fr"] .hero-title {
  max-width: 20ch;
  font-size: clamp(38px, 4.2vw, 60px);
}

.hero-emphasis {
  --stroke-bottom: -0.01em;
  --stroke-height: 0.2em;
  --stroke-tilt: -0.35deg;
  position: relative;
  display: inline-block;
  isolation: isolate;
  white-space: nowrap;
}

.hero-emphasis::after {
  content: "";
  position: absolute;
  z-index: 0;
  right: -0.035em;
  bottom: var(--stroke-bottom);
  left: -0.035em;
  height: var(--stroke-height);
  background: var(--underline-color);
  opacity: 0.92;
  clip-path: polygon(
    0% 42%, 5% 27%, 10% 39%, 15% 54%, 20% 35%, 25% 24%, 30% 43%, 35% 57%, 40% 39%, 45% 29%,
    50% 47%, 55% 59%, 60% 37%, 65% 26%, 70% 44%, 75% 55%, 80% 36%, 85% 23%, 90% 41%, 95% 52%, 100% 34%,
    100% 67%, 95% 78%, 90% 65%, 85% 53%, 80% 70%, 75% 82%, 70% 66%, 65% 54%, 60% 72%, 55% 84%,
    50% 69%, 45% 57%, 40% 73%, 35% 86%, 30% 68%, 25% 52%, 20% 69%, 15% 82%, 10% 64%, 5% 54%, 0% 73%
  );
  filter: blur(0.15px);
  pointer-events: none;
  transform: rotate(var(--stroke-tilt));
  transform-origin: left center;
}

.hero-emphasis-review {
  --underline-color: var(--red);
  --stroke-height: 0.19em;
  --stroke-tilt: -0.55deg;
}

.hero-emphasis-scientifically {
  --underline-color: var(--blue-mark);
  --stroke-bottom: -0.025em;
  --stroke-height: 0.22em;
  --stroke-tilt: 0.15deg;
}

.hero-emphasis-submission {
  --underline-color: var(--green-mark);
  --stroke-bottom: 0;
  --stroke-height: 0.185em;
  --stroke-tilt: -0.2deg;
}

.hero-lede {
  max-width: 56ch;
  margin-top: var(--v-half);
  color: var(--ink-soft);
  font-size: 18px;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-top: var(--v-1);
}

.hero-note {
  margin-top: var(--s-5);
  color: var(--ink-faint);
}

/* Confidentialité aux points de décision : même voix que la note qui la
   précède, sans la graisse, pour rester un complément. */
.privacy-note {
  max-width: 56ch;
  margin-top: var(--s-2);
  color: var(--ink-faint);
  font-size: 14px;
  line-height: 1.6;
}

.privacy-note a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.privacy-note a:hover {
  color: var(--ink-soft);
}

/* Note de marge : une carte teintée, comme un commentaire porté sous
   l'appel à l'action, dans le flux du texte. */
.margin-note {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  max-width: 46ch;
  margin-top: var(--v-1);
  border-radius: var(--r-lg);
  background: var(--red-soft);
  padding: var(--s-4) var(--s-5);
  color: var(--ink-soft);
  font-size: 15px;
  line-height: 1.6;
}

.margin-note-mark {
  flex: none;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border: 1.5px solid var(--red);
  border-radius: 50%;
  margin-top: 0.15em;
  color: var(--red);
  font-family: var(--font-meta);
  font-size: 12px;
  line-height: 1;
}

/* --------------------------------------------------------------------------
   Maquette de l'atelier
   -------------------------------------------------------------------------- */

.product-frame {
  position: relative;
  width: 100%;
  max-width: 540px;
  justify-self: end;
  margin: 0;
  overflow: hidden;
  border: 1px solid var(--rule);
  border-radius: var(--r-xl);
  background: var(--card);
  box-shadow: var(--page-shadow);
}

.frame-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  border-bottom: 1px solid var(--rule);
  background: var(--card-raised);
  padding: var(--s-3) var(--s-4);
}

.frame-file {
  color: var(--ink-soft);
}

.frame-status {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  color: var(--ink-faint);
  font-size: 13px;
}

.status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--red);
  box-shadow: 0 0 0 3px var(--red-soft);
}

.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
}

.process-frame {
  --process-loop: 8s;
  display: grid;
  gap: var(--s-4);
  padding: var(--s-4);
}

.process-track {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.process-track::before {
  content: "";
  position: absolute;
  top: 12px;
  right: 11%;
  left: 11%;
  height: 1px;
  background: var(--rule);
}

.process-step {
  position: relative;
  z-index: 1;
  display: grid;
  justify-items: center;
  gap: var(--s-1);
  color: var(--ink-faint);
  font-family: var(--font-meta);
  font-size: 11px;
  line-height: 1.2;
  text-align: center;
}

.process-step > span {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border: 1px solid var(--rule);
  border-radius: 50%;
  background: var(--card);
  color: var(--ink-soft);
  font-size: 10px;
  font-weight: var(--w-strong);
}

.process-step strong {
  font-weight: var(--w-strong);
}

.process-step::after {
  content: "";
  position: absolute;
  top: -3px;
  width: 30px;
  height: 30px;
  border: 1px solid var(--red);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
  transform: scale(0.92);
  animation: process-step-active var(--process-loop) linear infinite both;
}

.process-step:nth-child(2)::after { animation-delay: 2s; }
.process-step:nth-child(3)::after { animation-delay: 4s; }
.process-step:nth-child(4)::after { animation-delay: 6s; }

.process-workspace {
  display: grid;
  grid-template-columns: minmax(118px, 0.8fr) minmax(0, 1.2fr);
  gap: var(--s-3);
  min-height: 220px;
}

/* La feuille. Un aplat blanc ne ressemble pas à du papier : la lumière tombe
   d'en haut à gauche, le bord opposé s'assombrit, la fibre casse le plan, et
   l'épaisseur se lit sur la tranche. Ces couches ne servent qu'au manuscrit ;
   le reste de la page reste sans texture. */
.process-paper,
.specimen-page {
  --ms-text: rgba(15, 23, 42, 0.58);
  --ms-text-faint: rgba(15, 23, 42, 0.32);
  --word-a: 26px;
  --word-b: 41px;
  --word-c: 63px;
  --word-space: 4px;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border: 1px solid var(--ms-rule);
  background-color: var(--ms-paper);
  background-image:
    radial-gradient(132% 98% at 6% -8%, rgba(255, 255, 255, 0.96), rgba(255, 255, 255, 0) 56%),
    linear-gradient(197deg, #ffffff 0%, #fdfdfc 46%, #f3f5f9 100%);
  line-height: 1;
}

/* Le grain, posé en multiplication par-dessus l'encre comme par-dessus le
   papier : une marque imprimée prend la fibre de la feuille. */
.process-paper::after,
.specimen-page::after {
  content: "";
  position: absolute;
  z-index: 3;
  inset: 0;
  opacity: 0.22;
  mix-blend-mode: multiply;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.86' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23f)'/%3E%3C/svg%3E");
  background-size: 140px 140px;
}

.process-paper {
  --word-a: 11px;
  --word-b: 17px;
  --word-c: 29px;
  --word-space: 2.5px;
  display: grid;
  align-content: start;
  gap: 9px;
  padding: var(--s-5) var(--s-4);
  box-shadow:
    0 1px 1px rgba(2, 6, 23, 0.12),
    0 3px 7px rgba(2, 6, 23, 0.1),
    0 14px 30px rgba(2, 6, 23, 0.16);
}

.process-paper .specimen-head {
  gap: 5px;
}

.process-paper .specimen-title {
  height: 8px;
  width: 84%;
  -webkit-mask-image:
    repeating-linear-gradient(90deg, #000 0 17px, transparent 17px 21px),
    repeating-linear-gradient(90deg, #000 0 26px, transparent 26px 29px);
  mask-image:
    repeating-linear-gradient(90deg, #000 0 17px, transparent 17px 21px),
    repeating-linear-gradient(90deg, #000 0 26px, transparent 26px 29px);
}

.process-paper .specimen-byline {
  height: 3px;
  -webkit-mask-image: repeating-linear-gradient(90deg, #000 0 9px, transparent 9px 12px);
  mask-image: repeating-linear-gradient(90deg, #000 0 9px, transparent 9px 12px);
}

.process-paper .specimen-para {
  gap: 5px;
}

.process-paper .specimen-line {
  height: 4px;
}

.process-scan {
  position: absolute;
  z-index: 2;
  top: 20px;
  right: 0;
  left: 0;
  height: 2px;
  background: var(--red);
  opacity: 0;
  box-shadow: 0 0 12px var(--red-line);
  transform: translateY(0);
  animation: process-scan var(--process-loop) var(--ease-in-out) infinite both;
}

/* Le numéro se pose au bout de la ligne qu'il commente, là où un relecteur
   l'écrirait, et non à une hauteur fixe dans la marge. */
.process-marker {
  position: absolute;
  top: 50%;
  left: 100%;
  display: grid;
  place-items: center;
  width: 16px;
  height: 16px;
  border: 1.5px solid var(--ms-mark);
  border-radius: 50%;
  background: var(--ms-paper);
  margin-left: 4px;
  color: var(--ms-mark);
  font-family: var(--font-meta);
  font-size: 9px;
  font-style: normal;
  line-height: 1;
  opacity: 1;
  transform: translateY(-50%) scale(1);
  animation: process-marker-in var(--process-loop) var(--ease-out) infinite both;
}

.marker-two { animation-delay: 180ms; }

.process-findings {
  display: grid;
  align-content: start;
  gap: var(--s-3);
  border: 1px solid var(--rule-soft);
  background: var(--card-raised);
  padding: var(--s-3);
}

.process-finding {
  display: grid;
  gap: var(--s-2);
  border-radius: var(--r-md);
  background: var(--rule-soft);
  padding: var(--s-3);
  opacity: 1;
  transform: none;
  animation: process-finding-in var(--process-loop) var(--ease-out) infinite both;
}

.finding-minor {
  animation-delay: 280ms;
}

.process-delivery {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-2);
  border-top: 1px solid var(--rule);
  padding-top: var(--s-3);
  opacity: 1;
  transform: none;
  animation: process-delivery-in var(--process-loop) var(--ease-out) infinite both;
}

.delivery-file {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  min-width: 0;
  color: var(--ink-soft);
  font-family: var(--font-meta);
  font-size: 11px;
}

.delivery-file strong {
  flex: 0 0 auto;
  border: 1px solid var(--rule);
  border-radius: var(--r-sm);
  background: var(--card-raised);
  color: var(--ink);
  padding: 2px 5px;
  font-size: 9px;
  letter-spacing: 0.04em;
}

.delivery-ready {
  grid-column: 1 / -1;
  color: var(--red);
  font-family: var(--font-meta);
  font-size: 11px;
  font-weight: var(--w-strong);
  text-align: right;
}

.frame-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 290px;
  min-height: 380px;
}

.frame-canvas {
  display: grid;
  place-items: center;
  border-right: 1px solid var(--rule);
  background: var(--paper-deep);
  padding: var(--s-7);
}

/* La page du manuscrit reste blanche dans les deux thèmes : c'est du papier,
   et une feuille n'a pas d'angle arrondi. Ses proportions sont celles d'une
   page imprimée, et sa mise en page celle d'un article : titre, signature,
   filet, puis deux colonnes. */
.specimen-page {
  display: grid;
  align-content: start;
  gap: var(--s-3);
  width: 100%;
  padding: var(--s-6) var(--s-5);
  box-shadow:
    0 1px 1px rgba(15, 23, 42, 0.12),
    0 3px 8px rgba(15, 23, 42, 0.08),
    0 16px 34px rgba(15, 23, 42, 0.12),
    0 34px 64px rgba(15, 23, 42, 0.14);
}

.specimen-annotated {
  --word-a: 18px;
  --word-b: 27px;
  --word-c: 44px;
  --word-space: 3px;
  grid-template-rows: auto auto minmax(0, 1fr);
  aspect-ratio: 1 / 1.3;
  padding: 26px 30px 22px 26px;
}

.specimen-head {
  display: grid;
  justify-items: center;
  gap: 6px;
}

.specimen-title {
  height: 9px;
  width: 78%;
  background: var(--ms-ink);
  -webkit-mask-image:
    repeating-linear-gradient(90deg, #000 0 42px, transparent 42px 48px),
    repeating-linear-gradient(90deg, #000 0 63px, transparent 63px 68px);
  mask-image:
    repeating-linear-gradient(90deg, #000 0 42px, transparent 42px 48px),
    repeating-linear-gradient(90deg, #000 0 63px, transparent 63px 68px);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

.specimen-title.short {
  width: 52%;
}

.specimen-byline {
  height: 4px;
  width: 56%;
  background: var(--ms-text-faint);
  -webkit-mask-image: repeating-linear-gradient(90deg, #000 0 14px, transparent 14px 18px);
  mask-image: repeating-linear-gradient(90deg, #000 0 14px, transparent 14px 18px);
}

.specimen-rule {
  height: 1px;
  background: var(--ms-rule);
}

.specimen-columns {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-6);
  overflow: hidden;
}

.specimen-column {
  display: grid;
  align-content: start;
  gap: 9px;
}

.specimen-para {
  display: grid;
  gap: 5px;
  margin: 0;
}

/* Alinéa : la première ligne d'un paragraphe rentre, les suivantes non. */
.specimen-para + .specimen-para > .specimen-line:first-child {
  margin-left: 9px;
}

.specimen-heading {
  height: 6px;
  width: 46%;
  background: var(--ms-ink);
  -webkit-mask-image: repeating-linear-gradient(90deg, #000 0 20px, transparent 20px 24px);
  mask-image: repeating-linear-gradient(90deg, #000 0 20px, transparent 20px 24px);
}

.specimen-line {
  position: relative;
  height: 5px;
}

/* Un bloc de texte, pas une barre pleine : trois trames de périodes premières
   entre elles se recoupent, et les mots qui restent sont de longueurs
   inégales. L'encre vit dans le pseudo-élément, pour que les marques portées
   par la ligne échappent au masque. */
.specimen-line::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--ms-text);
  -webkit-mask-image:
    repeating-linear-gradient(90deg, #000 0 var(--word-a), transparent var(--word-a) calc(var(--word-a) + var(--word-space))),
    repeating-linear-gradient(90deg, #000 0 var(--word-b), transparent var(--word-b) calc(var(--word-b) + var(--word-space))),
    repeating-linear-gradient(90deg, #000 0 var(--word-c), transparent var(--word-c) calc(var(--word-c) + var(--word-space)));
  mask-image:
    repeating-linear-gradient(90deg, #000 0 var(--word-a), transparent var(--word-a) calc(var(--word-a) + var(--word-space))),
    repeating-linear-gradient(90deg, #000 0 var(--word-b), transparent var(--word-b) calc(var(--word-b) + var(--word-space))),
    repeating-linear-gradient(90deg, #000 0 var(--word-c), transparent var(--word-c) calc(var(--word-c) + var(--word-space)));
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

/* Décalage de la trame d'une ligne à l'autre : deux lignes voisines ne coupent
   pas leurs mots au même endroit. */
.specimen-line:nth-of-type(4n + 2)::before {
  -webkit-mask-position: -7px 0, -13px 0, -21px 0;
  mask-position: -7px 0, -13px 0, -21px 0;
}

.specimen-line:nth-of-type(4n + 3)::before {
  -webkit-mask-position: -15px 0, -25px 0, -9px 0;
  mask-position: -15px 0, -25px 0, -9px 0;
}

.specimen-line:nth-of-type(4n)::before {
  -webkit-mask-position: -4px 0, -19px 0, -34px 0;
  mask-position: -4px 0, -19px 0, -34px 0;
}

.specimen-line.w45 { width: 45%; }
.specimen-line.w60 { width: 60%; }
.specimen-line.w70 { width: 70%; }
.specimen-line.w80 { width: 80%; }
.specimen-line.w82 { width: 82%; }
.specimen-line.w85 { width: 85%; }
.specimen-line.w88 { width: 88%; }
.specimen-line.w90 { width: 90%; }

/* Le surligneur : un trait passé à la main, qui déborde du mot, dont les bouts
   ne sont pas d'équerre et dont la charge est plus forte au départ et à
   l'arrêt du geste. Il multiplie, l'encre reste donc lisible dessous. */
.specimen-line.marked::after,
.specimen-line.process-evidence::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -3px -5px -3px -3px;
  background: linear-gradient(
    92deg,
    rgba(250, 204, 21, 0.92) 0%,
    rgba(254, 240, 138, 0.7) 14%,
    rgba(254, 240, 138, 0.84) 66%,
    rgba(250, 204, 21, 0.95) 100%
  );
  clip-path: polygon(1.2% 9%, 99.4% 0%, 100% 89%, 0.4% 100%);
  mix-blend-mode: multiply;
  transform: rotate(-0.5deg);
}

.specimen-line.process-evidence::after {
  inset: -2px -4px -2px -2px;
}

/* Le trait de stylo : tracé d'un geste, il ondule et ne tient pas la ligne. */
.pen-underline {
  position: absolute;
  right: -3px;
  bottom: -5px;
  left: -2px;
  height: 6px;
  overflow: visible;
  fill: none;
  stroke: var(--ms-mark);
  stroke-width: 1.3;
  stroke-linecap: round;
}

/* La note du relecteur, écrite dans la marge du bas. */
.pen-note {
  position: absolute;
  bottom: 7px;
  left: 26px;
  width: 116px;
  height: 15px;
  fill: none;
  stroke: var(--ms-mark);
  stroke-width: 1.2;
  stroke-linecap: round;
  opacity: 0.85;
  transform: rotate(-1.2deg);
}

.specimen-figure {
  display: grid;
  gap: 6px;
  margin: 3px 0 0;
}

.specimen-plot {
  width: 100%;
  height: auto;
  fill: none;
  stroke: var(--ms-text);
  stroke-width: 1.1;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.specimen-plot .axis {
  stroke: rgba(15, 23, 42, 0.55);
}

.specimen-plot .dot {
  fill: rgba(15, 23, 42, 0.55);
  stroke: none;
}

.specimen-caption {
  height: 3px;
  background: var(--ms-text-faint);
  -webkit-mask-image: repeating-linear-gradient(90deg, #000 0 12px, transparent 12px 15px);
  mask-image: repeating-linear-gradient(90deg, #000 0 12px, transparent 12px 15px);
}

.specimen-caption.short {
  width: 64%;
}

/* Le numéro se pose au bout de la ligne qu'il commente, dans le blanc laissé
   par la colonne : c'est là qu'une main l'écrirait. */
.marker {
  position: absolute;
  top: 50%;
  left: 100%;
  display: grid;
  place-items: center;
  width: 19px;
  height: 19px;
  border: 1.5px solid var(--ms-mark);
  border-radius: 50%;
  background: var(--ms-paper);
  margin-left: 5px;
  color: var(--ms-mark);
  font-family: var(--font-meta);
  font-size: 11px;
  font-style: normal;
  line-height: 1;
  transform: translateY(-50%);
}

.frame-panel {
  display: grid;
  align-content: start;
  gap: var(--s-3);
  padding: var(--s-5) var(--s-4);
}

.frame-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--rule);
  padding-bottom: var(--s-3);
  color: var(--ink-faint);
  font-family: var(--font-meta);
  font-size: 13px;
  font-weight: var(--w-strong);
}

.frame-count {
  color: var(--red);
}

.specimen-card {
  border-radius: var(--r-md);
  background: var(--red-soft);
  padding: var(--s-3) var(--s-4);
}

.specimen-card-title {
  display: block;
  color: var(--ink);
  font-family: var(--font-meta);
  font-size: 13px;
  font-weight: var(--w-strong);
}

.specimen-card-body {
  margin-top: var(--s-2);
  color: var(--ink-soft);
  font-size: 14px;
  line-height: 1.6;
}

.specimen-card-evidence {
  display: block;
  margin-top: var(--s-2);
  color: var(--ink-faint);
  font-family: var(--font-meta);
  font-size: 13px;
  line-height: 1.6;
}

.mock-comment {
  display: grid;
  gap: var(--s-2);
  border-radius: var(--r-md);
  background: var(--rule-soft);
  padding: var(--s-3) var(--s-4);
}

.chip {
  justify-self: start;
  border: 1px solid var(--rule);
  border-radius: var(--r-pill);
  padding: var(--s-half) var(--s-3);
  color: var(--ink-faint);
  font-family: var(--font-meta);
  font-size: 12px;
  font-weight: var(--w-strong);
}

.chip-major {
  border-color: var(--red-line);
  color: var(--red);
}

.sk {
  height: 7px;
  border-radius: var(--r-pill);
  background: var(--rule);
}

.sk.strong { height: 11px; background: var(--rule); }
.sk.w45 { width: 45%; }
.sk.w60 { width: 60%; }
.sk.w70 { width: 70%; }
.sk.w80 { width: 80%; }
.sk.w82 { width: 82%; }
.sk.w90 { width: 90%; }

/* --------------------------------------------------------------------------
   Bande des garanties
   Une ligne de colophon : quatre promesses numérotées, séparées par des filets.
   -------------------------------------------------------------------------- */

.proof {
  margin-top: var(--v-4);
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding: var(--v-1) 0;
}

.proof-list {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: proof;
}

.proof-list li {
  counter-increment: proof;
  border-left: 1px solid var(--rule);
  padding: var(--s-1) var(--s-6);
  color: var(--ink-soft);
  font-size: 15px;
  line-height: 1.45;
}

.proof-list li:first-child {
  border-left: 0;
  padding-left: 0;
}

.proof-list li::before {
  content: "0" counter(proof);
  display: block;
  margin-bottom: var(--s-2);
  color: var(--red);
  font-family: var(--font-meta);
  font-size: 13px;
  font-weight: var(--w-strong);
}

/* --------------------------------------------------------------------------
   Sections
   -------------------------------------------------------------------------- */

.band {
  padding: var(--v-5) 0 0;
  scroll-margin-top: var(--v-3);
}

.section-head {
  max-width: 680px;
  margin-bottom: var(--v-2);
}

.section-head.center {
  margin-left: auto;
  margin-right: auto;
  text-align: center;
}

/* La mesure du texte se règle sur le texte, jamais sur le titre : un titre
   court n'a aucune raison de casser en deux parce que sa légende est étroite. */
.section-lede,
.section-head.center .section-lede {
  max-width: 46ch;
}

.section-head.center .section-lede {
  margin-left: auto;
  margin-right: auto;
}

.kicker {
  display: inline-block;
  margin-bottom: var(--s-4);
  color: var(--red);
}

.section-title {
  font-size: clamp(34px, 5.2vw, 68px);
}

.section-lede {
  margin-top: var(--s-5);
  color: var(--ink-soft);
  font-size: 18px;
}

.section-footnote {
  margin-top: var(--s-6);
  color: var(--ink-faint);
  font-size: 14px;
  line-height: 1.7;
}

.section-footnote.center {
  max-width: 52ch;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
}

.section-footnote.privacy-note {
  margin-top: var(--s-2);
}

/* --------------------------------------------------------------------------
   Livrables
   Rangées alternées, chacune ouverte par son numéro : le numéro d'un article
   dans un sommaire.
   -------------------------------------------------------------------------- */

.features {
  display: grid;
  gap: var(--v-5);
}

.feature {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--v-2);
  align-items: center;
}

.feature:nth-child(even) .feature-copy {
  order: 2;
}

.feature-copy {
  padding-top: var(--s-3);
}

/* Le numéro d'article ouvre le bloc, à la taille d'un libellé : un chiffre de
   pleine page derrière le titre se lit comme une texture, pas comme un
   repère. */
.feature-index {
  display: block;
  margin-bottom: var(--s-3);
  color: var(--red);
  font-family: var(--font-meta);
  font-size: 14px;
  font-weight: var(--w-strong);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.feature-copy h3 {
  font-size: clamp(27px, 3.4vw, 44px);
}

.feature-copy p {
  max-width: 48ch;
  margin-top: var(--s-5);
  color: var(--ink-soft);
}

.feature-visual {
  display: grid;
  place-items: center;
}

.mock-window {
  width: 100%;
  overflow: hidden;
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  background: var(--card);
  box-shadow: var(--page-shadow);
}

.md-lines {
  display: grid;
  gap: var(--s-3);
  padding: var(--s-6) var(--s-5);
}

.md-line {
  display: flex;
  align-items: center;
  gap: var(--s-3);
}

.md-line.indent {
  padding-left: var(--s-5);
}

.md-token {
  color: var(--red);
  font-family: ui-monospace, "SFMono-Regular", "Consolas", "Liberation Mono", monospace;
  font-size: 13px;
}

.md-line .sk {
  flex: 1;
}

.mock-code {
  margin: 0;
  padding: var(--s-6) var(--s-5);
  color: var(--ink-soft);
  font-family: ui-monospace, "SFMono-Regular", "Consolas", "Liberation Mono", monospace;
  font-size: 13px;
  line-height: 1.8;
  overflow-x: auto;
}

.mock-code .k { color: var(--ink); }
.mock-code .s { color: var(--red); }
.mock-code .p { color: var(--ink-faint); }

.paper-stack {
  position: relative;
  width: 100%;
  display: grid;
  justify-items: center;
  padding: var(--s-5) var(--v-1);
}

/* Les trois feuilles occupent la même cellule : la pile se tient par le
   décalage des tranches, non par l'inclinaison des pages. */
.paper-sheets {
  position: relative;
  display: grid;
  width: 100%;
  max-width: 340px;
}

.paper-sheets > .specimen-page {
  grid-area: 1 / 1;
}

.paper-back {
  background-image: linear-gradient(197deg, #fbfcfd 0%, #f4f6f9 52%, #e9edf3 100%);
  box-shadow: 0 2px 6px rgba(15, 23, 42, 0.1), 0 10px 22px rgba(15, 23, 42, 0.1);
}

.paper-back::after {
  opacity: 0.1;
}

.paper-back-near {
  transform: translate(5px, 7px);
}

.paper-back-far {
  transform: translate(10px, 14px);
}

/* --------------------------------------------------------------------------
   Protocole
   Une frise tenue par un filet vertical, chaque passe numérotée sur le filet.
   -------------------------------------------------------------------------- */

.how-layout {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: var(--v-3);
  align-items: start;
}

.how-intro {
  position: sticky;
  top: 96px;
}

.how-intro .section-head,
.how-intro .kicker {
  margin-bottom: 0;
}

.how-intro .section-title {
  margin-top: var(--s-4);
}

/* Le retrait de la frise et la position des pastilles sont une seule mesure :
   un jeton, pour qu'elles ne puissent pas deriver l'une sans l'autre. */
.timeline {
  --timeline-gutter: 46px;
  position: relative;
  margin: 0;
  padding: 0 0 0 var(--timeline-gutter);
  list-style: none;
  counter-reset: step;
}

.timeline::before {
  content: "";
  position: absolute;
  top: 8px;
  bottom: 8px;
  left: 11px;
  width: 1px;
  background: var(--rule);
}

/* Les pastilles passent au-dessus des deux filets : une passe interrompt la
   course, la course ne barre pas son numéro. */
.timeline li {
  position: relative;
  z-index: 1;
  counter-increment: step;
  padding: 0 0 var(--v-2);
}

.timeline li:last-child {
  padding-bottom: 0;
}

.timeline li::before {
  content: counter(step, decimal-leading-zero);
  position: absolute;
  top: 0;
  left: calc(var(--timeline-gutter) * -1);
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border: 1.5px solid var(--rule);
  border-radius: 50%;
  background: var(--paper);
  color: var(--ink-faint);
  font-family: var(--font-meta);
  font-size: 12px;
  line-height: 1;
  transition: border-color 200ms var(--ease-hover), color 200ms var(--ease-hover);
}

@media (hover: hover) and (pointer: fine) {
  .timeline li:hover::before {
    border-color: var(--red);
    color: var(--red);
  }
}

/* Le filet se remplit au défilement : une frise de passes n'est pas une liste,
   c'est une course, et elle avance au rythme où elle se lit. Il se superpose
   au filet gris, au pixel près, pour que la limite entre ce qui est couru et
   ce qui reste soit la seule chose qui bouge. */
.timeline.is-running::after {
  content: "";
  position: absolute;
  top: 8px;
  left: 11px;
  width: 1px;
  height: calc(100% - 16px);
  background: var(--red);
  transform: scaleY(var(--run, 0));
  transform-origin: top;
}

/* Une passe courue garde la marque du relecteur ; celle où le filet s'arrête
   la porte pleine. */
.timeline li.is-run::before {
  border-color: var(--red-line);
  color: var(--red);
}

.timeline li.is-active::before {
  border-color: var(--red);
  background: var(--red);
  color: var(--red-ink);
}

/* L'onde ne part qu'à l'instant où le filet atteint la pastille : elle date le
   passage, elle ne pulse pas. */
.timeline li::after {
  content: "";
  position: absolute;
  top: -4px;
  left: calc(var(--timeline-gutter) * -1 - 4px);
  width: 32px;
  height: 32px;
  border: 1px solid var(--red);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
}

.timeline li.is-active::after {
  animation: step-ring 900ms var(--ease-out) both;
}

@keyframes step-ring {
  0% {
    opacity: 0.7;
    transform: scale(0.78);
  }
  100% {
    opacity: 0;
    transform: scale(1.14);
  }
}

.timeline h3 {
  font-size: 26px;
}

.timeline p {
  max-width: 54ch;
  margin-top: var(--s-3);
  color: var(--ink-soft);
  font-size: 16px;
}

/* --------------------------------------------------------------------------
   Offres
   Deux cartes. La seconde porte sa mention.
   -------------------------------------------------------------------------- */

.plan-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-6);
  max-width: 860px;
  margin: 0 auto;
}

/* Colonne et non grille : la liste de points prend le reste de la hauteur, ce
   qui aligne les deux boutons d'un ticket a l'autre malgre des listes de
   longueurs differentes. */
.plan {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--rule);
  border-radius: var(--r-xl);
  background: var(--card);
  padding: var(--v-1) var(--s-7) var(--s-7);
  transition: transform 300ms var(--ease-out), border-color 300ms var(--ease-hover);
}

.plan.featured {
  border-color: var(--red-line);
}

@media (hover: hover) and (pointer: fine) {
  .plan:hover {
    border-color: var(--ink);
    transform: translateY(-4px);
  }
}

.plan h3 {
  font-size: 22px;
  font-weight: var(--w-display);
}

.plan-price {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
  margin-top: var(--s-5);
}

.plan-amount {
  font-family: var(--font-display);
  font-size: 72px;
  font-weight: var(--w-display);
  line-height: 0.9;
  letter-spacing: -0.03em;
  font-variant-numeric: lining-nums;
}

.plan-period {
  color: var(--ink-faint);
  font-family: var(--font-meta);
  font-size: 15px;
}

.plan-unit {
  margin-top: var(--s-3);
  color: var(--ink-faint);
}

.plan-points {
  flex: 1 1 auto;
  display: grid;
  align-content: start;
  gap: var(--s-3);
  margin: var(--s-6) 0 var(--s-7);
  padding: var(--s-6) 0 0;
  border-top: 1px solid var(--rule);
  list-style: none;
  color: var(--ink-soft);
  font-size: 15px;
}

.plan-points li {
  position: relative;
  padding-left: var(--s-6);
}

/* La coche du relecteur, pas une puce. */
.plan-points li::before {
  content: "✓";
  position: absolute;
  left: 0;
  color: var(--red);
  font-family: var(--font-meta);
  font-size: 14px;
}

.landing-body .plan-cta {
  width: 100%;
  height: 44px;
  justify-content: center;
}

/* La mention de l'offre retenue : une pastille teintée dans l'angle, du même
   crimson que les marques. */
.plan-flag {
  position: absolute;
  top: var(--s-5);
  right: var(--s-6);
  border-radius: var(--r-pill);
  background: var(--red-soft);
  padding: var(--s-1) var(--s-3);
  color: var(--red);
  font-size: 13px;
}

.pricing-error {
  margin-bottom: var(--s-6);
  scroll-margin-top: calc(var(--s-6) * 4);
  color: var(--red);
  font-family: var(--font-meta);
  font-size: 15px;
  text-align: center;
}

/* --------------------------------------------------------------------------
   Questions
   Filets seuls, aucun cadre : une liste de renvois en fin d'article.
   -------------------------------------------------------------------------- */

.faq {
  max-width: 760px;
  margin: 0 auto;
  border-top: 1px solid var(--rule);
}

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

.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  padding: var(--s-6) 0;
  color: var(--ink);
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: var(--w-strong);
  cursor: pointer;
  list-style: none;
  transition: color 180ms var(--ease-hover);
}

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

.faq-item summary::after {
  content: "+";
  flex: none;
  color: var(--red);
  font-family: var(--font-meta);
  font-size: 22px;
  font-weight: var(--w-text);
  line-height: 1;
  transition: transform 240ms var(--ease-out);
}

.faq-item[open] summary::after {
  transform: rotate(45deg);
}

@media (hover: hover) and (pointer: fine) {
  .faq-item summary:hover {
    color: var(--red);
  }
}

.faq-item p {
  max-width: 62ch;
  padding: 0 0 var(--s-6);
  color: var(--ink-soft);
  font-size: 16px;
}

/* --------------------------------------------------------------------------
   Appel final
   -------------------------------------------------------------------------- */

.cta-band {
  position: relative;
  margin: var(--v-5) 0;
  border: 1px solid var(--rule);
  border-radius: var(--r-xl);
  background: var(--card);
  padding: var(--v-4) var(--v-2) var(--v-4);
  text-align: center;
  overflow: hidden;
}

.cta-band > * {
  position: relative;
}

/* La mention d'ouverture : une pastille teintée, comme celle d'une offre. */
.stamp {
  display: inline-block;
  border-radius: var(--r-pill);
  background: var(--red-soft);
  margin-bottom: var(--s-7);
  padding: var(--s-2) var(--s-4);
  color: var(--red);
  font-family: var(--font-meta);
  font-size: 14px;
  font-weight: var(--w-strong);
}

.cta-band h2 {
  max-width: 19ch;
  margin: 0 auto;
  font-size: clamp(32px, 5.4vw, 72px);
}

.cta-band p {
  margin-top: var(--s-5);
  color: var(--ink-faint);
  font-family: var(--font-meta);
  font-size: 15px;
}

.cta-band .hero-actions {
  justify-content: center;
  margin-top: var(--v-1);
}

/* --------------------------------------------------------------------------
   Pied de page
   -------------------------------------------------------------------------- */

.site-footer {
  border-top: 1px solid var(--rule);
  background: var(--paper-deep);
}

.footer-inner {
  max-width: var(--content);
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr));
  gap: var(--v-2);
  margin: 0 auto;
  padding: var(--v-2) var(--gutter) var(--v-3);
}

.footer-brand p {
  max-width: 34ch;
  margin-top: var(--s-4);
  color: var(--ink-faint);
  font-family: var(--font-meta);
  font-size: 14px;
  line-height: 1.7;
}

.footer-col h2 {
  margin-bottom: var(--s-4);
  color: var(--ink-faint);
  font-weight: var(--w-strong);
}

.footer-col ul {
  display: grid;
  gap: var(--s-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.footer-col a {
  color: var(--ink-soft);
  font-size: 15px;
  text-decoration: none;
}


/* --------------------------------------------------------------------------
   Mouvement
   Une seule orchestration à l'ouverture, puis des apparitions au défilement.
   `[data-reveal]` n'est masqué que si le script a pris la main : sans lui, la
   page reste entièrement lisible.
   -------------------------------------------------------------------------- */

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(24px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}


@keyframes process-step-active {
  0%, 2% {
    opacity: 0;
    transform: scale(0.92);
  }
  4%, 20% {
    opacity: 1;
    transform: scale(1);
  }
  24%, 100% {
    opacity: 0;
    transform: scale(1.08);
  }
}

@keyframes process-scan {
  0%, 14% {
    opacity: 0;
    transform: translateY(0);
  }
  18% {
    opacity: 0.9;
  }
  52% {
    opacity: 0.9;
    transform: translateY(196px);
  }
  56%, 100% {
    opacity: 0;
    transform: translateY(196px);
  }
}

@keyframes process-marker-in {
  0%, 44% {
    opacity: 0;
    transform: translateY(-50%) scale(0.92);
  }
  50%, 90% {
    opacity: 1;
    transform: translateY(-50%) scale(1);
  }
  96%, 100% {
    opacity: 0;
    transform: translateY(-50%) scale(1.04);
  }
}

@keyframes process-finding-in {
  0%, 38% {
    opacity: 0;
    transform: translateY(8px);
  }
  44%, 88% {
    opacity: 1;
    transform: none;
  }
  94%, 100% {
    opacity: 0;
    transform: translateY(-4px);
  }
}

@keyframes process-delivery-in {
  0%, 68% {
    opacity: 0;
    transform: translateY(8px);
  }
  74%, 90% {
    opacity: 1;
    transform: none;
  }
  96%, 100% {
    opacity: 0;
    transform: translateY(-4px);
  }
}

.hero-copy > *,
.margin-note,
.product-frame {
  animation: rise 700ms var(--ease-out) both;
}

.hero-copy > .hero-title { animation-delay: 140ms; }
.hero-copy > .hero-lede { animation-delay: 280ms; }
.hero-copy > .hero-actions { animation-delay: 360ms; }
.hero-copy > .hero-note,
.hero-copy > .privacy-note { animation-delay: 430ms; }
.margin-note { animation-delay: 620ms; }
.product-frame { animation-delay: 280ms; }

.js-reveal [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 540ms var(--ease-out), transform 540ms var(--ease-out);
}

.js-reveal [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

.js-reveal .proof-list li[data-reveal]:nth-child(2) { transition-delay: 80ms; }
.js-reveal .proof-list li[data-reveal]:nth-child(3) { transition-delay: 160ms; }
.js-reveal .proof-list li[data-reveal]:nth-child(4) { transition-delay: 240ms; }

.js-reveal .plan-grid .plan[data-reveal]:nth-child(2) { transition-delay: 80ms; }
.js-reveal .faq .faq-item[data-reveal]:nth-child(2) { transition-delay: 60ms; }
.js-reveal .faq .faq-item[data-reveal]:nth-child(3) { transition-delay: 120ms; }
.js-reveal .faq .faq-item[data-reveal]:nth-child(4) { transition-delay: 180ms; }
.js-reveal .faq .faq-item[data-reveal]:nth-child(5) { transition-delay: 240ms; }
.js-reveal .faq .faq-item[data-reveal]:nth-child(6) { transition-delay: 300ms; }

/* Les soulignés du titre se tracent d'un geste, l'un après l'autre, une fois
   le titre posé : la lecture suit l'ordre des couleurs. `scale` et non
   `transform`, qui porte déjà l'inclinaison du trait. */
@keyframes stroke-draw {
  from { scale: 0 1; }
  to { scale: 1 1; }
}

.hero-emphasis::after {
  animation: stroke-draw 620ms var(--ease-out) both;
}

.hero-emphasis-review::after { animation-delay: 760ms; }
.hero-emphasis-scientifically::after { animation-delay: 940ms; }
.hero-emphasis-submission::after { animation-delay: 1120ms; }

/* Les articles arrivent de leur côté : le texte depuis sa colonne, le visuel
   depuis l'autre. Le bloc ne fait plus que son fondu, ses deux moitiés
   portent le déplacement. */
.js-reveal .feature[data-reveal] {
  transform: none;
}

.js-reveal .feature[data-reveal] > .feature-copy,
.js-reveal .feature[data-reveal] > .feature-visual {
  transition: transform 700ms var(--ease-out);
}

.js-reveal .feature[data-reveal] > .feature-copy { transform: translateX(-24px); }
.js-reveal .feature[data-reveal] > .feature-visual { transform: translateX(24px); transition-delay: 120ms; }
.js-reveal .feature[data-reveal]:nth-child(even) > .feature-copy { transform: translateX(24px); }
.js-reveal .feature[data-reveal]:nth-child(even) > .feature-visual { transform: translateX(-24px); }

.js-reveal .feature[data-reveal].is-revealed > .feature-copy,
.js-reveal .feature[data-reveal].is-revealed > .feature-visual {
  transform: none;
}

/* Sur les visuels, la correction s'écrit à l'arrivée : le stylo trace ses
   traits, puis les points et les numéros se posent. Le tracé en pointillés
   garde ses tirets et n'apparaît qu'en fondu. */
.js-reveal [data-reveal] .pen-underline path,
.js-reveal [data-reveal] .specimen-plot path:not(.axis):not([stroke-dasharray]) {
  stroke-dasharray: 140;
  stroke-dashoffset: 140;
  transition: stroke-dashoffset 1100ms var(--ease-out) 450ms;
}

.js-reveal [data-reveal] .specimen-plot path[stroke-dasharray] {
  opacity: 0;
  transition: opacity 600ms var(--ease-out) 900ms;
}

.js-reveal [data-reveal].is-revealed .pen-underline path,
.js-reveal [data-reveal].is-revealed .specimen-plot path:not(.axis):not([stroke-dasharray]) {
  stroke-dashoffset: 0;
}

.js-reveal [data-reveal].is-revealed .specimen-plot path[stroke-dasharray] {
  opacity: 1;
}

.js-reveal [data-reveal] .specimen-plot .dot,
.js-reveal [data-reveal] .marker {
  scale: 0;
  transform-box: fill-box;
  transform-origin: center;
  transition: scale 420ms cubic-bezier(0.34, 1.56, 0.64, 1) 900ms;
}

.js-reveal [data-reveal] .specimen-plot .dot:nth-of-type(2) { transition-delay: 990ms; }
.js-reveal [data-reveal] .specimen-plot .dot:nth-of-type(3) { transition-delay: 1080ms; }
.js-reveal [data-reveal] .specimen-plot .dot:nth-of-type(4) { transition-delay: 1170ms; }
.js-reveal [data-reveal] .specimen-plot .dot:nth-of-type(5) { transition-delay: 1260ms; }

.js-reveal [data-reveal].is-revealed .specimen-plot .dot,
.js-reveal [data-reveal].is-revealed .marker {
  scale: 1;
}

/* La revue en cours se signale par une onde autour de sa pastille. */
@keyframes ping {
  from { scale: 1; opacity: 0.6; }
  75%,
  to { scale: 2.6; opacity: 0; }
}

.status-dot {
  position: relative;
}

.status-dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: inherit;
  opacity: 0;
  animation: ping 2.2s cubic-bezier(0, 0, 0.2, 1) infinite;
}

/* L'offre mise en avant respire, dans le voile crimson qu'elle porte déjà. */
@keyframes glow-pulse {
  from { box-shadow: 0 0 0 0 var(--red-soft); }
  70%,
  to { box-shadow: 0 0 0 12px transparent; }
}

.plan.featured {
  animation: glow-pulse 3.2s var(--ease-out) infinite;
}

/* Un reflet traverse le bouton principal de temps en temps : il attire l'oeil
   sans clignoter. Il prend la couleur du papier, qui contraste avec la
   pastille dans les deux thèmes. */
@keyframes shimmer-slide {
  from,
  70% { translate: -120% 0; }
  to { translate: 220% 0; }
}

#heroStart {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

#heroStart::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  z-index: -1;
  width: 45%;
  background: linear-gradient(100deg, transparent, color-mix(in srgb, var(--paper) 35%, transparent), transparent);
  translate: -120% 0;
  pointer-events: none;
  animation: shimmer-slide 6s var(--ease-in-out) 1.6s infinite;
}

/* Les couleurs continuent de repondre, seuls les deplacements partent : couper
   aussi les transitions de couleur retirait tout retour au survol et a
   l'enfoncement, ce qui n'est pas ce que le reglage demande. */
@media (prefers-reduced-motion: reduce) {
  .landing-body *,
  .landing-body *::before,
  .landing-body *::after {
    animation: none !important;
    transition-property: opacity, color, background, background-color, border-color, box-shadow, outline-color,
      fill, stroke !important;
  }

  .plan {
    transform: none !important;
  }

  .js-reveal [data-reveal] {
    opacity: 1;
    transform: none;
  }

}

/* --------------------------------------------------------------------------
   Adaptatif
   -------------------------------------------------------------------------- */

@media (max-width: 1040px) {
  .hero {
    min-height: auto;
  }

  .hero-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s-7);
  }

  .hero-copy {
    max-width: 760px;
  }

  .product-frame {
    max-width: 680px;
    justify-self: start;
  }

  .how-layout {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s-8);
  }

  .how-intro {
    position: static;
  }

  .proof-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s-6) 0;
  }

  .proof-list li:nth-child(odd) {
    border-left: 0;
    padding-left: 0;
  }
}

/* Seuil mesuré : au-delà, tout tient sur la ligne du header, en français et avec
   une barre de défilement classique. */
@media (max-width: 1260px) {
  /* Le logo cède de la largeur plutôt que le bouton principal, « Ouvrir
     l'application » en français étant le cas le plus serré. */
  .brand {
    flex: 0 1 160px;
    min-width: 72px;
  }

  .landing-body .brand-mark {
    width: 100%;
  }

  .site-header-inner > .btn-solid {
    margin-left: auto;
  }

  .menu-toggle {
    display: inline-flex;
  }

  .site-menu {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: var(--s-4);
    /* 69 px : la hauteur du header, logo et marges compris. */
    max-height: calc(100dvh - 69px);
    overflow-y: auto;
    border-bottom: 1px solid var(--rule);
    background: var(--paper);
    /* Aligné sur le logo : la marge de `.site-header-inner` s'ajoute à sa largeur bornée. */
    padding: var(--s-3) max(calc(var(--gutter) * 2), calc((100% - var(--content)) / 2 + var(--gutter))) var(--s-5);
  }

  .site-menu.is-open {
    display: flex;
  }

  .site-nav {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin: 0;
  }

  .site-nav a {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  .site-actions {
    flex-wrap: wrap;
    border-top: 1px solid var(--rule);
    padding-top: var(--s-4);
  }

  .landing-body .site-actions .divider {
    display: none;
  }

  .site-actions .account-name {
    max-width: 100%;
  }

  .site-actions .header-link {
    display: flex;
    align-items: center;
    min-height: 44px;
    margin-left: auto;
  }
}

@media (max-width: 420px) {
  .site-header-inner {
    gap: var(--s-2);
  }

  .landing-body .site-header-inner > .btn-solid {
    padding: 0 var(--s-3);
    font-size: 14px;
  }
}

@media (max-width: 860px) {
  .frame-body {
    grid-template-columns: minmax(0, 1fr);
  }

  .frame-canvas {
    border-right: 0;
    border-bottom: 1px solid var(--rule);
  }

  .feature {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s-7);
  }

  .feature:nth-child(even) .feature-copy {
    order: 0;
  }

  /* Empilés, le texte et le visuel n'ont plus de côté d'où venir. */
  .js-reveal .feature[data-reveal] > .feature-copy,
  .js-reveal .feature[data-reveal] > .feature-visual,
  .js-reveal .feature[data-reveal]:nth-child(even) > .feature-copy,
  .js-reveal .feature[data-reveal]:nth-child(even) > .feature-visual {
    transform: translateY(16px);
  }

  .js-reveal .feature[data-reveal].is-revealed > .feature-copy,
  .js-reveal .feature[data-reveal].is-revealed > .feature-visual {
    transform: none;
  }

  .plan-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .footer-inner {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--v-1);
  }
}

@media (max-width: 560px) {
  .landing-body {
    --gutter: 18px;
    font-size: 16px;
  }

  .hero {
    padding-top: var(--v-2);
  }

  .hero-network {
    opacity: 0.72;
  }

  .hero-title {
    max-width: none;
    font-size: clamp(38px, 11vw, 54px);
  }

  .process-frame {
    gap: var(--s-3);
    padding: var(--s-3);
  }

  .process-step {
    font-size: 10px;
  }

  .process-workspace {
    grid-template-columns: 104px minmax(0, 1fr);
    gap: var(--s-2);
    min-height: 200px;
  }

  .process-paper {
    gap: 8px;
    padding: var(--s-4) var(--s-3);
  }

  .process-findings {
    gap: var(--s-2);
    padding: var(--s-2);
  }

  .process-finding {
    padding: var(--s-2);
  }

  .process-scan {
    animation-name: process-scan-mobile;
  }

  .delivery-file {
    align-items: flex-start;
  }

  .proof-list {
    grid-template-columns: minmax(0, 1fr);
  }

  .proof-list li {
    border-left: 0;
    padding-left: 0;
  }

  .band {
    padding-top: var(--v-3);
  }

  .features {
    gap: var(--v-3);
  }

  .cta-band {
    padding: var(--v-2) var(--s-6) var(--v-2);
  }

  .footer-inner {
    grid-template-columns: minmax(0, 1fr);
  }
}

@keyframes process-scan-mobile {
  0%, 14% {
    opacity: 0;
    transform: translateY(0);
  }
  18% {
    opacity: 0.9;
  }
  52% {
    opacity: 0.9;
    transform: translateY(172px);
  }
  56%, 100% {
    opacity: 0;
    transform: translateY(172px);
  }
}
