/* ============================================================================
   SITE AGENCE TRAFFIC MONKEYS — Design System v2
   Direction : Swiss / Grid (fidèle North Studio) + couleur signature Pétrole abyssal.
   Réf : _bmad-output/site-agence-v2/inputs/design-exploration/DESIGN-SYSTEM.md
   ============================================================================ */

/* ---- Fonts (self-host, pas de Google CDN) -------------------------------- */
@font-face {
  font-family: 'Archivo';
  src: url('/fonts/Archivo-Variable.woff2') format('woff2-variations');
  font-weight: 300 600;
  font-style: normal;
  font-display: swap;
}

/* ---- Variables ----------------------------------------------------------- */
:root {
  /* base monochrome */
  --paper: #f3f1ec; /* fond papier chaud */
  --ink: #1c1a17; /* encre — texte principal */
  --soft: #9a958c; /* gris doux — texte secondaire, labels */
  --line: #e4e1d9; /* filets de grille (très pâles) */

  /* couleur signature — pétrole abyssal minéral */
  --brand: #19394c; /* solide : texte/accent/boutons */
  --brand-deep: #0a1622; /* profond : fonds */
  --brand-grad: linear-gradient(140deg, #19394c 0%, #0a1622 100%); /* gros blocs */

  /* typo */
  --grotesk: 'Archivo', 'Helvetica Neue', Arial, sans-serif;

  /* layout */
  --maxw: 1280px;
  --pad: clamp(18px, 2.4vw, 28px);

  /* ---- Mouvement -------------------------------------------------------
     Ces valeurs sont les MEMES que celles de motion-studio/src/lib/tokens.ts,
     qui produit les boucles video. C'est ce qui fait qu'une video posee dans
     une section et l'entree de la section voisine ont l'air d'appartenir au
     meme objet : meme courbe, meme tempo.

     Personnalite retenue : Premium (durees longues, aucun rebond) tenue par
     une precision Corporate (trajectoires droites, decalages reguliers).
     Un mouvement rebondissant trahirait une DA suisse.
     -------------------------------------------------------------------- */
  --ease: cubic-bezier(0.4, 0, 0.2, 1); /* signature — 80 % des mouvements */
  --ease-emphasized: cubic-bezier(0.05, 0.7, 0.1, 1); /* entrees marquantes */
  --ease-exit: cubic-bezier(0.3, 0, 1, 1); /* sorties : partent et ne reviennent pas */

  --dur-quick: 350ms;
  --dur-standard: 550ms;
  --dur-slow: 800ms;

  /* Decalage entre elements d'un meme groupe. Le total d'un groupe ne doit
     jamais depasser 500 ms, sinon le dernier element parait oublie :
     3 elements x 90 ms = 180 ms, on est large. */
  --stagger: 90ms;
}

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

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

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--grotesk);
  font-weight: 400;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

/* ---- Grain minéral (texture sur les blocs dégradés) ---------------------- */
/* utilisé via .grain::after sur les grandes surfaces pétrole — anti-IA */
.grain {
  position: relative;
  isolation: isolate;
}
.grain::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0.05;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ============================================================================
   GRILLE SWISS (North) — 12 colonnes, filets fins, fond continu
   ============================================================================ */
.canvas {
  max-width: var(--maxw);
  margin: 0 auto;
  border-left: 1px solid var(--line);
  border-right: 1px solid var(--line);
  /* trame de fond continue 12 colonnes (filets très pâles) */
  background-image: repeating-linear-gradient(
    90deg,
    transparent,
    transparent calc(100% / 12 - 1px),
    var(--line) calc(100% / 12 - 1px),
    var(--line) calc(100% / 12)
  );
}

.band {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  border-top: 1px solid var(--line);
}
.band:first-child {
  border-top: none;
}

/* label de section (colonne 1, étroit) — numérotation Swiss */
.sect-label {
  grid-column: 1 / 2;
  padding: clamp(34px, 5vw, 56px) 0 0 var(--pad);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--soft);
}
.sect-num {
  display: block;
  color: var(--ink);
  margin-bottom: 16px;
}
.sect-dash {
  display: block;
  width: 20px;
  height: 1px;
  background: var(--brand);
  margin-bottom: 16px;
}

/* ============================================================================
   HEADER
   ============================================================================ */
