/* ============================================================
   REGA — Site agence v3
   DA : charte REGA (Brand REGA/tokens/rega-tokens.css)
   Regle d'or : zero noir pur. Le fonce est toujours un brun chaud.
   Structure & enchainement : inspires de kitemi.studio, reecrits REGA.
   ============================================================ */

/* ---------- 1. TOKENS ---------- */
:root {
  /* Neutres chauds */
  --cream:        #FAF5EE;
  --cream-2:      #F4ECDF;
  --cream-3:      #EFE4D2;

  /* Orange signature */
  --orange:       #EE4E27;
  --orange-deep:  #C73E1D;
  --orange-soft:  #FCD9CB;

  /* Encre brun chaud */
  --ink:          #2A100A;
  --ink-soft:     #5C3526;
  --ink-mute:     #8C6553;
  --line:         rgba(42, 16, 10, 0.12);
  --line-strong:  rgba(42, 16, 10, 0.22);

  /* Ombres teintees */
  --shadow-sm:    0 2px 8px rgba(42, 16, 10, 0.06);
  --shadow-md:    0 12px 40px rgba(42, 16, 10, 0.08);
  --shadow-lg:    0 30px 80px rgba(238, 78, 39, 0.18);

  /* Rayons */
  --r:            18px;
  --r-lg:         28px;
  --r-xl:         40px;

  /* Typo */
  --font:         'Sora', system-ui, -apple-system, sans-serif;
  --hand:         'Caveat', ui-rounded, cursive;
  --titre:        'Fraunces', 'Iowan Old Style', Georgia, serif;

  /* Rythme */
  --wrap:         1200px;
  --wrap-tight:   940px;
  --gutter:       clamp(20px, 5vw, 56px);
  --section-y:    clamp(84px, 11vw, 160px);

  /* Courbe maison (reprise des maquettes REGA) */
  --ease:         cubic-bezier(.22, 1, .36, 1);
}

/* ---------- 2. RESET ---------- */
*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font);
  font-weight: 400;
  font-size: clamp(15.5px, 1.05vw, 17px);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

body.is-locked { overflow: hidden; }

img, svg, picture, video { display: block; max-width: 100%; }
img { height: auto; }

a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }

h1, h2, h3, h4 {
  margin: 0;
  font-weight: 800;
  line-height: 1.04;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

::selection { background: var(--orange); color: var(--cream); }

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

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- 3. MATIERE : GRAIN PAPIER ---------- */
/* Texture subtile facon papier imprime, posee au-dessus de toute la page. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: .17;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E");
}

/* ---------- 4. UTILITAIRES ---------- */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.wrap--tight { max-width: var(--wrap-tight); }

/* Fond unique sur toute la page : aucune section ne porte de couleur propre,
   le rythme vient des espaces et des cartes, pas de bandes alternees. */
.section { padding-block: var(--section-y); position: relative; }

.script {
  font-family: var(--hand);
  font-weight: 700;
  letter-spacing: 0;
  color: var(--orange);
  font-size: 1.18em;
  line-height: .9;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--orange);
  margin-bottom: 22px;
}

.eyebrow::before {
  content: "";
  width: 28px;
  height: 2px;
  background: var(--orange);
  border-radius: 2px;
}

/* ---------- Partage des familles ----------
   Fraunces affirme, Sora informe, Caveat commente. Aucune ne fait le travail
   d'une autre : les grands titres passent en serif, tout ce qui sert a lire,
   cliquer ou comparer reste en grotesque.
   Une serif n'a pas besoin de forcer la graisse pour tenir un titre : la ou
   Sora demandait un 800, Fraunces affirme a 600. Meme raison pour le tracking,
   qui repasse pres de zero : resserrer une serif fait cogner ses empattements. */
.h2 {
  font-family: var(--titre);
  /* legerement plus petit qu'en Sora : la hauteur d'x de Fraunces est plus
     genereuse, a corps egal elle occupe davantage la ligne. */
  font-size: clamp(2rem, 4.9vw, 3.66rem);
  font-weight: 600;
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 34, 'WONK' 1;
  line-height: 1.1;
  letter-spacing: -0.008em;
}

.lead {
  margin-top: 24px;
  max-width: 60ch;
  font-size: clamp(1rem, 1.35vw, 1.16rem);
  color: var(--ink-soft);
  line-height: 1.7;
}

.head { margin-bottom: clamp(48px, 6vw, 78px); }
.head--center { text-align: center; }
.head--center .lead { margin-inline: auto; }
.head--center .eyebrow::before { display: none; }

/* ---------- 5. BOUTONS ---------- */
/* Pilule orange franche : la couleur de marque, une forme entierement
   arrondie, et rien d'autre. Pas de halo diffus, pas de degrade, pas de
   couches decalees : un aplat propre et un liseré plus dense en dessous, qui
   pose le bouton sur la page sans imiter un relief. */
.btn {
  --btn-bg: var(--orange);
  --btn-fg: var(--cream);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 15px 26px;
  border: 0;
  border-radius: 999px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: .95rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.01em;
  cursor: pointer;
  white-space: nowrap;
  box-shadow: 0 2px 0 0 var(--orange-deep);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease), background-color .25s ease;
  will-change: transform;
}

.btn:hover {
  transform: translateY(-2px);
  background: var(--orange-deep);
  /* le liseré s'epaissit d'un pixel, l'ombre reste dure et courte : aucun halo
     diffus, rien d'autre ne rayonne sur cette page */
  box-shadow: 0 3px 0 0 #A8300F;
}

.btn:active { transform: translateY(0); box-shadow: 0 1px 0 0 #A8300F; }

.btn__arrow {
  display: inline-block;
  transition: transform .35s var(--ease);
}

.btn:hover .btn__arrow { transform: translateX(4px); }

.btn--lg { padding: 18px 32px; font-size: 1.02rem; }

/* ---------- 5bis. LE CTA DE RENDEZ-VOUS ----------
   Le bouton principal est la meme pilule que les autres : c'est sa taille et
   sa pastille qui le distinguent, pas une forme a part. */
.btn--rdv {
  --pastille: 26px;
  --fleche: 14px;
  position: relative;
  --pose: 1px;                 /* descente optique, a peine perceptible */
  gap: 10px;
  /* C'est le libelle qui doit tomber au milieu, pas le groupe libelle +
     pastille : on recupere a droite la place que prend la pastille. */
  padding: 14px 12px 14px 28px;
  border-radius: 999px;
}

.btn--lg.btn--rdv {
  --pastille: 30px;
  --fleche: 16px;
  --pose: 1px;
  gap: 12px;
  padding: 16px 14px 16px 34px;
}

/* Le libelle descend un peu : sans descendantes, "Prendre rendez-vous" a son
   centre optique au-dessus du centre de sa ligne, et parait pose trop haut.
   La pastille suit la meme descente, sinon elle flotte au-dessus du texte. Une
   seule variable pour les deux : ils ne peuvent plus se desynchroniser. */
.btn__label { position: relative; top: var(--pose); }

.btn__pastille {
  display: grid;
  place-items: center;
  flex: none;
  width: var(--pastille);
  height: var(--pastille);
  position: relative;
  top: var(--pose);
  border-radius: 999px;
  background: rgba(255, 255, 255, .2);
  color: var(--cream);
  transition: transform .5s var(--ease), background-color .35s var(--ease);
}

.btn--rdv:hover .btn__pastille,
.btn--rdv:focus-visible .btn__pastille {
  transform: scale(1.06);
  background: rgba(255, 255, 255, .3);
}

/* Hublot d'une seule fleche de large : la premiere sort par la droite pendant
   que la seconde entre par la gauche. Le relais evite la fleche qui glisse et
   revient en arriere, un aller-retour qu'aucun geste reel ne fait. */
.btn__hublot {
  display: flex;
  width: var(--fleche);
  height: var(--fleche);
  overflow: hidden;
  transition: transform .45s var(--ease);
}

.btn__hublot svg {
  flex: none;
  width: var(--fleche);
  height: var(--fleche);
}

.btn--rdv:hover .btn__hublot,
.btn--rdv:focus-visible .btn__hublot { transform: translateX(-100%); }

.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--ink);
  border: 1.5px solid var(--line-strong);
}

.btn--ghost:hover {
  --btn-bg: var(--ink);
  --btn-fg: var(--cream);
  border-color: var(--ink);
  box-shadow: var(--shadow-md);
}

.btn--cream {
  --btn-bg: var(--cream);
  --btn-fg: var(--ink);
}

.btn--cream:hover {
  --btn-bg: #fff;
  box-shadow: 0 14px 32px rgba(0, 0, 0, .22);
}

/* ---------- 6. NAVIGATION ---------- */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 900;
  display: flex;
  align-items: center;
  gap: 24px;
  padding-block: 16px;
  /* le bloc logo + menu s'aligne sur un axe interieur plutot que sur le bord
     de l'ecran : le logo reste ainsi a portee du menu */
  padding-inline: max(var(--gutter), calc((100% - 1120px) / 2));
  transition: padding .4s var(--ease),
              transform .55s var(--ease),
              opacity .3s var(--ease),
              visibility 0s linear 0s;
}

/* Pendant la traversee des realisations, la barre s'efface : chaque panneau y
   montre l'en-tete du site d'un client, et deux barres de navigation l'une
   au-dessus de l'autre, on ne sait plus laquelle appartient a qui.
   La visibilite bascule a la fin du fondu, sinon les liens resteraient
   accessibles au clavier alors qu'on ne les voit plus. */
.nav.est-retiree {
  transform: translateY(-125%);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: padding .4s var(--ease),
              transform .55s var(--ease),
              opacity .3s var(--ease),
              visibility 0s linear .55s;
}

@media (prefers-reduced-motion: reduce) {
  .nav { transition: none; }
  .nav.est-retiree { transition: none; }
}

/* Barre transparente en permanence : plus aucune bande pleine largeur ni
   filet de separation, le fond de page passe dessous sans rupture.
   Au defilement, seuls les elements eux-memes se posent sur une pastille
   creme : sans elle, les liens deviennent illisibles des qu'un titre ou une
   carte passe derriere. La barre, elle, reste transparente. */
.nav { background: transparent; }

.nav.is-stuck { padding-block: 11px; }

.nav > * { position: relative; z-index: 1; }

.nav__logo img { width: 46px; height: auto; }

/* ---- Arrivee de la barre ----
   Les elements tombent un par un depuis le haut. `backwards` et non `both` :
   sinon l'animation garderait la main sur transform et neutraliserait les
   effets de survol des boutons. */
@keyframes nav-drop {
  from { opacity: 0; transform: translateY(-12px); }
  to   { opacity: 1; transform: none; }
}

.nav__logo,
.nav__links a,
.nav__preview,
.nav__cta {
  animation: nav-drop .65s var(--ease) backwards;
}

.nav__logo                 { animation-delay: .10s; }
.nav__links a:nth-child(1) { animation-delay: .20s; }
.nav__links a:nth-child(2) { animation-delay: .27s; }
.nav__links a:nth-child(3) { animation-delay: .34s; }
.nav__links a:nth-child(4) { animation-delay: .41s; }
.nav__preview              { animation-delay: .44s; }
.nav__cta                  { animation-delay: .52s; }

@media (prefers-reduced-motion: reduce) {
  .nav__logo,
  .nav__links a,
  .nav__preview,
  .nav__cta { animation: none; }

  /* le CTA garde sa lecture, il perd seulement le geste */
  .btn__hublot,
  .btn__pastille { transition: none; }
}

.nav__links {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: clamp(18px, 2.6vw, 42px);
}

.nav__links a {
  position: relative;
  padding: 9px 15px;
  border-radius: 999px;
  font-size: .93rem;
  font-weight: 600;
  color: var(--ink-soft);
  transition: color .25s ease, background-color .25s ease;
}

.nav__links a:hover,
.nav__links a.is-active {
  color: var(--ink);
  background: rgba(42, 16, 10, .05);
}

.nav__right {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-left: auto;
  z-index: 3;
}

/* CTA present dans le panneau mobile uniquement */
.nav__links-cta { display: none; }

/* Acces maquette : porte d'entree client, discrete mais reperable */
.nav__preview {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 17px;
  border: 1.5px dashed var(--line-strong);
  border-radius: 999px;
  font-size: .87rem;
  font-weight: 600;
  color: var(--ink-soft);
  transition: border-color .3s ease, color .3s ease, background-color .3s ease;
}

.nav__preview:hover {
  border-color: var(--orange);
  border-style: solid;
  color: var(--orange);
  background: rgba(238, 78, 39, .06);
}

.nav__preview svg { width: 15px; height: 15px; }

@media (min-width: 901px) {
  /* La pastille ne s'allume plus a un seuil : son opacite suit le defilement
     (--pill, calcule dans app.js). Un simple `is-stuck` la faisait apparaitre
     d'un coup, et la coupure se voyait. */
  .nav__logo,
  .nav__links,
  .nav__preview { position: relative; }

  .nav__logo::before,
  .nav__links::before,
  .nav__preview::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: 999px;
    background: rgba(250, 245, 238, .8);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    box-shadow: 0 2px 14px rgba(42, 16, 10, .05);
    opacity: var(--pill, 0);
    pointer-events: none;
  }

  .nav__links::before  { inset: 0 -6px; }
  .nav__logo::before   { inset: -6px; }
  .nav__preview::before { box-shadow: none; }

  /* le pointille de "Acces maquette" se resserre au meme rythme */
  .nav__preview {
    border-color: color-mix(in srgb, var(--line-strong), var(--line) calc(var(--pill, 0) * 100%));
    transition: border-color .3s ease, color .3s ease;
  }
}

.nav__burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 0 11px;
  border: 0;
  border-radius: 50%;
  background: var(--ink);
  cursor: pointer;
}

.nav__burger span {
  display: block;
  height: 2px;
  border-radius: 2px;
  background: var(--cream);
  transition: transform .35s var(--ease), opacity .25s ease;
}

.nav.is-open .nav__burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav.is-open .nav__burger span:nth-child(2) { opacity: 0; }
.nav.is-open .nav__burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.nav__scrim {
  position: fixed;
  inset: 0;
  z-index: 880;
  background: rgba(42, 16, 10, .5);
  backdrop-filter: blur(3px);
  opacity: 0;
  visibility: hidden;
  transition: opacity .35s ease, visibility .35s;
}

.nav__scrim.is-open { opacity: 1; visibility: visible; }

/* ---------- 7. HERO ---------- */
.hero {
  position: relative;
  padding-top: clamp(132px, 17vh, 190px);
  padding-bottom: clamp(48px, 6vw, 88px);
  overflow: hidden;
}

/* Halo organique orange, tres diffus : la chaleur de la marque */
.hero::before {
  content: "";
  position: absolute;
  top: -22%;
  left: 50%;
  width: min(1150px, 130vw);
  aspect-ratio: 1;
  transform: translateX(-50%);
  background: radial-gradient(circle at 50% 42%,
              rgba(238, 78, 39, .16) 0%,
              rgba(252, 217, 203, .28) 34%,
              rgba(250, 245, 238, 0) 66%);
  pointer-events: none;
  z-index: 0;
}

.hero__inner {
  position: relative;
  z-index: 1;
  text-align: center;
}

.tag {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 8px 18px 8px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, .6);
  box-shadow: var(--shadow-sm);
  font-size: .85rem;
  font-weight: 600;
  color: var(--ink-soft);
}

.tag__dot {
  position: relative;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--orange);
}

.tag__dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--orange);
  animation: pulse 2.4s var(--ease) infinite;
}

@keyframes pulse {
  0%   { transform: scale(1);   opacity: .7; }
  70%  { transform: scale(3.2); opacity: 0; }
  100% { transform: scale(3.2); opacity: 0; }
}

.hero__title {
  margin-top: 30px;
  font-size: clamp(2.7rem, 7.6vw, 6.1rem);
  letter-spacing: -0.045em;
}

.hero__title .line { display: block; }

/* Entree du hero : motif word-in repris des maquettes REGA
   (opacite 0->1, echelle 1.05->1, flou 16px->0) */
.word {
  display: inline-block;
  opacity: 0;
  animation: word-in 1.5s var(--ease) forwards;
}

@keyframes word-in {
  from { opacity: 0; transform: scale(1.05); filter: blur(16px); }
  to   { opacity: 1; transform: scale(1);    filter: blur(0); }
}

