/**
 * ÉPURE — la direction qui fait du site public le parent des pages bio.
 *
 * Les cinq premières maquettes ont un défaut commun que la comparaison entre
 * elles ne révèle pas : aucune ne ressemble à `bio.css`. Or la page bio est la
 * page la PLUS vue du service — un membre partage la sienne des dizaines de
 * fois, le site public ne se visite qu'une fois. Une identité qui s'arrête à
 * l'accueil est une identité que presque personne ne voit.
 *
 * Cette feuille reprend donc, à l'identique, le système de la page bio :
 *
 *   1. oklch piloté par UNE variable de teinte
 *   2. deux halos radiaux plutôt qu'un aplat
 *   3. le grain fractal
 *   4. la même mesure de texte (38rem) et la même pile de polices
 *
 * Différence unique et voulue : la teinte est FIXE ici (émeraude, 162), là où
 * la page bio en tire une des douze selon le membre. Le site est le tronc, les
 * pages membres sont les branches — elles varient, il ne varie pas.
 *
 * ── Ce qui a été retiré, et pourquoi ──────────────────────────────────
 *
 * Les pastilles « Facile · Gratuit · Immédiat », la fausse conversation, la
 * trame technique, le monospace décoratif, la seconde couleur d'accent. Chacun
 * de ces éléments ajoute une promesse visuelle que le produit ne tient pas.
 * Sobriété ne veut pas dire pauvreté : elle veut dire que tout ce qui reste
 * sert à quelque chose.
 */

.ep *,
.ep *::before,
.ep *::after {
  box-sizing: border-box;
}

.ep {
  /* La teinte du service. Voisine du vert de `base.css` (#2f6d55), et membre
     de la famille des douze palettes bio (.t2 « émeraude »). Changer cette
     seule valeur reteinte le site entier sans toucher au contraste : c'est
     l'intérêt d'oklch sur des valeurs hexadécimales. */
  --h: 162;

  --fond-1: oklch(97% 0.02 var(--h));
  --fond-2: oklch(93% 0.05 var(--h));
  --accent: oklch(52% 0.17 var(--h));
  --accent-clair: oklch(94% 0.04 var(--h));
  --encre: oklch(21% 0.03 var(--h));
  --encre-douce: oklch(47% 0.03 var(--h));
  --carte: oklch(100% 0 0);
  --trait: oklch(90% 0.02 var(--h));

  margin: 0;
  min-height: 100dvh;
  color: var(--encre);
  font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;

  background-color: var(--fond-1);
  background-image:
    radial-gradient(ellipse 80% 55% at 12% -5%, var(--fond-2), transparent 70%),
    radial-gradient(ellipse 70% 50% at 92% 8%, var(--accent-clair), transparent 65%);
  background-attachment: fixed;
}

@media (prefers-color-scheme: dark) {
  .ep {
    --fond-1: oklch(16% 0.025 var(--h));
    --fond-2: oklch(23% 0.06 var(--h));
    --accent: oklch(78% 0.15 var(--h));
    --accent-clair: oklch(26% 0.06 var(--h));
    --encre: oklch(95% 0.01 var(--h));
    --encre-douce: oklch(72% 0.02 var(--h));
    --carte: oklch(21% 0.02 var(--h));
    --trait: oklch(31% 0.025 var(--h));
  }
}

/* Le grain, repris à l'identique de la page bio — c'est ce qui fait que les
   deux surfaces se reconnaissent au premier coup d'œil. Moins d'un kilo-octet,
   aucune requête réseau. */
.ep::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: 0.42;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.35'/%3E%3C/svg%3E");
}

@media (prefers-color-scheme: dark) {
  .ep::before {
    opacity: 0.28;
  }
}

/* ── La mesure ─────────────────────────────────────────────────────────
 *
 * 38rem, exactement comme `.bio-wrap`. Une seule largeur de lecture dans tout
 * le produit : c'est la moitié du travail d'harmonie, et ça ne se remarque que
 * si on l'oublie.
 */
.ep-wrap {
  position: relative;
  z-index: 1;
  width: min(38rem, 100% - 2.5rem);
  margin-inline: auto;
}

/* ── Le titre ──────────────────────────────────────────────────────────
 *
 * ⚠️ L'ORDRE EST L'IDÉE. Le lien passe AVANT le titre.
 *
 * C'est ce que la maquette « Signal » avait trouvé de juste, et c'est la seule
 * chose qu'on lui reprend. Le produit EST le lien : le montrer d'abord dit en
 * un coup d'œil ce qu'aucune phrase ne dit aussi vite. Le titre, derrière, ne
 * fait plus que confirmer.
 *
 * Ce qu'on ne lui reprend PAS : la trame réglée, le décor de terminal, le vert
 * électrique. C'était l'habillage d'une bonne idée, pas la bonne idée.
 *
 * `text-wrap: balance` évite le mot orphelin sur la dernière ligne : sur un
 * titre de cette taille, une veuve se voit de loin.
 */
.ep-hero {
  padding-block: clamp(3rem, 10vh, 5.5rem) clamp(2.5rem, 8vh, 4.5rem);
  display: grid;
  gap: 1.35rem;
}

.ep-marque {
  margin: 0;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--encre-douce);
}

/* ── Le lien en vedette ────────────────────────────────────────────────
 *
 * Le seul endroit du site où le monospace est employé — parce qu'ici il porte
 * un sens : c'est une adresse, elle se recopie, chaque caractère compte. Le
 * monospace décoratif des maquettes « Outil » et « Signal » disait « logiciel »
 * sans rien apporter ; celui-ci dit « voici votre adresse ».
 *
 * Le prénom est la seule chose en couleur, parce que c'est la seule chose qui
 * change d'une personne à l'autre — et donc la seule qui parle du lecteur.
 */
.ep-vedette {
  margin: 0;
  display: grid;
  gap: 0.5rem;
}

.ep-vedette-label {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--encre-douce);
}

.ep-url {
  font-family: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, monospace;
  /* Volontairement plus grand que le titre. Sur un écran de téléphone, la
     ligne doit tenir sans coupure : à 375 px, `pureleads.fr/p/marie` fait
     20 caractères, d'où la borne basse. */
  font-size: clamp(1.32rem, 0.7rem + 3.1vw, 2.35rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--encre-douce);
  overflow-wrap: anywhere;
}

.ep-url b {
  font-weight: 700;
  color: var(--accent);
}

/* Le curseur, repris de « Signal ». Il clignote — c'est ce qui fait qu'on
   regarde le lien plutôt que de le survoler, et c'est le mouvement qui donne
   à la page son air vivant sans rien coûter.
   Le clignotement n'entre qu'APRÈS la frappe (voir `--ep-frappe`), sinon deux
   animations se disputent l'attention au même endroit. */
.ep-url i {
  display: inline-block;
  width: 0.52em;
  height: 0.95em;
  margin-left: 0.06em;
  vertical-align: -0.1em;
  background: var(--accent);
  opacity: 0.9;
}

.ep h1 {
  margin: 0;
  /* Plus petit que le lien : c'est lui la vedette, pas le titre. */
  font-size: clamp(1.7rem, 1.3rem + 1.9vw, 2.5rem);
  line-height: 1.15;
  letter-spacing: -0.025em;
  font-weight: 700;
  text-wrap: balance;
}

/* Le seul mot en couleur de toute la page. Un accent qui sert une fois est un
   accent ; un accent qui sert dix fois est une couleur de fond. */
.ep h1 em {
  font-style: normal;
  color: var(--accent);
}