.site-header {
  min-height: 70px;
  align-items: stretch;
}
.brand {
  grid-column: 1 / 3;
  display: flex;
  align-items: center;
  padding: 0 var(--pad);
  font-weight: 500;
  font-size: 15px;
  letter-spacing: 0.02em;
  border-right: 1px solid var(--line);
  text-decoration: none;
}
.brand sup {
  color: var(--brand);
}
.site-nav {
  grid-column: 4 / 9;
  display: flex;
  align-items: center;
  gap: clamp(20px, 3vw, 36px);
  font-size: 12px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}
.site-nav a {
  text-decoration: none;
  transition: color 0.18s var(--ease);
}
.site-nav a:hover {
  color: var(--brand);
}
.header-cta {
  grid-column: 11 / 13;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding: 0 var(--pad);
  font-size: 12px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  border-left: 1px solid var(--line);
}
.header-cta a {
  text-decoration: none;
  color: var(--brand);
}

/* ============================================================================
   HERO — résultat-commun, beaucoup de vide
   ============================================================================ */
.hero {
  min-height: 420px;
}
.hero__title {
  grid-column: 2 / 9;
  padding: clamp(40px, 6vw, 56px) 30px 0 6px;
  font-weight: 300;
  font-size: clamp(40px, 5vw, 68px);
  line-height: 1.08;
  letter-spacing: -0.02em;
}
/* Le mot-cle de la promesse. Le trait se TRACE sous le mot une demi-seconde
   apres l'arrivee : le temps que l'oeil se pose sur le titre et arrive au
   mot. C'est le seul geste du hero — voir la note LCP plus bas.
   AJOUT DE DA : sans ce bloc, "grandir" reste simplement colore comme avant. */
.hero__title u {
  text-decoration: none;
  color: var(--brand);
  position: relative;
}
.hero__title u::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0.06em;
  height: 2px;
  background: var(--brand);
  transform: scaleX(0);
  transform-origin: left center;
  animation: tm-draw var(--dur-slow) var(--ease-emphasized) 550ms both;
}
@keyframes tm-draw {
  to {
    transform: scaleX(1);
  }
}
.hero__aside {
  grid-column: 9 / 12;
  padding: clamp(44px, 6vw, 56px) var(--pad) 0;
}
.hero__aside p {
  font-size: 14px;
  color: var(--soft);
  line-height: 1.6;
}

.hero__actions {
  grid-column: 2 / 9;
  padding: 40px 6px 50px;
  display: flex;
  align-items: flex-end;
  gap: 56px;
}
.scrollcue {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--soft);
}
.scrollcue__arrow {
  display: block;
  width: 1px;
  height: 42px;
  background: var(--brand);
  margin-top: 12px;
  /* Il se trace vers le bas, marque un temps, disparait, recommence.
     Un trait fixe indique une direction ; un trait qui descend la SUGGERE.
     Cycle long (2,6 s) et pause : une boucle rapide devient un tic nerveux. */
  transform-origin: top center;
  animation: tm-scrollcue 2600ms var(--ease) infinite;
}
@keyframes tm-scrollcue {
  0% {
    transform: scaleY(0);
    opacity: 0;
  }
  22% {
    opacity: 1;
  }
  46% {
    transform: scaleY(1);
    opacity: 1;
  }
  /* la tenue : le trait reste entier, immobile */
  74% {
    transform: scaleY(1);
    opacity: 1;
  }
  100% {
    transform: scaleY(1);
    opacity: 0;
  }
}
.hero__link {
  grid-column: 9 / 12;
  padding: 0 var(--pad) 50px;
  display: flex;
  align-items: flex-end;
}
.hero__link a {
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  display: inline-flex;
  gap: 10px;
  border-bottom: 1px solid var(--ink);
  padding-bottom: 4px;
}

/* ============================================================================
   SECTION 02 — La preuve (bloc visuel plein pétrole + texte)
   ============================================================================ */
.feat__visual {
  grid-column: 2 / 8;
  padding: clamp(34px, 5vw, 40px) 30px 40px 6px;
}
.feat__frame {
  background: var(--brand-grad);
  aspect-ratio: 16 / 11;
  display: flex;
  align-items: flex-end;
  padding: 24px;
  color: var(--paper);
}

/* ============================================================================
   BLOCS ANIMES (motion design)
   ----------------------------------------------------------------------------
   Un bloc porteur de [data-motion] recoit une boucle video montee dans
   motion-studio/ (Remotion). La video est injectee par app.js seulement
   lorsque le bloc approche de l'ecran : ces pages recoivent du trafic Google
   Ads paye, et un octet telecharge pour rien se paie en vitesse de page,
   donc en Quality Score, donc en CPC.

   Sans JS, ou en "prefers-reduced-motion", le bloc reste ce qu'il etait :
   un aplat petrole grene. Rien ne casse.
   ========================================================================== */