.hero__sub {
  margin: 30px auto 0;
  max-width: 56ch;
  font-size: clamp(1.02rem, 1.5vw, 1.22rem);
  color: var(--ink-soft);
  line-height: 1.68;
  opacity: 0;
  animation: word-in 1.2s var(--ease) 1.05s forwards;
}

.hero__sub strong { color: var(--ink); font-weight: 700; }

.hero__ctas {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 14px;
  margin-top: 38px;
  opacity: 0;
  animation: word-in 1.2s var(--ease) 1.25s forwards;
}

.hero__hint {
  margin-top: 20px;
  font-size: .9rem;
  color: var(--ink-mute);
  opacity: 0;
  animation: word-in 1.2s var(--ease) 1.4s forwards;
}

.hero__hint strong { color: var(--ink-soft); }

.hero__scroll {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  margin-top: clamp(46px, 6vw, 76px);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--ink-mute);
  opacity: 0;
  animation: word-in 1.2s var(--ease) 1.6s forwards;
}

.hero__scroll-line {
  position: relative;
  width: 1.5px;
  height: 52px;
  overflow: hidden;
  background: var(--line);
  border-radius: 2px;
}

.hero__scroll-line::after {
  content: "";
  position: absolute;
  top: -60%;
  left: 0;
  width: 100%;
  height: 60%;
  background: var(--orange);
  border-radius: 2px;
  animation: scroll-run 2.1s var(--ease) infinite;
}

@keyframes scroll-run {
  0%   { top: -60%; }
  100% { top: 100%; }
}

/* ---------- 8. TICKER METIERS ---------- */
.ticker {
  position: relative;
  z-index: 1;
  margin-top: clamp(40px, 5vw, 66px);
  padding-block: 18px;
  border-block: 1px solid var(--line);
  background: rgba(244, 236, 223, .55);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}

.ticker__track {
  display: flex;
  width: max-content;
  gap: 46px;
  animation: ticker 42s linear infinite;
}

.ticker:hover .ticker__track { animation-play-state: paused; }

.ticker__track span {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: .95rem;
  font-weight: 600;
  color: var(--ink-mute);
  white-space: nowrap;
}

.ticker__icon { width: 15px; opacity: .55; }

@keyframes ticker {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ---------- 9. CONSTAT (deux preuves, requetes en fond) ----------
   Le centre ne porte que les chiffres : rien ne doit venir se mettre a leur
   hauteur. Les recherches flottent autour, assez pales pour qu'on les prenne
   pour une matiere de fond, assez nettes pour qu'on les reconnaisse. */
.constat {
  position: relative;
  overflow-x: clip;             /* les cartes debordent, la page ne defile pas */
  /* Sans repere de section ni titre au-dessus, le rythme vertical habituel
     laissait un grand vide en entree. La section demarre plus haut, la phrase
     enchaine directement sur le hero. */
  padding-top: clamp(52px, 6.5vw, 96px);
}

.constat__fond {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

/* le titre passe au-dessus des cartes, sinon une requete peut venir se poser
   en travers de la ligne "Il trouve ton concurrent" */
.constat .wrap { position: relative; z-index: 1; }

.req {
  --dy: 0px;                    /* derive au defilement, pilotee par app.js */
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  max-width: 62vw;
  padding: 11px 18px 11px 15px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 252, 248, .55);
  font-size: .92rem;
  font-weight: 500;
  color: var(--ink-mute);
  white-space: nowrap;
  /* Assez efface pour rester un fond. Au dela, l'oeil se met a les lire et
     abandonne les chiffres, qui sont pourtant tout le propos de la section.
     Valeur de repli : app.js pilote ensuite l'opacite pendant l'entree, mais
     sans JS les cartes doivent rester visibles. */
  opacity: .5;
  transform: translateY(calc(var(--dy) + var(--flot, 0px))) rotate(var(--tilt, 0deg));
}

.req__ico {
  width: 15px;
  height: 15px;
  flex: none;
  color: var(--orange);
  opacity: .75;
}

/* Posees a des hauteurs et des distances differentes : une nappe reguliere se
   lirait comme un motif, pas comme des recherches en train de se faire.
   Ramenees vers l'axe : plaquees aux bords, elles n'appartenaient plus a la
   meme scene que les chiffres et se lisaient comme une decoration de marge. */
.req--a { top:  8%; left:   6%;  --tilt: -2.4deg; }
.req--b { top: 16%; right:  5%;  --tilt:  1.9deg; }
.req--c { top: 42%; left:  11%;  --tilt:  1.4deg; }
.req--d { top: 56%; right:  9%;  --tilt: -1.7deg; }
.req--e { top: 76%; left:   7%;  --tilt:  2.1deg; }
.req--f { top: 87%; right:  6%;  --tilt: -1.2deg; }

/* ---- L'alerte en direct ----
   Le constat ne s'annonce plus, il se produit sous les yeux du visiteur. Le
   champ se tape tout seul juste avant les chiffres : la preuve chiffree arrive
   alors comme une explication, pas comme une affirmation de plus. */
.direct {
  position: relative;
  z-index: 1;
  /* Le bloc prend toute la largeur utile. Chaque element pose ensuite sa
     propre mesure : un seul cadre etroit pour les trois ecrasait le titre sur
     quatre lignes alors que la ligne d'intro, elle, tenait large. */
  margin: 0 auto;
  text-align: center;
}

/* Deux lignes pleines plutot que quatre lignes maigres : a corps egal, un
   titre court sur des lignes larges se lit d'un seul coup d'oeil. */
.direct__titre {
  max-width: 21ch;
  margin-inline: auto;
  text-wrap: balance;
}

/* les points de suspension portent l'attente : c'est le seul endroit du titre
   ou il se passe quelque chose */
.direct__pts { color: var(--orange); }

.direct__intro {
  max-width: 38ch;
  margin: clamp(20px, 2.6vw, 28px) auto 0;
  font-size: clamp(1.02rem, 1.32vw, 1.18rem);
  line-height: 1.72;
  color: var(--ink-mute);
}

.direct__bar {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 17px 32px 17px 26px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 252, 248, .92);
  box-shadow: var(--shadow-sm);
  max-width: 100%;
}

.direct__ico {
  width: 19px;
  height: 19px;
  flex: none;
  color: var(--orange);
}

/* Chasse fixe, prise au systeme : c'est ce qui fait lire un champ de saisie
   plutot qu'une phrase. Aucune police supplementaire a telecharger, et le mot
   qui se tape ne fait plus danser la ligne a chaque lettre. */
.direct__champ {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: clamp(1rem, 1.22vw, 1.12rem);
  color: var(--ink);
  white-space: nowrap;
}

.direct__caret {
  display: inline-block;
  width: 2px;
  height: 1.05em;
  margin: 0 1px;
  vertical-align: -.16em;
  background: var(--orange);
  animation: caret-bat 1.05s steps(1) infinite;
}

@keyframes caret-bat {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0; }
}

.direct__suffixe {
  margin-left: .5em;
  color: var(--ink-mute);
}

/* ---- Le verdict ----
   Ce n'est pas une ligne de plus sous la barre, c'est une annotation qui la
   designe. Elle est donc posee a cote, dans la marge, reliee par un trait au
   feutre : le meme geste que les etiquettes du hero. Centree dessous, elle
   flottait comme une legende orpheline. */
.direct__scene {
  position: relative;
  display: inline-block;
  margin-top: clamp(26px, 3.4vw, 38px);
}

.direct__verdict {
  position: absolute;
  top: calc(100% - 2px);
  left: calc(100% - 26px);      /* elle mord sur la barre, comme une note jetee */
  display: flex;
  align-items: flex-start;
  gap: 2px;
  text-align: left;
  white-space: nowrap;
  opacity: 0;                   /* posee seulement une fois le mot tape */
}

.direct__vtxt {
  margin-top: 26px;             /* le texte demarre sous la fin de la fleche */
  font-family: var(--hand);
  font-weight: 700;
  font-size: clamp(1.28rem, 1.75vw, 1.6rem);
  line-height: 1.14;
  color: var(--ink-soft);
}

.direct__vfleche {
  width: clamp(64px, 5.6vw, 88px);
  height: auto;
  flex: none;
  overflow: visible;
  fill: none;
  stroke: var(--orange);
  stroke-width: 2.1;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: .85;
}

/* Le trait part epais et s'affine, comme un feutre qu'on releve : c'est le
   geste des fleches du hero, repris a l'identique. */
.direct__vtrait {
  stroke-dasharray: 140;
  stroke-dashoffset: 140;
}

.direct__vpointe { opacity: 0; }

/* La sequence ne demarre qu'a l'entree a l'ecran, et seulement apres que le
   premier metier a fini de se taper : le verdict commente quelque chose qui
   vient de se produire, il ne peut pas arriver avant. */
.direct.est-vu .direct__verdict { animation: verdict-pose .6s var(--ease) 2.5s both; }
.direct.est-vu .direct__vtrait  { animation: verdict-trait .5s cubic-bezier(.2,.8,.3,1) 2.7s both; }
.direct.est-vu .direct__vpointe { animation: verdict-pointe .26s cubic-bezier(.34,1.5,.64,1) 3.16s both; }

@keyframes verdict-pose {
  from { opacity: 0; transform: translate(-8px, 10px) rotate(-3.4deg); }
  to   { opacity: 1; transform: translate(0, 0) rotate(-1.4deg); }
}

@keyframes verdict-trait {
  0%   { stroke-dashoffset: 140; stroke-width: 4.2; }
  100% { stroke-dashoffset: 0;   stroke-width: 2.1; }
}

@keyframes verdict-pointe {
  from { opacity: 0; transform: scale(.5); }
  to   { opacity: 1; transform: scale(1); }
}

/* En dessous, la marge droite n'existe plus : l'annotation repasse dans le
   flux, sous la barre, et la fleche disparait faute de quoi designer. */
@media (max-width: 900px) {
  .direct__scene { display: block; }

  .direct__verdict {
    position: static;
    justify-content: center;
    margin-top: 20px;
    opacity: 1;
    white-space: normal;
  }

  .direct__vfleche { display: none; }
  .direct__vtxt { margin-top: 0; text-align: center; }
  .direct.est-vu .direct__verdict { animation: none; transform: rotate(-1.2deg); }
}

@media (prefers-reduced-motion: reduce) {
  .direct__verdict { opacity: 1; transform: rotate(-1.4deg); }
  .direct__vtrait { stroke-dashoffset: 0; }
  .direct__vpointe { opacity: 1; }
  .direct.est-vu .direct__verdict,
  .direct.est-vu .direct__vtrait,
  .direct.est-vu .direct__vpointe { animation: none; }
}

@media (prefers-reduced-motion: reduce) {
  .direct__caret { animation: none; }
}

/* ---- Apparitions et flottements ----
   Rien de nouveau n'est invente ici : la section reprend les trois gestes deja
   poses dans le hero. Le titre s'encre mot a mot comme celui de la fenetre, le
   reste se depose, et une fois tout en place chaque bloc respire au lieu de se
   figer. C'est cette continuite qui fait lire la page comme un seul mouvement
   plutot que comme une suite d'ecrans. */

/* Une variable animable : le flottement doit s'ajouter a la derive du scroll
   sans l'ecraser, et une animation CSS classique remplacerait tout le
   transform. Sans support, la valeur de repli garde les cartes immobiles. */
@property --flot {
  syntax: '<length>';
  inherits: false;
  initial-value: 0px;
}

/* le titre du constat s'encre mot a mot, comme celui du hero */
.direct__titre .mot {
  --pose: var(--ink);
  display: inline-block;
  opacity: 0;
}

.direct.est-vu .direct__titre .mot { animation: encre-seche .8s var(--ease) both; }
.direct.est-vu .direct__titre .mot:nth-child(1) { animation-delay: .04s; }
.direct.est-vu .direct__titre .mot:nth-child(2) { animation-delay: .10s; }
.direct.est-vu .direct__titre .mot:nth-child(3) { animation-delay: .16s; }
.direct.est-vu .direct__titre .mot:nth-child(4) { animation-delay: .22s; }
.direct.est-vu .direct__titre .mot:nth-child(5) { animation-delay: .28s; }
.direct.est-vu .direct__titre .mot:nth-child(6) { animation-delay: .34s; }

/* l'intro et le champ se deposent, sans decoupe : meme geste que le
   sous-titre et les boutons du hero */
.direct__intro,
.direct__scene { opacity: 0; }

.direct.est-vu .direct__intro { animation: ink-lay .75s var(--ease) .52s both; }

/* Deux temps sur le meme element : la depose, puis le flottement qui prend le
   relais une fois l'element arrive. Le second ecrase le transform du premier,
   il ne demarre donc qu'apres sa fin. */
.direct.est-vu .direct__scene {
  animation: ink-lay .75s var(--ease) .66s both,
             flot-scene 7.6s ease-in-out 1.7s infinite;
}

/* La barre et son annotation flottent ensemble : separees, le trait au feutre
   se decalerait de la barre qu'il designe. */
@keyframes flot-scene {
  0%, 100% { transform: translateY(0)    rotate(0deg); }
  50%      { transform: translateY(-7px) rotate(.22deg); }
}

/* Les chiffres respirent, la phrase reste fixe : c'est le chiffre qu'on
   regarde, et un texte qui bouge se lit mal. Phases decalees, sinon les deux
   stats montent et descendent au meme rythme et l'ensemble tangue.

   La preuve entiere est en plus retenue au defilement : elle se deplace
   nettement moins vite que la page, donc elle reste sous les yeux pendant que
   les cartes, elles, filent normalement. C'est ce retard qui la met au premier
   plan. La variable est posee sur la figure et heritee par ses trois enfants,
   ce qui evite d'entrer en conflit avec le transform de son apparition. */
.preuve__num {
  transform: translateY(calc(var(--pdy, 0px) + var(--flot, 0px)));
  animation: flot-chiffre 9.4s ease-in-out infinite;
}

/* la phrase et la source suivent le meme retard que leur chiffre, sinon la
   preuve se disloque en trois morceaux pendant le defilement */
.preuve__txt,
.preuve__src { transform: translateY(var(--pdy, 0px)); }

.preuve:nth-child(2) .preuve__num { animation-delay: -4.7s; }

@keyframes flot-chiffre {
  0%, 100% { --flot: 0px;  }
  50%      { --flot: -9px; }
}

/* Les cartes de fond flottent en plus de leur derive au defilement. Durees
   toutes differentes : des cycles egaux finissent par se resynchroniser et
   le fond se met a battre la mesure. */
.req { animation: flot-req 11s ease-in-out infinite; }
.req--a { animation-duration: 10.4s; animation-delay: -1.2s; }
.req--b { animation-duration: 12.7s; animation-delay: -4.8s; }
.req--c { animation-duration:  9.6s; animation-delay: -2.5s; }
.req--d { animation-duration: 13.4s; animation-delay: -7.1s; }
.req--e { animation-duration: 11.3s; animation-delay: -3.4s; }
.req--f { animation-duration: 12.1s; animation-delay: -6.2s; }

@keyframes flot-req {
  0%, 100% { --flot: 0px; }
  50%      { --flot: -12px; }
}

@media (prefers-reduced-motion: reduce) {
  .direct__titre .mot,
  .direct__intro,
  .direct__scene { opacity: 1; }

  .direct.est-vu .direct__titre .mot,
  .direct.est-vu .direct__intro,
  .direct.est-vu .direct__scene,
  .preuve__num,
  .req { animation: none; }
}

/* ---- Les deux preuves ---- */
.preuves {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(70px, 11vh, 130px);
  /* L'annotation du verdict est posee en absolu : elle ne compte pas dans la
     hauteur du bloc au-dessus et venait donc mordre sur le premier chiffre.
     La marge doit couvrir sa retombee, environ 75 px, plus la respiration. */
  margin-top: clamp(200px, 25vh, 320px);
  text-align: center;
}

.preuve {
  margin: 0;
  /* Assez large pour que la phrase tienne sur une seule ligne : c'est ce qui
     donne au chiffre son socle horizontal au lieu d'une colonne de texte. */
  max-width: 100%;
}

.preuve__num {
  font-family: var(--titre);
  /* Enorme, et c'est le sujet : le chiffre doit se lire de l'autre bout de la
     piece, la phrase seulement quand on s'approche. */
  font-size: clamp(4.6rem, 11.5vw, 8.8rem);
  font-weight: 600;
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 34, 'WONK' 1;
  line-height: .86;
  letter-spacing: -0.03em;
  color: var(--ink);
  /* les chiffres tabulaires ne dansent pas pendant le comptage */
  font-variant-numeric: tabular-nums;
}

