/* ═══════════════════════════════════════════════════════════════════════════
   offre.css — feuille partagée par les trois pages du tunnel d'offre
   ═══════════════════════════════════════════════════════════════════════════
   creation-site-internet.html · rendez-vous.html · rendez-vous-confirme.html

   Ce fichier ne touche à AUCUNE page existante du portfolio : il n'est chargé
   que par les trois pages ci-dessus. Les tokens sont recopiés de index.html
   pour que la page tienne debout sans dépendre d'une autre feuille.
   La nav et le footer injectent leur propre CSS depuis js/site-nav.js et
   js/site-footer.js, on ne les redéclare pas ici.
   ─────────────────────────────────────────────────────────────────────────── */

:root {
  --brand-9:  #c9a84c;
  --brand-10: #dbb96a;
  --neutral-1:  #111;
  --neutral-2:  #191919;
  --neutral-3:  #222;
  --neutral-4:  #2a2a2a;
  --neutral-7:  #484848;
  --neutral-8:  #606060;
  --neutral-10: #7b7b7b;
  --neutral-11: #b4b4b4;
  --neutral-12: #eee;

  --page-width: 1280px;
  --h-pad: 24px;
  --gap: 24px;

  /* Rythme vertical : un seul jeu de valeurs, pas de nombres choisis un à un */
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  24px;
  --space-6:  32px;
  --space-7:  48px;
  --space-8:  64px;
  --section-y: clamp(64px, 8vw, 120px);
}

*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

html {
  font-size: 16px;
  line-height: 1.5;
  scroll-behavior: smooth;
}

body {
  background-color: var(--neutral-1);
  color: var(--neutral-11);
  font-family: 'Bricolage Grotesque', system-ui, -apple-system, sans-serif;
  font-weight: 400;
  letter-spacing: -0.02em;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }

.container {
  max-width: calc(var(--page-width) + var(--h-pad) * 2);
  margin: 0 auto;
  padding: 0 var(--h-pad);
}

/* Libellé de section : typographie pure, ni pastille ni pilule ni point coloré */
.offre-eyebrow {
  display: block;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--brand-9);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  margin-bottom: 18px;
}

/* ─── Bouton plein doré ───────────────────────────────────────────────────
   Défini ici plutôt que repris de site-footer.js : ce dernier n'injecte son
   CSS qu'en fin de page, le bouton du hero apparaîtrait nu pendant un instant. */
.offre-btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: inherit;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: #000;
  text-decoration: none;
  background: var(--brand-9);
  border: none;
  cursor: pointer;
  padding: 17px 34px;
  border-radius: 100px;
  box-shadow:
    0 1px 0 rgba(255,255,255,0.25) inset,
    0 10px 24px -12px rgba(201,168,76,0.55),
    0 24px 60px -30px rgba(201,168,76,0.45);
  transition: background 0.2s ease, transform 0.18s cubic-bezier(0.34,1.4,0.64,1), box-shadow 0.25s ease;
}
.offre-btn svg { transition: transform 0.25s cubic-bezier(0.34,1.4,0.64,1); }
.offre-btn:hover {
  background: var(--brand-10);
  transform: translateY(-2px);
  box-shadow:
    0 1px 0 rgba(255,255,255,0.3) inset,
    0 14px 30px -12px rgba(201,168,76,0.6),
    0 30px 70px -30px rgba(201,168,76,0.5);
}
.offre-btn:hover svg { transform: translateX(4px); }
.offre-btn:active { transform: translateY(0); }
.offre-btn:focus-visible {
  outline: 2px solid var(--brand-10);
  outline-offset: 4px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   HERO
   ═══════════════════════════════════════════════════════════════════════════
   Fond sombre obligatoire : la nav est transparente en haut de page, un fond
   clair rendrait son texte illisible. Pas de #page-loader sur ces pages, le
   hero doit s'afficher immédiatement après un clic publicitaire facturé. */
.offre-hero {
  position: relative;
  min-height: 88vh;          /* fallback pour les navigateurs sans svh */
  min-height: 88svh;
  display: flex;
  align-items: center;
  /* Paddings équilibrés : align-items:center ne centre pas optiquement si le
     haut et le bas diffèrent, le bloc tombe sous le centre. */
  padding: 120px 0;
  overflow: hidden;
  isolation: isolate;
}

/* Image de fond plein cadre. Aucun dégradé radial décoratif : l'image porte
   seule l'atmosphère, et le halo doré dans un coin est un marqueur d'IA. */
.offre-hero-img {
  position: absolute;
  top: 0; bottom: 0; right: 0; left: auto;
  z-index: -3;
  width: 58%;
  height: 100%;
  object-fit: cover;
  /* Cadre le visage et la colonne de braises, qui sont l'axe de l'image.
     Une valeur basse pousse le sujet vers la droite du cadre et dégage le
     titre : les braises ne doivent toucher aucune lettre. */
  object-position: 30% center;
  filter: saturate(0.9) contrast(1.05) brightness(0.94);
  /* Le bord gauche se dissout dans la page : pas de rectangle rapporté. */
  -webkit-mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,0.55) 16%, #000 42%);
          mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,0.55) 16%, #000 42%);
}