[data-motion] {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.motion-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover; /* la video est au ratio exact du bloc : aucun recadrage */
  z-index: 1;

  /* VISIBLE PAR DEFAUT. Ne jamais revenir a `opacity: 0`.
     ------------------------------------------------------------------------
     La video partait a opacity 0 et n'etait revelee qu'a la reception d'un
     evenement de chargement (loadeddata / canplay / playing). Consequence :
     quand ces evenements n'arrivaient pas — cas courant depuis un cache
     chaud, ou dans un onglet ralenti par le navigateur — la boucle tournait
     REELLEMENT, mais invisible, derriere son affiche fixe. Le bloc paraissait
     fige alors que tout fonctionnait, et aucune verification technique ne
     pouvait le voir : la video jouait, son temps avancait.
     C'est ce qui a fait perdre plusieurs jours sur ce chantier.
     L'attribut `poster` couvre deja le moment ou aucune image n'est encore
     decodee : il n'y a rien a masquer, donc rien a reveler. */
  opacity: 1;

  /* Fondu d'apparition en animation et non en transition : une animation se
     joue au montage de l'element, sans dependre du moindre evenement, et
     finit toujours a 1. */
  animation: motion-appear 0.6s var(--ease) both;
}
@keyframes motion-appear {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* Grain vivant, AU-DESSUS de la video.
   Il est ici et pas dans le fichier video pour une raison mesuree : anime a
   l'interieur de la video, il empeche le codec de predire une image a partir
   de la precedente et alourdit le fichier de 37 % (408 ko -> 230 ko une fois
   sorti). En CSS il ne coute rien, et il continue de bouger — c'est lui qui
   empeche le bloc de se figer en image. */
[data-motion]::before {
  content: '';
  position: absolute;
  inset: -24px;
  z-index: 2;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: motion-grain 3.2s steps(1) infinite;
}
/* Par a-coups volontaires (steps) : un grain qui glisse en continu se lit
   comme un decor qui derive ; un grain qui saute se lit comme de la matiere. */
@keyframes motion-grain {
  0% {
    transform: translate(0, 0);
  }
  25% {
    transform: translate(-12px, 7px);
  }
  50% {
    transform: translate(9px, -11px);
  }
  75% {
    transform: translate(-7px, -6px);
  }
}

/* La legende du bloc reste lisible par-dessus tout le reste. */
[data-motion] > span {
  position: relative;
  z-index: 3;
}
.feat__frame span {
  color: rgba(243, 241, 236, 0.55);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.feat__text {
  grid-column: 9 / 13;
  padding: clamp(34px, 5vw, 40px) var(--pad);
  display: flex;
  flex-direction: column;
}
.feat__ey {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--soft);
  margin-bottom: 16px;
}
.feat__text h3 {
  font-weight: 300;
  font-size: clamp(24px, 2.4vw, 34px);
  line-height: 1.12;
  letter-spacing: -0.015em;
  margin-bottom: 16px;
}
.feat__text p {
  font-size: 14px;
  color: var(--soft);
  line-height: 1.6;
}
.feat__meta {
  display: flex;
  gap: 20px;
  margin-top: 30px;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--soft);
}
/* variante "texte seul" (sans bloc visuel à côté) — page Acquisition §06 */
.feat__text--wide {
  grid-column: 2 / 10;
  padding-right: 30px;
}
.feat__text--wide h3 {
  font-size: clamp(26px, 2.8vw, 38px);
  max-width: 22ch;
}
.feat__text--wide p {
  max-width: 56ch;
}

/* ============================================================================
   SECTION 03 — Les 3 pôles
   ============================================================================ */