/* Le pour-cent se cale sur le haut des chiffres, pas sur leur ligne de pied. */
.preuve__num i {
  font-style: normal;
  font-size: .58em;
  color: var(--orange);
  vertical-align: .42em;
  margin-left: .04em;
}

/* Le multiplicateur, lui, precede le chiffre et se pose a mi-hauteur : accroche
   en haut comme un exposant, il se lirait comme une note de bas de page. */
.preuve__num .preuve__mult {
  font-size: .5em;
  vertical-align: .16em;
  margin: 0 .04em 0 0;
}

.preuve__txt {
  margin: clamp(20px, 2.6vw, 30px) auto 0;
  font-size: clamp(1.06rem, 1.45vw, 1.3rem);
  line-height: 1.6;
  color: var(--ink-soft);
}

.preuve__txt strong {
  font-weight: 700;
  color: var(--ink);
}

.preuve__src {
  /* Alignee a droite sous la phrase : une source est une note de bas de page,
     elle ne se met pas au milieu de la composition. */
  margin-top: 16px;
  text-align: right;
  font-size: .74rem;
  letter-spacing: .04em;
  color: var(--ink-mute);
  opacity: .62;
}

@media (max-width: 700px) {
  .preuve__src { text-align: center; padding-right: 0; }
}

@media (max-width: 900px) {
  /* sur telephone les cartes viendraient sous les chiffres : on n'en garde
     que quatre, poussees vers les bords */
  .req--c, .req--d { display: none; }
  .req { font-size: .82rem; padding: 9px 14px 9px 12px; }
}

/* ---------- 10. SERVICES ----------
   Trois cartes posees sur le fond, chacune coiffee d'un onglet qui depasse
   comme sur un dossier suspendu. L'onglet dit la famille, le titre dit l'offre :
   deux niveaux de lecture au lieu d'un seul titre qui doit tout porter. */

/* Le titre tient sur une ligne et se hierarchise mot a mot : les mots
   grammaticaux s'effacent, les mots porteurs restent en encre pleine, le
   dernier prend la couleur. L'oeil attrape "services tailles pour ton metier"
   sans avoir lu la phrase entiere. Deux lignes entieres de gris differents,
   elles, coupaient le titre en deux blocs sans rapport. */
.offres__titre,
.offres__sous { transform: translateY(var(--pdy, 0px)); }

.offres__titre { text-wrap: balance; }

/* ---- Les titres de section s'encrent mot a mot ----
   Meme geste que le titre du hero et celui du constat : le mot arrive un peu
   trop grand et en orange vif, puis reprend sa taille et se repose sur son
   encre. La couleur d'arrivee est portee par le mot lui-meme (--pose), donc un
   mot en retrait et un mot cle ne se reposent pas au meme endroit. */
.titre-encre .mot {
  --pose: var(--ink);
  display: inline-block;
  opacity: 0;
}

.titre-encre .mot--doux { --pose: var(--ink-mute); font-weight: 400; }
.titre-encre .mot--cle  { --pose: var(--orange);   font-weight: 700; }

.titre-encre.est-vu .mot { animation: encre-seche .8s var(--ease) both; }
.titre-encre.est-vu .mot:nth-child(1) { animation-delay: .04s; }
.titre-encre.est-vu .mot:nth-child(2) { animation-delay: .10s; }
.titre-encre.est-vu .mot:nth-child(3) { animation-delay: .16s; }
.titre-encre.est-vu .mot:nth-child(4) { animation-delay: .22s; }
.titre-encre.est-vu .mot:nth-child(5) { animation-delay: .28s; }
.titre-encre.est-vu .mot:nth-child(6) { animation-delay: .34s; }
.titre-encre.est-vu .mot:nth-child(7) { animation-delay: .40s; }
.titre-encre.est-vu .mot:nth-child(8) { animation-delay: .46s; }
.titre-encre.est-vu .mot:nth-child(9) { animation-delay: .52s; }

@media (prefers-reduced-motion: reduce) {
  .titre-encre .mot { opacity: 1; animation: none; color: var(--pose); }
}

.offres__lien {
  color: var(--ink-mute);
  font-weight: 400;
}

.offres__cle {
  color: var(--orange);
  font-weight: 700;
}

.offres__sous {
  margin-top: clamp(14px, 1.8vw, 20px);
  font-size: clamp(1rem, 1.25vw, 1.12rem);
  color: var(--ink-mute);
}

.cartes {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(20px, 2.4vw, 34px);
  /* stretch et non start : les trois cartes prennent la hauteur de la plus
     haute et se ferment sur la meme ligne. Avec start, chacune s'arretait ou
     son texte finissait et le bas de la rangee partait en escalier. */
  align-items: stretch;
  margin-top: clamp(64px, 8vh, 104px);
}

.carte {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: clamp(38px, 3.4vw, 52px) clamp(24px, 2.4vw, 36px) clamp(32px, 3vw, 44px);
  border-radius: var(--r-lg);
  /* un cran plus dense que le fond de page, sans bordure : la carte se detache
     par la matiere, pas par un trait */
  background: var(--cream-2);
  text-align: center;
  transition: transform .5s var(--ease), box-shadow .5s var(--ease);
}

.carte:hover {
  transform: translateY(-6px);
  box-shadow: var(--shadow-md);
}

/* Celle du milieu remonte : trois cartes parfaitement alignees forment une
   barre, et l'oeil ne sait plus par ou entrer. */
.carte--haute { margin-top: -22px; }

/* L'onglet mord sur le haut de la carte et deborde au-dessus, comme la
   languette d'un dossier. */
.carte__onglet {
  position: absolute;
  top: -15px;
  left: 50%;
  transform: translateX(-50%);
  padding: 7px 22px 6px;
  border-radius: 999px;
  background: var(--cream-3);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--orange);
  white-space: nowrap;
}

.carte__titre {
  font-family: var(--titre);
  font-size: clamp(1.4rem, 1.9vw, 1.72rem);
  font-weight: 600;
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 34, 'WONK' 1;
  line-height: 1.16;
  letter-spacing: -0.005em;
  color: var(--ink);
}

.carte__accroche {
  margin-top: 10px;
  font-size: .96rem;
  color: var(--ink-mute);
}

/* Le schema tient la moitie de la carte : c'est lui qui fait comprendre
   l'offre avant meme qu'on lise le paragraphe. */
.carte__vue {
  margin: clamp(26px, 3vw, 40px) auto;
  width: 100%;
  max-width: 232px;
  color: var(--ink-soft);
}

.carte__vue svg { width: 100%; height: auto; display: block; }

/* Le schema avance quand on survole sa carte. Le geste porte sur le conteneur
   et non sur les pieces : leurs transform servent deja aux boucles, et une
   valeur posee ici les ecraserait. */
.carte__vue {
  transition: transform .55s var(--ease);
}

.carte:hover .carte__vue { transform: scale(1.06); }

/* ---- Les trois schemas : construction puis vie propre ----
   Chaque schema se monte piece par piece quand sa carte entre a l'ecran, puis
   passe en boucle. Deux animations se succedent sur les memes elements : la
   seconde ne demarre qu'apres la fin de la premiere, sinon elle ecraserait son
   transform en plein vol. Les rotations utilisent transform-box: view-box,
   sans quoi le repere devient la boite de l'element et le dessin part de
   travers. */

/* rien n'est visible tant que la carte n'est pas entree */
.v1__grille, .v1__face, .v1__dos, .v1__cercle, .v1__demi,
.v2__loin, .v2__cote, .v2__avant,
.v3__sauve, .v3__ecu, .v3__coche { opacity: 0; }

/* ================= 1 - Ton image =================
   La grille se pose, la forme de marque tombe dessus, la palette arrive en
   tournant. Ensuite la roue continue et la lumiere passe d'une face a l'autre. */
.carte.is-in .v1__grille {
  animation: pose-fondu .6s var(--ease) .30s both,
             v1-grille 5.4s ease-in-out .9s infinite;
}

.carte.is-in .v1__face {
  transform-box: view-box;
  transform-origin: 62px 92px;
  animation: v1-tombe .62s cubic-bezier(.22, 1.4, .36, 1) .46s both,
             v1-lumiere 4.6s ease-in-out 1.3s infinite;
}

.carte.is-in .v1__dos {
  transform-box: view-box;
  transform-origin: 118px 38px;
  animation: v1-tombe .62s cubic-bezier(.22, 1.4, .36, 1) .58s both,
             v1-lumiere-inv 4.6s ease-in-out 1.3s infinite;
}

.carte.is-in .v1__cercle { animation: pose-fondu .5s var(--ease) .72s both; }

.carte.is-in .v1__demi {
  transform-box: view-box;
  transform-origin: 134px 80px;
  animation: v1-arrive .7s cubic-bezier(.22, 1.2, .36, 1) .72s both,
             v1-palette 9s linear 1.5s infinite;
}

@keyframes v1-grille {
  0%, 100% { opacity: .10; transform: translateX(0); }
  50%      { opacity: .36; transform: translateX(6px); }
}

@keyframes v1-tombe {
  from { opacity: 0; transform: translateY(-14px) scale(.72); }
  to   { opacity: 1; transform: none; }
}

@keyframes v1-arrive {
  from { opacity: 0;   transform: rotate(-150deg); }
  to   { opacity: .82; transform: rotate(0deg); }
}

@keyframes v1-palette {
  from { opacity: .82; transform: rotate(0deg); }
  to   { opacity: .82; transform: rotate(360deg); }
}

/* La lumiere bascule d'une face a l'autre ET le volume pivote : une variation
   d'opacite seule se lit comme un clignotement, c'est le mouvement qui fait
   croire a un objet qu'on tourne dans la main. */
@keyframes v1-lumiere {
  0%, 100% { opacity: 1;   transform: rotate(0deg)     scale(1); }
  50%      { opacity: .40; transform: rotate(-4.5deg)  scale(.97); }
}

@keyframes v1-lumiere-inv {
  0%, 100% { opacity: .30; transform: rotate(0deg)    scale(1); }
  50%      { opacity: .95; transform: rotate(4.5deg)  scale(1.03); }
}

/* ================= 2 - Tes clients =================
   Les fenetres arrivent du fond vers l'avant, chacune par son cote. Puis elles
   flottent a des rythmes distincts et le contenu se recharge. */
.carte.is-in .v2__loin {
  animation: v2-entre-g .7s var(--ease) .34s both,
             v2-loin 6.4s ease-in-out 1.2s infinite;
}

.carte.is-in .v2__cote {
  animation: v2-entre-d .7s var(--ease) .46s both,
             v2-cote 5.6s ease-in-out 1.3s infinite;
}

.carte.is-in .v2__avant {
  transform-box: view-box;
  transform-origin: 106px 82px;
  animation: v2-entre-av .68s cubic-bezier(.22, 1.3, .36, 1) .60s both,
             v2-avant 4.8s ease-in-out 1.4s infinite;
}

@keyframes v2-entre-g  { from { opacity: 0; transform: translate(-20px, 8px); } to { opacity: .5;  transform: none; } }
@keyframes v2-entre-d  { from { opacity: 0; transform: translate(20px, 8px);  } to { opacity: .55; transform: none; } }
@keyframes v2-entre-av { from { opacity: 0; transform: translateY(26px) scale(.86); } to { opacity: 1; transform: none; } }

@keyframes v2-loin  { 0%, 100% { opacity: .5;  transform: translate(0, 0) rotate(0deg); }    50% { opacity: .5;  transform: translate(-9px, -12px) rotate(-1.2deg); } }
@keyframes v2-cote  { 0%, 100% { opacity: .55; transform: translate(0, 0) rotate(0deg); }    50% { opacity: .55; transform: translate(12px, 9px) rotate(1.4deg); } }
@keyframes v2-avant { 0%, 100% { opacity: 1;   transform: translateY(0) rotate(0deg) scale(1); } 50% { opacity: 1; transform: translateY(-13px) rotate(-1.7deg) scale(1.025); } }

/* la vignette respire au rythme ou le contenu se recharge */
.carte.is-in .v2__vignette {
  transform-box: view-box;
  transform-origin: 84px 78px;
  animation: v2-vignette 4.4s ease-in-out 1.4s infinite;
}

@keyframes v2-vignette {
  0%, 100% { transform: scale(1)    rotate(0deg); }
  50%      { transform: scale(1.22) rotate(-5deg); }
}

/* la pastille de la barre bat comme un temoin d'activite */
.carte.is-in .v2__pt {
  transform-box: view-box;
  transform-origin: 72px 51px;
  animation: v2-pt 3.4s ease-in-out 1.4s infinite;
}

@keyframes v2-pt {
  0%, 100% { transform: scale(1);   opacity: 1; }
  50%      { transform: scale(1.7); opacity: .55; }
}

/* Les lignes portent pathLength="1" : un trace identique quelle que soit leur
   longueur reelle, sans calculer un dasharray par ligne. Le retour a vide se
   fait a opacite nulle, sinon elles se retireraient a rebours. */
.v2__ligne {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  opacity: 0;
}

.carte.is-in .v2__ligne { animation: v2-remplit 3.4s ease-in-out 1.05s infinite; }
.carte.is-in .v2__ligne:nth-child(2) { animation-delay: 1.17s; }
.carte.is-in .v2__ligne:nth-child(3) { animation-delay: 1.29s; }
.carte.is-in .v2__ligne:nth-child(4) { animation-delay: 1.41s; }

@keyframes v2-remplit {
  0%        { stroke-dashoffset: 1; opacity: 0; }
  8%        { opacity: .5; }
  30%       { stroke-dashoffset: 0; opacity: .5; }
  84%       { stroke-dashoffset: 0; opacity: .5; }
  95%, 100% { stroke-dashoffset: 0; opacity: 0; }
}

/* ================= 3 - Ta tranquillite =================
   Les sauvegardes se posent en cascade, l'ecusson se deploie par-dessus, la
   coche se trace en dernier. Ensuite le cycle recommence : les sauvegardes
   passent chacune leur tour, puis la verification se refait. */
.carte.is-in .v3__sauve {
  transform-box: view-box;
  transform-origin: center;
  animation: v3-pose .5s cubic-bezier(.22, 1.3, .36, 1) both,
             v3-sauve 5s ease-in-out 1.5s infinite;
}

.carte.is-in .v3__sauve--1 { animation-delay: .30s, 1.50s; }
.carte.is-in .v3__sauve--2 { animation-delay: .40s, 1.75s; }
.carte.is-in .v3__sauve--3 { animation-delay: .50s, 2.00s; }
.carte.is-in .v3__sauve--4 { animation-delay: .60s, 2.25s; }

@keyframes v3-pose {
  from { opacity: 0;   transform: translateY(12px) scale(.88); }
  to   { opacity: .34; transform: none; }
}

@keyframes v3-sauve {
  0%, 100% { opacity: .24; transform: translateY(0)    scale(1); }
  18%      { opacity: .78; transform: translateY(-6px) scale(1.05); }
  46%      { opacity: .24; transform: translateY(0)    scale(1); }
}

.carte.is-in .v3__ecu {
  transform-box: view-box;
  transform-origin: 100px 62px;
  animation: v3-deploie .66s cubic-bezier(.22, 1.35, .36, 1) .70s both,
             v3-ecu 5s ease-in-out 1.5s infinite;
}

@keyframes v3-deploie {
  from { opacity: 0;   transform: scale(.6); }
  to   { opacity: .13; transform: none; }
}

/* l'ecusson se gonfle quand la verification passe */
@keyframes v3-ecu {
  0%, 100% { opacity: .10; transform: scale(1)    rotate(0deg); }
  40%      { opacity: .32; transform: scale(1.13) rotate(-1.5deg); }
  62%      { opacity: .18; transform: scale(1.02) rotate(.6deg); }
}

.v3__coche {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}

.carte.is-in .v3__coche { animation: v3-coche 5s cubic-bezier(.3, 1, .4, 1) 1s infinite; }

@keyframes v3-coche {
  0%        { stroke-dashoffset: 1; opacity: 0; }
  6%        { opacity: 1; }
  26%       { stroke-dashoffset: 0; }
  82%       { stroke-dashoffset: 0; opacity: 1; }
  94%, 100% { stroke-dashoffset: 0; opacity: 0; }
}