.ep-chapeau {
  margin: 0;
  font-size: clamp(1.05rem, 0.98rem + 0.35vw, 1.2rem);
  color: var(--encre-douce);
  max-width: 32rem;
  text-wrap: pretty;
}

/* ── Les actions ───────────────────────────────────────────────────────
 *
 * Un bouton plein, un lien souligné. Deux boutons de même poids obligent à
 * choisir, donc retardent — et sur un téléphone, retarder c'est perdre.
 */
.ep-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.9rem 1.5rem;
  margin-top: 0.5rem;
}

.ep-cta {
  display: inline-block;
  padding: 0.95rem 1.9rem;
  border-radius: 999px;
  background: var(--accent);
  /* Sur le vert clair du mode sombre, un texte blanc ne passerait pas le
     contraste. La couleur de fond sert d'encre : elle est garantie foncée. */
  color: var(--fond-1);
  font-weight: 650;
  font-size: 1.02rem;
  text-decoration: none;
  transition: transform 0.12s ease, opacity 0.12s ease;
}

.ep-cta:hover {
  opacity: 0.92;
  transform: translateY(-1px);
}

.ep-lien {
  color: var(--encre-douce);
  text-decoration: underline;
  text-underline-offset: 0.28em;
  text-decoration-thickness: 1px;
  font-size: 0.98rem;
}

.ep-lien:hover {
  color: var(--accent);
}

.ep-rassurance {
  margin: 0;
  font-size: 0.92rem;
  color: var(--encre-douce);
}

/* Une phrase de chute après une liste a besoin d'air, sinon elle se lit comme
   la fin du dernier élément — et sur « Trois étapes », cette phrase est
   justement l'argument de la section. */
.ep-liste + .ep-rassurance {
  margin-top: 1.75rem;
}

/* ── Les sections ──────────────────────────────────────────────────────
 *
 * Un filet fin plutôt qu'une carte. Les cartes empilées fabriquent le look
 * « tableau de bord » que cette direction cherche justement à éviter.
 */
.ep-section {
  padding-block: clamp(2.5rem, 8vh, 4rem);
  border-top: 1px solid var(--trait);
}

.ep h2 {
  margin: 0 0 2rem;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--encre-douce);
}

/* ── La liste numérotée ────────────────────────────────────────────────
 *
 * Le numéro est discret et aligné sur la ligne de base du titre. Ailleurs il
 * est énorme et coloré : c'est du décor qui prend la place du texte qu'on est
 * venu lire.
 */
.ep-liste {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2rem;
}

.ep-liste li {
  display: grid;
  grid-template-columns: 2.25rem 1fr;
  align-items: start;
  gap: 0.5rem;
}

.ep-num {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  padding-top: 0.28rem;
}

.ep-liste h3 {
  margin: 0 0 0.3rem;
  font-size: 1.12rem;
  font-weight: 650;
  letter-spacing: -0.01em;
}

.ep-liste p {
  margin: 0;
  color: var(--encre-douce);
  text-wrap: pretty;
}

/* ── La citation ───────────────────────────────────────────────────────
 *
 * Pas de guillemets géants, pas d'italique : le texte porte seul. Un filet
 * vertical suffit à dire « ceci est une voix, pas notre argumentaire ».
 */
.ep-citation {
  margin: 0;
  padding-left: 1.35rem;
  border-left: 2px solid var(--accent);
  font-size: clamp(1.2rem, 1rem + 0.8vw, 1.5rem);
  line-height: 1.4;
  letter-spacing: -0.015em;
  text-wrap: pretty;
}

/* ── Le catalogue ──────────────────────────────────────────────────────
 *
 * Deux groupes, « disponibles » et « en préparation ». La distinction n'est pas
 * cosmétique : annoncer un catalogue qu'on n'a pas est la façon la plus rapide
 * de perdre quelqu'un à sa première visite dans son espace.
 */
.ep-groupe {
  margin-top: 2rem;
}

.ep-groupe-titre {
  margin: 0 0 0.9rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--encre-douce);
}