.poles {
  grid-column: 2 / 13;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
.pole {
  padding: clamp(28px, 4vw, 40px) var(--pad);
  border-left: 1px solid var(--line);
}
.pole:first-child {
  border-left: none;
}
.pole__name {
  font-size: 17px;
  font-weight: 500;
  letter-spacing: 0.01em;
}
.pole__name--hero {
  color: var(--brand);
}
.pole__desc {
  display: block;
  font-weight: 400;
  font-size: 13px;
  color: var(--soft);
  letter-spacing: 0.02em;
  margin-top: 8px;
  line-height: 1.55;
}

/* ============================================================================
   SECTION 04 — TARIFS (3 packs en escalier)
   ============================================================================ */
.packs {
  grid-column: 2 / 13;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
.pack {
  padding: clamp(28px, 4vw, 40px) var(--pad) clamp(32px, 4vw, 44px);
  border-left: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
  position: relative;
}
.pack:first-child {
  border-left: none;
}
/* pack mis en avant : fond pétrole texturé */
.pack--featured {
  background: var(--brand-grad);
  color: var(--paper);
  border-left: none;
}
.pack--featured .pack__price,
.pack--featured .pack__name {
  color: var(--paper);
}
.pack--featured .pack__mrr,
.pack--featured .pack__incl {
  color: rgba(243, 241, 236, 0.65);
}
.pack--featured .pack__badge {
  color: var(--paper);
  border-color: rgba(243, 241, 236, 0.4);
}
.pack--featured .pack__cta {
  background: var(--paper);
  color: var(--brand-deep);
}

.pack__badge {
  align-self: flex-start;
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brand);
  border: 1px solid var(--line);
  padding: 4px 9px;
  margin-bottom: 22px;
}
.pack__name {
  font-size: 15px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 500;
  margin-bottom: 18px;
}
.pack__price {
  font-weight: 300;
  font-size: clamp(34px, 3.4vw, 46px);
  line-height: 1;
  letter-spacing: -0.02em;
}
.pack__price small {
  font-size: 14px;
  color: var(--soft);
  letter-spacing: 0;
}
.pack__mrr {
  font-size: 13px;
  color: var(--soft);
  margin-top: 10px;
}
.pack__incl {
  font-size: 13px;
  color: var(--soft);
  line-height: 1.55;
  margin: 22px 0;
  flex: 1;
}
.pack__cta {
  align-self: flex-start;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: var(--brand);
  color: var(--paper);
  padding: 12px 18px;
  text-decoration: none;
  transition:
    transform 0.16s var(--ease),
    box-shadow 0.16s var(--ease);
}
.pack__cta:hover {
  box-shadow: 0 6px 18px rgba(10, 22, 34, 0.18);
}

/* ============================================================================
   SECTION 05 — PROCESS (3 phases / ~4 semaines)
   ============================================================================ */
.process {
  grid-column: 2 / 13;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
.phase {
  padding: clamp(28px, 4vw, 40px) var(--pad);
  border-left: 1px solid var(--line);
}
.phase:first-child {
  border-left: none;
}
.phase__week {
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--brand);
  margin-bottom: 16px;
}
.phase__name {
  font-weight: 300;
  font-size: clamp(22px, 2.2vw, 30px);
  letter-spacing: -0.01em;
  margin-bottom: 14px;
}
.phase__desc {
  font-size: 14px;
  color: var(--soft);
  line-height: 1.6;
}

/* ============================================================================
   SECTION 06 — CONTACT (CTA final)
   ============================================================================ */
.contact {
  grid-column: 2 / 13;
  padding: clamp(48px, 7vw, 88px) var(--pad);
}
.contact h2 {
  font-weight: 300;
  font-size: clamp(32px, 4vw, 56px);
  line-height: 1.06;
  letter-spacing: -0.02em;
  max-width: 18ch;
}
.contact p {
  font-size: 15px;
  color: var(--soft);
  margin: 20px 0 32px;
  max-width: 52ch;
  line-height: 1.6;
}
.contact__cta {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: 14px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: var(--brand);
  color: var(--paper);
  padding: 16px 26px;
  text-decoration: none;
  transition:
    transform 0.16s var(--ease),
    box-shadow 0.16s var(--ease);
}
.contact__cta:hover {
  box-shadow: 0 8px 22px rgba(10, 22, 34, 0.22);
}

/* ============================================================================
   FORMULAIRE MULTI-STEP (lead-form)
   ============================================================================ */
.lead-form {
  margin-top: 36px;
  max-width: 560px;
}
.lead-form__progress {
  height: 2px;
  background: var(--line);
  margin-bottom: 32px;
}
.lead-form__progress-bar {
  display: block;
  height: 100%;
  width: 20%;
  background: var(--brand);
  transition: width 0.3s var(--ease);
}

.form-step {
  border: none;
  padding: 0;
  margin: 0;
}
.form-step__q {
  font-weight: 300;
  font-size: clamp(22px, 2.4vw, 30px);
  letter-spacing: -0.015em;
  margin-bottom: 22px;
  padding: 0;
}

.choices {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.choice {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  border: 1px solid var(--line);
  cursor: pointer;
  transition:
    border-color 0.16s var(--ease),
    background 0.16s var(--ease);
}
.choice:hover {
  border-color: var(--brand);
}
.choice input {
  accent-color: var(--brand);
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}
.choice span {
  font-size: 15px;
}
.choice small {
  color: var(--soft);
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-left: 6px;
}
.choice:has(input:checked) {
  border-color: var(--brand);
  background: rgba(25, 57, 76, 0.04);
}

.form-input {
  display: block;
  width: 100%;
  font-family: var(--grotesk);
  font-size: 15px;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--line);
  padding: 15px 16px;
  margin-bottom: 12px;
}
.form-input::placeholder {
  color: var(--soft);
}
.form-input:focus {
  outline: none;
  border-color: var(--brand);
}

.form-error {
  color: #b3261e;
  font-size: 13px;
  margin: 4px 0 0;
}

.lead-form__nav {
  display: flex;
  gap: 12px;
  margin-top: 28px;
}
.btn-solid,
.btn-ghost {
  font-family: var(--grotesk);
  font-size: 14px;
  letter-spacing: 0.03em;
  padding: 14px 24px;
  cursor: pointer;
  border: 1px solid var(--brand);
  transition:
    box-shadow 0.16s var(--ease),
    background 0.16s var(--ease);
}
.btn-solid {
  background: var(--brand);
  color: var(--paper);
}
.btn-solid:hover {
  box-shadow: 0 6px 18px rgba(10, 22, 34, 0.2);
}
.btn-ghost {
  background: transparent;
  color: var(--brand);
}
.btn-ghost:hover {
  background: rgba(25, 57, 76, 0.06);
}

/* ============================================================================
   PAGES PÔLES — éléments partagés (intro, offre, vitrine, FAQ)
   ============================================================================ */

/* Intro de page pôle : texte chapeau large, posé sur la grille */
.pole-intro {
  grid-column: 2 / 10;
  padding: clamp(40px, 6vw, 56px) 30px clamp(28px, 4vw, 40px) 6px;
}
.pole-intro h1 {
  font-weight: 300;
  font-size: clamp(34px, 4.4vw, 60px);
  line-height: 1.08;
  letter-spacing: -0.02em;
}
.pole-intro h1 u {
  text-decoration: none;
  color: var(--brand);
}
.pole-intro__lead {
  grid-column: 10 / 12;
  padding: clamp(44px, 6vw, 56px) var(--pad) 0;
}
.pole-intro__lead p {
  font-size: 14px;
  color: var(--soft);
  line-height: 1.6;
}

/* Bloc "ce qu'on fait" : prose posée, 2 colonnes texte/détail */
.pole-prose {
  grid-column: 2 / 9;
  padding: clamp(34px, 5vw, 40px) 30px 40px 6px;
}
.pole-prose h2,
.pole-prose h3 {
  font-weight: 300;
  letter-spacing: -0.015em;
}
.pole-prose h2 {
  font-size: clamp(24px, 2.6vw, 36px);
  line-height: 1.12;
  margin-bottom: 18px;
}
.pole-prose p {
  font-size: 15px;
  color: var(--ink);
  line-height: 1.65;
  margin-bottom: 16px;
  max-width: 58ch;
}
.pole-prose p.muted {
  color: var(--soft);
}
.pole-aside {
  grid-column: 9 / 13;
  padding: clamp(34px, 5vw, 40px) var(--pad);
}
.pole-aside__ey {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--soft);
  margin-bottom: 18px;
}