/* pose commune, pour les elements sans geste propre */
@keyframes pose-fondu {
  from { opacity: 0;  transform: scale(.94); }
  to   { opacity: .9; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .v1__grille, .v1__face, .v1__dos, .v1__cercle, .v1__demi,
  .v2__loin, .v2__cote, .v2__avant, .v2__vignette, .v2__ligne,
  .v3__sauve, .v3__ecu, .v3__coche,
  .carte.is-in .v1__grille, .carte.is-in .v1__face, .carte.is-in .v1__dos,
  .carte.is-in .v1__cercle, .carte.is-in .v1__demi,
  .carte.is-in .v2__loin, .carte.is-in .v2__cote, .carte.is-in .v2__avant,
  .carte.is-in .v2__vignette, .carte.is-in .v2__ligne,
  .carte.is-in .v3__sauve, .carte.is-in .v3__ecu, .carte.is-in .v3__coche {
    animation: none;
    transform: none;
  }

  /* etat final fige, sinon les traces resteraient a vide */
  .v1__grille { opacity: .22; }
  .v1__face, .v1__cercle, .v2__avant { opacity: 1; }
  .v1__dos { opacity: .34; }
  .v1__demi { opacity: .82; }
  .v2__loin { opacity: .5; }
  .v2__cote { opacity: .55; }
  .v2__ligne { opacity: .45; stroke-dashoffset: 0; }
  .v3__sauve { opacity: .42; }
  .v3__ecu { opacity: .14; }
  .v3__coche { opacity: 1; stroke-dashoffset: 0; }
}

@media (max-width: 1080px) {
  .cartes { grid-template-columns: 1fr; max-width: 520px; margin-inline: auto; }
  /* en colonne, le decalage de la carte du milieu n'a plus de sens : il ne
     ferait qu'ouvrir un trou dans la pile */
  .carte--haute { margin-top: 0; }
}

/* ---------- 11. METHODE (parcours en 5 etapes) ----------
   Trois colonnes et cinq rangees de hauteur fixe : c'est la rangee qui impose
   le rythme, pas les marges des blocs. On ne voit jamais deux etapes a la fois,
   donc on avance forcement une par une.
   L'axe central se trace au feutre pendant la descente, avec une tete d'encre
   a son extremite. Une barre qui grandit ferait mecanique ; un trait qui se
   dessine, c'est le geste deja pose dans le hero. */
/* clip et non hidden : hidden ferait de la section un conteneur de defilement
   et casserait tout position: sticky en dessous */
.methode { overflow-x: clip; }

.parcours {
  /* La grille deborde volontairement le wrap de 1200 : la methode est la seule
     section qui prend toute la largeur de l'ecran, pour eloigner les etapes de
     l'axe et laisser respirer chaque rangee. */
  --etale: min(1360px, calc(100vw - 2 * var(--gutter)));

  /* Position horizontale de l'axe : SOURCE UNIQUE. L'axe, la tache de depart,
     la tete d'encre et les cinq jalons s'y accrochent, et app.js la reprend
     pour poser la tete et les jalons sur le tremble du trait.
     Une seule ligne a changer par point de rupture. Avant, le 50% etait ecrit
     en dur dans app.js : sur telephone l'axe passait a gauche mais les numeros
     restaient plantes au milieu, par-dessus le texte. */
  --axe: 50%;

  position: relative;
  display: grid;
  grid-template-columns: 1fr clamp(140px, 15vw, 264px) 1fr;
  grid-auto-rows: clamp(232px, 28vh, 318px);
  align-items: center;
  width: var(--etale);
  margin-inline: calc((100% - var(--etale)) / 2);
  margin-top: clamp(56px, 7vh, 92px);
}

/* ---- L'axe ---- */
.parcours__axe {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--axe);
  width: 20px;
  height: 100%;
  transform: translateX(-50%);
  fill: none;
  /* le trait garde son epaisseur malgre l'etirement vertical du SVG */
  vector-effect: non-scaling-stroke;
  overflow: visible;
}

/* le chemin restant, juste suggere : la meme forme, presque effacee */
.parcours__fond {
  fill: var(--ink);
  opacity: .1;
}

/* le chemin parcouru. Il n'est plus tronque par un pointille mais revele par
   une fenetre qui descend (clipPath), seule facon d'animer une forme pleine. */
.parcours__encre { fill: var(--orange); }

/* la bavure : la meme encre, deposee une seconde fois et a peine decalee */
.parcours__bave {
  fill: var(--orange-deep);
  opacity: .26;
  mix-blend-mode: multiply;
}

/* mediane de calcul, jamais rendue */
.parcours__guide {
  fill: none;
  stroke: none;
  pointer-events: none;
}

/* La pointe du feutre. Pas un point avec un halo : ca, c'est une diode, et le
   site n'en a nulle part. Une goutte d'encre fraiche, un peu de travers,
   posee hors du SVG qui est etire en hauteur et l'ovaliserait. */
.parcours__tete {
  position: absolute;
  left: var(--axe);
  top: 0;
  z-index: 2;
  width: 11px;
  margin: -9px 0 0 -5.5px;
  opacity: 0;
  transition: opacity .4s var(--ease);
}

.parcours__tete svg {
  display: block;
  width: 100%;
  height: auto;
  fill: var(--orange-deep);
  transform: rotate(-6deg);
}

.parcours.est-lance .parcours__tete { opacity: 1; }

/* La plume se pose : une tache d'encre marque le depart du geste, avant que
   le trait ne parte. Posee hors du SVG, qui est etire en hauteur et rendrait
   toute forme ronde ovale. */
.parcours__depart {
  position: absolute;
  top: -6px;
  left: var(--axe);
  z-index: 2;
  width: 26px;
  height: 26px;
  margin-left: -13px;
  opacity: 0;
  transform: scale(.4) rotate(-14deg);
  transition: opacity .5s var(--ease), transform .6s cubic-bezier(.22, 1.4, .36, 1);
}

.parcours__depart svg { width: 100%; height: 100%; fill: var(--orange); }
/* la tache reste posee une fois le geste amorce : le feutre ne se releve pas */
.parcours.est-entame .parcours__depart { opacity: .9; transform: none; }

/* Jalons : chaque etape est entouree a main levee quand l'encre arrive a sa
   hauteur. Le cercle n'est jamais deux fois le meme, il se trace en 0,7 s et
   depasse legerement, comme un vrai entourage au feutre. */
.parcours__jalon {
  position: absolute;
  left: var(--axe);
  z-index: 3;
  display: grid;
  place-items: center;
  width: clamp(52px, 4.4vw, 64px);
  aspect-ratio: 1;
  translate: -50% -50%;
}

.jalon__rond {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* Meme outil que l'axe : deux passages d'encre. Le premier pose l'entourage,
   le second repasse a peine decale, comme la bavure du trait. Sans ce doublon,
   le rond restait un cercle vectoriel a cote d'un trait au feutre. */
.jalon__rond path {
  fill: none;
  stroke: var(--orange);
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  opacity: 0;
  transition: stroke-dashoffset .78s var(--ease), opacity .2s var(--ease);
}

.jalon__rond .r1 { stroke-width: 1.9; }

.jalon__rond .r2 {
  stroke: var(--orange-deep);
  stroke-width: 1.15;
  transition-delay: .07s;
  mix-blend-mode: multiply;
}

.jalon__num {
  position: relative;
  font-family: var(--titre);
  font-size: clamp(.94rem, 1.1vw, 1.12rem);
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--ink);
  opacity: .28;
  transform: rotate(-2deg);
  transition: color .45s var(--ease), opacity .45s var(--ease);
}

.parcours__jalon.est-passe .jalon__rond .r1 { stroke-dashoffset: 0; opacity: 1; }
.parcours__jalon.est-passe .jalon__rond .r2 { stroke-dashoffset: 0; opacity: .55; }

.parcours__jalon.est-passe .jalon__num {
  color: var(--orange-deep);
  opacity: 1;
}

/* ---- Les etapes ---- */
.etape {
  /* Posees a distance de l'axe et transparentes : elles entrent par leur cote
     quand la rangee arrive a l'ecran. */
  display: flex;
  align-items: center;
  text-align: left;
  gap: clamp(18px, 2vw, 34px);
  opacity: 0;
  transform: translateX(var(--vient, -70px));
  transition: opacity .5s var(--ease), transform 1.15s var(--ease);
}

/* Une rangee par etape, ecrite noir sur blanc : sans ca le placement
   automatique remonte une etape sur la rangee de la precedente, sa colonne y
   etant libre, et les deux se retrouvent face a face.
   On compte en nth-of-type et non en nth-child : le trait, la tete d'encre et
   les cinq jalons sont freres des etapes dans le conteneur, donc la premiere
   etape est le huitieme enfant. En nth-child, aucune de ces regles ne tombait
   sur la bonne etape. */
.etape:nth-of-type(1) { grid-row: 1; }
.etape:nth-of-type(2) { grid-row: 2; }
.etape:nth-of-type(3) { grid-row: 3; }
.etape:nth-of-type(4) { grid-row: 4; }
.etape:nth-of-type(5) { grid-row: 5; }

/* Les blocs sont pousses vers les bords, pas ramenes contre l'axe : c'est ce
   qui creuse le vide au centre et donne la lecture en quinconce. La
   composition, elle, ne se retourne jamais : icone a gauche, texte a droite,
   ferre a gauche des deux cotes. Un texte ferre a droite se lirait moins bien
   pour rien. */
/* Chaque etape entre depuis le bord d'ecran qui lui fait face, pas de
   quelques dizaines de pixels : la distance se calcule sur la largeur reelle
   de la grille, donc le bloc part toujours du bord, quel que soit l'ecran. Un
   depart fixe en pixels serait trop court sur grand ecran et hors sujet sur
   petit. */
.etape:nth-of-type(odd) {
  grid-column: 3;
  justify-self: end;
  --vient: calc((100vw - var(--etale)) / 2 + 96px);
}

.etape:nth-of-type(even) {
  grid-column: 1;
  justify-self: start;
  --vient: calc((var(--etale) - 100vw) / 2 - 96px);
}

.etape.est-la {
  opacity: 1;
  transform: none;
}

/* Icone d'etape : un petit dessin bicolore pose sur une tache de feutre. Le
   contour reprend l'encre du texte, l'accent orange designe ce qui bouge a
   cette etape la. Aucune pastille bordee : le fond est dans le dessin.

   Trois mouvements se superposent ici, chacun sur son etage pour ne pas se
   marcher dessus : l'entree est portee par le conteneur, le retard au
   defilement et le flottement par le dessin lui-meme. Une animation en boucle
   posee sur le meme element qu'une transition d'entree ecrase toujours cette
   derniere. */
.etape__icone {
  display: block;
  flex: none;
  width: clamp(56px, 4.8vw, 76px);
}

.etape__icone svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  transform: translateY(calc(var(--pdy, 0px) + var(--flot, 0px)));
  animation: flot-etape 9.7s ease-in-out infinite;
}

/* Durees et phases toutes differentes : des cycles egaux se resynchronisent au
   bout de quelques tours et les cinq icones se mettent a battre la mesure. */
.etape:nth-of-type(2) .etape__icone svg { animation-duration: 11.2s; animation-delay: -3.4s; }
.etape:nth-of-type(3) .etape__icone svg { animation-duration: 8.9s;  animation-delay: -6.1s; }
.etape:nth-of-type(4) .etape__icone svg { animation-duration: 12.4s; animation-delay: -1.8s; }
.etape:nth-of-type(5) .etape__icone svg { animation-duration: 10.3s; animation-delay: -5.2s; }

@keyframes flot-etape {
  0%, 100% { --flot: 0px; }
  50%      { --flot: -9px; }
}

/* le texte traine aussi, mais deux fois moins : sinon le bloc se disloque */
.etape__corps { transform: translateY(var(--pdy, 0px)); }

/* ---- Entree en cascade ----
   Le bloc arrive par son cote, puis ses morceaux se posent l'un apres l'autre.
   L'icone ouvre la marche avec le meme geste que les titres du hero : elle
   grandit legerement et sort du flou. */
.etape__icone,
.etape__meta,
.etape__titre,
.etape__txt {
  opacity: 0;
  transition: opacity .8s var(--ease), transform .8s var(--ease), filter .8s var(--ease);
}

.etape__icone { transform: scale(.86); filter: blur(7px); }
.etape__meta,
.etape__titre,
.etape__txt { transform: translateY(15px); }

.etape.est-la .etape__icone,
.etape.est-la .etape__meta,
.etape.est-la .etape__titre,
.etape.est-la .etape__txt {
  opacity: 1;
  transform: none;
  filter: none;
}

.etape.est-la .etape__icone { transition-delay: .05s; }
.etape.est-la .etape__meta  { transition-delay: .16s; }
.etape.est-la .etape__titre { transition-delay: .24s; }
.etape.est-la .etape__txt   { transition-delay: .34s; }