.ep-jetons {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.ep-jetons li {
  padding: 0.45rem 0.9rem;
  border: 1px solid var(--trait);
  border-radius: 999px;
  background: var(--carte);
  font-size: 0.95rem;
  font-weight: 500;
}

/* Les pages à venir se lisent, mais ne se confondent pas avec les vraies. Un
   trait discontinu dit « pas encore » sans avoir à l'écrire sur chaque ligne. */
.ep-jetons-attente li {
  border-style: dashed;
  background: transparent;
  color: var(--encre-douce);
}

/* ── L'encart de l'offreur ─────────────────────────────────────────────
 *
 * Le seul endroit du site qui pousse vers l'extérieur. Il est volontairement
 * gros : c'est la contrepartie de la gratuité, et la seule que l'offreur
 * touche. Le cacher serait malhonnête envers lui autant qu'envers le lecteur.
 *
 * ⚠️ Ce n'est PAS une publicité au sens habituel : aucun suivi, aucun pixel,
 * aucune régie. Un lien, et c'est tout. C'est ce qui permet d'écrire « sans
 * publicité » ailleurs sur le site sans mentir.
 */
.ep-offreur {
  display: block;
  margin-top: 0.5rem;
  padding: clamp(1.5rem, 5vw, 2.25rem);
  border: 1px solid var(--trait);
  border-radius: 1.25rem;
  background: var(--carte);
  color: inherit;
  text-decoration: none;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.ep-offreur:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
}

.ep-offreur-nom {
  display: block;
  font-size: clamp(1.5rem, 1.1rem + 2vw, 2.1rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.1;
}

.ep-offreur-quoi {
  display: block;
  margin-top: 0.6rem;
  color: var(--encre-douce);
  text-wrap: pretty;
}

/* La flèche avance au survol. Un mouvement de deux pixels suffit à dire
   « ceci part ailleurs » — une icône de lien externe le dirait moins bien et
   pèserait davantage. */
.ep-offreur-aller {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1.4rem;
  font-weight: 650;
  color: var(--accent);
}

.ep-offreur-aller::after {
  content: '→';
  transition: transform 0.15s ease;
}

.ep-offreur:hover .ep-offreur-aller::after {
  transform: translateX(3px);
}

/* ⚠️ Par sélecteur et non par `style=""` : la politique de sécurité du site
   interdit les styles en ligne. Même règle que dans `bio.css`. */
.ep-offreur + .ep-rassurance {
  margin-top: 1.5rem;
}

/* ── Le pied ───────────────────────────────────────────────────────────── */

.ep-pied {
  padding-block: 2.5rem 3.5rem;
  border-top: 1px solid var(--trait);
  font-size: 0.9rem;
  color: var(--encre-douce);
}

.ep-pied a {
  color: inherit;
  text-underline-offset: 0.25em;
}

/* ══ LE MOUVEMENT ═══════════════════════════════════════════════════════
 *
 * Quatre animations, zéro octet de JavaScript, zéro dépendance à suivre. Tout
 * est natif : le navigateur les exécute sur son fil de composition, donc elles
 * restent fluides sur un Android d'entrée de gamme — ce qu'aucune bibliothèque
 * d'animation ne peut promettre.
 *
 * ⚠️ TOUT est sous `prefers-reduced-motion: no-preference`. Ce n'est pas une
 * politesse : le mouvement déclenche des nausées chez les personnes sujettes
 * au mal des transports, et le système d'exploitation connaît déjà leur
 * réponse. Une page qui ignore ce réglage rend malade sans jamais le savoir.
 */
@media (prefers-reduced-motion: no-preference) {
  /* ── 1. La frappe ────────────────────────────────────────────────────
   *
   * Le prénom s'écrit, caractère par caractère. C'est LE geste qui raconte le
   * produit sans une phrase : cette adresse va porter VOTRE nom.
   *
   * En monospace, l'unité `ch` vaut exactement une chasse de caractère : la
   * largeur finale tombe donc juste au pixel, sans mesure ni calcul. Le
   * nombre de pas de `steps()` est le nombre de lettres.
   */
  .ep-url b {
    display: inline-block;
    overflow: hidden;
    white-space: nowrap;
    vertical-align: bottom;
    animation: ep-frappe 0.62s steps(5) both;
  }

  @keyframes ep-frappe {
    from {
      width: 0;
    }
    to {
      width: 5ch;
    }
  }

  /* ── 2. Le curseur ───────────────────────────────────────────────────
   *
   * `steps(1)` donne le clignotement franc d'un terminal plutôt qu'un fondu
   * mou. Il ne démarre qu'une fois la frappe finie.
   */
  .ep-url i {
    animation: ep-curseur 1.06s steps(1) 0.62s infinite;
  }

  @keyframes ep-curseur {
    50% {
      opacity: 0.12;
    }
  }

  /* ── 3. L'apparition au défilement ───────────────────────────────────
   *
   * Liée au SCROLL, pas à une minuterie : le bloc se révèle à mesure qu'il
   * entre dans l'écran, et se referme si on remonte. C'est ce qui distingue
   * une page qui répond du doigt d'une page qui joue une séquence.
   *
   * `@supports` parce que les navigateurs qui l'ignorent doivent afficher la
   * page normalement — jamais des blocs restés invisibles.
   */
  @supports (animation-timeline: view()) {
    .ep-section {
      animation: ep-apparait linear both;
      animation-timeline: view();
      animation-range: entry 2% cover 26%;
    }

    .ep-liste li {
      animation: ep-apparait linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 20%;
    }

    @keyframes ep-apparait {
      from {
        opacity: 0;
        transform: translateY(1rem);
      }
    }
  }

  /* ── 4. Le passage d'une page à l'autre ──────────────────────────────
   *
   * Le fondu enchaîné entre deux pages du site, sans routeur, sans cadriciel,
   * sans transformer le site en application. Le réglage lui-même est plus bas,
   * hors du `@media` : `@view-transition` est une règle de document, et
   * l'enfermer dans une requête média la rend inopérante chez une partie des
   * navigateurs. On neutralise donc l'animation plus bas plutôt que de
   * conditionner la déclaration.
   */
  ::view-transition-old(root) {
    animation: ep-sortie 0.16s ease both;
  }

  ::view-transition-new(root) {
    animation: ep-entree 0.26s ease both;
  }

  @keyframes ep-sortie {
    to {
      opacity: 0;
    }
  }

  @keyframes ep-entree {
    from {
      opacity: 0;
      transform: translateY(0.5rem);
    }
  }
}

/* Déclarée au premier niveau — voir le point 4 ci-dessus. */
@view-transition {
  navigation: auto;
}

/* Le fondu par défaut du navigateur reste un mouvement : on le coupe aussi. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none;
  }
}

/* ══ SUR GRAND ÉCRAN ════════════════════════════════════════════════════
 *
 * ⚠️ LA MESURE DE LECTURE N'EST PAS LA LARGEUR DE LA PAGE.
 *
 * Les 38 rem de `.ep-wrap` sont la bonne longueur de ligne pour de la prose —
 * au-delà, l'œil perd le début de la ligne suivante. Mais appliquée à TOUTE la
 * page, cette contrainte donne sur un écran de 1440 px une colonne de 608 px
 * centrée dans du vide : la page paraît être une version agrandie du
 * téléphone, ce qu'elle est effectivement.
 *
 * La correction ne consiste donc pas à élargir le texte — ce serait le rendre
 * moins lisible — mais à laisser les STRUCTURES respirer : listes en colonnes,
 * catalogue étalé, tandis que les paragraphes gardent leur mesure.
 *
 * Le seuil est en `rem` et non en pixels : quelqu'un qui a grossi la police de
 * son système passe en une colonne plus tôt, ce qui est exactement ce qu'il
 * faut pour lui.
 */
@media (min-width: 64rem) {
  .ep-wrap {
    width: min(64rem, 100% - 4rem);
  }

  /* Le texte, lui, garde sa mesure. Sans ces bornes, le titre et le chapeau
     s'étireraient sur toute la largeur et deviendraient pénibles à lire. */
  .ep h1,
  .ep-chapeau,
  .ep-citation,
  .ep-vedette {
    max-width: 34rem;
  }

  .ep-hero {
    padding-block: clamp(4rem, 14vh, 8rem) clamp(3rem, 9vh, 5rem);
  }

  /* Deux colonnes : les étapes et les arguments se lisent d'un coup d'œil au
     lieu de demander trois écrans de défilement. */
  .ep-liste {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2.25rem 3.5rem;
  }

  .ep-liste p {
    max-width: 28rem;
  }

  /* Le titre de section passe en marge : la structure de la page devient
     lisible sans lire, ce qui est tout l'intérêt d'un grand écran. */
  .ep-section {
    display: grid;
    grid-template-columns: 11rem minmax(0, 1fr);
    gap: 0 3rem;
  }

  .ep-section > h2 {
    grid-column: 1;
    margin: 0;
    padding-top: 0.35rem;
  }

  .ep-section > *:not(h2) {
    grid-column: 2;
  }
}

/* ══ LES MINI-SITES ═════════════════════════════════════════════════════
 *
 * Les pages du catalogue, servies à /p/{alias}/{page}.
 *
 * ⚠️ Elles utilisaient `base.css`, qui dit de lui-même en commentaire : « Ce
 * n'est PAS une direction artistique. C'est un gris décent. » C'était le
 * placeholder d'avant Épure — et il donnait des pages ternes là où la page bio
 * et le site public avaient déjà une identité.
 *
 * Le mini-site est ce qu'un membre partage sur WhatsApp : c'est la surface qui
 * doit le plus donner envie. La laisser sur le placeholder était l'erreur la
 * plus visible du moteur.
 */
.ep-ms {
  padding-block: clamp(2rem, 7vh, 3.5rem) 3rem;
  display: grid;
  gap: 1.75rem;
}

.ep-ms-entete {
  display: grid;
  gap: 0.6rem;
}

.ep-ms-membre {
  margin: 0;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--encre-douce);
}

.ep-ms h1 {
  font-size: clamp(1.9rem, 1.4rem + 2.4vw, 3rem);
}

/* Le corps rendu depuis le Markdown. Les balises viennent du convertisseur
   strict — on ne peut donc styler que ce qu'il produit. */
.ep-corps > * {
  margin-block: 0 0.85rem;
  max-width: 34rem;
}

.ep-corps h2 {
  margin-block: 2.25rem 0.85rem;
  font-size: clamp(1.25rem, 1.05rem + 0.8vw, 1.55rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  text-wrap: balance;

  /* ⚠️ Annule la règle large `.ep h2`, qui met les intertitres du SITE en
     petites capitales espacées. Sur un mini-site, ces titres viennent du
     Markdown : ce sont des titres de lecture, pas des étiquettes de section.
     Les laisser en capitales rendait des paragraphes entiers illisibles. */
  text-transform: none;
  letter-spacing: -0.02em;
  color: var(--encre);
}

.ep-corps p {
  color: var(--encre-douce);
  text-wrap: pretty;
}

.ep-corps strong {
  color: var(--encre);
  font-weight: 650;
}

.ep-corps ul,
.ep-corps ol {
  padding-left: 1.2rem;
  color: var(--encre-douce);
}

.ep-corps li {
  margin-block: 0.35rem;
}

/* ── Le formulaire ─────────────────────────────────────────────────────
 *
 * Identique sur toutes les pages : c'est lui qui garantit la capture, et une
 * capture qui varierait d'une page à l'autre demanderait d'être vérifiée à
 * chaque page produite.
 */
.ep-form {
  margin-top: 1rem;
  padding: clamp(1.35rem, 5vw, 2rem);
  border: 1px solid var(--trait);
  border-radius: 1.25rem;
  background: var(--carte);
  display: grid;
  gap: 1rem;
}

.ep-form h2 {
  margin: 0;
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-transform: none;
  color: var(--encre);
}

.ep-form > p {
  margin: 0;
  color: var(--encre-douce);
  font-size: 0.95rem;
}

.ep-champs {
  display: grid;
  gap: 0.85rem;
}

@media (min-width: 34rem) {
  .ep-champs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .ep-champ-large {
    grid-column: 1 / -1;
  }
}

.ep-champ {
  display: grid;
  gap: 0.3rem;
}

.ep-champ label {
  font-size: 0.88rem;
  font-weight: 600;
}

.ep-champ input,
.ep-champ textarea {
  width: 100%;
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--trait);
  border-radius: 0.7rem;
  background: var(--fond-1);
  color: var(--encre);
  font: inherit;
}

.ep-champ input:focus-visible,
.ep-champ textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.ep-rappel {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.95rem;
  color: var(--encre-douce);
  cursor: pointer;
}

.ep-envoi {
  padding: 0.95rem 1.5rem;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: var(--fond-1);
  font: inherit;
  font-weight: 650;
  font-size: 1.02rem;
  cursor: pointer;
}

.ep-envoi:hover {
  opacity: 0.92;
}

.ep-mention {
  margin: 0;
  font-size: 0.82rem;
  color: var(--encre-douce);
}

.ep-mention a {
  color: inherit;
  text-underline-offset: 0.25em;
}

.facultatif {
  font-weight: 400;
  color: var(--encre-douce);
}

/* ── Mise en page « chiffres » ──────────────────────────────────────────
 *
 * Née de la relecture du corpus existant : la page /bien-etre/ portait des
 * données de marché solides et sourcées, noyées dans des paragraphes. Ces
 * nombres SONT l'argument — ils doivent donc être la structure de la page.
 *
 * Chaque donnée est une carte : la valeur en grand, ce qu'elle mesure en
 * dessous, la source en petit. La source n'est pas une note de bas de page :
 * sans elle, un chiffre n'est qu'une affirmation, et c'est la première chose
 * que vérifie un lecteur qui doute.
 */
.ms-donnees ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.75rem;
}