/* Voile de lisibilité. Le texte passe à gauche, l'image respire à droite.
   Le bas se fond vers var(--neutral-1) pour raccorder à la page. */
.offre-hero-scrim {
  position: absolute;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    linear-gradient(to right,
      rgba(12,12,12,0.55) 0%,
      rgba(12,12,12,0.30) 34%,
      transparent 58%),
    linear-gradient(to top,
      var(--neutral-1) 0%,
      rgba(17,17,17,0.45) 11%,
      transparent 26%),
    radial-gradient(46% 42% at 72% 30%, rgba(201,168,76,0.10) 0%, transparent 70%);
}

/* Grain : unifie l'image et le voile, comme sur le loader du site. */
.offre-hero::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0.14;
  mix-blend-mode: overlay;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='250' height='250'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='250' height='250' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");
}

.offre-hero-inner {
  max-width: 940px;
}

.offre-hero h1 {
  font-size: clamp(2.4rem, 6vw, 4.6rem);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.04em;
  color: var(--neutral-12);
  max-width: 16ch;
  text-wrap: balance;
  text-shadow: 0 4px 40px rgba(0,0,0,0.65);
}

/* La coupure après « minutes. » est voulue : elle isole la promesse courte
   avant la promesse longue. */
.offre-hero h1 .hero-line { display: block; }

.offre-hero-sub {
  margin-top: var(--space-6);
  /* S'arrête avant la colonne de braises : aucune ligne ne finit sur la flamme */
  max-width: 50ch;
  font-size: clamp(1.02rem, 1.35vw, 1.22rem);
  line-height: 1.7;
  color: var(--neutral-11);
}

.offre-hero-actions {
  margin-top: var(--space-7);
  display: flex;
  align-items: center;
  gap: var(--space-5);
  flex-wrap: wrap;
}

/* Ligne de preuve sous le bouton : sobre, pas de logo, pas de compteur. */
.offre-hero-proof {
  margin-top: var(--space-7);
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--neutral-11);
  max-width: 46ch;
}

/* ═══════════════════════════════════════════════════════════════════════════
   SECTIONS COURANTES
   ═══════════════════════════════════════════════════════════════════════════ */
.offre-section {
  position: relative;
  padding: var(--section-y) 0;
}

/* Mesure en pixels, pas en ch : l'unité ch se calcule sur la police du
   conteneur, 16 px ici, pas sur celle du titre. 30ch donnait 240 px de large
   et cassait le h2 en cinq lignes. */
.offre-section-head {
  max-width: 760px;
  margin: 0 auto;
  text-align: center;
}
/* Mesure élargie, réservée aux titres en deux phrases dont la coupure est
   imposée par .h2-phrase : la seconde phrase doit tenir sur une seule ligne. */
.offre-section-head--large { max-width: 880px; }

.offre-h2 {
  font-size: clamp(1.85rem, 3.6vw, 3rem);
  font-weight: 600;
  line-height: 1.14;
  letter-spacing: -0.035em;
  color: var(--neutral-12);
  text-wrap: balance;
}

/* Coupe le titre à la fin de la phrase plutôt qu'au hasard de la mesure.
   Sans elle, « On vous cherche déjà. Le » laissait « Le » pendre en fin de
   ligne et la seconde phrase commençait au milieu de la première. */
.offre-h2 .h2-phrase { display: block; }

/* ═══════════════════════════════════════════════════════════════════════════
   LA PRIVATION
   ═══════════════════════════════════════════════════════════════════════════
   Registre : on ne reproche rien au lecteur, on décrit ce qui n'apparaît nulle
   part. Trois blocs sans encadré, sans icône, sans pastille : un filet doré,
   un mot fort en tête, deux lignes. Le mot en tête tient lieu de marqueur, il
   n'y a donc pas de picto à inventer. */