/* tache de fond */
.etape__icone .b { fill: rgba(238, 78, 39, .09); }
/* contour a l'encre */
.etape__icone .t {
  fill: none;
  stroke: var(--ink);
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* aplats du papier, pour que les formes se recouvrent proprement */
.etape__icone .c { fill: var(--cream); }
/* accents */
.etape__icone .a { fill: var(--orange); }
.etape__icone .s {
  fill: none;
  stroke: var(--orange);
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.etape__meta {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}

/* Qui travaille a cette etape. C'est l'argument de la section : sur cinq
   etapes, deux seulement le concernent. */
.etape__qui {
  padding: 4px 11px;
  border-radius: 999px;
  background: rgba(42, 16, 10, .06);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.etape__qui--toi {
  background: var(--orange);
  color: var(--cream);
}

.etape__titre {
  font-family: var(--titre);
  font-size: clamp(1.5rem, 2.4vw, 2.05rem);
  font-weight: 600;
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 34, 'WONK' 1;
  line-height: 1.12;
  letter-spacing: -0.006em;
  color: var(--ink);
}

.etape__txt {
  max-width: 42ch;
  margin-top: 14px;
  font-size: .99rem;
  line-height: 1.7;
  color: var(--ink-soft);
}

/* ---- Responsive ----
   Sous 900px il n'y a plus de place pour deux colonnes : l'axe passe a gauche
   et toutes les etapes s'alignent a sa droite. */
@media (max-width: 900px) {
  .parcours {
    grid-template-columns: 44px 1fr;
    grid-auto-rows: auto;
    row-gap: clamp(44px, 7vh, 72px);
    align-items: start;
    width: 100%;
    margin-inline: 0;
  }

  /* L'axe passe a gauche : on ne deplace QUE la variable, tout suit
     (axe, tache de depart, tete d'encre et les cinq jalons, y compris
     ceux que app.js repositionne sur le tremble du trait). */
  .parcours { --axe: 22px; }
  .parcours__jalon { width: 44px; }

  .etape:nth-of-type(odd),
  .etape:nth-of-type(even) {
    grid-column: 2;
    grid-row: auto;
    justify-self: stretch;
    flex-direction: row;
    align-items: flex-start;
    gap: 16px;
    text-align: left;
    padding-inline: 0;
    --vient: 40px;
  }

  .etape__icone { width: 48px; }

}

@media (prefers-reduced-motion: reduce) {
  .etape { opacity: 1; transform: none; transition: none; }
  .etape__icone,
  .etape__meta,
  .etape__titre,
  .etape__txt { opacity: 1; transform: none; filter: none; transition: none; }
  .etape__icone svg { animation: none; transform: none; }
  .etape__corps { transform: none; }
  /* sans animation, la fenetre de revelation ne descend jamais : on la retire
     et le trait est encre d'emblee sur toute sa hauteur */
  .parcours__couche { clip-path: none; }
  .parcours__tete { display: none; }
  .parcours__depart { opacity: .9; transform: none; }
  .jalon__rond path { stroke-dashoffset: 0; opacity: 1; }
  .jalon__num { color: var(--orange-deep); opacity: 1; }
}

/* ---------- 12. REALISATIONS (vitrine horizontale) ----------
   Un panneau plein ecran par client, traverses lateralement pendant qu'on
   descend. Le rail mesure quatre hauteurs d'ecran : le bloc colle en haut de
   fenetre, et la part de rail deja parcourue decale la piste d'autant. Le
   defilement reste donc celui du navigateur, on ne detourne jamais la molette,
   et un clavier ou une barre de defilement continuent de fonctionner. */
.vitrine { padding-bottom: 0; }

.vitrine__rail {
  position: relative;
  /* Pres de trois hauteurs d'ecran par panneau. La traversee doit se lire au
     rythme d'une lecture, pas d'un feuilletage : c'est le seul endroit du site
     ou on montre du travail livre. */
  height: 1120vh;
  margin-top: clamp(40px, 5vh, 72px);
}

.vitrine__colle {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
}

.vitrine__piste {
  display: flex;
  height: 100%;
  width: max-content;
  will-change: transform;
}

/* ---- Un panneau ---- */
.cas {
  /* Le nom et les etiquettes sont poses par-dessus, dans la bande basse : la
     capture recupere ainsi toute la hauteur du panneau au lieu de partager la
     colonne avec eux. C'est ce qui fait la difference entre une vignette et
     une vitrine. */
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100%;
  padding: clamp(26px, 3.4vh, 40px) clamp(24px, 3.6vw, 64px) clamp(30px, 4vh, 46px);
  background: linear-gradient(158deg, var(--cas-a) 0%, var(--cas-b) 100%);
  color: var(--sur);
}

/* ---- La fenetre de navigateur ----
   Une barre, trois pastilles, et la capture dessous. Le cadre est ce qui dit
   au visiteur qu'il regarde un site en ligne, pas une image de catalogue. */
/* La zone donne la hauteur disponible, le cadre s'y inscrit a la proportion
   exacte de la capture. Sans ca, le cadre s'etirait a la place laissee et
   l'image, recadree pour remplir, se retrouvait zoomee et coupee. */
/* La zone donne la hauteur disponible, le cadre s'y inscrit a la proportion
   exacte de la capture. Sans ca, le cadre s'etire a la place laissee et
   l'image, recadree pour remplir, se retrouve zoomee et coupee. */
.cas__cadre {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  width: auto;
  max-width: 100%;
  /* 1200 x 675 de capture (16/9), plus les 32 px de la barre de fenetre */
  aspect-ratio: 1200 / 707;
  /* au-dela, on etirerait une image de 1200 px de large */
  max-height: 1000px;
  border-radius: 14px;
  overflow: hidden;
  background: #F3F1EE;
  box-shadow: 0 34px 70px -22px var(--cas-ombre),
              0 4px 14px rgba(0, 0, 0, .12);
}

.cas__barre {
  flex: none;
  display: flex;
  align-items: center;
  gap: 7px;
  height: 32px;
  padding-inline: 14px;
  background: #E4E0DA;
}

.cas__barre i {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #C9C4BC;
}

.cas__barre i:nth-child(1) { background: #E7695C; }
.cas__barre i:nth-child(2) { background: #E7B04A; }
.cas__barre i:nth-child(3) { background: #6FBE6B; }

/* La capture s'eteint dans le fond du panneau sur sa derniere bande : sans ce
   fondu, le nom pose par-dessus tomberait dans le contenu du site client. */
.cas__cadre::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: clamp(96px, 15vh, 168px);
  background: linear-gradient(to top,
              var(--cas-b) 8%,
              color-mix(in srgb, var(--cas-b) 72%, transparent) 46%,
              transparent 100%);
  pointer-events: none;
}

.cas__cadre img {
  flex: 1;
  min-height: 0;
  width: 100%;
  object-fit: cover;
  object-position: top center;
}

/* La zone est un lien : tout le cadre se clique. Rien ne vient s'afficher
   par-dessus la capture, le mouvement suffit a dire qu'elle s'ouvre. */
.cas__zone {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--sur);
}

.cas__zone .cas__cadre {
  transition: transform .55s cubic-bezier(.22, 1.2, .36, 1),
              box-shadow .55s var(--ease);
}

/* la fenetre se souleve et son ombre s'ecarte : elle se decolle du panneau,
   comme une feuille qu'on attrape */
.cas__zone:hover .cas__cadre,
.cas__zone:focus-visible .cas__cadre {
  transform: translateY(-12px);
  box-shadow: 0 52px 90px -30px var(--cas-ombre),
              0 8px 22px rgba(0, 0, 0, .16);
}

/* Le cartouche ne bouge pas : le nom du client et son logo restent poses,
   c'est la fenetre seule qui reagit au survol. */

@media (prefers-reduced-motion: reduce) {
  .cas__zone .cas__cadre { transition: none; }
}

/* Pose dans la bande basse, aux deux bords du panneau : le nom cote gauche,
   les prestations cote droit, comme les cartouches d'une vitrine. */
.cas__pied {
  position: absolute;
  z-index: 2;
  left: clamp(24px, 3.6vw, 64px);
  right: clamp(24px, 3.6vw, 64px);
  bottom: clamp(20px, 2.8vh, 34px);
  display: flex;
  align-items: center;          /* nom et etiquettes sur la meme ligne */
  justify-content: space-between;
  gap: 24px;
}

/* Le logo detoure du client, pose contre son nom : c'est lui qu'on reconnait
   d'un coup d'oeil, avant meme d'avoir lu. */
.cas__ident {
  display: flex;
  align-items: center;
  gap: clamp(13px, 1.4vw, 22px);
}

.cas__logo {
  flex: none;
  height: clamp(38px, 3.6vw, 58px);
  width: auto;
  object-fit: contain;
}

.cas__nom {
  font-family: var(--titre);
  font-size: clamp(1.5rem, 3vw, 2.5rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -.015em;
}

.cas__ligne {
  margin-top: 8px;
  font-size: clamp(.92rem, 1.1vw, 1.05rem);
  opacity: .72;
}

.cas__tags {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
  list-style: none;
}

/* Meme famille que les onglets de cartes et les badges d'etapes : pastille
   pleine et translucide, pas de cerclage. Un filet de 1 px autour d'un texte
   deja tres espace fait bricolage, et sur fond sombre il grise tout.
   Le point orange en tete est la marque REGA, deja posee sur les surtitres. */
.cas__tags li {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 17px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--sur) 10%, transparent);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .17em;
  text-transform: uppercase;
  opacity: .88;
}

.cas__tags li::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--orange);
  opacity: .9;
}

/* ---- Jauge d'avancement ----
   Sans reperes, un defilement horizontal donne l'impression d'etre bloque : la
   page ne descend plus alors qu'on tourne la molette. La jauge dit combien il
   reste. */
.vitrine__jauge {
  position: absolute;
  left: 50%;
  bottom: clamp(16px, 2.4vh, 26px);
  width: min(320px, 42vw);
  height: 2px;
  transform: translateX(-50%);
  background: currentColor;
  opacity: .18;
  border-radius: 2px;
  color: var(--sur, var(--ink));
  pointer-events: none;
}

.vitrine__barre {
  display: block;
  height: 100%;
  width: 100%;
  border-radius: inherit;
  background: var(--orange);
  transform: scaleX(var(--avance, 0));
  transform-origin: left center;
}

/* ---- Responsive ----
   Sous 900px on abandonne le rail : coller un panneau plein ecran sur un
   telephone donne surtout l'impression que la page ne repond plus. Les cas se
   remettent les uns sous les autres. */
@media (max-width: 900px) {
  .vitrine__rail { height: auto; margin-top: 32px; }
  .vitrine__colle { position: static; height: auto; overflow: visible; }
  .vitrine__piste { display: block; width: auto; transform: none !important; }
  .vitrine__jauge { display: none; }

  .cas {
    width: auto;
    height: auto;
    gap: 20px;
    padding: clamp(28px, 6vw, 44px) clamp(18px, 5vw, 32px);
    display: flex;
    flex-direction: column;
    border-radius: 18px;
    margin-bottom: 18px;
  }

  .cas__zone { display: block; }
  .cas__cadre::after { display: none; }
  .cas__cadre { height: auto; width: 100%; max-width: none; aspect-ratio: auto; }
  .cas__cadre img { height: auto; object-fit: contain; }

  .cas__pied {
    position: static;
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    margin-top: 18px;
  }
  .cas__tags { justify-content: flex-start; }
}

/* ---------- 13. CE QUI NOUS INSPIRE ----------
   Les logos sont poses nus, sans tuile ni cadre : les encadrer un par un en
   ferait un tableau de partenaires, alors qu'il s'agit de references.
   Chacun garde ses couleurs. Deux enseignes ne diffusent leur logo qu'en
   blanc, invisible sur le creme : celles-la sont ramenees a l'encre du site,
   le dessin est intact, seule la couleur change. */
.inspire__bande {
  margin-top: clamp(38px, 5vh, 68px);
  /* elle se depose apres le titre : classe reveal dans le HTML, retard ici */
  transition-delay: .12s;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}

.inspire__piste {
  display: flex;
  align-items: center;
  width: max-content;
  gap: clamp(52px, 6vw, 104px);
  list-style: none;
  animation: inspire-defile 58s linear infinite;
}

.inspire__bande:hover .inspire__piste { animation-play-state: paused; }

@keyframes inspire-defile {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* Chaque logo est livre sur une planche de meme dimension, mise a l'echelle
   pour que la masse d'encre soit comparable d'une marque a l'autre. Un
   monogramme carre et un logotype en bandeau n'occupent pas la meme place,
   mais ils pesent desormais pareil a l'oeil. */
.marque {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.marque img {
  height: clamp(38px, 3.6vw, 52px);
  width: auto;
  object-fit: contain;
  /* au repos les logos sont retenus : ce sont des references, pas des clients,
     ils ne doivent pas crier plus fort que le reste de la page */
  opacity: .58;
  filter: saturate(.35);
  transform: translateY(0) scale(1);
  transition: opacity .45s var(--ease), filter .45s var(--ease),
              transform .45s cubic-bezier(.22, 1.3, .36, 1);
}

/* Au survol, la marque reprend ses couleurs et se souleve. Un trait de feutre
   se tire dessous dans le meme geste : le meme soulignement que le hero. */
.marque:hover img {
  opacity: 1;
  filter: saturate(1);
  transform: translateY(-6px) scale(1.04);
}

.marque::after {
  content: "";
  position: absolute;
  left: 12%;
  right: 12%;
  bottom: -12px;
  height: 2px;
  border-radius: 2px;
  background: var(--orange);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .45s var(--ease);
}

.marque:hover::after { transform: scaleX(1); }

@media (max-width: 900px) {
  .inspire__piste { gap: 40px; }
  .marque img { height: 34px; }
}

@media (prefers-reduced-motion: reduce) {
  .inspire__bande { overflow-x: auto; }
  .inspire__piste { animation: none; }
  .marque img { opacity: 1; filter: none; transition: none; }
}

/* ---------- 14. AVIS ----------
   Trois cartes claires, sans cadre appuye : c'est la parole qui doit ressortir,
   pas la boite qui la contient.
   Deux etages de mouvement, chacun sur son element : l'entree est portee par
   l'article, le flottement par la carte a l'interieur. Une animation en boucle
   posee sur le meme element qu'une transition d'entree ecrase cette derniere. */
.avisliste {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* stretch et non start : les trois colonnes prennent la hauteur de la plus
     haute, donc les trois cartes sont rigoureusement de la meme taille quelle
     que soit la longueur du temoignage. */
  align-items: stretch;
  gap: clamp(18px, 2vw, 30px);
  margin-top: clamp(44px, 5.5vh, 76px);
  /* la carte du milieu descend hors de sa rangee : on lui rend la place */
  padding-bottom: 34px;
}

.avis { display: flex; }

.avis__carte {
  display: flex;
  flex-direction: column;
  flex: 1;
  height: 100%;
  border-radius: var(--r-lg);
  background: linear-gradient(168deg,
              color-mix(in srgb, var(--cream-2) 78%, transparent) 0%,
              color-mix(in srgb, var(--cream-3) 42%, transparent) 100%);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .7) inset,
              0 18px 40px -28px rgba(42, 16, 10, .5);
  overflow: hidden;
  /* La carte flotte par son transform, pas par une variable interposee :
     une custom property animee force un recalcul de style a chaque image et
     le mouvement se met a saccader des qu'il y a une ombre a repeindre.
     Anime directement, le transform reste sur la couche graphique. */
  animation: flot-avis 11.4s ease-in-out infinite;
  will-change: transform;
}

/* Durees et phases distinctes : a cycles egaux, les trois cartes se
   resynchronisent et la rangee se met a tanguer d'un bloc. */
.avis:nth-child(3) .avis__carte { animation-duration: 9.8s;  animation-delay: -7.2s; }

/* Le decalage du milieu est porte par le meme transform que le flottement, pas
   par une marge : une marge aurait raccourci la carte d'autant, et on serait
   revenu a trois hauteurs differentes. */
.avis:nth-child(2) .avis__carte {
  animation-name: flot-avis-bas;
  animation-duration: 13.1s;
  animation-delay: -4.6s;
}

@keyframes flot-avis {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(0, -10px, 0); }
}

@keyframes flot-avis-bas {
  0%, 100% { transform: translate3d(0, 32px, 0); }
  50%      { transform: translate3d(0, 22px, 0); }
}

/* ---- L'entree : une carte qu'on pose sur la table ----
   Elle arrive de plus bas, un peu de travers et un peu trop petite, puis se
   redresse en depassant legerement sa position finale. Chaque carte penche
   dans un sens different : trois inclinaisons identiques feraient un bloc qui
   bascule, pas trois cartes posees l'une apres l'autre.
   L'effet est porte par l'article et non par la carte : celle-ci a deja le
   flottement sur son transform.
   Le retard entre les trois est pose par app.js, qui echelonne les voisins
   d'une meme grille. */
.avis.reveal {
  opacity: 0;
  transform: translateY(42px) rotate(var(--pose, -2.2deg)) scale(.94);
  transform-origin: 50% 115%;
  transition: opacity .5s var(--ease),
              transform .95s cubic-bezier(.22, 1.14, .32, 1);
}

.avis:nth-child(1) { --pose: -2.6deg; }
.avis:nth-child(2) { --pose:  2deg; }
.avis:nth-child(3) { --pose: -1.4deg; }

.avis.reveal.is-in { opacity: 1; transform: none; }

/* le contenu se depose apres la carte, sinon tout arrive d'un seul tenant */
.avis__texte,
.avis__pied {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
}

.avis.is-in .avis__texte { opacity: 1; transform: none; transition-delay: .3s; }
.avis.is-in .avis__pied  { opacity: 1; transform: none; transition-delay: .42s; }

/* le guillemet s'encre en dernier, comme une signature */
.avis__texte::before { opacity: 0; transition: opacity .5s var(--ease) .52s; }
.avis.is-in .avis__texte::before { opacity: .32; }

/* le bandeau : un aplat a peine plus dense que la carte */
.avis__tete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 13px clamp(20px, 2vw, 28px);
  background: color-mix(in srgb, var(--cream-3) 52%, transparent);
  border-bottom: 1px solid rgba(42, 16, 10, .06);
}

.avis__label {
  font-size: .66rem;
  font-weight: 700;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--ink-mute);
  opacity: .72;
}

.avis__guillemets {
  width: 22px;
  height: auto;
  fill: var(--orange);
  opacity: .55;
}

/* Le temoignage est ferre a gauche et pose en serif : centre, un paragraphe
   de cinq lignes se lit mal, chaque ligne repartant d'un bord different. La
   serif le distingue du reste de la page, qui parle a la premiere personne du
   pluriel : ici, c'est quelqu'un d'autre qui parle. */
.avis__texte {
  flex: 1;
  position: relative;
  padding: clamp(30px, 3.4vw, 44px) clamp(24px, 2.6vw, 36px) clamp(24px, 2.8vw, 34px);
  font-family: var(--titre);
  font-size: clamp(1.02rem, 1.2vw, 1.14rem);
  font-weight: 400;
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 28, 'WONK' 0;
  line-height: 1.66;
  letter-spacing: -.004em;
  color: var(--ink-soft);
  text-wrap: pretty;
}

/* la premiere lettre part sous un guillemet ouvrant, pose dans la marge */
.avis__texte::before {
  content: "«";
  position: absolute;
  left: clamp(10px, 1.1vw, 16px);
  top: clamp(26px, 3.1vw, 40px);
  font-family: var(--titre);
  font-size: 1.5em;
  line-height: 1;
  color: var(--orange);
}

/* Pied : l'enseigne a gauche, la personne a droite, sur la meme ligne, avec un
   filet qui les separe du temoignage. */
.avis__pied {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-inline: clamp(22px, 2.4vw, 34px);
  padding: clamp(18px, 2vw, 24px) 0 clamp(24px, 2.6vw, 32px);
  border-top: 1px solid rgba(42, 16, 10, .08);
}

.avis__marque {
  display: grid;
  place-items: center;
  flex: none;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--cream);
  box-shadow: 0 2px 10px -4px rgba(42, 16, 10, .3);
}

.avis__marque img {
  width: 62%;
  height: 62%;
  object-fit: contain;
}

.avis__signature { text-align: right; line-height: 1.35; }