@media (min-width: 40rem) {
  .ms-donnees ul {
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  }
}

.ms-donnees li {
  padding: 1.1rem 1.25rem;
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  background: var(--carte);
  display: grid;
  gap: 0.2rem;
}

.ms-donnee-valeur {
  margin: 0;
  font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.ms-donnee-libelle {
  margin: 0;
  font-weight: 500;
  line-height: 1.4;
}

.ms-donnee-source {
  margin: 0.2rem 0 0;
  font-size: 0.82rem;
  line-height: 1.4;
  color: var(--encre-douce);
}

/* ⚠️ La date de relevé est affichée, toujours. Un chiffre de marché sans date
   devient faux en silence : la page d'origine citait une étude de janvier 2023
   trois ans après sa publication. */
.ms-donnees-date {
  margin: 1rem 0 0;
  font-size: 0.85rem;
  color: var(--encre-douce);
}
/* ── L'image de tête ───────────────────────────────────────────────────
 *
 * `aspect-ratio` réserve la place avant le chargement : sans lui, le texte
 * saute quand l'image arrive — précisément au moment où le lecteur commence à
 * lire, en 4G, dans le navigateur intégré d'Instagram.
 */
.ms-heros {
  margin: 0 0 1.75rem;
}

.ms-heros img {
  display: block;
  width: 100%;
  /* ⚠️ 4/3, PAS 16/9. Le catalogue est fait de photos de PRODUIT, et un
     produit se photographie debout : sachet, flacon, boîte. Un cadre 16/9
     imposé décapitait le sujet — testé sur le premier vrai visuel, le haut du
     sachet disparaissait. Le 4/3 laisse respirer les formats verticaux sans
     pour autant occuper tout le premier écran. */
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--rayon);
}

/* ── Questions-réponses ────────────────────────────────────────────────
 *
 * Chaque question du Markdown devient une carte numérotée. Le visiteur balaye
 * la liste, s'arrête sur l'objection qui est la sienne, lit la réponse. Un
 * texte suivi l'obligerait à chercher — et il ne chercherait pas.
 *
 * ⚠️ UNE QUESTION, C'EST UN « ## » SUIVI D'UN PARAGRAPHE. RIEN D'AUTRE.
 *
 * Une première version mettait en carte TOUS les titres de la page. Une page
 * qui finissait par « Ce qu'en disent ceux qui ont commencé » puis un
 * témoignage, et « Ce que vous saurez » puis une liste, se retrouvait avec des
 * questions numérotées 06 et 07 qui n'en étaient pas — et le témoignage
 * encadré à l'intérieur d'une carte de réponse, boîte dans une boîte.
 *
 * `:has(+ p)` règle le tri : un titre suivi d'un paragraphe est une question,
 * un titre suivi d'une citation ou d'une liste est un titre de section. Le
 * rédacteur n'a rien à baliser, et une page mixte reste lisible.
 *
 * Le combinateur `>` est indispensable : sans lui, le paragraphe D'UNE
 * CITATION hériterait du cadre de réponse.
 */
.ep-qr {
  counter-reset: qr;
  display: grid;
  /* ⚠️ AUCUN ÉCART, ET C'EST LA CLÉ DE LA CARTE. Une question et sa réponse
     sont deux éléments frères (h2 puis p) soudés en une seule carte par leurs
     bordures. Le moindre `gap` les sépare et donne deux boîtes flottantes. */
  gap: 0;
}

.ep-qr > h2:has(+ p) {
  counter-increment: qr;
  position: relative;
  margin: 0;
  padding: 1.4rem 1.5rem 0.5rem 4.2rem;
  border: 1px solid var(--trait);
  border-bottom: 0;
  border-radius: var(--rayon) var(--rayon) 0 0;
  background: var(--carte);
  font-size: 1.25rem;
  line-height: 1.35;
  text-transform: none;
  letter-spacing: normal;
  text-wrap: balance;
}

/* Le numéro dans la marge : il donne un rythme à la liste sans ajouter un mot.
   Le contenu généré n'est pas lu par les lecteurs d'écran — c'est exactement
   l'usage voulu. */
.ep-qr > h2:has(+ p)::before {
  content: counter(qr, decimal-leading-zero);
  position: absolute;
  left: 1.5rem;
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--accent);
  opacity: 0.75;
}

/* La réponse : le paragraphe qui suit la question, et le suivant. Au-delà de
   deux, ce n'est plus une réponse, c'est un article — et il vaut mieux qu'il
   se compose comme un article. */
.ep-qr > h2:has(+ p) + p,
.ep-qr > h2:has(+ p) + p + p {
  margin: 0;
  padding: 0.2rem 1.5rem 1.5rem 4.2rem;
  border: 1px solid var(--trait);
  border-top: 0;
  border-radius: 0 0 var(--rayon) var(--rayon);
  background: var(--carte);
  color: var(--encre-douce);
}