.privation-lead {
  max-width: 34ch;
  margin: clamp(28px, 3.5vw, 48px) auto 0;
  text-align: center;
  font-size: clamp(1.2rem, 2vw, 1.6rem);
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: -0.03em;
  color: var(--neutral-11);
  text-wrap: balance;
}

.trois {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(30px, 3.6vw, 56px);
  max-width: 1080px;
  margin: clamp(44px, 5vw, 72px) auto 0;
}

.trois-bloc::before {
  content: '';
  display: block;
  height: 1px;
  margin-bottom: var(--space-5);
  background: linear-gradient(to right, rgba(201,168,76,0.65), rgba(201,168,76,0.06));
}

.trois-label {
  font-size: clamp(1.05rem, 1.5vw, 1.22rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.2;
  color: var(--brand-9);
  margin-bottom: var(--space-3);
}
.trois-texte {
  font-size: clamp(0.98rem, 1.1vw, 1.04rem);
  line-height: 1.75;
  color: var(--neutral-11);
}

/* Clôture de section : une seule phrase, elle porte tout l'angle. */
.privation-cloture {
  /* 28ch cassait la phrase allongée en quatre lignes. */
  max-width: 44ch;
  margin: clamp(52px, 6vw, 88px) auto 0;
  text-align: center;
  font-size: clamp(1.35rem, 2.6vw, 2.1rem);
  font-weight: 500;
  line-height: 1.32;
  letter-spacing: -0.035em;
  color: var(--neutral-12);
  text-wrap: balance;
}

@media (max-width: 860px) {
  .trois { grid-template-columns: 1fr; gap: var(--space-7); max-width: 560px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LE DÉROULÉ EN QUATRE ÉTAPES
   ═══════════════════════════════════════════════════════════════════════════
   Liste verticale, pas une grille de quatre cartes : l'étape 4 porte le prix et
   l'engagement, elle est volontairement plus longue que les autres et une grille
   l'obligerait à s'aligner sur la plus courte.
   Ni encadré, ni icône, ni pastille. Un rail doré relie les numéros. */
.etapes {
  position: relative;
  list-style: none;   /* la numérotation est portée par .etape-num, en doré */
  max-width: 720px;
  margin: clamp(44px, 5.5vw, 76px) auto 0;
}

/* Rail de liaison. Il court derrière les numéros, qui le masquent chacun sur
   leur hauteur : la ligne semble passer d'un chiffre à l'autre. */
.etapes::before {
  content: '';
  position: absolute;
  left: 26px;
  top: 10px;
  bottom: 34px;
  width: 1px;
  background: linear-gradient(
    to bottom,
    rgba(201,168,76,0.55) 0%,
    rgba(201,168,76,0.22) 62%,
    rgba(201,168,76,0) 100%);
  z-index: 0;
}

.etape {
  display: grid;
  grid-template-columns: 54px 1fr;
  column-gap: var(--space-6);
  padding-bottom: clamp(40px, 5vw, 68px);
}
.etape:last-child { padding-bottom: 0; }

.etape-num {
  position: relative;
  z-index: 1;
  grid-row: span 2;
  align-self: start;
  font-size: clamp(1.9rem, 3vw, 2.5rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.05em;
  color: var(--brand-9);
  font-variant-numeric: tabular-nums;
  /* Masque le rail sur sa propre hauteur */
  background: var(--neutral-1);
  padding: 2px 0 12px;
}

.etape-titre {
  font-size: clamp(1.15rem, 1.7vw, 1.45rem);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.03em;
  color: var(--neutral-12);
  margin-bottom: var(--space-3);
  align-self: center;
}
.etape-texte {
  font-size: clamp(1.02rem, 1.2vw, 1.12rem);
  line-height: 1.75;
  color: var(--neutral-11);
  /* La colonne de la grille borne déjà la mesure : une contrainte de plus
     laisserait du vide à droite du texte. */
}

@media (max-width: 768px) {
  .etapes::before { left: 18px; }
  .etape {
    grid-template-columns: 40px 1fr;
    column-gap: var(--space-5);
  }
  .etape-num { font-size: 1.7rem; padding-bottom: 10px; }
}

/* Relance après le déroulé. Le lecteur vient d'apprendre qu'il ne paie rien
   avant d'avoir vu le résultat : c'est le sommet de conviction de la page, et
   le prochain bouton était à 5 000 px plus bas. Aucun texte d'accompagnement,
   la section qui précède a déjà tout dit. */
.relance {
  display: flex;
  justify-content: center;
  margin-top: clamp(48px, 6vw, 84px);
}

/* ═══════════════════════════════════════════════════════════════════════════
   LES PREUVES
   ═══════════════════════════════════════════════════════════════════════════
   Deux cartes larges, alternées, chacune avec une capture réelle du site et un
   lien sortant. Le visiteur vérifie au lieu de croire : c'est le principe de
   toute la page. Pas de logo client, aucun accord n'a été demandé pour ça. */
.preuves {
  display: grid;
  gap: clamp(56px, 7vw, 104px);
  max-width: 1120px;
  margin: clamp(44px, 5vw, 76px) auto 0;
}

.preuve {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: clamp(28px, 3.6vw, 56px);
  align-items: center;
}
/* La seconde carte inverse le sens de lecture : deux blocs identiques à la
   suite se liraient comme un gabarit répété. */
.preuve:nth-child(even) .preuve-media { order: 2; }

.preuve-media {
  display: block;
  border-radius: 14px;
  overflow: hidden;
  border: 1px solid rgba(255,255,255,0.09);
  background: var(--neutral-2);
  box-shadow:
    0 2px 6px rgba(0,0,0,0.4),
    0 18px 40px -20px rgba(0,0,0,0.8),
    0 40px 90px -50px rgba(201,168,76,0.25);
  transition: transform 0.4s cubic-bezier(0.16,1,0.3,1), box-shadow 0.4s ease;
}
.preuve-media img {
  width: 100%;
  height: auto;
  display: block;
  transition: transform 0.7s cubic-bezier(0.16,1,0.3,1);
}
.preuve-media:hover { transform: translateY(-3px); }
.preuve-media:hover img { transform: scale(1.025); }
.preuve-media:focus-visible {
  outline: 2px solid var(--brand-9);
  outline-offset: 4px;
}

.preuve-nom {
  font-size: clamp(1.3rem, 2.1vw, 1.75rem);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.15;
  color: var(--neutral-12);
  margin-bottom: var(--space-4);
}
.preuve-texte {
  font-size: clamp(0.98rem, 1.1vw, 1.05rem);
  line-height: 1.75;
  color: var(--neutral-11);
  margin-bottom: var(--space-4);
}

/* Le résultat est la seule ligne chiffrée de la page : elle se détache. */
.preuve-resultat {
  font-size: clamp(1rem, 1.2vw, 1.1rem);
  line-height: 1.6;
  color: var(--neutral-12);
  padding-top: var(--space-4);
  border-top: 1px solid rgba(201,168,76,0.28);
}
.preuve-chiffre {
  color: var(--brand-9);
  font-weight: 600;
}

.preuve-lien {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: var(--space-5);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--brand-9);
  text-decoration: none;
  border-bottom: 1px solid rgba(201,168,76,0.3);
  padding-bottom: 2px;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.preuve-lien svg { transition: transform 0.25s cubic-bezier(0.34,1.4,0.64,1); }
.preuve-lien:hover { color: var(--brand-10); border-bottom-color: var(--brand-10); }
.preuve-lien:hover svg { transform: translateX(3px); }
.preuve-lien:focus-visible { outline: 2px solid var(--brand-9); outline-offset: 3px; }

/* Ligne honnête de clôture : pas de nom, rien n'est livré sur ces deux-là. */
.preuves-suite {
  max-width: 52ch;
  margin: clamp(48px, 5.5vw, 76px) auto 0;
  text-align: center;
  font-size: clamp(1rem, 1.2vw, 1.1rem);
  line-height: 1.7;
  color: var(--neutral-10);
}

@media (max-width: 860px) {
  .preuve {
    grid-template-columns: 1fr;
    gap: var(--space-6);
  }
  .preuve:nth-child(even) .preuve-media { order: 0; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CE QUI EST COMPRIS
   ═══════════════════════════════════════════════════════════════════════════
   Liste calquée sur le devis signé, jamais inventée. Ni coche verte, ni picto :
   le marqueur est un filet doré tracé en CSS, donc aucun caractère de tiret
   dans le texte. Deux colonnes sur desktop, une seule sur mobile. */
.compris {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  column-gap: clamp(32px, 5vw, 88px);
  row-gap: 0;
  list-style: none;
  max-width: 960px;
  margin: clamp(44px, 5vw, 76px) auto 0;
}

.compris li {
  display: grid;
  grid-template-columns: 22px 1fr;
  align-items: baseline;
  column-gap: var(--space-4);
  padding: var(--space-4) 0;
  border-bottom: 1px solid rgba(255,255,255,0.06);
  font-size: clamp(0.98rem, 1.1vw, 1.05rem);
  line-height: 1.6;
  color: var(--neutral-11);
}

/* Les deux derniers éléments ferment chacun leur colonne : pas de filet
   suspendu sous le bas de la liste. */
.compris li:nth-last-child(-n+2) { border-bottom: none; }

/* Marqueur : un filet doré, pas une coche. */
.compris li::before {
  content: '';
  display: block;
  width: 14px;
  height: 1.5px;
  border-radius: 2px;
  background: var(--brand-9);
  transform: translateY(-0.35em);
}

.compris-note {
  max-width: 46ch;
  margin: clamp(32px, 4vw, 52px) auto 0;
  text-align: center;
  font-size: 0.95rem;
  line-height: 1.7;
  color: var(--neutral-10);
}

@media (max-width: 760px) {
  .compris { grid-template-columns: 1fr; max-width: 560px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   QUI JE SUIS
   ═══════════════════════════════════════════════════════════════════════════
   Seule section de la page dont le titre est aligné à gauche : elle porte une
   photo, et la règle du projet veut le texte à gauche quand une image
   l'accompagne. Ça casse aussi le rythme des titres centrés.
   Aucun mot sur l'âge, les études ou le fait de travailler seul. */
.portrait-bloc {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: clamp(32px, 4.5vw, 72px);
  align-items: center;
  max-width: 1000px;
  margin: 0 auto;
}

.portrait {
  position: relative;
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid rgba(255,255,255,0.08);
  box-shadow:
    0 2px 6px rgba(0,0,0,0.4),
    0 24px 50px -26px rgba(0,0,0,0.9),
    0 50px 100px -60px rgba(201,168,76,0.3);
}
.portrait img {
  width: 100%;
  height: auto;
  display: block;
  /* La photo est prise en plein jour : sans traitement elle jure sur une page
     sombre. On l'assombrit et on la désature légèrement. */
  filter: saturate(0.82) contrast(1.06) brightness(0.86);
}
/* Couche de traitement : chaleur dorée en fondu, et bas assombri pour marier
   l'image au fond de la page. */
.portrait::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(to top, rgba(17,17,17,0.55) 0%, transparent 46%),
    radial-gradient(72% 60% at 30% 18%, rgba(201,168,76,0.16) 0%, transparent 70%);
  mix-blend-mode: multiply;
}

.portrait-corps .offre-h2 {
  font-size: clamp(1.6rem, 2.9vw, 2.4rem);
  margin-bottom: var(--space-5);
}
.portrait-texte {
  font-size: clamp(1rem, 1.15vw, 1.08rem);
  line-height: 1.8;
  color: var(--neutral-11);
  max-width: 58ch;
}
/* Le SIRET est la seule ligne vérifiable en un clic de toute la page : il est
   posé à part, en petit, sans emphase commerciale. */
.portrait-siret {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid rgba(255,255,255,0.07);
  font-size: 0.88rem;
  line-height: 1.6;
  color: var(--neutral-10);
}
.portrait-siret strong {
  color: var(--neutral-11);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 860px) {
  .portrait-bloc {
    grid-template-columns: 1fr;
    gap: var(--space-6);
    max-width: 560px;
  }
  .portrait { max-width: 260px; }
}

/* Demande de Hugo (tâche 24, téléphone) : la photo était petite et calée à
   gauche sur mobile — `.portrait` hérite de `justify-self: stretch` du grid
   parent en une seule colonne, et un `max-width` plus étroit que la colonne
   ne recentre rien tout seul sans marge automatique. Bornée à 600px : au-delà
   (tablette 601–860px), la mise en page ci-dessus reste inchangée, seul le
   mobile (390px) est concerné. Desktop (>860px) déjà harmonieux, intouché. */
@media (max-width: 600px) {
  .portrait {
    max-width: min(84vw, 340px);
    margin: 0 auto;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LA LIGNE DE QUESTION, PUIS LE CTA FINAL
   ═══════════════════════════════════════════════════════════════════════════
   Pas d'accordéon, pas de bloc « questions fréquentes », pas de pictogramme de
   point d'interrogation : une seule ligne sobre, qui n'attire l'attention sur
   rien. Un titre « combien ça coûte » planterait la question dans la tête de
   quelqu'un qui ne se la posait pas. */
.question-ligne {
  max-width: 56ch;
  /* Elle vit entre deux sections et n'a donc aucune marge propre : sans ça,
     elle se retrouvait à 65 px du titre suivant sur mobile. */
  margin: clamp(8px, 1.5vw, 20px) auto clamp(48px, 6vw, 80px);
  padding: 0 var(--h-pad);
  text-align: center;
  font-size: clamp(0.98rem, 1.1vw, 1.05rem);
  line-height: 1.7;
  color: var(--neutral-10);
}
.question-ligne a {
  color: var(--neutral-11);
  text-decoration: none;
  border-bottom: 1px solid rgba(201,168,76,0.35);
  padding-bottom: 1px;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.question-ligne a:hover { color: var(--brand-9); border-bottom-color: var(--brand-9); }
.question-ligne a:focus-visible { outline: 2px solid var(--brand-9); outline-offset: 3px; }

/* Surface légèrement différenciée : le dernier écran doit se détacher. */
.cta-final {
  background: var(--neutral-2);
  border-top: 1px solid rgba(255,255,255,0.05);
  text-align: center;
}
.cta-final-inner {
  max-width: 620px;
  margin: 0 auto;
}
.cta-final .offre-h2 { margin-bottom: var(--space-5); }
.cta-final-sous {
  font-size: clamp(1rem, 1.2vw, 1.12rem);
  line-height: 1.7;
  color: var(--neutral-11);
  margin-bottom: var(--space-7);
}

/* ═══════════════════════════════════════════════════════════════════════════
   VARIANTE « NUAGE » du hero
   ═══════════════════════════════════════════════════════════════════════════
   Le texte se pose à l'intérieur du nuage d'encre, en haut de l'image, et le
   sujet reste lisible dessous : les braises montent de sa tête vers la
   promesse. Image en plein cadre derrière, texte centré.
   Le titre est plafonné plus bas que dans la version en colonne : à 4.6rem il
   déborderait du nuage et viendrait s'écraser sur le visage. */
.offre-hero.hero-nuage {
  /* Bande de nuage ajoutée AU-DESSUS de l'image. La couleur est relevée sur
     la première rangée de pixels du fichier, uniforme sur toute la largeur :
     rgb(21,35,43). Le raccord est donc invisible, et le voile passe par-dessus
     les deux, ce qui les assombrit identiquement.
     Elle sert à loger tout le bloc dans le nuage sans écraser le titre. */
  --nuage-lift: 190px;
  background-color: #15232b;

  min-height: calc(100vh + var(--nuage-lift));
  min-height: calc(100svh + var(--nuage-lift));
  align-items: flex-start;
  padding: 132px 0 var(--space-7);
  text-align: center;
}

.hero-nuage .offre-hero-img {
  left: 0; right: 0;
  width: 100%;
  /* Ancrée en bas : la bande occupe le haut, l'image garde sa taille et le
     sujet reste entier. */
  top: auto;
  bottom: 0;
  height: calc(100% - var(--nuage-lift));
  object-position: center center;
  /* Fond enchaîné sur la bande par un dégradé de la même couleur : pas de
     ligne de raccord même là où une étoile touche le bord. */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 9%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 9%);
}

/* Assombrit le nuage pour la lecture, laisse le ciel et le visage intacts. */
.hero-nuage .offre-hero-scrim {
  background:
    /* Bande resserrée sur la ligne du bas, mesurée à 43-45 % de la hauteur du
       hero : c'est là que la colonne de braises est la plus vive et elle
       ramenait le contraste à 3.0, sous le seuil. Voile ciblé plutôt que
       nuage globalement assombri, pour ne pas éteindre la flamme. */
    radial-gradient(44% 11% at 50% 44%,
      rgba(8,8,10,0.94) 0%,
      rgba(8,8,10,0.60) 52%,
      transparent 100%),
    /* Épaissit le nuage derrière le bloc de texte. Un dégradé radial se lit
       comme une densité de nuage, pas comme un cartouche rapporté. */
    radial-gradient(38% 30% at 50% 26%,
      rgba(8,8,10,0.78) 0%,
      rgba(8,8,10,0.42) 58%,
      transparent 100%),
    linear-gradient(to bottom,
      rgba(8,8,10,0.82) 0%,
      rgba(8,8,10,0.66) 30%,
      rgba(8,8,10,0.24) 48%,
      transparent 62%),
    linear-gradient(to top,
      var(--neutral-1) 0%,
      rgba(17,17,17,0.5) 9%,
      transparent 22%);
}

/* Mesure large et interlignes serrés : au centre le nuage remonte, c'est par
   là que passent les braises. Tout le bloc doit tenir au-dessus de ce creux,
   bouton et ligne de preuve compris. */
.hero-nuage .offre-hero-inner {
  max-width: 1020px;
  margin: 0 auto;
}
/* La bande rend la hauteur qui manquait : le titre remonte vers sa taille
   de la version en colonne au lieu d'être plafonné par le creux du nuage. */
.hero-nuage h1 {
  font-size: clamp(2.2rem, 5vw, 4.1rem);
  max-width: none;
  margin: 0 auto;
}
.hero-nuage .offre-hero-sub {
  margin-top: var(--space-5);
  font-size: clamp(1rem, 1.2vw, 1.14rem);
  max-width: 58ch;
  margin-left: auto;
  margin-right: auto;
}
.hero-nuage .offre-hero-actions {
  justify-content: center;
  margin-top: var(--space-6);
}
.hero-nuage .offre-btn { padding: 15px 30px; }
.hero-nuage .offre-hero-proof {
  margin-top: var(--space-5);
  max-width: 48ch;
  margin-left: auto;
  margin-right: auto;
}

@media (max-width: 768px) {
  /* L'image reste en plein cadre : le nuage porte le texte, comme en desktop. */
  .offre-hero.hero-nuage {
    display: flex;
    align-items: flex-start;
    padding: 104px 0 var(--space-7);
    min-height: 100vh;
    min-height: 100svh;
  }
  .hero-nuage .offre-hero-img {
    position: absolute;
    height: 100%;
    aspect-ratio: auto;
    /* Cadre la tête entière : à 50 % la chevelure était coupée à gauche. */
    object-position: 44% center;
    margin-bottom: 0;
    -webkit-mask-image: none;
            mask-image: none;
  }
  /* Le voile radial est exprimé en pourcentage de la boîte : sur un écran
     étroit il se réduit à une ellipse au milieu et laisse les extrémités des
     lignes sur la flamme. Il est réécrit large ici, pas hérité. */
  .hero-nuage .offre-hero-scrim {
    display: block;
    background:
      /* Même bande ciblée, mais la ligne tombe plus bas sur écran étroit :
         mesurée à 54,6-60,4 % de la hauteur, contre 43-45 % en desktop. */
      radial-gradient(126% 13% at 50% 57.5%,
        rgba(8,8,10,0.95) 0%,
        rgba(8,8,10,0.62) 52%,
        transparent 100%),
      radial-gradient(132% 38% at 50% 20%,
        rgba(8,8,10,0.88) 0%,
        rgba(8,8,10,0.58) 62%,
        transparent 100%),
      linear-gradient(to bottom,
        rgba(8,8,10,0.86) 0%,
        rgba(8,8,10,0.62) 32%,
        rgba(8,8,10,0.16) 50%,
        transparent 62%),
      linear-gradient(to top,
        var(--neutral-1) 0%,
        rgba(17,17,17,0.5) 8%,
        transparent 20%);
  }
  /* Demande de Hugo (tâche 24 bis, téléphone) : tout le hero centré en une
     colonne, pas seulement le titre et le bouton. Remplace la décision
     antérieure (paragraphe et ligne de preuve repassés à gauche, jugés plus
     lisibles ainsi sur écran étroit) — explicite ici, même si le parent
     `.offre-hero.hero-nuage` porte déjà `text-align: center` : les margin
     auto qui centrent le bloc lui-même restent celles du bloc desktop
     (lignes ci-dessus), non répétées ici. */
  .hero-nuage .offre-hero-sub { text-align: center; }
  .hero-nuage .offre-hero-proof { text-align: center; }
}

/* ─── Reveal ponctuel au chargement ───────────────────────────────────────
   Une seule orchestration, jamais en boucle. Le blur qui se résout sur le
   titre est explicitement autorisé par le plan de construction ; tout le
   reste ne bouge qu'en transform et opacity. Depuis la tâche 25, ce blur est
   retiré sur mobile (≤768px) pour le coût de recomposition qu'il imposait —
   voir le commentaire sous `.reveal-title` ci-dessous. */
@keyframes offre-rise {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes offre-title-in {
  from { opacity: 0; transform: translateY(26px); filter: blur(16px); }
  to   { opacity: 1; transform: translateY(0);    filter: blur(0); }
}

.reveal {
  opacity: 0;
  animation: offre-rise 0.85s cubic-bezier(0.16,1,0.3,1) forwards;
}
.reveal-title {
  opacity: 0;
  animation: offre-title-in 1.1s cubic-bezier(0.16,1,0.3,1) forwards;
}
/* Diagnostic tâche 25 (téléphone, « ça rame ») : `offre-title-in` anime
   `filter`, seule dérogation connue à la règle transform/opacity du dépôt —
   explicitement autorisée par le plan de construction, mais coûteuse sur
   mobile. Le titre porte `font-size: clamp(2.2rem, 5vw, 4.1rem)`, quasi
   pleine largeur du hero à cette largeur d'écran : le navigateur recompose
   un calque flouté de cette taille à chaque frame pendant 1.1s, par-dessus
   l'image hero et ses dégradés, au moment précis où il décode déjà cette
   image en priorité haute (fetchpriority="high", pas de #page-loader sur
   cette page). C'est le blur, pas l'animation en elle-même, qui coûte : sur
   mobile on retire uniquement le filtre, le titre garde le même fondu et le
   même glissement. Desktop inchangé, la puissance GPU y absorbe le coût. */
@media (max-width: 768px) {
  .reveal-title { animation-name: offre-rise; }
}
.reveal-d1 { animation-delay: 0.10s; }
.reveal-d2 { animation-delay: 0.22s; }
.reveal-d3 { animation-delay: 0.34s; }
.reveal-d4 { animation-delay: 0.46s; }

/* ─── Reveal au scroll ────────────────────────────────────────────────────
   Le masquage est conditionné à la classe .js posée sur <html> : sans
   JavaScript, tout s'affiche normalement et rien ne reste invisible.
   Transform et opacity uniquement. */
.js .rise {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity   0.75s cubic-bezier(0.16,1,0.3,1),
    transform 0.75s cubic-bezier(0.16,1,0.3,1);
}
.js .rise.is-in {
  opacity: 1;
  transform: translateY(0);
}
.js .rise-d1 { transition-delay: 0.06s; }
.js .rise-d2 { transition-delay: 0.12s; }
.js .rise-d3 { transition-delay: 0.18s; }
.js .rise-d4 { transition-delay: 0.24s; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal, .reveal-title {
    opacity: 1;
    animation: none;
  }
  .js .rise {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ─── Mobile ──────────────────────────────────────────────────────────────
   Le cadrage bascule : l'image occupe le haut, le texte se pose en bas sur
   les épaules, qui sont la zone sombre de la photo. Le regard du sujet monte,
   le texte descend, les deux ne se disputent pas la même zone.
   Le titre passe en pleine largeur : à 390 px, 16ch le couperait trop court. */
@media (max-width: 768px) {
  /* Sur un écran étroit, superposer le texte à l'image efface le visage et
     abîme la lecture. Les deux se succèdent au lieu de se disputer la place :
     l'image occupe le haut, le texte se pose dessous sur fond propre. */
  .offre-hero {
    display: block;
    min-height: 0;
    padding: 0 0 var(--space-7);
  }
  .offre-hero-img {
    position: static;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 12;
    object-position: 50% 32%;
    margin-bottom: var(--space-6);
    /* Le bas se dissout dans la page, le texte n'a pas de bord franc au-dessus */
    -webkit-mask-image: linear-gradient(to bottom, #000 52%, rgba(0,0,0,0.45) 78%, transparent 100%);
            mask-image: linear-gradient(to bottom, #000 52%, rgba(0,0,0,0.45) 78%, transparent 100%);
  }
  .offre-hero-scrim { display: none; }
  .offre-hero h1 { max-width: none; }
  .offre-hero-sub { margin-top: var(--space-5); }
  .offre-hero-actions { margin-top: var(--space-6); }
  .offre-btn { width: 100%; justify-content: center; }
}