.avis__nom {
  display: block;
  font-family: var(--titre);
  font-size: 1.04rem;
  font-weight: 700;
  color: var(--ink);
}

.avis__role {
  font-size: .84rem;
  color: var(--ink-mute);
}

@media (max-width: 1080px) {
  .avisliste { grid-template-columns: 1fr; max-width: 620px; margin-inline: auto; padding-bottom: 0; }
  .avis:nth-child(2) .avis__carte { animation-name: flot-avis; }
}

@media (prefers-reduced-motion: reduce) {
  .avis__carte { animation: none; transform: none; }
  .avis:nth-child(2) .avis__carte { transform: translateY(32px); }
  .avis.reveal,
  .avis__texte,
  .avis__pied { opacity: 1; transform: none; transition: none; }
  .avis__texte::before { opacity: .32; }
}

/* ---------- 15. OFFRE / TARIFS ---------- */
.offer {
  display: grid;
  grid-template-columns: .88fr 1.12fr;
  gap: clamp(24px, 3vw, 40px);
  align-items: stretch;
}

.price {
  display: flex;
  flex-direction: column;
  padding: clamp(32px, 3.6vw, 46px);
  border-radius: var(--r-xl);
  background: linear-gradient(165deg, var(--orange) 0%, var(--orange-deep) 100%);
  color: var(--cream);
  box-shadow: var(--shadow-lg);
  position: relative;
  overflow: hidden;
}

.price::before {
  content: "";
  position: absolute;
  top: -40%;
  right: -30%;
  width: 78%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: rgba(255, 255, 255, .1);
  pointer-events: none;
}

.price > * { position: relative; }

.price__eyebrow {
  font-size: .76rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  opacity: .8;
}

.price__main {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-top: 14px;
}

.price__num {
  font-size: clamp(4rem, 9vw, 6rem);
  font-weight: 800;
  line-height: .85;
  letter-spacing: -0.055em;
}

.price__curr { font-size: 2.2rem; font-weight: 700; }

.price__once {
  margin-top: 12px;
  font-size: .96rem;
  opacity: .84;
}

.price__sep {
  height: 1px;
  margin-block: 26px;
  background: rgba(250, 245, 238, .28);
}

.price__month {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}

.price__month-num {
  font-size: clamp(1.9rem, 3.6vw, 2.5rem);
  font-weight: 800;
  letter-spacing: -0.04em;
}

.price__month-lbl { font-size: .98rem; opacity: .84; }

.price__tagline {
  margin-top: 14px;
  font-family: var(--hand);
  font-size: 1.6rem;
  font-weight: 700;
  color: var(--orange-soft);
}

.price__cta { margin-top: 30px; align-self: flex-start; }

.price__extra {
  margin-top: 30px;
  padding: 18px 20px;
  border-radius: var(--r);
  background: rgba(42, 16, 10, .2);
  font-size: .92rem;
  line-height: 1.55;
}

.price__extra strong { font-size: 1.1rem; }

.sheet {
  padding: clamp(30px, 3.4vw, 44px);
  border-radius: var(--r-xl);
  background: var(--cream);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
}

.sheet__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 20px;
  border-bottom: 1px dashed var(--line-strong);
}

.sheet__title {
  font-size: 1.35rem;
  font-weight: 800;
  letter-spacing: -0.03em;
}

.sheet__stamp {
  padding: 7px 15px;
  border: 1.5px solid var(--orange);
  border-radius: 999px;
  transform: rotate(-4deg);
  color: var(--orange);
  font-size: .76rem;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.sheet__list {
  display: grid;
  gap: 13px;
  margin-top: 24px;
}

.sheet__list li {
  display: flex;
  gap: 13px;
  font-size: .97rem;
  color: var(--ink-soft);
  line-height: 1.5;
}

.sheet__check {
  display: grid;
  place-items: center;
  width: 21px;
  height: 21px;
  flex: none;
  margin-top: 2px;
  border-radius: 50%;
  background: var(--orange-soft);
  color: var(--orange-deep);
  font-size: .72rem;
  font-weight: 800;
}

.sheet__note {
  font-style: normal;
  color: var(--ink-mute);
  font-size: .88rem;
}

.sheet__foot {
  margin-top: 26px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
  font-size: .95rem;
  color: var(--ink-soft);
  line-height: 1.6;
}

.sheet__link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 18px;
  font-weight: 700;
  font-size: .95rem;
  color: var(--orange);
  border-bottom: 1.5px solid transparent;
  transition: border-color .3s ease;
}

.sheet__link:hover { border-color: var(--orange); }

/* ---------- 16. FAQ ---------- */
/* ---------- FAQ ----------
   Une liste, pas des cartes : chaque question tient sur une ligne, separee par
   un filet. La reponse se deplie sous elle.
   L'element reste un <details> natif : il s'ouvre meme sans JavaScript, il est
   annonce correctement par les lecteurs d'ecran, et la recherche du navigateur
   trouve le texte replie. */
.faq {
  max-width: 900px;
  margin-inline: auto;
  margin-top: clamp(40px, 5vh, 68px);
}

.faq__item {
  position: relative;
  border-radius: 14px;
  border-bottom: 1px solid var(--line);
  transition: background-color .4s var(--ease);
}

.faq__item:last-child { border-bottom: 0; }

/* la question ouverte se pose sur un aplat creme et perd son filet : elle
   devient un bloc, le temps qu'on la lise */
.faq__item[open]:not(.js-faq),
.faq__item.est-ouverte {
  background: color-mix(in srgb, var(--cream-2) 55%, transparent);
  border-bottom-color: transparent;
}

.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 22px;
  padding: clamp(20px, 2.4vw, 27px) clamp(14px, 1.6vw, 22px);
  cursor: pointer;
  list-style: none;
}

.faq__q::-webkit-details-marker { display: none; }

.faq__texte {
  position: relative;
  font-family: var(--titre);
  font-size: clamp(1.02rem, 1.5vw, 1.16rem);
  font-weight: 600;
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 30, 'WONK' 1;
  line-height: 1.35;
  letter-spacing: -.008em;
  color: var(--ink);
  transition: color .3s var(--ease), transform .4s var(--ease);
}

/* le meme trait de feutre que sous les logos : il se tire au survol */
.faq__texte::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -5px;
  height: 2px;
  border-radius: 2px;
  background: var(--orange);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .45s var(--ease);
}

.faq__item:hover .faq__texte { color: var(--orange-deep); transform: translateX(4px); }
.faq__item:hover .faq__texte::after { transform: scaleX(1); }
.faq__item[open] .faq__texte { color: var(--orange-deep); }
.faq__item.js-faq:not(.est-ouverte) .faq__texte { color: var(--ink); }
.faq__item[open]:hover .faq__texte { transform: none; }
.faq__item[open] .faq__texte::after { transform: scaleX(0); }

/* Le signe : deux traits qui pivotent d'un quart de tour. La barre verticale
   s'efface en meme temps, donc le plus devient un moins au lieu de se
   contenter de tourner. */
.faq__signe {
  display: grid;
  place-items: center;
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1.5px solid var(--line-strong);
  color: var(--ink-soft);
  transition: transform .45s var(--ease), background-color .35s var(--ease),
              border-color .35s var(--ease), color .35s var(--ease);
}

.faq__signe svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
}

.faq__item:hover .faq__signe { border-color: var(--orange); color: var(--orange); }

.faq__item[open] .faq__signe {
  transform: rotate(135deg);
  background: var(--orange);
  border-color: var(--orange);
  color: var(--cream);
}

/* pendant le repli, open est encore la mais la classe est deja partie : le
   signe et le titre reviennent au repos en meme temps que la reponse */
.faq__item.js-faq:not(.est-ouverte) .faq__signe {
  transform: none;
  background: transparent;
  border-color: var(--line-strong);
  color: var(--ink-soft);
}

/* Le depliage : une rangee de grille qui passe de 0 a sa hauteur naturelle.
   C'est la seule facon d'animer une hauteur inconnue sans la mesurer en JS.
   Une transition et non une animation : elle se joue dans les deux sens, donc
   le repli est aussi doux que l'ouverture. */
.faq__corps {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows .48s var(--ease), opacity .34s var(--ease);
}

/* sans JavaScript, l'attribut natif suffit : tout s'ouvre, sans transition */
.faq__item[open]:not(.js-faq) .faq__corps { grid-template-rows: 1fr; opacity: 1; }

/* avec JavaScript, c'est la classe qui pilote : elle survit au repli, le temps
   que l'animation aille au bout avant que open ne soit retire */
.faq__item.est-ouverte .faq__corps { grid-template-rows: 1fr; opacity: 1; }

.faq__corps > p {
  min-height: 0;
  overflow: hidden;
  margin: 0;
  padding: 0 clamp(14px, 1.6vw, 22px) clamp(22px, 2.4vw, 30px);
  max-width: 74ch;
  color: var(--ink-soft);
  font-size: 1rem;
  line-height: 1.75;
  /* le texte remonte legerement pendant le repli : il accompagne le geste au
     lieu d'etre coupe net par le bord de la rangee */
  transform: translateY(-6px);
  transition: transform .48s var(--ease);
}

.faq__item.est-ouverte .faq__corps > p { transform: none; }

.faq__corps > p strong { color: var(--ink); font-weight: 700; }

/* l'entree en liste : chaque ligne arrive apres la precedente, decalee par
   app.js comme les autres grilles du site */
.faq__item.reveal { transform: translateY(18px); }

@media (prefers-reduced-motion: reduce) {
  .faq__corps { transition: none; }
  .faq__texte::after { display: none; }
}

/* ---------- 17. CTA FINAL ---------- */
/* ---------- 17. CTA FINAL ----------
   Un titre, une phrase, un numero. Rien d'autre : c'est le dernier ecran, le
   visiteur a deja tout lu, il ne reste qu'a decrocher. */
.final { text-align: center; }

.final__titre { max-width: 18ch; margin-inline: auto; }

.final__sous {
  max-width: 44ch;
  margin: clamp(16px, 2vw, 22px) auto 0;
  font-size: clamp(1rem, 1.25vw, 1.12rem);
  color: var(--ink-mute);
  transform: translateY(var(--pdy, 0px));
}

.final__actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  margin-top: clamp(34px, 4vw, 48px);
}

/* le bouton d'appel respire un peu plus que les autres du site */
.final__appel {
  padding-inline: clamp(30px, 4vw, 46px);
  font-size: clamp(1.04rem, 1.5vw, 1.18rem);
}

.final__mail {
  font-size: .95rem;
  color: var(--ink-mute);
  border-bottom: 1px solid transparent;
  transition: color .3s var(--ease), border-color .3s var(--ease);
}

.final__mail:hover { color: var(--orange); border-color: var(--orange); }

/* ---- Les deux visages ----
   Deux jetons poses l'un sur l'autre, chacun sa couleur : on voit deux
   personnes, pas un sigle a deux lettres. Plus de pastille autour : le cadre
   creme en faisait un bouton, alors que rien ne se clique ici. */
.final__duo {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  margin-top: clamp(36px, 4.4vw, 52px);
}

.duo__faces { display: inline-flex; }

.duo__face {
  display: grid;
  place-items: center;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  border: 3px solid var(--cream);
  font-family: var(--titre);
  font-size: 1.14rem;
  font-weight: 700;
  color: var(--cream);
  box-shadow: 0 10px 22px -12px rgba(42, 16, 10, .55);
  /* les jetons arrivent de travers et se redressent avec le bloc */
  transform: rotate(var(--pose, 0deg));
  transition: transform .55s cubic-bezier(.22, 1.3, .36, 1);
}

.duo__face--r {
  --pose: -7deg;
  background: linear-gradient(150deg, var(--orange), var(--orange-deep));
}

.duo__face--g {
  --pose: 6deg;
  margin-left: -16px;
  background: linear-gradient(150deg, #4A2A1E, var(--ink));
}

/* au survol ils s'ecartent et se redressent, comme deux personnes qui se
   tournent vers toi */
.final__duo:hover .duo__face--r { transform: translateX(-6px) rotate(-2deg); }
.final__duo:hover .duo__face--g { transform: translateX(6px) rotate(2deg); }

.duo__noms {
  font-family: var(--titre);
  font-size: clamp(1.04rem, 1.3vw, 1.16rem);
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -.01em;
}

/* l'esperluette passe a la main : c'est le seul mot manuscrit de la page */
.duo__noms i {
  font-family: var(--hand);
  font-style: normal;
  font-size: 1.4em;
  font-weight: 700;
  color: var(--orange);
  margin-inline: .1em;
  vertical-align: -.06em;
}

/* a l'entree, les jetons tombent un peu plus bas et de plus loin que le nom */
.final__duo.reveal .duo__face { transform: translateY(16px) rotate(var(--pose, 0deg)) scale(.9); }
.final__duo.reveal.is-in .duo__face--r { transform: rotate(-7deg); transition-delay: .1s; }
.final__duo.reveal.is-in .duo__face--g { transform: rotate(6deg); transition-delay: .2s; }

@media (prefers-reduced-motion: reduce) {
  .duo__face,
  .final__duo.reveal .duo__face { transform: none; transition: none; }
}

/* ---------- 17bis. PAGE LEGALE ----------
   Une page qu'on lit en diagonale et qu'on ne relit qu'en cas de doute : elle
   suit la charte du site, mais sans effet. Colonne etroite, sections separees
   par un filet, encadres seulement pour ce qui engage vraiment. */
.loi { padding-top: clamp(96px, 12vh, 150px); }

.loi__sommaire {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
  margin-top: clamp(38px, 5vh, 60px);
  padding-bottom: clamp(30px, 4vh, 46px);
  border-bottom: 1px solid var(--line);
}

.loi__sommaire a {
  padding: 7px 14px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--cream-2) 60%, transparent);
  font-size: .82rem;
  font-weight: 600;
  color: var(--ink-soft);
  transition: background-color .3s var(--ease), color .3s var(--ease);
}

.loi__sommaire a:hover { background: var(--orange); color: var(--cream); }

.loi__bloc {
  padding-block: clamp(34px, 4.4vh, 54px);
  border-bottom: 1px solid var(--line);
  /* la barre collee en haut ne doit pas recouvrir le titre vise par une ancre */
  scroll-margin-top: 100px;
}

.loi__bloc:last-of-type { border-bottom: 0; }

.loi__bloc h2 {
  font-family: var(--titre);
  font-size: clamp(1.3rem, 2.2vw, 1.66rem);
  font-weight: 600;
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 32, 'WONK' 1;
  line-height: 1.2;
  letter-spacing: -.012em;
  color: var(--ink);
  margin-bottom: clamp(16px, 2vw, 22px);
}

.loi__bloc h3 {
  margin-top: clamp(22px, 2.6vw, 30px);
  margin-bottom: 8px;
  font-size: .96rem;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--ink);
}

.loi__bloc p,
.loi__bloc li {
  font-size: .99rem;
  line-height: 1.75;
  color: var(--ink-soft);
}

.loi__bloc p + p { margin-top: 14px; }

.loi__bloc ul {
  margin-top: 12px;
  padding-left: 0;
  list-style: none;
}

.loi__bloc li {
  position: relative;
  padding-left: 20px;
  margin-top: 8px;
}

/* la puce reprend le point orange des surtitres */
.loi__bloc li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: .68em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--orange);
  opacity: .8;
}

.loi__bloc strong { color: var(--ink); font-weight: 700; }

.loi__bloc a {
  color: var(--orange-deep);
  border-bottom: 1px solid rgba(199, 62, 29, .3);
  transition: border-color .3s var(--ease);
}

.loi__bloc a:hover { border-color: var(--orange); }

/* Encadres : la carte pour les informations qu'on vient verifier (SIRET,
   hebergeur), la note pour ce qui engage le client. */
.loi__carte,
.loi__note,
.loi__bonne {
  margin-top: clamp(16px, 2vw, 22px);
  padding: clamp(18px, 2.2vw, 26px);
  border-radius: 16px;
  background: color-mix(in srgb, var(--cream-2) 62%, transparent);
}

.loi__note,
.loi__bonne {
  border-left: 3px solid var(--orange);
  border-radius: 4px 16px 16px 4px;
}

.loi__carte p + p { margin-top: 6px; }

.loi__fin {
  margin-top: clamp(38px, 5vh, 60px);
  padding-top: clamp(26px, 3vh, 36px);
  border-top: 1px solid var(--line);
  text-align: center;
  font-size: .96rem;
  color: var(--ink-mute);
}