/* Le premier des deux ne ferme pas le cadre : sinon chaque paragraphe
   deviendrait sa propre boîte et la question se détacherait de sa fin de
   réponse. */
.ep-qr > h2:has(+ p) + p:has(+ p) {
  border-radius: 0;
  padding-bottom: 0.9rem;
}

.ep-qr > h2:not(:first-child) {
  margin-top: 1.1rem;
}

/* ⚠️ LA CARTE N'EST PAS DE LA PROSE. `.ep-corps > *` borne tout à 34 rem —
   la bonne mesure pour un paragraphe, pas pour un cadre. Sur grand écran, la
   carte gardait donc la largeur d'une colonne de texte et flottait dans la
   moitié gauche de la page, alors que c'est elle la structure. */
@media (min-width: 48rem) {
  .ep-qr { max-width: 46rem; }
  .ep-qr > * { max-width: none; }
  .ep-qr > h2:has(+ p) { padding-left: 5rem; font-size: 1.4rem; }
  .ep-qr > h2:has(+ p) + p,
  .ep-qr > h2:has(+ p) + p + p { padding-left: 5rem; }
  .ep-qr > h2:has(+ p)::before { left: 1.9rem; }
}

/* ══ LE RELIEF D'UN MINI-SITE ══════════════════════════════════════════
 *
 * Tout ce qui suit sert un seul objectif : qu'une page ne se lise pas comme un
 * document. Un mini-site de prospection est jugé en trois secondes, avant
 * lecture — sur son rythme visuel, pas sur ses arguments.
 */

/* ── Le témoignage ─────────────────────────────────────────────────────
 *
 * La seule chose qu'un visiteur croit vraiment, c'est quelqu'un comme lui.
 * D'où la mise en avant : un témoignage enterré dans un paragraphe ne compte
 * pas, et un témoignage sans nom ni ville ne compte pas non plus. */
.ep-corps blockquote {
  margin: 2rem 0;
  padding: 1.5rem 1.5rem 1.5rem 1.75rem;
  border: 0;
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--rayon) var(--rayon) 0;
  background: var(--accent-clair);
}

.ep-corps blockquote p {
  margin: 0;
  color: var(--encre);
  font-size: 1.1rem;
  line-height: 1.6;
  text-wrap: pretty;
}

.ep-corps blockquote cite {
  display: block;
  margin-top: 0.85rem;
  color: var(--encre-douce);
  font-size: 0.85rem;
  font-style: normal;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* ── La respiration ────────────────────────────────────────────────────
 *
 * Un filet court et centré, pas une barre pleine largeur : il marque un
 * changement de sujet sans donner l'impression que la page est finie. */
.ep-corps hr {
  width: 4rem;
  height: 2px;
  margin: 2.75rem 0;
  border: 0;
  border-radius: 2px;
  background: var(--accent);
  opacity: 0.5;
}

/* ── Les listes en cartes ──────────────────────────────────────────────
 *
 * Une liste à puces est ce que le rédacteur écrit le plus spontanément, et
 * c'est ce qui rend une page la plus terne. Même Markdown, autre lecture. */
.ep-corps ul {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}

.ep-corps li {
  position: relative;
  margin: 0;
  padding: 0.85rem 1.1rem 0.85rem 2.6rem;
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  background: var(--carte);
  color: var(--encre-douce);
}

/* La puce est dessinée, pas typographiée : un point centré à la ligne du
   texte, qui garde sa place même sur un élément de trois lignes. */
.ep-corps li::before {
  content: "";
  position: absolute;
  left: 1.1rem;
  top: 1.35rem;
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background: var(--accent);
}

/* ── L'image de tête ───────────────────────────────────────────────────
 *
 * ⚠️ SANS ELLE, LE MOTEUR PRODUIT DES ARTICLES, PAS DES MINI-SITES. Elle
 * occupe le premier écran ; le texte vient après. Une page sans image se
 * reconnaît immédiatement comme du contenu de remplissage. */
.ms-heros img {
  box-shadow: 0 1rem 3rem oklch(0% 0 0 / 0.25);
}

.ms-heros figcaption {
  margin-top: 0.6rem;
  color: var(--encre-douce);
  font-size: 0.85rem;
}

/* ── L'appel à l'action collant ────────────────────────────────────────
 *
 * ⚠️ C'EST LA SEULE ADDITION DE CETTE FEUILLE QUI CHANGE UN TAUX.
 *
 * Le formulaire est en bas de page : un visiteur convaincu au tiers de sa
 * lecture doit faire défiler pour agir, et beaucoup ne le font pas. La barre
 * l'accompagne et disparaît dès qu'il atteint le formulaire — être sollicité
 * par une barre alors qu'on remplit déjà le champ est agaçant.
 *
 * Elle n'apparaît qu'après le premier écran : proposer de laisser ses
 * coordonnées avant d'avoir rien lu, c'est de la publicité, pas une page. */
.ep-cta-collant {
  position: fixed;
  z-index: 20;
  left: 50%;
  bottom: max(1rem, env(safe-area-inset-bottom));
  translate: -50% 0;
  width: min(30rem, calc(100% - 2rem));

  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.7rem 0.7rem 0.7rem 1.1rem;

  border: 1px solid var(--trait);
  border-radius: 999px;
  background: color-mix(in oklab, var(--fond-1) 88%, transparent);
  backdrop-filter: blur(14px);
  box-shadow: 0 0.75rem 2.5rem oklch(0% 0 0 / 0.3);

  opacity: 0;
  translate: -50% 1.5rem;
  pointer-events: none;
  transition: opacity 0.25s ease, translate 0.25s ease;
}

.ep-cta-collant.visible {
  opacity: 1;
  translate: -50% 0;
  pointer-events: auto;
}

.ep-cta-collant p {
  flex: 1;
  min-width: 0;
  margin: 0;
  color: var(--encre);
  font-size: 0.9rem;
  line-height: 1.3;
}

.ep-cta-collant a {
  flex: none;
  padding: 0.55rem 1.1rem;
  border-radius: 999px;
  background: var(--accent);
  color: var(--fond-1);
  font-size: 0.9rem;
  font-weight: 650;
  text-decoration: none;
  white-space: nowrap;
}

/* ── L'apparition au défilement ────────────────────────────────────────
 *
 * Native : `animation-timeline: view()` lie l'animation à la position de
 * l'élément dans la fenêtre. Aucun script, aucun observateur, rien à charger —
 * et sur un navigateur qui ne connaît pas la propriété, le bloc est simplement
 * là, sans animation. C'est la bonne dégradation.
 *
 * ⚠️ L'animation part de opacity .001 et non de 0. À zéro, un navigateur qui
 * comprend `animation` mais pas `animation-timeline` jouerait l'animation une
 * seule fois au chargement et laisserait invisible tout ce qui est plus bas :
 * une page vide. Le repli doit être « moins joli », jamais « illisible ». */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .ep-corps > *,
    .ms-heros,
    .ep-ms-chiffre {
      animation: ep-apparition linear both;
      animation-timeline: view();
      animation-range: entry 8% cover 26%;
    }
  }
}