/* Liste de sous-services / inclusions, alignée sur la grille */
.pole-list {
  list-style: none;
  display: flex;
  flex-direction: column;
}
.pole-list li {
  display: flex;
  gap: 16px;
  padding: 18px 0;
  border-top: 1px solid var(--line);
  font-size: 14px;
  line-height: 1.55;
}
.pole-list li:first-child {
  border-top: none;
}
.pole-list .pole-list__k {
  flex-shrink: 0;
  width: 14px;
  color: var(--brand);
  font-size: 12px;
  letter-spacing: 0.04em;
}
.pole-list strong {
  font-weight: 500;
}
.pole-list .pole-list__d {
  display: block;
  color: var(--soft);
  margin-top: 4px;
}

/* Bloc offre / prix d'entrée (deux modes) */
.offer {
  grid-column: 2 / 13;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
}
.offer__card {
  padding: clamp(28px, 4vw, 40px) var(--pad) clamp(32px, 4vw, 44px);
  border-left: 1px solid var(--line);
  display: flex;
  flex-direction: column;
}
.offer__card:first-child {
  border-left: none;
}
.offer__k {
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--brand);
  margin-bottom: 18px;
}
.offer__price {
  font-weight: 300;
  font-size: clamp(30px, 3.2vw, 44px);
  line-height: 1;
  letter-spacing: -0.02em;
}
.offer__price small {
  font-size: 14px;
  color: var(--soft);
  letter-spacing: 0;
}
.offer__mrr {
  font-size: 13px;
  color: var(--soft);
  margin-top: 10px;
}
.offer__desc {
  font-size: 14px;
  color: var(--soft);
  line-height: 1.6;
  margin: 20px 0 0;
}