.loi__fin a { color: var(--orange-deep); border-bottom: 1px solid rgba(199, 62, 29, .3); }

@media (max-width: 700px) {
  .loi__sommaire a { font-size: .78rem; padding: 6px 12px; }
}

/* ---------- 17ter. FICHE PROJET ----------
   Meme decoupage que les fiches de la version precedente : identite, apercu,
   entreprise, brief, direction artistique decodee, sections cles, telephone,
   projet suivant. La charte, elle, est celle de la v3 : creme, Fraunces,
   traits au feutre, aucun cadre inutile. */

/* ---- L'entete, aux couleurs du client ---- */
.fiche__tete {
  padding: clamp(112px, 14vh, 168px) 0 clamp(44px, 6vh, 72px);
  background: linear-gradient(158deg, var(--cas-a) 0%, var(--cas-b) 100%);
  color: var(--sur);
}

.fiche__fil {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: .82rem;
  opacity: .66;
}

.fiche__fil a { color: inherit; border-bottom: 1px solid transparent; transition: border-color .3s var(--ease); }
.fiche__fil a:hover { border-color: currentColor; }
.fiche__fil b { font-weight: 700; }

/* L'enseigne du client occupe la moitie droite de l'entete : c'est elle qu'on
   reconnait avant d'avoir lu le titre. Sous 900 px elle passe au-dessus du
   texte, plus petite. */
.fiche__haut {
  display: grid;
  grid-template-columns: 1.15fr .85fr;
  align-items: center;
  gap: clamp(28px, 4vw, 64px);
  margin-top: clamp(26px, 3.4vh, 42px);
}

.fiche__marque {
  display: grid;
  place-items: center;
  padding: clamp(10px, 1.6vw, 22px);
}

.fiche__marque img {
  width: auto;
  max-width: 100%;
  max-height: clamp(150px, 20vw, 250px);
  object-fit: contain;
  /* legere respiration, comme les captures plus bas dans la page */
  transform: translateY(var(--flot, 0px));
  animation: flot-fiche 12.6s ease-in-out infinite;
}

.fiche__eyebrow {
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  opacity: .6;
}

.fiche__titre {
  margin-top: 14px;
  font-family: var(--titre);
  font-size: clamp(2.4rem, 6.4vw, 4.6rem);
  font-weight: 700;
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 28, 'WONK' 1;
  line-height: .98;
  letter-spacing: -.028em;
}

.fiche__chapo {
  max-width: 58ch;
  margin-top: clamp(20px, 2.6vh, 30px);
  font-size: clamp(1.02rem, 1.35vw, 1.16rem);
  line-height: 1.72;
  opacity: .86;
}

/* la fiche d'identite : six lignes, sans tableau ni cadre */
.fiche__id {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  margin-top: clamp(30px, 4vh, 48px);
  border-top: 1px solid color-mix(in srgb, var(--sur) 16%, transparent);
}

.fiche__id > div {
  padding: 16px 18px 16px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--sur) 16%, transparent);
}

.fiche__id dt {
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  opacity: .55;
}

.fiche__id dd {
  margin-top: 6px;
  font-family: var(--titre);
  font-size: 1rem;
  font-weight: 600;
}

/* ---- Titres de la fiche ---- */
.fiche__h2 {
  font-family: var(--titre);
  font-size: clamp(1.5rem, 3vw, 2.3rem);
  font-weight: 600;
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 32, 'WONK' 1;
  line-height: 1.14;
  letter-spacing: -.018em;
  color: var(--ink);
}

.fiche__h2 em { font-style: normal; color: var(--orange); }
.fiche__h2--centre { text-align: center; }
.fiche__h2--clair { color: var(--sur); }
.fiche__h2--clair em { color: inherit; opacity: .68; }

.fiche__intro {
  max-width: 56ch;
  margin: clamp(14px, 1.8vw, 20px) auto 0;
  text-align: center;
  font-size: 1rem;
  line-height: 1.7;
  color: var(--ink-mute);
}

.fiche__intro--clair { color: var(--sur); opacity: .74; }

/* ---- L'apercu ----
   La page d'accueil en grand, dans une fenetre de navigateur, et un lien vers
   le site en ligne quand il existe. Pas d'iframe : les sites livres refusent
   d'etre affiches dans un cadre etranger (X-Frame-Options), la fenetre
   serait restee blanche. */
.apercu {
  max-width: 1120px;
  margin: clamp(34px, 4.5vh, 56px) auto 0;
  border-radius: 16px;
  overflow: hidden;
  background: #F3F1EE;
  box-shadow: 0 44px 90px -36px rgba(42, 16, 10, .58);
}

.apercu__chrome {
  display: flex;
  align-items: center;
  gap: 14px;
  height: 44px;
  padding-inline: 16px;
  background: #E4E0DA;
}

.apercu__dots { display: flex; gap: 7px; }
.apercu__dots i { width: 10px; height: 10px; border-radius: 50%; background: #C9C4BC; }
.apercu__dots i:nth-child(1) { background: #E7695C; }
.apercu__dots i:nth-child(2) { background: #E7B04A; }
.apercu__dots i:nth-child(3) { background: #6FBE6B; }

.apercu__url {
  padding: 5px 16px;
  border-radius: 999px;
  background: var(--cream);
  font-size: .8rem;
  color: var(--ink-soft);
}

.apercu img { display: block; width: 100%; height: auto; }

.apercu__pied {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  margin-top: clamp(26px, 3.4vh, 38px);
}

.apercu__domaine {
  font-size: .84rem;
  letter-spacing: .04em;
  color: var(--ink-mute);
}

/* ---- L'entreprise et le brief ---- */
.fiche__duo {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(32px, 5vw, 74px);
}

.recit__eyebrow {
  margin-bottom: 12px;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--orange);
}

.recit__eyebrow--clair { color: var(--sur); opacity: .6; text-align: center; }

.recit p {
  margin-top: 16px;
  font-size: 1rem;
  line-height: 1.75;
  color: var(--ink-soft);
}

.recit p strong { color: var(--ink); font-weight: 700; }

/* ---- La direction artistique, sur un fond aux couleurs du client ---- */
.da {
  background: linear-gradient(158deg, var(--cas-a) 0%, var(--cas-b) 100%);
  color: var(--sur);
}

.da__grille {
  display: grid;
  grid-template-columns: 1.2fr 1fr 1fr;
  gap: clamp(20px, 3vw, 44px);
  margin-top: clamp(38px, 5vh, 62px);
  padding: clamp(24px, 3vw, 38px);
  border-radius: 20px;
  background: color-mix(in srgb, var(--sur) 7%, transparent);
}

.da__bloc h3 {
  margin-bottom: 16px;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  opacity: .6;
}

.da__palette { display: grid; gap: 10px; list-style: none; }

.da__palette li {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: .9rem;
}

.da__pastille {
  width: 26px;
  height: 26px;
  flex: none;
  border-radius: 8px;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--sur) 22%, transparent) inset;
}

.da__palette b { font-weight: 700; }

.da__palette code {
  margin-left: auto;
  font-size: .78rem;
  letter-spacing: .04em;
  opacity: .6;
}

.da__typo { margin-bottom: 16px; }
.da__typo span { display: block; font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; opacity: .55; }
.da__typo b { display: block; margin-top: 4px; font-family: var(--titre); font-size: 1.24rem; font-weight: 600; }

.da__vibe { font-family: var(--hand); font-size: 1.5rem; line-height: 1.35; }

/* les trois raisons : pourquoi ces couleurs, ces caracteres, cette structure */
.da__pourquoi {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(18px, 2.4vw, 30px);
  margin-top: clamp(20px, 2.6vw, 32px);
}

.da__carte {
  padding: clamp(22px, 2.6vw, 30px);
  border-radius: 18px;
  background: color-mix(in srgb, var(--sur) 7%, transparent);
}

.da__carte-eyebrow {
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  opacity: .55;
}

.da__carte h3 {
  margin-top: 10px;
  font-family: var(--titre);
  font-size: 1.14rem;
  font-weight: 600;
  line-height: 1.24;
}

.da__carte p {
  margin-top: 12px;
  font-size: .95rem;
  line-height: 1.7;
  opacity: .84;
}

.da__carte p strong { font-weight: 700; opacity: 1; }

/* ---- Les sections cles ----
   Deux colonnes, la capture puis sa legende dessous : un intitule en petites
   capitales orange et une phrase. Meme decoupage que sur la version
   precedente du site, ou cette grille se lisait tres vite. */
.cles {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(40px, 5vw, 80px) clamp(28px, 3.6vw, 56px);
  margin-top: clamp(44px, 5.5vh, 74px);
  /* la grille deborde le gabarit de 1200 : les captures ont besoin de place
     pour qu'on distingue ce qu'elles montrent */
  width: min(1420px, calc(100vw - 2 * var(--gutter)));
  margin-inline: calc((100% - min(1420px, calc(100vw - 2 * var(--gutter)))) / 2);
}

.cle img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 14px;
  box-shadow: 0 26px 56px -30px rgba(42, 16, 10, .5);
}

.cle figcaption { margin-top: clamp(18px, 2.2vw, 26px); }

.cle__kicker {
  font-size: .76rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--orange);
}

.cle__txt {
  margin-top: 12px;
  max-width: 46ch;
  font-size: clamp(1.04rem, 1.2vw, 1.14rem);
  line-height: 1.72;
  color: var(--ink-soft);
}

.cle__txt strong { color: var(--ink); font-weight: 700; }

/* ---- Le telephone ---- */
.ecrans {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(24px, 3.4vw, 48px);
  margin-top: clamp(40px, 5vh, 64px);
}

.ecran { text-align: center; }

.ecran__tel {
  width: min(230px, 100%);
  margin: 0 auto clamp(18px, 2.4vw, 26px);
  padding: 10px;
  border-radius: 32px;
  background: linear-gradient(160deg, #3A2A22, var(--ink));
  box-shadow: 0 26px 50px -26px rgba(42, 16, 10, .62);
}

.ecran__tel img { display: block; width: 100%; height: auto; border-radius: 23px; }

.ecran h3 {
  font-family: var(--titre);
  font-size: 1.08rem;
  font-weight: 600;
  color: var(--ink);
}

.ecran p {
  max-width: 34ch;
  margin: 10px auto 0;
  font-size: .93rem;
  line-height: 1.68;
  color: var(--ink-soft);
}

/* ---- Le projet suivant ---- */
.suite__lien {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 12px 24px;
  padding: clamp(26px, 3.4vw, 40px);
  border-radius: 22px;
  background: color-mix(in srgb, var(--cream-2) 62%, transparent);
  transition: background-color .4s var(--ease), transform .45s var(--ease);
}

.suite__lien:hover { background: color-mix(in srgb, var(--cream-3) 70%, transparent); transform: translateY(-3px); }

.suite__label {
  grid-column: 1;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--orange);
}

.suite__nom {
  grid-column: 1;
  font-family: var(--titre);
  font-size: clamp(1.4rem, 2.6vw, 2rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -.02em;
  color: var(--ink);
}

.suite__meta { grid-column: 1; font-size: .92rem; color: var(--ink-mute); }

.suite__fleche {
  grid-column: 2;
  grid-row: 1 / 4;
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: var(--orange);
  color: var(--cream);
  font-size: 1.2rem;
  transition: transform .45s cubic-bezier(.22, 1.3, .36, 1);
}

.suite__lien:hover .suite__fleche { transform: translateX(5px); }

@media (max-width: 900px) {
  .fiche__haut { grid-template-columns: 1fr; }
  .fiche__marque { order: -1; justify-items: start; padding: 0 0 6px; }
  .fiche__marque img { max-height: 110px; }
  .fiche__id { grid-template-columns: repeat(2, 1fr); }
  .fiche__duo { grid-template-columns: 1fr; }
  .da__grille { grid-template-columns: 1fr; }
  .da__pourquoi { grid-template-columns: 1fr; }
  .cles { grid-template-columns: 1fr; width: 100%; margin-inline: 0; }
  .ecrans { grid-template-columns: 1fr; }
}

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

/* la couche de fond se cale sur toute la hauteur de la page */
main { position: relative; }

/* ---- Recherches en fond ----
   Les memes pastilles que sur l'accueil, reprises sur toute la hauteur de la
   fiche : ce sont les recherches qui doivent mener au site du client. Elles
   derivent au defilement par le meme attribut data-glisse que le reste du
   site, il n'y a pas de script propre a cette page. */
.fondreq {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}

.freq {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  max-width: 58vw;
  padding: 10px 17px 10px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 252, 248, .5);
  font-size: .88rem;
  font-weight: 500;
  color: var(--ink-mute);
  white-space: nowrap;
  /* assez effacees pour rester un fond : au-dela, on se met a les lire */
  opacity: .42;
  transform: translateY(var(--pdy, 0px)) rotate(var(--tilt, 0deg));
}

.freq__ico {
  width: 14px;
  height: 14px;
  flex: none;
  fill: none;
  stroke: var(--orange);
  stroke-width: 2.2;
  stroke-linecap: round;
  opacity: .7;
}

/* sur les fiches sombres, la pastille s'inverse pour rester lisible */
.fiche__tete ~ main .freq { color: inherit; }

@media (max-width: 900px) {
  /* sur telephone, elles passeraient sous le texte : on les retire */
  .fondreq { display: none; }
}

/* ---------- 17quater. MOUVEMENTS DE LA FICHE PROJET ----------
   Meme grammaire que l'accueil : les blocs se deposent a l'arrivee, les
   captures flottent ensuite. L'entree est portee par le conteneur, le
   flottement par l'image : une animation en boucle posee sur le meme element
   qu'une transition d'entree ecraserait cette derniere. */

/* ---- L'apercu : la fenetre se pose comme une feuille ---- */
.apercu.reveal { transform: translateY(34px) scale(.97); }
.apercu.reveal.is-in { transform: none; }
.apercu { transition: opacity .8s var(--ease), transform 1s cubic-bezier(.22, 1.12, .34, 1); }

.apercu img {
  transform: translateY(var(--flot, 0px));
  animation: flot-fiche 13s ease-in-out infinite;
}

/* ---- Les captures des sections cles ----
   Chaque vignette flotte a son rythme. Six cycles egaux se
   resynchroniseraient et la grille se mettrait a battre la mesure. */
.cle img {
  transform: translateY(var(--flot, 0px));
  animation: flot-fiche 11.6s ease-in-out infinite;
  transition: box-shadow .5s var(--ease);
}

.cle:nth-child(2) img { animation-duration: 13.4s; animation-delay: -3.1s; }
.cle:nth-child(3) img { animation-duration: 10.2s; animation-delay: -6.4s; }
.cle:nth-child(4) img { animation-duration: 14.1s; animation-delay: -1.8s; }
.cle:nth-child(5) img { animation-duration: 12.3s; animation-delay: -8.2s; }
.cle:nth-child(6) img { animation-duration: 9.8s;  animation-delay: -4.6s; }

/* l'entree des vignettes, decalee par app.js comme les autres grilles */
.cle.reveal { transform: translateY(26px); }

/* ---- Les telephones ----
   Ils montent plus haut que les captures : un ecran de telephone tenu a la
   main ne tient jamais parfaitement immobile. */
.ecran__tel {
  transform: translateY(var(--flot, 0px));
  animation: flot-fiche 10.4s ease-in-out infinite;
}

.ecran:nth-child(2) .ecran__tel { animation-duration: 12.8s; animation-delay: -4.2s; }
.ecran:nth-child(3) .ecran__tel { animation-duration: 9.2s;  animation-delay: -7.5s; }

/* le telephone du milieu est pose un cran plus bas, comme les avis de
   l'accueil : trois ecrans parfaitement alignes figent la rangee */
.ecrans .ecran:nth-child(2) { margin-top: clamp(14px, 2.6vh, 34px); }

@keyframes flot-fiche {
  0%, 100% { --flot: 0px; }
  50%      { --flot: -11px; }
}

/* ---- Les cartes de direction artistique ---- */
.da__carte.reveal { transform: translateY(24px) scale(.97); }
.da__carte { transition: opacity .7s var(--ease), transform .8s cubic-bezier(.22, 1.16, .34, 1); }

/* ---- Les recits, l'entreprise et le brief ---- */
.recit.reveal { transform: translateY(28px); }
.recit:nth-child(2) { transition-delay: .12s; }

/* ---- Le bloc du projet suivant ---- */
.suite__lien.reveal { transform: translateY(24px); }