@keyframes ep-apparition {
  from {
    opacity: 0.001;
    translate: 0 1.25rem;
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}

/* Le repère du premier écran, posé par lead.js. Invisible, hors flux, sans
   effet sur la mise en page : il ne sert qu'à être observé. */
.ep-repere {
  position: absolute;
  top: 70vh;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

/* ── La teinte d'une page ──────────────────────────────────────────────
 *
 * ⚠️ UNE CLASSE, PAS UN STYLE EN LIGNE, ET C'EST LA CSP QUI L'IMPOSE.
 *
 * Le service sert « style-src 'self' » : ni <style> dans la page, ni attribut
 * style= ne sont appliqués. Les deux existaient bien dans le HTML, le
 * navigateur les ignorait en silence — la page restait verte pendant que sa
 * vignette était violette, sans la moindre erreur nulle part.
 *
 * Assouplir la CSP pour colorer une page serait un très mauvais échange :
 * 'unsafe-inline' rouvrirait l'injection de style, qui sert à maquiller un
 * formulaire de capture. Les classes coûtent moins d'un kilo-octet.
 *
 * Les noms suivent les degrés oklch : .h162 est l'émeraude du service.
 * Engendrées depuis la même liste que internal/pages/couleur.go, et
 * TestChaqueTeinteAUneClasse vérifie que les deux restent d'accord. */
.ep.h162 { --h: 162; }
.ep.h0 { --h: 0; }
.ep.h15 { --h: 15; }
.ep.h30 { --h: 30; }
.ep.h45 { --h: 45; }
.ep.h60 { --h: 60; }
.ep.h75 { --h: 75; }
.ep.h90 { --h: 90; }
.ep.h105 { --h: 105; }
.ep.h120 { --h: 120; }
.ep.h135 { --h: 135; }
.ep.h150 { --h: 150; }
.ep.h165 { --h: 165; }
.ep.h180 { --h: 180; }
.ep.h195 { --h: 195; }
.ep.h210 { --h: 210; }
.ep.h225 { --h: 225; }
.ep.h240 { --h: 240; }
.ep.h255 { --h: 255; }
.ep.h270 { --h: 270; }
.ep.h285 { --h: 285; }
.ep.h300 { --h: 300; }
.ep.h315 { --h: 315; }
.ep.h330 { --h: 330; }
.ep.h345 { --h: 345; }

/* ── La confirmation d'envoi ───────────────────────────────────────────
 *
 * ⚠️ ELLE REMPLACE LE FORMULAIRE. Une ligne de texte sous un formulaire qui se
 * vide n'est pas une confirmation : le visiteur voit ses champs s'effacer et
 * ne sait pas si son message est parti. Quelqu'un qui vient de confier ses
 * coordonnées est la dernière personne à laisser dans le doute.
 */
.ep-merci {
  padding: 2rem 1.75rem;
  border: 1px solid var(--accent);
  border-radius: var(--rayon);
  background: var(--accent-clair);
  display: grid;
  gap: 0.75rem;
}

/* ⚠️ `display: grid` ÉCRASE L'ATTRIBUT `hidden`. La règle du navigateur qui
   cache un élément `hidden` (display: none) cède devant toute règle d'auteur
   sur `display`. Sans cette ligne, la confirmation s'affichait EN PERMANENCE
   au-dessus du formulaire, sur toutes les pages — l'inverse exact de « elle
   remplace le formulaire ». */
.ep-merci[hidden] {
  display: none;
}

.ep-merci:focus {
  outline: none;
}

.ep-merci-titre {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--accent);
}

.ep-merci p {
  margin: 0;
  color: var(--encre-douce);
  text-wrap: pretty;
}

/* L'état d'erreur du formulaire. `.lead-etat` n'avait AUCUN style : le message
   d'échec s'affichait en texte nu, à la taille du corps, sans couleur — donc
   invisible au moment précis où il compte. */
.lead-etat.erreur {
  color: oklch(62% 0.2 25);
  font-weight: 600;
}

.lead-etat.ok {
  color: var(--accent);
  font-weight: 600;
}

/* ══ MISE EN PAGE PRODUIT ══════════════════════════════════════════════
 *
 * Une photo pleine largeur, un argument, une photo. Rien d'autre.
 *
 * ⚠️ TROIS VERSIONS ONT ÉTÉ RATÉES AVANT CELLE-CI. Ce qui suit est le résumé
 * de ce qui n'a PAS marché — c'est plus utile que la description de ce qui
 * marche, parce que ce sont des réflexes qui reviennent.
 *
 *   1. « Article » appliqué à un produit → un article SUR un produit. La photo
 *      sage, les chiffres noyés dans une liste à puces, une couleur tirée au
 *      hasard pendant que le packaging en a déjà une.
 *
 *   2. Héros cinéma : photo plein cadre VOILÉE de sombre, titre posé dedans.
 *      Le voile éteint exactement les couleurs qui font vendre, et le titre
 *      tombe là où la photo est la plus chargée.
 *
 *   3. Deux colonnes, packshot dans une carte blanche à ombre portée. Propre,
 *      et totalement plat : une carte transforme un produit en illustration
 *      d'article. C'est le réflexe le plus difficile à réprimer — devant un
 *      espace vide, on veut y poser un cadre.
 *
 * LA RÈGLE : une image touche les deux bords, ou elle n'est pas là. On
 * assombrit là où on écrit, et seulement là. Le vide n'est pas un problème à
 * combler, c'est ce qui donne l'échelle.
 */

.ep-produit {
  /* Les bandes touchent les bords : la marge vit dans .ep-wrap, jamais ici. */
  overflow-x: hidden;
}

/* ── L'écran d'ouverture ───────────────────────────────────────────────── */
.ep-pr-heros {
  position: relative;
  isolation: isolate;
  min-height: min(72vh, 38rem);
  display: grid;
  align-items: end;
  background: oklch(96% 0.01 var(--h));
}

.ep-pr-photo {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 42%;
}

/* La vidéo de héros — même cadrage que la photo, posée juste au-dessus
   d'elle. La photo reste dessous : c'est elle qu'on voit pendant le
   chargement (et c'est elle que le partage social emploie). */
.ep-pr-video {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 42%;
}

/* Le visiteur a demandé moins d'animations : la photo suffit. */
@media (prefers-reduced-motion: reduce) {
  .ep-pr-video {
    display: none;
  }
}

/* ⚠️ LE DÉGRADÉ EST CONFINÉ AU TIERS BAS. Une version l'étendait à toute la
   photo pour que le titre reste lisible où qu'il tombe : la photo devenait
   grise et le produit perdait ses couleurs. On n'assombrit que la bande où
   l'on écrit. */
.ep-pr-heros-bas {
  padding: 4rem 0 clamp(1.75rem, 4vh, 2.75rem);
  background: linear-gradient(
    to bottom,
    transparent 0%,
    oklch(16% 0.03 var(--h) / 0.55) 38%,
    oklch(13% 0.03 var(--h) / 0.92) 100%
  );
}

.ep-pr-marque {
  margin: 0 0 0.85rem;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: oklch(90% 0.06 var(--h));
}

.ep-produit h1 {
  margin: 0;
  font-size: clamp(2.5rem, 1.1rem + 6vw, 5.5rem);
  line-height: 0.98;
  letter-spacing: -0.04em;
  color: oklch(99% 0.004 var(--h));
  text-wrap: balance;
  max-width: 14ch;
}

.ep-pr-chapeau {
  margin: 1.2rem 0 0;
  max-width: 30ch;
  font-size: clamp(1.05rem, 0.95rem + 0.5vw, 1.35rem);
  line-height: 1.5;
  color: oklch(93% 0.02 var(--h));
  text-wrap: pretty;
}

/* ── Le bandeau de chiffres ────────────────────────────────────────────
 *
 * Pleine largeur, sur l'accent. C'est la seule surface colorée de la page :
 * elle marque la fin de l'ouverture et le début de la démonstration. */
.ep-pr-bandeau {
  padding: clamp(1.75rem, 4vh, 2.75rem) 0;
  background: var(--accent-clair);
}

.ep-pr-bandeau ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(1.75rem, 4vw, 3rem);
}