/* Vitrine / portfolio : grille de cartes, dégradé pétrole + grain */
.vitrine {
  grid-column: 2 / 13;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
.vit-card {
  padding: clamp(24px, 3vw, 32px) var(--pad) clamp(28px, 3.4vw, 36px);
  border-left: 1px solid var(--line);
  display: flex;
  flex-direction: column;
}
.vit-card:first-child {
  border-left: none;
}
.vit-card__frame {
  background: var(--brand-grad);
  aspect-ratio: 16 / 10;
  display: flex;
  align-items: flex-end;
  padding: 18px;
  margin-bottom: 18px;
}
.vit-card__frame span {
  color: rgba(243, 241, 236, 0.55);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.vit-card__name {
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.01em;
}
.vit-card__desc {
  font-size: 13px;
  color: var(--soft);
  line-height: 1.55;
  margin-top: 8px;
}
/* Note honnêteté sous la vitrine */
.vitrine-note {
  grid-column: 2 / 13;
  padding: 0 var(--pad) clamp(28px, 4vw, 40px);
  font-size: 13px;
  color: var(--soft);
  line-height: 1.6;
  max-width: 62ch;
}

/* CTA de bas de page pôle (rappel vers le formulaire de la home) */
.pole-cta {
  grid-column: 2 / 13;
  padding: clamp(48px, 7vw, 80px) var(--pad);
}
.pole-cta h2 {
  font-weight: 300;
  font-size: clamp(30px, 3.6vw, 52px);
  line-height: 1.06;
  letter-spacing: -0.02em;
  max-width: 18ch;
}
.pole-cta p {
  font-size: 15px;
  color: var(--soft);
  margin: 20px 0 32px;
  max-width: 52ch;
  line-height: 1.6;
}

@media (max-width: 900px) {
  .pole-intro,
  .pole-intro__lead,
  .pole-prose,
  .pole-aside,
  .vitrine-note,
  .pole-cta {
    grid-column: 1 / 13;
    padding-left: var(--pad);
    padding-right: var(--pad);
  }
  .offer,
  .vitrine {
    grid-column: 1 / 13;
    grid-template-columns: 1fr;
  }
  .offer__card,
  .vit-card {
    border-left: none;
    border-top: 1px solid var(--line);
  }
  .offer__card:first-child,
  .vit-card:first-child {
    border-top: none;
  }
}

/* ============================================================================
   FOOTER
   ============================================================================ */
.site-footer {
  grid-column: 1 / 13;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  padding: clamp(28px, 4vw, 40px) 0;
  gap: 12px;
}
.site-footer .f-brand {
  grid-column: 1 / 4;
  padding-left: var(--pad);
  font-weight: 500;
}
.site-footer .f-links {
  grid-column: 5 / 10;
  display: flex;
  gap: 24px;
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--soft);
}
.site-footer .f-links a {
  text-decoration: none;
}
.site-footer .f-tag {
  grid-column: 11 / 13;
  padding-right: var(--pad);
  text-align: right;
  font-size: 11px;
  color: var(--soft);
  letter-spacing: 0.04em;
}

/* ============================================================================
   RESPONSIVE
   ============================================================================ */
@media (max-width: 900px) {
  .canvas {
    background: none;
  }
  .brand {
    grid-column: 1 / 8;
    border-right: none;
  }
  .header-cta {
    grid-column: 9 / 13;
    border-left: none;
  }
  .site-nav,
  .sect-label,
  .scrollcue {
    display: none;
  }
  .hero__title,
  .hero__aside,
  .hero__actions,
  .hero__link,
  .feat__visual,
  .feat__text,
  .feat__text--wide {
    grid-column: 1 / 13;
    padding-left: var(--pad);
    padding-right: var(--pad);
  }
  .poles,
  .packs,
  .process {
    grid-column: 1 / 13;
    grid-template-columns: 1fr;
  }
  .pole,
  .pack,
  .phase {
    border-left: none;
    border-top: 1px solid var(--line);
  }
  .pole:first-child,
  .pack:first-child,
  .phase:first-child {
    border-top: none;
  }
  .contact {
    grid-column: 1 / 13;
  }
  .site-footer .f-brand,
  .site-footer .f-links,
  .site-footer .f-tag {
    grid-column: 1 / 13;
    text-align: left;
    padding: 4px var(--pad);
  }
}

/* ============================================================================
   ENTREES DE SECTION — la cadence
   ----------------------------------------------------------------------------
   Amelioration progressive : on ne cache les sections QUE si le JS est actif
   (classe .js posee sur <html> par app.js). Sans JS, tout reste visible.

   CE QUI A CHANGE, ET POURQUOI
   Avant, chaque section entrait d'un seul bloc : trois offres apparaissaient
   ensemble, comme une diapositive. C'est l'un des deux mecanismes qui rendent
   le site froid — l'autre etant l'immobilite complete.

   Maintenant, ce sont les ENFANTS DIRECTS du bloc qui entrent, l'un apres
   l'autre. Trois offres qui arrivent decalees de 90 ms se lisent dans l'ordre :
   l'oeil parcourt au lieu de constater. Sur la section Process, ce decalage
   raconte litteralement le propos — semaine 1, puis 2-3, puis 4.

   Budget tenu : 3 elements x 90 ms = 180 ms de decalage total. Au-dela de
   500 ms, le dernier element parait oublie plutot que choregraphie.

   NOTE PERFORMANCE (LCP)
   Le titre du hero n'est deliberement PAS anime. C'est l'element le plus
   grand de la premiere fenetre, donc tres probablement l'element mesure par
   le LCP ; or un element a opacity 0 n'est pas considere comme peint, et un
   fondu d'entree repousserait mecaniquement la mesure. Sur des pages qui
   achetent leur trafic (Google Ads), cela se paie en Quality Score donc en
   CPC. Le hero recoit du mouvement autrement : le trait sous "grandir" et le
   repere de defilement.
   ========================================================================== */
.js [data-reveal] > * {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity var(--dur-standard) var(--ease),
    transform var(--dur-standard) var(--ease);
  will-change: opacity, transform;
}
.js [data-reveal].is-revealed > * {
  opacity: 1;
  transform: none;
}
.js [data-reveal].is-revealed > *:nth-child(2) {
  transition-delay: var(--stagger);
}
.js [data-reveal].is-revealed > *:nth-child(3) {
  transition-delay: calc(var(--stagger) * 2);
}
.js [data-reveal].is-revealed > *:nth-child(4) {
  transition-delay: calc(var(--stagger) * 3);
}
/* Au-dela de 4, on plafonne : le decalage cesse de choregraphier et devient
   une file d'attente. */
.js [data-reveal].is-revealed > *:nth-child(n + 5) {
  transition-delay: calc(var(--stagger) * 4);
}

/* ---- Etats de survol : la personnalite se joue aussi a la souris --------- */
/* Un site ne parait vivant que s'il REPOND. Ces reponses sont sous 150 ms,
   seuil au-dela duquel une reaction cesse d'etre percue comme immediate. */
.pole__name {
  display: inline-block;
  transition: transform var(--dur-quick) var(--ease);
}
.pole:hover .pole__name {
  transform: translateX(6px);
}
.pole {
  transition: background-color var(--dur-quick) var(--ease);
}
.pole:hover {
  background-color: rgba(25, 57, 76, 0.03);
}

.pack__cta {
  transition:
    transform var(--dur-quick) var(--ease),
    opacity var(--dur-quick) var(--ease);
}
.pack__cta:hover {
  transform: translateY(-2px);
}

/* Le pack mis en avant se pose au lieu d'apparaitre : 98,5 % -> 100 %.
   Aucun rebond — la personnalite est Premium, pas Playful. */
.js .packs .pack--featured {
  transform: translateY(18px) scale(0.985);
  transform-origin: center bottom;
}
.js .packs.is-revealed .pack--featured {
  transform: none;
}

/* ---- Accessibilité : reduced motion -------------------------------------- */
/* ---- Interrupteur d'animations (pied de page) --------------------------- */
.motion-toggle {
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--soft);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-align: left;
}
.motion-toggle:hover {
  color: var(--ink);
}