@media (prefers-reduced-motion: reduce) {
  .apercu img,
  .cle img,
  .ecran__tel { animation: none; transform: none; }
  .ecrans .ecran:nth-child(2) { margin-top: 0; }
}

/* ---------- 17quinquies. LE CURSEUR ----------
   La fleche du pointeur, redessinee : creme pleine, cernee d'un filet orange
   fin. Le creme la detache des aplats orange et des panneaux sombres, le filet
   la detache du fond de page. Sa pointe tombe exactement sur la position de la
   souris : aucun decalage de centrage, contrairement a une pastille.
   Rien dans le HTML : app.js cree la fleche et masque alors seulement le
   curseur natif. Sans JavaScript, ou sur un ecran tactile, le pointeur du
   systeme reste en place. */
.curseur {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10000;              /* au-dessus du grain de papier, qui tient 9999 */
  /* Indispensable : la fleche est posee pile sous la souris. Sans cette ligne
     elle recoit tous les clics a la place des boutons. */
  pointer-events: none;
  width: 21px;
  height: 27px;
  opacity: 0;
  transform: translate3d(-100px, -100px, 0);
  /* Aucune transition sur le deplacement : la fleche doit coller a la souris
     au pixel pres. Le moindre lissage se sent comme une latence. */
  transition: opacity .22s var(--ease);
  filter: drop-shadow(0 2px 5px rgba(42, 16, 10, .28));
}

.curseur svg { width: 100%; height: 100%; display: block; }

.curseur .curseur__corps {
  fill: var(--cream);
  stroke: var(--orange);
  stroke-width: 1.6;
  stroke-linejoin: round;
  transition: fill .22s var(--ease), stroke .22s var(--ease);
}

/* elle n'apparait qu'au premier mouvement, jamais avant */
html.curseur-vu .curseur { opacity: 1; }

/* le curseur natif ne disparait qu'une fois le notre en place */
html.a-curseur,
html.a-curseur * { cursor: none !important; }

/* Sur ce qui se clique, la fleche s'inverse : orange pleine, cernee de creme.
   Le changement se voit sur tous les fonds, y compris sur un bouton orange. */
html.curseur-actif .curseur .curseur__corps {
  fill: var(--orange);
  stroke: var(--cream);
}

html.curseur-actif .curseur { transform-origin: 2px 2px; }

/* souris hors de la fenetre */
html.curseur-parti .curseur { opacity: 0; }

/* Ni sur les ecrans tactiles, ni pour qui demande moins d'animations. */
@media (hover: none), (pointer: coarse), (prefers-reduced-motion: reduce) {
  .curseur { display: none; }
  html.a-curseur,
  html.a-curseur * { cursor: auto !important; }
}

/* ---------- 17sexies. PANNEAU DE PRISE DE RENDEZ-VOUS ----------
   Trois voies vers le meme numero. Un commercant ne decroche pas toujours,
   n'ecrit pas toujours sur WhatsApp : on ne choisit pas a sa place.
   Le panneau est masque par l'attribut hidden ; sans JavaScript il ne s'ouvre
   jamais et les boutons restent des ancres vers le bloc de contact. */
.rdv {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: grid;
  place-items: center;
  padding: var(--gutter);
}

.rdv[hidden] { display: none; }

.rdv__voile {
  position: absolute;
  inset: 0;
  border: 0;
  padding: 0;
  background: rgba(42, 16, 10, .42);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  cursor: pointer;
  animation: rdv-voile .3s var(--ease) both;
}

.rdv__carte {
  position: relative;
  width: min(460px, 100%);
  padding: clamp(28px, 4vw, 40px);
  border-radius: 24px;
  background: var(--cream);
  box-shadow: 0 40px 90px -30px rgba(42, 16, 10, .6);
  animation: rdv-carte .45s cubic-bezier(.22, 1.2, .36, 1) both;
}

@keyframes rdv-voile { from { opacity: 0; } to { opacity: 1; } }
@keyframes rdv-carte {
  from { opacity: 0; transform: translateY(22px) scale(.96); }
  to   { opacity: 1; transform: none; }
}

.rdv__fermer {
  position: absolute;
  top: 14px;
  right: 16px;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--ink-mute);
  cursor: pointer;
  transition: background-color .3s var(--ease), color .3s var(--ease);
}

.rdv__fermer:hover { background: var(--cream-3); color: var(--ink); }

.rdv__eyebrow {
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--orange);
}

.rdv__titre {
  margin-top: 10px;
  font-family: var(--titre);
  font-size: clamp(1.5rem, 3vw, 1.92rem);
  font-weight: 600;
  font-optical-sizing: auto;
  font-variation-settings: 'SOFT' 32, 'WONK' 1;
  line-height: 1.12;
  letter-spacing: -.018em;
  color: var(--ink);
}

.rdv__titre em { font-style: normal; color: var(--orange); }

.rdv__txt {
  margin-top: 12px;
  font-size: .96rem;
  line-height: 1.65;
  color: var(--ink-soft);
}

.rdv__voies {
  display: grid;
  gap: 10px;
  margin-top: clamp(20px, 2.6vw, 26px);
}

.rdv__voie {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 16px;
  border-radius: 16px;
  border: 1px solid var(--line);
  background: color-mix(in srgb, var(--cream-2) 55%, transparent);
  transition: border-color .3s var(--ease), background-color .3s var(--ease),
              transform .3s var(--ease);
}

.rdv__voie:hover {
  border-color: var(--orange);
  background: color-mix(in srgb, var(--orange) 7%, transparent);
  transform: translateX(3px);
}

/* l'appel est la voie principale : c'est la seule qui aboutit tout de suite */
.rdv__voie--fort {
  border-color: transparent;
  background: var(--orange);
  color: var(--cream);
}

.rdv__voie--fort:hover {
  background: var(--orange-deep);
  border-color: transparent;
}

.rdv__ico {
  display: grid;
  place-items: center;
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: color-mix(in srgb, currentColor 12%, transparent);
}

.rdv__ico svg { width: 19px; height: 19px; fill: currentColor; }

.rdv__voie b { display: block; font-size: .98rem; font-weight: 700; }
.rdv__voie i { font-style: normal; font-size: .84rem; opacity: .7; }

/* sur ordinateur, le bouton « Envoyer un message » mene deja a WhatsApp :
   la ligne dediee ferait doublon */
.rdv--ordinateur .rdv__voie--wa { display: none; }

.rdv__pied {
  margin-top: 18px;
  text-align: center;
  font-size: .88rem;
  color: var(--ink-mute);
}

.rdv__pied a { color: var(--orange-deep); border-bottom: 1px solid rgba(199, 62, 29, .3); }

@media (prefers-reduced-motion: reduce) {
  .rdv__voile, .rdv__carte { animation: none; }
}

/* ---------- 18. FOOTER ----------
   Une ligne, pas quatre colonnes : la marque d'un cote, les liens de l'autre,
   la mention legale dessous. Tout ce qui s'y trouvait en double est deja dans
   la page ou dans le menu. */
.foot {
  margin-top: clamp(48px, 6vw, 84px);
  padding-block: clamp(26px, 3vw, 36px) 22px;
  border-top: 1px solid var(--line);
  color: var(--ink-mute);
}

.foot__ligne {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 18px 30px;
}

.foot__marque {
  display: inline-flex;
  align-items: center;
  opacity: .9;
  transition: opacity .3s var(--ease), transform .4s var(--ease);
}

.foot__marque:hover { opacity: 1; transform: translateY(-2px); }

.foot__marque img { width: 38px; height: auto; }

.foot__liens {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
  font-size: .92rem;
}

.foot__liens a {
  color: var(--ink-mute);
  border-bottom: 1px solid transparent;
  transition: color .3s var(--ease), border-color .3s var(--ease);
}

.foot__liens a:hover { color: var(--orange); border-color: var(--orange); }

.foot__bas {
  margin-top: clamp(20px, 2.4vw, 28px);
  padding-top: 18px;
  border-top: 1px solid var(--line);
  font-size: .84rem;
  color: var(--ink-mute);
  opacity: .8;
}

@media (max-width: 700px) {
  .foot__ligne { flex-direction: column; align-items: flex-start; }
  .foot__liens { gap: 8px 18px; }
}

/* ---------- 19. REVEAL AU SCROLL ---------- */
.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .8s var(--ease), transform .8s var(--ease);
}

.reveal.is-in { opacity: 1; transform: none; }

/* ---------- 20. RESPONSIVE ---------- */
@media (max-width: 1080px) {
  .offer    { grid-template-columns: 1fr; }
  .constat__grid { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
  .nav__links {
    position: fixed;
    top: 0; right: 0;
    z-index: 2;
    margin-left: 0;
    flex-direction: column;
    align-items: stretch;
    justify-content: center;
    gap: 6px;
    width: min(320px, 84vw);
    height: 100dvh;
    padding: 88px 24px 32px;
    background: var(--cream);
    border-left: 1px solid var(--line);
    box-shadow: -20px 0 60px rgba(42, 16, 10, .16);
    transform: translateX(102%);
    transition: transform .45s var(--ease);
  }

  .nav.is-open .nav__links { transform: none; }

  .nav__links a {
    padding: 14px 16px;
    font-size: 1.05rem;
    border-radius: var(--r);
  }

  .nav__burger { display: flex; }
  .nav__cta { display: none; }

  .nav__links-cta {
    display: inline-flex;
    justify-content: center;
    margin-top: 22px;
  }
  .nav__preview { padding: 9px 14px; font-size: .82rem; }

  .works { grid-template-columns: 1fr; }
}

@media (max-width: 700px) {
  .work__body { flex-direction: column; align-items: flex-start; }



  .nav__preview span { display: none; }
  .nav__preview { padding: 10px; }
  .nav__preview svg { width: 17px; height: 17px; }
}

@media (max-width: 460px) {
  .searchbox__text { font-size: .92rem; }
  .price__cta { align-self: stretch; justify-content: center; }
}

/* ---------- 20bis. CONFORT AU DOIGT (telephone et tablette) ----------
   Rien ici ne change l'apparence sur ordinateur : tout est sous 900px.

   Un doigt n'est pas un curseur. Une cible de moins de 44 px se rate une fois
   sur trois, et sur un site dont le seul but est qu'on appelle, un lien rate
   est un client perdu. On elargit donc la zone tactile, sans grossir le texte :
   c'est du remplissage, pas de la typographie.

   Reference : WCAG 2.1, critere 2.5.5 (Target Size), 44 x 44 px minimum. */
@media (max-width: 900px) {

  /* Le bouton « Accès maquette » de la barre : 39 px, il s'en fallait de peu. */
  .nav__preview {
    min-width: 44px;
    min-height: 44px;
    justify-content: center;
  }

  /* Liens du pied de page : ils faisaient 25 px de haut et se touchaient
     presque. On ecarte les rangees et on epaissit la zone de chaque lien. */
  .foot__liens {
    gap: 2px 22px;
  }
  .foot__liens a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* Le logo du pied de page est un lien de retour : 38 px, on le passe a 44. */
  .foot__marque { padding: 3px; }

  /* L'adresse mail du bloc de contact : 26 px de haut, c'est le lien le plus
     important de la page apres le telephone. */
  .final__mail {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* Sommaire des mentions legales : des pastilles de 33 px. */
  .loi__sommaire a { padding: 13px 16px; }

  /* Fiches d'information des mentions legales : le mail de contact et le site
     de l'hebergeur y sont les seules choses a toucher, sur une ligne de 21 px.
     Les autres liens de la page restent tels quels : ils sont au milieu de
     phrases, et la norme les exempte pour ne pas disloquer l'interligne. */
  .loi__carte li a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* Fil d'ariane des fiches projet : 23 px de haut. Le « REGA » ne fait que
     33 px de large parce que le mot est court : on elargit par le remplissage
     et on reprend la meme valeur en marge negative, pour que l'espacement
     reste rigoureusement celui d'avant. */
  .fiche__fil a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding-inline: 6px;
    margin-inline: -6px;
  }

  /* Sur un ecran tactile il n'y a pas de survol, mais iOS garde l'etat :hover
     apres une tape. Sans ca, le trait de survol resterait colle sous un lien
     dont on vient d'agrandir la zone, donc loin du texte. */
  @media (hover: none) {
    .foot__liens a:hover,
    .final__mail:hover,
    .fiche__fil a:hover { border-color: transparent; }
  }

  /* Micro-libelles : 10,9 px passe encore sur un ecran d'ordinateur a 60 cm,
     pas sur un telephone tenu a bout de bras. On monte au plancher de 12 px,
     sans toucher au dessin (majuscules, interlettrage, couleur inchanges).
     On ne remonte que ce qui se lit vraiment : les surtitres, les sources et
     l'adresse decorative de la fausse fenetre restent a leur taille, c'est
     leur petitesse qui les tient au second plan. */
  .carte__onglet,
  .etape__qui { font-size: .75rem; }

  /* Etiquettes des fiches projet (Client, Lieu, Type, Livraison, Statut) :
     de l'information, pas de la decoration. */
  .fiche__id dt { font-size: .73rem; }

  /* Panneau de prise de rendez-vous. Il s'ouvre par-dessus la page, donc
     l'audit automatique ne le voit pas : ces deux cibles se reperent en
     ouvrant reellement le panneau au doigt.
     Les trois boutons Appeler / WhatsApp / SMS font deja 79 px, rien a y faire.

     La croix de fermeture passe de 34 a 44 px. On decale le haut et la droite
     de 5 px en sens inverse pour que son centre optique ne bouge pas d'un
     cheveu ; le rond de survol etant transparent au repos, rien ne se voit. */
  .rdv__fermer {
    width: 44px;
    height: 44px;
    top: 9px;
    right: 11px;
  }

  /* « Ou par mail : contact@agence-rega.fr », 19 px de haut : c'est une des
     trois facons de nous joindre, elle merite la meme zone que les autres. */
  .rdv__pied a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* ---------- 21. MOUVEMENT REDUIT ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

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

  .word, .hero__sub, .hero__ctas, .hero__hint, .hero__scroll { opacity: 1; }
  .reveal { opacity: 1; transform: none; }
}

/* ---------- 22. IMPRESSION ---------- */
@media print {
  .nav, .nav__scrim, .ticker, .hero__scroll, .ck, body::after { display: none !important; }
  body { background: #fff; color: #000; }
}


/* ============================================================
   BANDEAU COOKIES
   Posé en bas à gauche, il ne recouvre jamais le contenu ni le
   bouton de rendez-vous. Les deux réponses ont le même poids
   visuel : refuser doit coûter exactement un clic, comme accepter.
   ============================================================ */

.ck {
  position: fixed;
  left: clamp(14px, 3vw, 28px);
  bottom: clamp(14px, 3vw, 28px);
  z-index: 90;
  width: min(384px, calc(100vw - 28px));
  opacity: 0;
  transform: translateY(14px) scale(.985);
  transition: opacity .5s var(--ease), transform .5s var(--ease);
}

.ck--ouvert { opacity: 1; transform: none; }

.ck__boite {
  background: var(--cream);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow-md);
  padding: clamp(18px, 2.4vw, 24px);
}

.ck__titre {
  margin: 0 0 8px;
  font-family: var(--font);
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink);
}

.ck__texte {
  margin: 0 0 16px;
  font-size: .875rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

.ck__actions {
  display: flex;
  gap: 10px;
}

.ck__btn {
  flex: 1 1 0;
  padding: 11px 14px;
  border-radius: 999px;
  font-family: var(--font);
  font-size: .875rem;
  font-weight: 600;
  cursor: pointer;
  transition: transform .3s var(--ease), background .3s var(--ease),
              border-color .3s var(--ease), color .3s var(--ease);
}

.ck__btn--non {
  background: transparent;
  border: 1px solid var(--line-strong);
  color: var(--ink);
}

.ck__btn--non:hover { border-color: var(--ink); background: var(--cream-2); }

.ck__btn--oui {
  background: var(--orange);
  border: 1px solid var(--orange);
  color: #fff;
}

.ck__btn--oui:hover { background: var(--orange-deep); border-color: var(--orange-deep); }

.ck__btn:active { transform: translateY(1px); }

.ck__btn:focus-visible,
.ck__savoir:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 3px;
}

.ck__savoir {
  display: inline-block;
  margin-top: 12px;
  font-size: .8125rem;
  color: var(--ink-mute);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.ck__savoir:hover { color: var(--ink); }

@media (prefers-reduced-motion: reduce) {
  .ck { transition: opacity .2s linear; transform: none; }
}