.ep-pr-valeur {
  margin: 0;
  font-size: clamp(2.4rem, 1.5rem + 2.6vw, 3.6rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.045em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.ep-pr-libelle {
  margin: 0.55rem 0 0;
  color: var(--encre);
  font-size: 0.95rem;
  line-height: 1.4;
  text-wrap: pretty;
}

.ep-pr-bandeau .ep-mention {
  margin-top: 1.75rem;
}

/* ── L'écran d'argument ────────────────────────────────────────────────
 *
 * Une idée, énoncée très grand, suivie d'une phrase courte. Ce qui coûte
 * cher n'est pas la police, c'est le vide autour : devant une page qui paraît
 * fade, le premier réflexe est d'ajouter, alors qu'il faut retirer et
 * agrandir. */
/* ⚠️ LES MARGES SE DOUBLAIENT ENTRE DEUX SECTIONS CONSÉCUTIVES.
 *
 * Chaque section portait jusqu'à 8 rem en haut ET en bas : deux sections qui
 * se suivent créaient donc 16 rem de vide, soit un écran de téléphone entier
 * sans rien dedans. Sur sept sections, la page atteignait dix-huit écrans.
 *
 * Le vide donne l'échelle — c'est vrai — mais du vide DOUBLÉ ne donne rien du
 * tout : il ne se lit pas comme une respiration, il se lit comme une page qui
 * n'en finit pas. Deux sections qui se suivent ne partagent plus qu'une seule
 * marge. */
.ep-pr-arg {
  padding-block: clamp(1.75rem, 4.5vh, 3rem);
}

.ep-pr-arg + .ep-pr-arg {
  padding-top: 0;
}

.ep-pr-arg-intro {
  padding-bottom: 0;
}

.ep-pr-arg h2 {
  margin: 0 0 0.7rem;
  font-size: clamp(1.9rem, 1.1rem + 3vw, 3.4rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.035em;
  color: var(--encre);
  text-wrap: balance;
  max-width: 15ch;
}

.ep-pr-texte > * {
  max-width: 36rem;
}

.ep-pr-texte p {
  font-size: clamp(1.05rem, 0.98rem + 0.4vw, 1.22rem);
  line-height: 1.6;
  color: var(--encre-douce);
}

.ep-pr-arg-intro .ep-pr-texte p {
  font-size: clamp(1.3rem, 1rem + 1.3vw, 2rem);
  line-height: 1.35;
  letter-spacing: -0.015em;
  color: var(--encre);
  max-width: 24ch;
}

/* ── La photo pleine largeur ───────────────────────────────────────────
 *
 * Elle touche les deux bords. Pas de rayon, pas de bordure, pas d'ombre —
 * chacun de ces trois ajouts la ramène au statut d'illustration. */
.ep-pr-plein {
  margin: 0;
  position: relative;
  /* ⚠️ LE MÊME FOND POUR TOUTE LA SÉRIE. Les photos s'enchaînent : marbre
     chaud, bois chaud… un blanc de studio au milieu se lit comme « une autre
     page » dans la même page. La bande porte donc toujours le crème de la
     série, y compris derrière une photo qui ne la remplit pas. */
  background: oklch(96.5% 0.012 var(--h));
}

.ep-pr-plein img {
  display: block;
  width: 100%;
  /* Assez haute pour porter l'écran, assez basse pour qu'on la dépasse d'un
     geste. Une photo qui remplit la fenêtre oblige à deux défilements pour
     revenir au texte. */
  height: clamp(13rem, 34vh, 22rem);
  object-fit: cover;
  object-position: 50% 45%;
}

/* ⚠️ APRÈS la règle générale, ET AVEC DEUX CLASSES. Posée avant, à
   spécificité égale, elle était écrasée par `.ep-pr-plein img` : le packshot
   restait rogné et rien ne le signalait — la classe était bien là dans le HTML.
   Le genre de défaut qu'on cherche dans le gabarit alors qu'il est dans
   l'ordre de la feuille de style.

   Un packshot est centré sur son fond : le rogner lui coupe la tête et les
   pieds. On le contient, quitte à laisser du fond de part et d'autre — le fond
   est le même que celui de la bande, la différence ne se voit pas. */
.ep-pr-plein.ep-pr-plein-detoure img {
  object-fit: contain;
  padding-block: 1rem;
}

.ep-pr-plein figcaption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 3rem 0 1.1rem;
  background: linear-gradient(to bottom, transparent, oklch(13% 0.03 var(--h) / 0.8));
  color: oklch(96% 0.01 var(--h));
  font-size: 0.85rem;
  letter-spacing: 0.02em;
}

.ep-pr-fin {
  padding-top: clamp(2rem, 5vh, 3rem);
}

@media (min-width: 48rem) {
  .ep-pr-bandeau ol {
    grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  }
}

/* ── La galerie du produit ─────────────────────────────────────────────
 *
 * ⚠️ UNE SEULE PHOTO NE VEND PAS UN PRODUIT. On veut le voir sous plusieurs
 * angles, et savoir à quoi ressemble ce qu'on reçoit. Une page qui n'en montre
 * qu'une laisse le doute entier — et le doute ne devient pas un contact. */
.ep-pr-galerie {
  margin-top: clamp(3rem, 8vh, 5rem);
}

.ep-pr-galerie ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0.85rem;
}

.ep-pr-galerie button {
  display: block;
  width: 100%;
  padding: 0;
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  background: var(--carte);
  cursor: zoom-in;
  overflow: hidden;
  font: inherit;
  color: inherit;
  text-align: left;
  transition: border-color 0.2s ease, translate 0.2s ease;
}

.ep-pr-galerie button:hover,
.ep-pr-galerie button:focus-visible {
  border-color: var(--accent);
  translate: 0 -2px;
}

.ep-pr-galerie img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
}

.ep-pr-galerie span {
  display: block;
  padding: 0.6rem 0.75rem;
  font-size: 0.82rem;
  line-height: 1.35;
  color: var(--encre-douce);
}

/* ── La visionneuse ────────────────────────────────────────────────────
 *
 * <dialog> natif : la touche Échap ferme, le focus est piégé, l'arrière-plan
 * devient inerte — trois comportements qu'on écrirait mal à la main, et une
 * bibliothèque de moins à charger sur un téléphone en 4G. */
.ep-visionneuse {
  width: min(60rem, 92vw);
  max-height: 92vh;
  padding: 0;
  border: 0;
  border-radius: var(--rayon);
  background: var(--carte);
  color: var(--encre);
  overflow: hidden;
}

.ep-visionneuse::backdrop {
  background: oklch(8% 0.02 var(--h) / 0.82);
  backdrop-filter: blur(6px);
}

.ep-visionneuse img {
  display: block;
  width: 100%;
  max-height: 78vh;
  object-fit: contain;
  background: oklch(12% 0.01 var(--h));
}

.ep-visionneuse-legende {
  margin: 0;
  padding: 0.9rem 1.25rem;
  font-size: 0.9rem;
  color: var(--encre-douce);
}

.ep-visionneuse-legende:empty {
  display: none;
}

.ep-visionneuse-fermer {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  width: 2.4rem;
  height: 2.4rem;
  border: 0;
  border-radius: 50%;
  background: oklch(12% 0.02 var(--h) / 0.7);
  color: oklch(98% 0 0);
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
}