/* ============================================================================
   MOUVEMENT — ce qui est coupe, et par quoi
   ----------------------------------------------------------------------------
   DEUX regimes distincts, et c'est deliberé :

   1. `prefers-reduced-motion` (reglage systeme) coupe les animations DE PAGE :
      entrees de section au defilement, repere de defilement, trait sous
      "grandir". Ce sont elles qui posent un probleme vestibulaire, parce
      qu'elles sont couplees au scroll. Les boucles video, elles, continuent
      de tourner : elles sont confinees dans un bloc, sans parallaxe ni
      clignotement, et elles font partie du contenu.

      Une premiere version coupait tout. Consequence concrete : le
      proprietaire du site, qui a ce reglage actif, ne voyait plus rien sur
      son propre site — et il aurait fallu un parametre d'URL en production
      pour que le site fonctionne. Un reglage systeme est un signal, pas un
      ordre de masquer le contenu.

   2. `.motion-off` (choix explicite du visiteur, via le pied de page) coupe
      TOUT, videos comprises. Celui-la est un ordre : il vient de quelqu'un
      qui a clique.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  /* Securite : en reduced-motion le contenu reste visible.
     Le selecteur porte aussi sur les ENFANTS depuis que ce sont eux qui
     entrent : sans cette ligne, un utilisateur en reduced-motion verrait des
     sections entierement vides. */
  .js [data-reveal],
  .js [data-reveal] > * {
    opacity: 1 !important;
    transform: none !important;
  }
  /* Le repere de defilement ne clignote pas : il reste simplement trace. */
  .scrollcue__arrow {
    opacity: 1 !important;
    transform: none !important;
  }
  .hero__title u::after {
    transform: scaleX(1) !important;
  }
}

/* Choix explicite du visiteur : tout est fige, y compris les boucles video
   (app.js retire les <video> et pose les affiches). */
:root.motion-off *,
:root.motion-off *::before,
:root.motion-off *::after {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
  scroll-behavior: auto !important;
}
:root.motion-off .js [data-reveal],
:root.motion-off .js [data-reveal] > * {
  opacity: 1 !important;
  transform: none !important;
}
:root.motion-off .scrollcue__arrow,
:root.motion-off [data-motion]::before {
  animation: none !important;
  opacity: 1 !important;
  transform: none !important;
}
:root.motion-off .hero__title u::after {
  transform: scaleX(1) !important;
}

/* focus visible partout (a11y) */
:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
}

/* ============================================================================
   ONBOARDING CIRCUIT (circuit-paris.html)
   Réutilise .lead-form / .form-step / .choices / .form-input / .btn-*.
   N'ajoute que ce qui n'existe pas déjà : sous-libellés intra-étape,
   cases à cocher, écran de remerciement, helper a11y.
   ============================================================================ */
.sr-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Sous-libellé d'une question au sein d'une étape multi-champs. */
.form-sublabel {
  font-size: 14px;
  color: var(--soft);
  margin: 26px 0 12px;
}
.form-step > .form-sublabel:first-of-type {
  margin-top: 0;
}

/* Textarea partage l'apparence de .form-input mais respire un peu plus. */
textarea.form-input {
  resize: vertical;
  min-height: 64px;
  line-height: 1.5;
}

/* Cases à cocher (accès techniques) — même grammaire visuelle que .choice. */
.checks {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.check {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  border: 1px solid var(--line);
  cursor: pointer;
  transition:
    border-color 0.16s var(--ease),
    background 0.16s var(--ease);
}
.check:hover {
  border-color: var(--brand);
}
.check input {
  accent-color: var(--brand);
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}
.check span {
  font-size: 15px;
}
.check:has(input:checked) {
  border-color: var(--brand);
  background: rgba(25, 57, 76, 0.04);
}

/* Écran de remerciement après soumission. */
.onb-thanks {
  max-width: 560px;
  margin-top: 24px;
}
.onb-thanks h2 {
  font-weight: 300;
  font-size: clamp(24px, 3vw, 34px);
  letter-spacing: -0.02em;
  margin-bottom: 14px;
}
.onb-thanks p {
  color: var(--soft);
  font-size: 16px;
  line-height: 1.6;
}