/* ── La mention réglementaire ──────────────────────────────────────────
 *
 * ⚠️ MISE EN VALEUR, PAS MISE DE CÔTÉ. Les mentions obligatoires doivent être
 * « aisément visibles et clairement lisibles » (règlement UE 1169/2011,
 * art. 13). Les replier derrière un clic ou les composer en gris pâle les rend
 * conformes sur le papier et invisibles en pratique.
 *
 * Le cartouche répond à la vraie demande — que la page reste belle — sans rien
 * concéder : une hiérarchie claire vaut mieux qu'un paragraphe noyé, pour le
 * lecteur comme pour le graphisme. */
.ep-legal {
  margin: 1.5rem 0;
  padding: 1.35rem 1.5rem;
  border: 1px solid var(--trait);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--rayon) var(--rayon) 0;
  background: var(--carte);
}

.ep-legal p {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.65;
  color: var(--encre-douce);
  text-wrap: pretty;
}

.ep-legal strong {
  color: var(--encre);
}

/* ══ MISE EN PAGE OPPORTUNITÉ ══════════════════════════════════════════
 *
 * ⚠️ L'OPPOSÉ DE « PRODUIT », ET LES CONFONDRE EST L'ERREUR QUI A COÛTÉ LE
 * PLUS CHER SUR CE PROJET. Cinq versions d'une page produit ont été peaufinées
 * avant qu'on s'aperçoive que le modèle attendu était celui-ci.
 *
 *   produit       le nom du produit, ses photos, ses chiffres, des phrases
 *                 courtes. On convainc d'essayer quelque chose.
 *   opportunité   une promesse adressée au lecteur, une illustration, du
 *                 texte qui ARGUMENTE. On convainc quelqu'un de se lancer.
 *
 * ⚠️ L'HARMONIE VIENT DE L'ILLUSTRATION, PAS DE LA MISE EN PAGE. Des photos de
 * provenances différentes ne s'accordent jamais, quel que soit le soin apporté
 * au cadre. Une illustration au trait, transparente, posée sur la couleur de
 * la page s'accorde par construction : c'est la PAGE qui donne la couleur, pas
 * l'image. Cent pages tiennent alors ensemble sans que personne n'y veille.
 */

/* ── L'écran d'ouverture ───────────────────────────────────────────────
 *
 * Un aplat profond de la couleur de la page, l'illustration posée dessus. Pas
 * de photo, pas de dégradé, pas de voile : une seule surface. C'est ce qui
 * rend la page reconnaissable en une demi-seconde. */
.ep-opp-heros {
  background: oklch(32% 0.09 var(--h));
  color: oklch(97% 0.01 var(--h));
  padding: clamp(2.5rem, 7vh, 5rem) 0 clamp(2rem, 6vh, 4rem);
  overflow: hidden;
}

.ep-opp-heros > .ep-wrap {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
}

.ep-opp h1 {
  margin: 0;
  font-size: clamp(2rem, 1.1rem + 3.6vw, 3.5rem);
  line-height: 1.06;
  letter-spacing: -0.03em;
  color: inherit;
  text-wrap: balance;
  max-width: 17ch;
}

.ep-opp-chapeau {
  margin: 1.1rem 0 0;
  max-width: 34ch;
  font-size: clamp(1.02rem, 0.95rem + 0.45vw, 1.25rem);
  line-height: 1.55;
  color: oklch(88% 0.03 var(--h));
  text-wrap: pretty;
}

.ep-opp-heros .ep-cta {
  margin-top: 1.75rem;
  background: oklch(92% 0.09 var(--h));
  color: oklch(28% 0.09 var(--h));
}

/* L'illustration : transparente, donc posée directement sur l'aplat. Aucun
   cadre, aucune ombre — ce sont eux qui trahissent une image rapportée. */
.ep-opp-illu {
  display: block;
  width: 100%;
  max-height: min(46vh, 24rem);
  object-fit: contain;
}

/* ── Les blocs d'argument ──────────────────────────────────────────────
 *
 * ⚠️ ON N'ABRÈGE PAS. Sur une page produit, une phrase courte suffit : le
 * produit se voit. Ici il n'y a rien à voir — c'est le raisonnement qui
 * convainc. Les paragraphes sont longs, et la mesure de ligne est réglée pour
 * qu'on les lise, pas pour qu'ils fassent joli. */
.ep-opp-bloc {
  padding-block: clamp(2rem, 5vh, 3.25rem);
}

.ep-opp-bloc + .ep-opp-bloc {
  padding-top: 0;
}

.ep-opp-bloc h2 {
  margin: 0 0 0.9rem;
  /* ⚠️ Annule la règle large `.ep h2`, qui met les intertitres du SITE en
     petites capitales espacées. Ici ce sont des titres de LECTURE, venus du
     Markdown : en capitales, un titre de huit mots devient illisible. Le même
     oubli avait déjà frappé `.ep-corps h2` — la règle large est un piège que
     chaque nouvelle mise en page retrouve. */
  text-transform: none;
  font-size: clamp(1.55rem, 1.1rem + 1.7vw, 2.3rem);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.025em;
  color: var(--accent);
  text-wrap: balance;
  max-width: 20ch;
}

.ep-opp-texte > * {
  max-width: 36rem;
}

.ep-opp-texte p {
  font-size: 1.05rem;
  line-height: 1.7;
  color: var(--encre-douce);
}

.ep-opp-bloc-intro .ep-opp-texte p {
  font-size: clamp(1.15rem, 1rem + 0.7vw, 1.4rem);
  line-height: 1.5;
  color: var(--encre);
}

/* ── Les chiffres du marché ────────────────────────────────────────────
 *
 * Ils appuient un raisonnement déjà commencé, ils ne l'ouvrent pas — d'où
 * leur place après le premier argument, et non en tête. */
.ep-opp-chiffres {
  padding-block: clamp(2rem, 5vh, 3.25rem);
  background: var(--accent-clair);
}

.ep-opp-chiffres ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(1.5rem, 4vw, 2.5rem);
}

.ep-opp-valeur {
  margin: 0;
  font-size: clamp(1.9rem, 1.3rem + 1.9vw, 2.7rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.ep-opp-libelle {
  margin: 0.45rem 0 0;
  color: var(--encre);
  font-size: 0.95rem;
  line-height: 1.4;
}

/* La source reste, en petit : un chiffre de marché sans source n'est qu'une
   affirmation, et c'est précisément ce qu'une page de recrutement doit éviter. */
.ep-opp-source {
  margin: 0.3rem 0 0;
  font-size: 0.75rem;
  line-height: 1.35;
  color: var(--encre-douce);
  opacity: 0.8;
}

/* ── L'illustration d'intercalaire ─────────────────────────────────────
 *
 * Sur un fond doux, jamais pleine largeur : une illustration étirée bord à
 * bord perd son trait et devient un décor. */
.ep-opp-illu-bloc {
  margin: 0;
  padding-block: clamp(1.5rem, 4vh, 2.5rem);
  background: var(--fond-2);
}

.ep-opp-illu-bloc img {
  display: block;
  width: 100%;
  max-width: 34rem;
  max-height: min(40vh, 20rem);
  margin-inline: auto;
  object-fit: contain;
}

.ep-opp-illu-bloc figcaption {
  margin-top: 0.75rem;
  text-align: center;
  font-size: 0.85rem;
  color: var(--encre-douce);
}

.ep-opp-fin {
  padding-top: clamp(2rem, 5vh, 3rem);
}

@media (min-width: 52rem) {
  .ep-opp-heros > .ep-wrap {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    gap: clamp(2rem, 5vw, 4rem);
  }
  .ep-opp-chiffres ol {
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  }
}
