/* ==========================================================================
   CMC 6 : couche FX (glassmorphisme + motion poussé, budget perf strict)
   Chargée APRES styles.css. Transform/opacity uniquement (GPU). Tout le
   motion non essentiel tombe sous prefers-reduced-motion.
   Fil de lecture : je comprends > tu es credible > je vois des preuves > je reserve
   ========================================================================== */

/* ---------- Variables FX ---------- */
:root {
  --glass-bg: rgba(255, 255, 255, 0.045);
  --glass-stroke-strong: rgba(255, 255, 255, 0.5);
  --glass-stroke-soft: rgba(255, 255, 255, 0.14);
  --ease-spring: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --page-max: 1440px;        /* largeur max structurante (grand ecran) */
}

/* Bouton WhatsApp flottant (bas-droite), comme sur cmc6.fr.
   Valeurs prises telles quelles sur .link-block.wa / .lottie-animation-3
   du CSS Webflow d'origine (refs-live/webflow.css) : c'est ce lien, pas le
   conteneur autour, qui porte le fond vert flouté. */
.whatsapp-fab {
  position: fixed;
  right: var(--s-4);
  bottom: var(--s-4);
  z-index: 90;
  width: 90px;
  height: 89px;
  display: grid;
  place-items: center;
  border-radius: 100px;
  background-color: #075e5457;
  -webkit-backdrop-filter: saturate(200%) blur(46px);
  backdrop-filter: saturate(200%) blur(46px);
  overflow: hidden;
  transition: background-color 0.25s var(--ease-out);
}
.whatsapp-fab:hover { background-color: #075e54c4; }
.whatsapp-lottie {
  width: 100%;
  height: 100%;
  filter: brightness(200%);
  margin: -26px -25px -30px;
}
.whatsapp-lottie svg { display: block; }
@media (max-width: 767.98px) {
  /* Sous 768px le FAB s'aligne sur le dock de navigation au lieu de flotter
     au-dessus : meme axe horizontal, lui a droite, le dock au centre. Les deux
     forment une seule barre d'actions en bas d'ecran plutot que deux objets
     empiles.
     Le calcul de `bottom` centre le FAB sur l'axe du dock quelles que soient
     leurs hauteurs respectives : il reste juste si l'une des deux bouge.
     Il perd aussi son backdrop-filter (saturate(200%) blur(46px)) au profit
     d'un aplat : un backdrop-filter sur element fixe se recalcule a chaque
     image de defilement, et le fondu bas (.mnav-veil) fait deja le travail de
     separation avec le contenu.
     --mnav-dock-* sont declares avec la couche .mnav, en fin de fichier. */
  .whatsapp-fab,
  .whatsapp-fab:hover {
    --wa-taille: 62px;
    right: var(--s-4);
    bottom: calc(
      var(--mnav-dock-bottom) + (var(--mnav-dock-h) - var(--wa-taille)) / 2
    );
    width: var(--wa-taille);
    height: var(--wa-taille);
    background-color: rgba(7, 94, 84, 0.92);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  /* Marges negatives proportionnelles a la taille du bouton : le Lottie est
     cadre plus large que son cercle, ces valeurs le recentrent. */
  .whatsapp-lottie { margin: -17px -13px -20px; }
}

/* ==========================================================================
   2. Systeme glass reactif
   ========================================================================== */
.glass {
  position: relative;
  overflow: hidden;
  border: none;
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(18px) saturate(165%);
  backdrop-filter: blur(18px) saturate(165%);
  box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.12);
}
.glass::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1.4px;
  background: linear-gradient(
    160deg,
    var(--glass-stroke-strong) 0%,
    var(--glass-stroke-soft) 22%,
    transparent 45%,
    transparent 58%,
    var(--glass-stroke-soft) 80%,
    var(--glass-stroke-strong) 100%
  );
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
          mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
  z-index: 1;
}

/* Carte plate, fidele au live (pas de glassmorphisme : le site source n'a ni
   backdrop-filter ni tilt 3D sur ses cartes, juste des blocs colores a coins
   tres arrondis). Fond beige (--beige, meme teinte que le texte clair du live)
   sur les sections claires, accent crimson au survol. */
.glass-card {
  position: relative;
  border-radius: var(--radius);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  /* C'est CETTE regle qui gagne, pas celle de styles.css : ce fichier est
     charge apres, et a specificite egale la derniere l'emporte. Toute
     surcharge du fond de carte posee dans styles.css est morte.
     --card-voile et --card-opacite sont pilotables depuis /charte. Le voile est
     desormais SOMBRE (--night-deep a 70 %) et le texte de la carte est clair,
     comme le reste du site : c'est le couple qui tient le contraste sur une
     aurore qui va du magenta vif au noir. Si le voile repasse un jour en clair,
     il faut remettre la bascule de variables en texte sombre sur .glass-card,
     les deux vont ensemble. */
  background: color-mix(
    in oklab,
    var(--card-voile, var(--beige, #fff4f0)) calc(var(--card-opacite, 1) * 100%),
    transparent
  );
  box-shadow: 0 18px 40px -30px rgba(36, 36, 90, 0.35);
  transition: transform 0.35s var(--ease-out), box-shadow 0.35s var(--ease-out);
}
.glass-card:hover {
  box-shadow: 0 24px 54px -28px rgba(246, 25, 66, 0.28);
}

/* Lift au survol. NB : sur la home les cartes sont aussi [data-fx], et la regle
   de reveal `.js [data-fx].is-in { transform: none }` (spec 0,3,0) ecrase le
   transform de .glass-card. Il faut donc une regle :hover plus specifique pour
   que le lift prenne. Gate hover+motion : pas de hover collant sur tactile, pas
   de mouvement en reduced-motion. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .js [data-fx].glass-card.is-in:hover { transform: translateY(-5px); }
  .js [data-fx].formula.is-in:hover { transform: translateY(-4px); }
}
.glass-card > * { position: relative; z-index: 1; }

/* Pilule plate (eyebrow, badges) : crimson sur beige, pas de glass */
.glass-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.5rem 1rem;
  border-radius: var(--radius-pill);
  background: var(--beige, #fff4f0);
  font-size: var(--text-label);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ember);
}
/* Dans un hero, la pilule surmonte un titre de grande taille et rien ne les
   separait : elle paraissait collee au sommet des lettres. Meme respiration
   que sur l'accueil, qui utilise .hero-eyebrow et pose deja 16 px. Scope au
   hero : ailleurs, la pilule sert d'etiquette en ligne et n'a pas a pousser
   ce qui la suit. */
.hero .glass-pill {
  margin-bottom: var(--s-4);
}

.glass-pill .dot-live {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ember);
  box-shadow: 0 0 0 0 rgba(246, 25, 66, 0.6);
  animation: pulseLive 2.4s var(--ease-out) infinite;
}
@keyframes pulseLive {
  0% { box-shadow: 0 0 0 0 rgba(246, 25, 66, 0.55); }
  70% { box-shadow: 0 0 0 8px rgba(246, 25, 66, 0); }
  100% { box-shadow: 0 0 0 0 rgba(246, 25, 66, 0); }
}

/* ==========================================================================
   3. Hero cinetique
   ========================================================================== */
/* Hero COMPACT comme le live (mesure : contenu de 542px, section demarre a
   250px sous le nav, la section suivante pointe deja dans le premier ecran
   a 900px de haut). Plus de min-height:100svh centre qui repoussait les
   logos hors champ ("chez toi ça s'arrête avant les logos"). */
.hero {
  min-height: auto;
  padding-top: clamp(6rem, 14vh, 9rem);
  padding-bottom: clamp(1.5rem, 4vh, 2.5rem);
}
.hero-inner { padding-block: 0; }

/* Titre : degrade anime + clip reveal ligne par ligne.
   Le degrade background-clip:text est porte par le SPAN (le texte), pas par
   le h1 : un parent .clip-line en overflow:hidden empeche sinon le degrade
   de remplir les glyphes (texte transparent = invisible). */
.hero h1 { color: var(--cream); }
.hero h1 .clip-line > span {
  background: linear-gradient(100deg, var(--cream) 0%, var(--cream) 42%, #ffd7e1 55%, var(--cream) 70%, var(--cream) 100%);
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
@keyframes titleSheen {
  0%, 100% { background-position: 0% 0; }
  50% { background-position: 100% 0; }
}

.clip-line { display: block; overflow: hidden; padding-bottom: 0.08em; }
/* Auto-play a l'ouverture : robuste meme si motion.js echoue */
.js .clip-line > span {
  display: block;
  animation: lineIn 0.95s var(--ease-spring) both, titleSheen 9s var(--ease-out) infinite;
  animation-delay: calc(var(--i, 0) * 90ms + 150ms), 0s;
}
@keyframes lineIn {
  from { transform: translateY(110%); }
  to { transform: translateY(0); }
}

/* Entree douce des autres blocs du hero */
.js .hero-rise {
  animation: riseIn 0.85s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 90ms + 400ms);
}
@keyframes riseIn {
  from { opacity: 0; transform: translateY(22px); }
  to { opacity: 1; transform: none; }
}

/* Logos clients de confiance sous le hero */
.hero-trust {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.5rem;
  margin-top: var(--s-8);
  color: var(--lavender-dim);
  font-size: 0.9rem;
}
.hero-trust .trust-logos {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.25rem;
  list-style: none;
  padding: 0;
}
.hero-trust .trust-logos a {
  display: inline-flex;
  align-items: center;
  opacity: 1;
  transition: transform 0.25s var(--ease-spring);
}
.hero-trust .trust-logos a:hover { transform: translateY(-2px); }
/* Vrais logos clients en COULEURS d'origine sur fond sombre. Legerement attenues
   au repos, pleins au survol. Elema est un logo NOIR (concu pour fond clair) :
   on l'inverse en blanc pour qu'il soit visible (cf .ti-invert). */
.hero-trust .trust-logos img {
  height: 24px;
  width: auto;
  max-width: 124px;
  object-fit: contain;
  opacity: 0.88;
  transition: opacity 0.25s var(--ease-out);
}
.hero-trust .trust-logos .ti-invert {
  filter: brightness(0) invert(1);
  opacity: 0.78;
}
.hero-trust .trust-logos a:hover img { opacity: 1; }

/* Indice de scroll */
.scroll-cue {
  position: absolute;
  left: 50%;
  bottom: clamp(1.25rem, 4vh, 2.5rem);
  transform: translateX(-50%);
  display: grid;
  justify-items: center;
  gap: 0.5rem;
  color: var(--lavender-dim);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.scroll-cue .line {
  width: 1px;
  height: 38px;
  background: linear-gradient(var(--lavender), transparent);
  animation: cueDrop 2.2s var(--ease-out) infinite;
  transform-origin: top;
}
@keyframes cueDrop {
  0% { transform: scaleY(0); opacity: 0; }
  35% { transform: scaleY(1); opacity: 1; }
  100% { transform: scaleY(1) translateY(12px); opacity: 0; }
}

/* L'ancien "will-change: transform" ici (residu d'un mecanisme de parallaxe
   JS retire) forcait .hero-shapes a creer son propre contexte d'empilement
   (will-change: transform en cree un, exactement comme un vrai transform) :
   ca coupait le calcul de mix-blend-mode:overlay (.hs-blend) de l'arriere-
   plan sombre de .page-aurora, le blend voyait un fond quasi-gris au lieu
   du noir et n'assombrissait presque plus rien (retour operateur : "pas
   assez de zones sombres"). */

/* ==========================================================================
   4. Reveals scroll-driven (data-fx + stagger via --i)
   ========================================================================== */
.js [data-fx] {
  opacity: 0;
  will-change: transform, opacity;
  transition: opacity 0.7s var(--ease-out), transform 0.9s var(--ease-spring), filter 0.7s var(--ease-out);
  /* --pas : intervalle entre deux elements d'une meme cascade. Reste a 80 ms
     partout, sauf la ou une liste demande un rythme plus serre (la FAQ). */
  transition-delay: calc(var(--i, 0) * var(--pas, 80ms));
}
.js [data-fx="up"] { transform: translateY(34px); }
/* Cartes qui se posent : la meme montee, plus un leger retrait d'echelle.
   Utilise par la cascade FAQ, ou les items sont des cartes empilees et non
   des lignes ; le retrait donne le relief d'un jeu qu'on repose. */
.js [data-fx="pile"] { transform: translateY(44px) scale(0.97); }
.js [data-fx="scale"] { transform: scale(0.94); }
.js [data-fx="blur"] { filter: blur(14px); transform: translateY(18px); }
.js [data-fx="left"] { transform: translateX(-40px); }
.js [data-fx="right"] { transform: translateX(40px); }
.js [data-fx].is-in {
  opacity: 1;
  transform: none;
  filter: none;
}

/* --------------------------------------------------------------------------
   Sortie d'ecran (.is-out) : l'element ne se contente plus d'apparaitre une
   fois pour toutes, il repart quand il quitte le haut de la fenetre et
   revient si on remonte.

   Trois differences volontaires avec l'entree :
   1. Plus rapide (0,45 s contre 0,7 s). L'entree est l'evenement, la sortie
      n'est qu'un adieu ; a duree egale on voit surtout un contenu qui traine.
   2. Aucun stagger. Le decalage --i * 80 ms sert a faire arriver une grille
      en cascade ; a la sortie il fait partir les elements en trainee molle.
   3. Sortie en ease-out, jamais en ressort : un ressort renvoie vers une
      position qu'on ne regarde plus, ca se lit comme un tremblement.

   Le parti pris de mouvement est porte par html[data-fx-sortie], pose par
   motion.js, ce qui permet de comparer en direct avec ?fx=.
   -------------------------------------------------------------------------- */
.js [data-fx].is-out {
  opacity: 0;
  transition-delay: 0s;
  transition-duration: 0.45s, 0.5s, 0.45s;
  transition-timing-function: var(--ease-out);
}

/* Le mouvement continue dans le sens de lecture : l'element poursuit sa
   montee au lieu de s'evaporer sur place. */
html.js[data-fx-sortie="suite"] [data-fx].is-out {
  transform: translateY(-28px);
}

/* L'element s'eloigne au lieu de monter : la page gagne une profondeur, le
   contenu lu passe derriere plutot qu'au-dessus. */
html.js[data-fx-sortie="recul"] [data-fx].is-out {
  transform: scale(0.965) translateY(-10px);
}

/* html[data-fx-sortie="fondu"] : aucune regle de transform, l'element s'en
   va en opacite seule. C'est le parti pris le plus sobre, celui qui tient
   quand beaucoup d'elements sortent en meme temps. */

/* Texte qui s'eclaire mot par mot au scroll (statement) */
.kinetic { line-height: 1.18; }
.kinetic .word {
  /* Lisible de base (gris lavande), s'eclaire en cream au scroll */
  color: var(--lavender-dim);
  transition: color 0.5s var(--ease-out);
}
.kinetic .word.lit { color: var(--cream); }
.kinetic .word.accent.lit { color: var(--ember); }

/* ==========================================================================
   5. Boutons magnetiques + glass CTA renforce
   ========================================================================== */
.magnetic { will-change: transform; }
.btn { position: relative; overflow: hidden; }
.btn-primary::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(120px circle at var(--mx, 50%) var(--my, 50%), rgba(246, 25, 66, 0.25), transparent 60%);
  opacity: 0;
  transition: opacity 0.3s var(--ease-out);
}
.btn-primary:hover::after { opacity: 1; }

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

/* ==========================================================================
   6. Marquee glass
   ========================================================================== */
.proof .marquee {
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.proof .marquee-track li {
  position: relative;
  transition: color 0.25s var(--ease-out);
}

/* ==========================================================================
   7. Cartes resultats / projets / engagements en glass
   ========================================================================== */
.results-grid,
.pledges-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--s-6);
}
.result-card .metric {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2.8rem, 6vw, 4.2rem);
  line-height: 1;
  letter-spacing: -0.03em;
  background: linear-gradient(180deg, var(--cream), color-mix(in oklab, var(--ember) 60%, var(--cream)));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  margin-bottom: var(--s-3);
}
.result-card .metric sup { font-size: 0.4em; vertical-align: super; -webkit-text-fill-color: var(--ember); }
.result-card h3 { font-size: 1.15rem; margin-bottom: var(--s-2); }
.result-card p { color: var(--lavender); font-size: 0.98rem; }
.result-card .src {
  display: inline-block;
  margin-top: var(--s-4);
  font-size: var(--text-label);
  letter-spacing: 0.05em;
  color: var(--lavender-dim);
}

/* Carte projet : screenshot + survol. Bandeau en defilement AUTOMATIQUE
   (meme mecanique que .avis-marquee/.marquee-track : boucle par
   duplication des items) EN CSS PAR DEFAUT (fallback sans JS), repris par
   motion.js qui pilote le meme translate3d en JS des que possible pour
   ajouter le glisser/swiper manuel (voir la doc plus bas sur .proj-marquee).
   Un premier essai avait pose ce glisser directement sur overflow-x:auto
   natif : le scroll+touch s'y est revele fragile (tactile qui retombe en
   scroll de page, overflow-y force par le spec CSS qui capturait la
   molette). Piloter le transform nous-memes evite ces pieges structurels.
   Pause au survol/focus : contrairement au bandeau de logos (rien de
   cliquable dedans), ces cartes contiennent un lien "Voir le site" et un
   declencheur d'info-bulle qu'il faut pouvoir viser sans que la bande
   continue de glisser dessous. */
.proj-marquee .marquee-track {
  align-items: stretch;
  gap: var(--s-6);
  animation-duration: 50s;
}
/* Sur mobile, les cartes restent a leur largeur minimale (clamp 260px) alors
   que le cadre visible retrecit a la largeur de l'ecran : une seule carte
   tient a l'ecran a la fois au lieu de 3-4 sur desktop. A vitesse (px/s)
   egale, la meme duree de 50s pour toute la piste fait donc defiler
   quasiment l'intégralite du contenu visible toutes les ~8s, sans la
   respiration qu'offrent les cartes voisines sur desktop (constate par
   l'operateur : "ca defile beaucoup trop vite sur mobile"). Et comme le
   survol n'existe pas au doigt (seul moyen de mettre en pause), la piste
   doit tourner assez lentement pour rester lisible sans jamais s'arreter. */
@media (max-width: 640px) {
  .proj-marquee .marquee-track {
    /* Deja monte une fois a 110s, retour operateur : encore trop rapide.
       200s ici pour matcher pDurationMs dans motion.js (le glisser au
       doigt reste dispo pour avancer plus vite si on le souhaite). */
    animation-duration: 200s;
  }
  /* Bord a bord du cadre de verre (demande operateur du 13/09) : les cartes
     semblent entrer et sortir sous la bordure du bloc. On annule la marge du
     .container (meme clamp que styles.css) et le coussin du cadre, comme
     .cta-band. Le width/max-width de .marquee (styles.css) est ecrase ici :
     ce fichier se charge apres, a specificite egale il gagne. Le cadre de
     verre est en overflow: clip, la bande s'arrete donc a sa bordure. */
  .proj-marquee {
    width: calc(100% + 2 * (clamp(1.25rem, 4vw, 2.5rem) + var(--glass-pad-x, 0px)));
    max-width: none;
    margin-inline: calc(-1 * (clamp(1.25rem, 4vw, 2.5rem) + var(--glass-pad-x, 0px)));
  }
}
.proj-marquee .marquee-track:hover,
.proj-marquee .marquee-track:focus-within {
  animation-play-state: paused;
}
.proj-marquee::before,
.proj-marquee::after {
  content: none;
}
.proj-marquee {
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
  /* Glisser/swiper manuel (motion.js) : chaque carte est translatee une a
     une en JS (plus de piste unique : Safari iOS ne dessinait pas la partie
     lointaine d'une piste de 4 000 px, 13/09/2026), plutot qu'un overflow-x
     natif (dont le scroll+touch s'est deja revele fragile ici). pan-y
     laisse le scroll vertical passer normalement ; motion.js verrouille
     l'axe horizontal lui-meme des qu'un geste s'avere plus horizontal que
     vertical. */
  cursor: grab;
  touch-action: pan-y;
}
.proj-marquee.is-dragging {
  cursor: grabbing;
}
.proj-marquee.is-dragging .proj-card {
  pointer-events: none;
}
.proj-card {
  padding: 0;
  flex: 0 0 clamp(260px, 32vw, 360px);
}
.proj-card .shot {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border-radius: var(--radius) var(--radius) 0 0;
}
.proj-card .shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.02);
  transition: transform 0.7s var(--ease-spring);
}
.proj-card:hover .shot img { transform: scale(1.08); }
.proj-card .shot::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 50%, rgba(13, 9, 20, 0.65));
}
.proj-card .proj-body { padding: clamp(1.25rem, 3vw, 1.75rem); }
.proj-card .proj-body h3 { font-size: 1.25rem; margin-bottom: 0.35rem; }
.proj-card .proj-meta { color: var(--lavender-dim); font-size: 0.85rem; margin-bottom: var(--s-3); }
.proj-card .proj-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-weight: 600;
  color: var(--cream);
  text-decoration: none;
}
.proj-card .proj-link span { transition: transform 0.3s var(--ease-spring); }
.proj-card:hover .proj-link span { transform: translate(3px, -3px); }

/* ==========================================================================
   8. Accordeon FAQ glass
   ========================================================================== */
.faq-glass { display: grid; gap: var(--s-3); max-width: 880px; }
.faq-glass details {
  border-radius: var(--radius);
  padding: 0 clamp(1.1rem, 3vw, 1.6rem);
  /* Meme materiau que les autres surfaces, pilote par le meme reglage. */
  background: color-mix(
    in oklab,
    var(--night-deep) calc(var(--bloc-opacite, 0.7) * 100%),
    transparent
  );
  /* backdrop-filter retire : il y a jusqu'a sept items empiles, chacun aurait
     recalcule son flou a chaque image de defilement pour un gain invisible
     derriere un fond deja opaque a 70 %. */
  border: 1px solid var(--lavender-15);
  box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.05);
  transition: border-color 0.25s var(--ease-out);
}
.faq-glass details:hover,
.faq-glass details[open] {
  border-color: var(--lavender-30);
}
.faq-glass summary:focus-visible {
  outline: 2px solid var(--ember);
  outline-offset: -4px;
  border-radius: var(--radius);
}
/* Pendant l'animation seulement : la hauteur est bornee par le script, il faut
   masquer ce qui depasse. Hors animation, aucun overflow n'est impose, ce qui
   evite de couper un focus ou une selection. */
.faq-glass details.is-animating > *:not(summary) {
  overflow: hidden;
}
.faq-glass summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s-4);
  padding: clamp(1rem, 2.5vw, 1.35rem) 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.1rem;
}
.faq-glass summary::-webkit-details-marker { display: none; }
.faq-glass summary .chev {
  flex: none;
  width: 22px;
  height: 22px;
  transition: transform 0.35s var(--ease-spring);
  color: var(--ember);
}
.faq-glass details[open] summary .chev { transform: rotate(45deg); }
.faq-glass details p {
  color: var(--lavender);
  padding-bottom: clamp(1rem, 2.5vw, 1.35rem);
  max-width: 68ch;
}

/* ==========================================================================
   9. Rythme de sections + accents typo
   ========================================================================== */
.section-head { max-width: 60ch; margin-bottom: clamp(2.5rem, 6vh, 4.5rem); }
.section-head h2 { font-size: var(--text-h2); margin-block: var(--s-3) var(--s-4); }
.section-head p { color: var(--lavender); font-size: var(--text-lead); }

/* Numeral geant en filigrane de section */
.big-numeral {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(9rem, 26vw, 22rem);
  line-height: 0.8;
  letter-spacing: -0.04em;
  color: transparent;
  -webkit-text-stroke: 1px var(--lavender-15);
  pointer-events: none;
  user-select: none;
}

/* ==========================================================================
   10. Responsive + reduced-motion
   ========================================================================== */
@media (max-width: 720px) {
  .glass-card { transform: none !important; }
  .hero h1 { animation-duration: 12s; }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-progress,
  .scroll-cue,
  .hero h1,
  .dot-live { animation: none !important; }
  .hero h1 { background-position: 0 0; }
  .clip-line > span,
  .hero-rise,
  .js [data-fx] {
    transform: none !important;
    opacity: 1 !important;
    filter: none !important;
    transition: none !important;
    animation: none !important;
  }
  .glass-card { transform: none !important; }
  .kinetic .word { color: var(--cream); }
  .proj-card .shot img { transform: none !important; }
}

/* ==========================================================================
   FX v2 : rouleaux, volet, séquence méthode. Toujours transform/opacity,
   tout tombe sous reduced-motion / tactile.
   ========================================================================== */

/* ---------- Compteurs a rouleaux (odometre) ---------- */
.roll { display: inline-flex; align-items: center; font-variant-numeric: tabular-nums; }
.roll .col {
  display: inline-block;
  height: 1em;
  overflow: hidden;
  vertical-align: baseline;
}
.roll .reel {
  display: flex;
  flex-direction: column;
  transform: translateY(0);
  transition: transform 1.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.roll .reel span { height: 1em; line-height: 1; display: block; text-align: center; }
/* Chaque glyphe porte le degrade (overflow:hidden empeche le clip parent) */
.result-card .metric.is-rolled .roll-aff,
.result-card .metric.is-rolled .reel span {
  background: linear-gradient(180deg, var(--cream), color-mix(in oklab, var(--ember) 60%, var(--cream)));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.result-card .metric.is-rolled .roll-aff.suffix { -webkit-text-fill-color: var(--ember); }

/* L'ancien reveal "en volet" (clip-path pilote par [data-fx] + IntersectionObserver
   -> classe .is-in) supposait une carte qui n'apparait qu'une fois au scroll. Les
   cartes de .proj-marquee defilent en boucle continue (sans data-fx, comme les
   avis) : une carte peut re-entrer dans le champ visible plusieurs fois, et
   .is-in n'est de toute facon plus jamais posee ici -> l'image restait clippee
   a 0% de hauteur pour toujours (constate : cartes visuellement vides). Retire,
   pas remplace : la transition transform (scale au survol) suffit. */

/* ---------- Sequence epinglee Methode 21 (desktop) ---------- */
.method-rail {
  position: relative;
  height: 2px;
  margin: var(--s-12) 0 var(--s-8);
  background: var(--lavender-15);
  border-radius: 2px;
}
.method-rail .rail-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--fill, 8%);
  background: linear-gradient(90deg, var(--shape-periwinkle), var(--ember));
  border-radius: 2px;
  transition: width 0.25s var(--ease-out);
}
.method-rail .rail-step {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  display: grid;
  justify-items: center;
  gap: 0.5rem;
  font-size: var(--text-label);
  color: var(--lavender-dim);
  letter-spacing: 0.05em;
  white-space: nowrap;
}
.method-rail .rail-step::before {
  content: "";
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--night-raised);
  box-shadow: inset 0 0 0 1.5px var(--lavender-30);
  transition: background-color 0.3s var(--ease-out), box-shadow 0.3s var(--ease-out), transform 0.3s var(--ease-spring);
}
.method-rail .rail-step span { transform: translateY(2px); }
.method-rail .rail-step.done::before { background: var(--ember); box-shadow: inset 0 0 0 1.5px var(--ember), 0 0 16px var(--ember-glow); transform: scale(1.15); }
.method-rail .rail-step.done { color: var(--cream); }

.phase-card {
  transition: transform 0.5s var(--ease-spring), box-shadow 0.5s var(--ease-out), opacity 0.5s var(--ease-out);
}
.phase-card .phase-num {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1rem;
  letter-spacing: 0.05em;
  color: var(--ember);
}

/* La sequence Methode n'est plus epinglee : section normale, 3 phases visibles
   d'emblee, a egalite (plus de dim ni de scroll-jacking). */

/* ==========================================================================
   Reduced-motion / tactile : on neutralise toute la couche FX v2
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .proj-card .shot img { clip-path: none !important; transition: none !important; }
  .roll .reel { transition: none !important; }
  .method-seq { height: auto !important; }
  .method-seq .method-pin { position: static !important; min-height: 0 !important; }
  .method-seq .phase-card { opacity: 1 !important; transform: none !important; }
  .method-rail .rail-fill { width: 100% !important; }
}
@media (hover: none) {
  .method-seq { height: auto; }
  .method-seq .method-pin { position: static; min-height: 0; }
  .method-seq .phase-card { opacity: 1; transform: none; }
}

/* Rail Methode : sequence epinglee desktop seulement */
@media (max-width: 860px) { .method-rail { display: none; } }

/* ==========================================================================
   HERO : bandeau SOMBRE PLEIN ECRAN, bord a bord (pas de coque encadree/
   arrondie a la MonaHub : le live n'a ni gutter ni border-radius autour du
   hero, cf. .section-ultra-gradients/.ultra-gradient-wrapper dans
   webflow.css, qui couvrent width/height:100%).
   ========================================================================== */
/* Body transparent : le fond vient de .page-aurora (fixe, pose dans
   Layout.astro), pas d'un aplat --night ici, sinon il masquerait l'aurore. */
.shell-page {
  background-color: transparent;
}

.hero-shell {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  width: 100%;
  margin: 0;
  border-radius: 0;
  background: transparent;
  /* PAS de min-height:100svh : ca laissait un vide sous le hero desormais
     compact (contenu ~450-550px), avant la section suivante. Le live n'a
     pas de zone morte ici (mesure : section suivante pointe des 900px). */
}

/* .shell-bg ne porte plus le fond du hero (deplace dans .page-aurora) : ne
   reste utile que pour les pages qui y placent encore .hero-metal (shader). */
.hero-shell .shell-bg { position: absolute; inset: 0; z-index: 0; }

/* ==========================================================================
   Nav : pilule flottante CLASSIQUE (pas de notch/morph, comme sur cmc6.fr :
   la pilule reste identique en haut de page et au scroll, seule une legere
   ombre/opacite se renforce, cf. .nav.scrolled dans styles.css).
   ========================================================================== */
.nav {
  position: fixed;
  inset-inline: 0;
  top: var(--s-4, 16px);
  z-index: 96;
  display: flex;
  justify-content: center;
  padding-inline: 1rem;
  pointer-events: none;
}
.nav-pill {
  pointer-events: auto;
  width: min(900px, calc(100% - 32px));
  max-width: 900px;
}

/* Logo de marque : un seul fichier (couleur), la nav est toujours sur fond
   sombre (coque hero ou pilule glass), pas besoin de variante noire. */
.nav-logo {
  position: relative;
  display: inline-flex;
  height: 31px;
}
.nav-logo .brand-logo {
  display: block;
  height: 31px;
  width: auto;
}
.nav-logo .logo-black { display: none; }
@media (max-width: 767.98px) {
  .nav-logo { height: 26px; }
  .nav-logo .brand-logo { height: 26px; }
}

/* ==========================================================================
   Navbar : disposition 3 zones equilibree + liens raffines (classe)
   logo a gauche | liens parfaitement centres | CTA a droite
   ========================================================================== */
@media (min-width: 768px) {
  .nav-pill {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: var(--s-6);
  }
  .nav-pill .nav-logo { grid-column: 1; justify-self: start; margin: 0; }
  .nav-pill .nav-links { grid-column: 2; justify-self: center; }
  .nav-pill .nav-cta  { grid-column: 3; justify-self: end; }
}

/* Desktop ETROIT (761-1080px) : 5 liens + logo + CTA deviennent serres et le
   CTA debordait sur 2 lignes. On compacte (gaps, taille, on cache la fleche)
   sans passer au menu burger (la nav du bas est pour le pouce mobile). */
@media (min-width: 768px) and (max-width: 1080px) {
  .nav-pill { gap: var(--s-2); padding-left: 1rem; }
  .nav-links { gap: clamp(0.25rem, 0.7vw, 0.8rem); }
  .nav-links a { font-size: 0.85rem; padding: 0.3rem 0; letter-spacing: 0; }
  .nav-cta .btn { padding: 0.5rem 0.85rem; font-size: 0.85rem; gap: 0; }
  .nav-cta .cta-arrow { display: none; }
  .nav-logo { height: 27px; }
  .nav-logo .brand-logo { height: 27px; }
}

/* Liens centres + INDICATEUR GLISSANT (pastille qui glisse sous le lien
   survole et se gare sur le lien actif quand la souris quitte la nav).
   Position/largeur de .nav-indicator pilotees par motion.js. */
.nav-links {
  position: relative;
  gap: clamp(0.6rem, 2.2vw, 2.1rem);
}
.nav-indicator {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.16);
  pointer-events: none;
  z-index: 0;
  transition: transform 0.2s var(--ease-out), width 0.2s var(--ease-out), opacity 0.15s var(--ease-out);
  opacity: 0;
}
.nav-indicator.is-visible { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .nav-indicator { transition: opacity 0.15s var(--ease-out); }
}
.nav-links a {
  position: relative;
  z-index: 1;
  padding: 0.3rem 0.15rem;
  border-radius: 0;
  background: none;
  font-weight: 500;
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  color: var(--lavender);
  transition: color 0.3s var(--ease-out);
}
.nav-links a:hover,
.nav-links a:focus-visible { color: var(--cream); background: none; } /* tue le fond-pilule de base (carre blanc) */
.nav-links a[aria-current="page"] { color: var(--cream); }

/* Logo : leger feedback au survol */
.nav-logo { transition: opacity 0.3s var(--ease-out); }
.nav-logo:hover { opacity: 0.82; }

/* CTA pilule cream + fleche qui avance au survol */
.nav-cta .btn { padding: 0.62rem 1.4rem; font-weight: 600; letter-spacing: 0.01em; gap: 0.45em; }
.cta-arrow { display: inline-block; transition: transform 0.35s var(--ease-spring); }
.nav-cta .btn:hover .cta-arrow { transform: translateX(4px); }

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

/* ==========================================================================
   Le noir plat (.ultra-gradient-wrapper { background-color:#1b1b1b } sur le
   live) vit desormais sur .page-aurora (Layout.astro, calque fixe unique),
   pas ici : .hero-shell reste transparent pour laisser l'aurore fixe visible.
   ========================================================================== */
.hero-metal { position: absolute; inset: 0; }

/* ==========================================================================
   PAGES INTERNES (.page-inner) : meme navbar a notch + hero shader que la home.
   Le hero-shell interne est un BANDEAU plus court que la home sur desktop, mais
   PLEIN ECRAN sur mobile pour que le notch du bas se creuse dans le shader (pas
   dans le contenu). h1 a une echelle de page interne (plus petit que l'accueil).
   ========================================================================== */
.page-inner .hero-shell {
  min-height: clamp(360px, 56svh, 580px);
}
.page-inner .hero h1 {
  font-size: clamp(2.4rem, 3vw + 1.4rem, 3.7rem);
}
@media (max-width: 767.98px) {
  /* Bandeau (pas plein ecran) sur mobile : sur une page de contenu, un hero qui
     remplit l'ecran enterre le contenu. On garde un hero dominant mais qui laisse
     le contenu depasser sous le pli (affordance de scroll). Les heros riches
     (offres, audit) grandissent au-dela pour tenir leur contenu. Contrepartie
     assumee : au repos le notch du bas se creuse dans le contenu sombre (discret)
     plutot que dans le shader ; des qu'on scrolle il flotte de toute facon. */
  .page-inner .hero-shell {
    min-height: clamp(440px, 72svh, 720px);
  }
}

/* Le live montre la ligne "En ligne depuis 2016 : logos" DANS le hero (mesure
   getBoundingClientRect : top:700, section hero finit a 792 sur viewport 900),
   en plus du marquee plus bas. display:none retire (round 3 s'est trompe). */
.hero-trust {
  justify-content: center;
  margin-top: var(--s-8);
}

/* Les rangees crimson degradees ont ete retirees (demande operateur : le bloc
   FAQ n'etait pas beau). Elles empilaient trois a sept bandes rouges pleines,
   qui parlaient plus fort que le bouton principal de la page et juraient avec
   les surfaces sombres translucides adoptees partout ailleurs.
   L'accordeon reprend maintenant le materiau des cartes, defini dans
   styles.css, et l'accent ne sert plus qu'au signe d'ouverture.
   Note de cascade : cette regle avait ete posee ICI expres, en fin du dernier
   fichier charge, pour recouvrir une regle plus haute. La retirer suffit donc,
   il n'y a rien a reecrire ailleurs. */

/* ==========================================================================
   FIDELITE LIVE round 4 : nav logo hors pilule, bande CMC Flow, footer aurore.
   Pose en fin de styles-fx.css (dernier charge) pour gagner la cascade.
   ========================================================================== */

/* --- Nav : logo CMC a gauche HORS de la pilule (cf. vp-0 du live) --- */
.nav-bar {
  pointer-events: none;
  /* Meme formule que .glass-frame/.marquee (retour operateur : "rien sur le
     site ne doit etre plus large que le cadre de verre") - le max-width de
     1240px fixe ne suffisait pas a le garantir a toutes les largeurs
     d'ecran (la gouttiere du cadre peut le retrecir en dessous de 1240). */
  width: calc(100% - (var(--glass-gutter) * 2) - 32px);
  max-width: calc(var(--glass-max-width) - 32px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}
@media (min-width: 768px) {
  .nav-pill {
    width: auto;
    max-width: none;
    display: flex;
    align-items: center;
    gap: clamp(1rem, 2.5vw, 2.4rem);
    padding-inline: 1.8rem 0.5rem;
  }
}
@media (max-width: 767.98px) {
  .nav-bar { width: 100%; }
}

/* ==========================================================================
   Style "FH3c" devenu le style PAR DEFAUT de la navbar (choisi par
   l'operateur apres exploration, cf. historique git pour les variantes
   ecartees : F, G, FH1/2/4/5/6, FH3/3a/3b/3d). Notch compact centre, logo
   integre, pose sur une bande de flou degrade (#navblur) plutot qu'un
   flou applique au notch lui-meme. Toutes les valeurs en variables CSS
   --navfh-* : reglables en direct via le panneau ?navtune=1 (nav-tune.js),
   qui reste dispo en permanence pour retoucher ces tokens sans deploiement.
   ========================================================================== */
:root {
  --navfh-rest-fill: 0;
  --navfh-rest-border: 0;
  --navfh-scroll-fill: 0.52;
  --navfh-scroll-border: 0;
  --navfh-rest-blur: 0px;
  --navfh-scroll-blur: 12px;
  --navfh-transition: 2s;
  --navfh-band-height: 130px;
  --navfh-band-falloff: 52%;
  --navfh-radius: 26px;
}

.nav-bar { justify-content: center; width: auto; max-width: none; }
.nav { top: 8px; }
/* Retour visuel plus marque que le simple changement de couleur (blanc vs
   creme etaient quasi identiques a l'oeil, cf. --navfh-rest-fill:0 qui ne
   laisse plus de fond derriere pour faire ressortir la couleur seule) : un
   petit chip qui apparait derriere le lien, plus fort et persistant sur la
   page active. Transition rapide (0.25s), independante de --navfh-transition
   qui ne gouverne que le fondu repos/scroll de la navbar entiere. */
.nav-links a {
  position: relative;
  z-index: 1;
  font-size: 0.82rem;
  color: #fff;
  border-radius: 999px;
  transition: color 0.25s var(--ease-out);
  /* Le padding herite (0.3rem 0.15rem, ligne 771) etait calibre pour un
     indicateur glissant jamais implemente a l'epoque : le fond posait
     directement sur le lien, avec ce padding ca collait a l'ecriture sur
     les cotes. Corrige ici, a la source. Le fond lui-meme vient maintenant
     de .nav-indicator (pastille partagee pilotee par motion.js), plus d'un
     background pose lien par lien. */
  padding: 0.5rem 0.85rem;
}
.nav-links a:hover,
.nav-links a:focus-visible,
.nav-links a[aria-current="page"] {
  color: var(--cream);
}
.nav-links a[aria-current="page"] {
  font-weight: 700;
}
.nav-pill-logo {
  display: inline-flex;
  color: #fff;
  text-decoration: none;
  font-weight: 800;
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  margin-right: 14px;
  padding-right: 14px;
  border-right: 1px solid rgba(255, 255, 255, 0.15);
  transition: opacity 0.25s var(--ease-out);
}
.nav-pill-logo:hover { opacity: 0.75; }
.nav-pill,
#navblur {
  transition: background-color var(--navfh-transition) var(--ease-out),
    border-color var(--navfh-transition) var(--ease-out),
    backdrop-filter var(--navfh-transition) var(--ease-out),
    box-shadow var(--navfh-transition) var(--ease-out);
}
.nav-pill {
  background: rgba(10, 7, 16, var(--navfh-rest-fill));
  border: 1px solid rgba(255, 255, 255, var(--navfh-rest-border));
  border-radius: var(--navfh-radius);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: none;
  padding: 0.5rem 0.5rem 0.5rem 1.2rem;
}
#navblur {
  display: block;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--navfh-band-height);
  z-index: 40;
  pointer-events: none;
  backdrop-filter: blur(var(--navfh-rest-blur));
  -webkit-backdrop-filter: blur(var(--navfh-rest-blur));
  mask-image: linear-gradient(to bottom, black 0%, black var(--navfh-band-falloff), transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, black 0%, black var(--navfh-band-falloff), transparent 100%);
}
.nav.scrolled .nav-pill {
  background: rgba(10, 7, 16, var(--navfh-scroll-fill));
  border-color: rgba(255, 255, 255, var(--navfh-scroll-border));
  /* Neutralise l'ombre du style de base du site (.nav.scrolled .nav-pill
     plus haut dans ce fichier / styles.css, box-shadow sans transition) :
     elle apparaissait d'un coup, hors du look "sans cadre". */
  box-shadow: none;
}
#navblur.is-scrolled {
  backdrop-filter: blur(var(--navfh-scroll-blur));
  -webkit-backdrop-filter: blur(var(--navfh-scroll-blur));
}
.nav-cta .btn-primary {
  background: transparent;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.55);
  /* background/color/border : fondu lent, cale sur le rythme repos/scroll
     de toute la navbar. transform/box-shadow : rapides, c'est le retour
     de survol (herite normalement de .btn en base, mais la transition
     ci-dessus etant plus specifique elle les ecrasait sans ces deux lignes
     - le survol devenait mou). */
  transition: background-color var(--navfh-transition) var(--ease-out),
    color var(--navfh-transition) var(--ease-out),
    border-color var(--navfh-transition) var(--ease-out),
    transform 0.3s var(--ease-out),
    box-shadow 0.3s var(--ease-out);
}
/* Reprend le comportement du CTA "On en discute ?" du hero de cmc6.fr :
   fond plein rouge de marque, texte blanc, leger effet loupe, transition
   lente et arrondie (mesure sur le site de base). Meme rendu qu'on soit
   au repos ou scrolle. */
.nav-cta .btn-primary:hover,
.nav.scrolled .nav-cta .btn-primary:hover {
  background: #f61942;
  color: #fff;
  border-color: #f61942;
  transform: scale(1.1);
  box-shadow: none;
  transition: background-color 1s cubic-bezier(0, 0.926, 0.25, 1),
    color 1s cubic-bezier(0, 0.926, 0.25, 1),
    border-color 1s cubic-bezier(0, 0.926, 0.25, 1),
    transform 1s cubic-bezier(0, 0.926, 0.25, 1);
}
.nav.scrolled .nav-cta .btn-primary {
  background: #fff;
  color: #171022;
  border-color: transparent;
}

/* H : sans cadre, flou degrade - gardee de cote par l'operateur ("sous le
   coude") au cas ou, activable via le panneau ?navswitch=1. Reinitialise
   ce que le style par defaut ci-dessus a change (centrage/notch) ; utilise
   le "CMC" texte comme le style par defaut (le logo image a ete retire). */
html.nav-style-h .nav-bar { justify-content: space-between; width: min(1240px, calc(100% - 32px)); max-width: none; }
html.nav-style-h .nav-pill {
  background: transparent;
  border: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: none;
  gap: 2.4rem;
  padding: 0;
}
html.nav-style-h .nav-pill-logo {
  margin-right: 0;
  padding-right: 0;
  border-right: none;
}
html.nav-style-h .nav-links { gap: 2.2rem; }
html.nav-style-h .nav-links a { font-size: 0.85rem; letter-spacing: 0.06em; color: #fff; }
html.nav-style-h .nav-cta .btn {
  background: transparent;
  border: none;
  color: #fff;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 4px;
}
html.nav-style-h #navblur {
  height: 150px;
  backdrop-filter: blur(30px);
  -webkit-backdrop-filter: blur(30px);
  mask-image: linear-gradient(to bottom, black 0%, black 40%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, black 0%, black 40%, transparent 100%);
}

/* --- Bande CMC Flow (live : bande sombre pleine largeur du cadre) --- */
.cmcflow-band {
  position: relative;
  background: rgba(18, 13, 28, 0.72);
  margin: var(--section) -30px 0;
  padding: clamp(2.5rem, 5vw, 4rem) clamp(1.5rem, 5vw, 4.5rem);
  display: grid;
  gap: 1rem;
  justify-items: start;
}
.cmcflow-band-new {
  color: var(--cream);
  font-size: 0.9rem;
  opacity: 0.85;
}
.cmcflow-band h2 {
  color: #fff;
  font-size: clamp(1.5rem, 2.4vw, 2.2rem);
  margin: 0;
}
@media (max-width: 767.98px) {
  .cmcflow-band { margin-inline: -5px; }
}

/* --- Footer : l'aurore s'eteint en fondu long, le texte se lit sur du sombre ---
   Avant le 2026-09-10 : `.footer { background: transparent }` laissait l'aurore
   traverser toute la grille, et seule la barre du bas posait un aplat gris
   (`--footer-bg`) via .footer-bottom::before. Le texte creme s'en sortait ; la
   signature en rouge --ember, elle, disparaissait quand l'aurore virait au rouge
   sous elle. Contraste mesure alors : 1,4:1.

   Le voile s'arrete a 80 % d'opacite, pas 100 : la couleur reste devinable en
   bas de page. Il commence 420 px AU-DESSUS du footer pour que la transition ne
   se voie pas, d'ou le ::after qui deborde et le border-top retire (il tracait
   une ligne nette au milieu du fondu).

   Verifie sur six instants de l'animation (elle dure 26 s) : au pire moment,
   4,3:1 pour le rouge de la signature (seuil 3 en grand texte) et 4,6:1 pour les
   intertitres de colonnes (seuil 4,5). */
.footer {
  background: rgba(16, 11, 24, 0.80);
  overflow: visible;
}
.footer::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -420px;
  height: 420px;
  background: linear-gradient(to bottom,
    rgba(16, 11, 24, 0) 0%,
    rgba(16, 11, 24, 0.30) 45%,
    rgba(16, 11, 24, 0.62) 78%,
    rgba(16, 11, 24, 0.80) 100%);
  pointer-events: none;
  z-index: 0;
}

/* ==========================================================================
   HERO fidele vp-0 (live) : eyebrow au-dessus du titre, UN CTA pilule
   blanche pleine, lead relegue en petit sous le CTA (le live n'a pas de
   paragraphe, on garde le contenu PME mais discret).
   ========================================================================== */
.hero-eyebrow {
  display: block;
  color: var(--cream);
  font-size: 0.95rem;
  opacity: 0.9;
  margin-bottom: var(--s-4);
}
.hero-cta-white {
  background: #fff;
  color: #171022;
  border-radius: 999px;
  padding: 0.85rem 1.9rem;
  font-weight: 600;
  font-size: 0.95rem;
}
/* Meme comportement que .btn-primary : fond rouge de marque + loupe au
   survol, mesure sur le "On en discute ?" du hero de cmc6.fr. */
.hero-cta-white:hover {
  background: var(--ember);
  color: #fff;
  transform: scale(1.1);
  transition: background-color 1s cubic-bezier(0, 0.926, 0.25, 1),
    color 1s cubic-bezier(0, 0.926, 0.25, 1),
    transform 1s cubic-bezier(0, 0.926, 0.25, 1);
}
.hero-lead-discret {
  margin-top: var(--s-6);
  margin-bottom: 0;
  max-width: 54ch;
  font-size: 0.98rem;
  line-height: 1.6;
  opacity: 0.68;
}
/* le titre respire davantage (le live a beaucoup d'air autour) */
.hero-content > h1 { margin-bottom: var(--s-4); }

/* ==========================================================================
   Lead PME reloge hors du hero (demande operateur : "la ligne En ligne
   depuis 2016 s'enleve" + "la phrase est bien mais trop compacte, ailleurs,
   qu'elle donne envie de la lire"). Section dediee, aeree, grande taille de
   lecture, premiere ligne mise en valeur (::first-line, resiste a toute
   edition du texte via le portail).
   ========================================================================== */
.hero-lead-section {
  /* Aligne sur le rythme --section (mesure live) plutot qu'un padding
     propre, sinon le texte flotte trop loin du haut du cadre de verre. */
  padding-block: var(--section);
}
.hero-lead-text {
  max-width: 44ch;
  margin-inline: auto;
  text-align: center;
  font-size: clamp(1.15rem, 1.1vw + 0.75rem, 1.5rem);
  line-height: 1.75;
  letter-spacing: 0.005em;
  color: var(--lavender);
}
.hero-lead-text::first-line {
  color: var(--cream);
  font-weight: 600;
}

/* ==========================================================================
   NAVIGATION MOBILE (< 768px) : dock fixe en bas + bottom sheet
   --------------------------------------------------------------------------
   Remplace la pilule ancree en haut (morph clip-path + filter) : liens hors
   zone de pouce et morph juge pas fluide sur telephone reel.

   CONTRAT D'ANIMATION : dans toute cette couche, SEULES transform et opacity
   sont animees. Aucun width/height/max-height/top/bottom/left/right/margin/
   padding/clip-path/filter/backdrop-filter/box-shadow/border-radius/
   background-color anime. Toute regression sur ce point ramene la saccade.

   Asymetrie ouverture/fermeture : la duree LENTE est posee sur la regle
   .is-open (etat cible a l'ouverture), la RAPIDE sur la regle de base (etat
   cible a la fermeture). Le navigateur prend toujours la transition de
   l'etat vers lequel il va.

   Empilement : .mnav-veil 88 < .whatsapp-fab 90 < .mnav-scrim 92 <
   .mnav-sheet 94 < .mnav-dock 96. .mnav lui-meme ne porte NI transform NI
   filter NI opacity : il ne doit pas devenir bloc conteneur de ses enfants
   position:fixed.
   ========================================================================== */
:root {
  --mnav-dock-h: 52px;
  --mnav-dock-w: 150px;
  /* Repose sur le home indicator sans le toucher ; 16px de plancher sur les
     appareils sans encoche (env() vaut alors 0). */
  --mnav-dock-bottom: max(16px, calc(12px + env(safe-area-inset-bottom, 0px)));
  /* Hauteur totale occupee en bas de l'ecran par le dock (degagement du
     contenu, coussin bas du panneau). */
  --mnav-dock-clear: calc(var(--mnav-dock-bottom) + var(--mnav-dock-h));

  /* Courbes propres au panneau. --ease-out du site
     (cubic-bezier(0.16, 1, 0.3, 1)) est une deceleration tres agressive :
     mesure au rAF, le panneau parcourait 92% de sa course en 180ms puis
     rampait. A l'ouverture ca vidait le mouvement de sa substance (le
     panneau etait arrive avant que la cascade des liens ne demarre), a la
     fermeture ca le rendait carrement invisible - les deux signalees par
     l'operateur ("plus complete" / "j'en vois pas").
     Ouverture : courbe de panneau coulissant (depart franc, vitesse tenue au
     milieu, arrivee amortie), la course reste lisible sur toute sa duree.
     Fermeture : acceleration, le panneau part doucement puis file - c'est ce
     qui rend une sortie perceptible plutot qu'escamotee. */
  --mnav-ease-open: cubic-bezier(0.32, 0.72, 0, 1);
  --mnav-ease-close: cubic-bezier(0.4, 0, 1, 1);
}

/* Desktop : rien. Le header .nav gouverne, cette couche n'existe pas. */
.mnav { display: none; }

@media (max-width: 767.98px) {
  /* Le logo et la nav quittent totalement le haut de l'ecran. */
  .nav { display: none; }
  /* Bande de flou haute : elle servait le header, qui n'est plus la. Son
     backdrop-filter etait recalcule a chaque image de scroll. Conservee pour
     le desktop (etat scrolle de la navbar), coupee ici. */
  #navblur { display: none; }

  .mnav { display: block; }

  /* Verrou de scroll pendant l'ouverture (classe posee par script.js). */
  html.nav-locked,
  html.nav-locked body {
    overflow: hidden;
  }
  html.nav-locked {
    overscroll-behavior: none;
  }

  /* Le footer ne doit pas finir sous le dock (liens legaux inatteignables). */
  .footer {
    padding-bottom: calc(var(--mnav-dock-clear) + 16px);
  }

  /* ---------- Fondu givre de bas de page (reprend #navblur, en bas) --------
     Rendu givre demande par l'operateur, en version contenue : rayon 10px au
     lieu des 12px de l'ancien #navblur, et bande raccourcie a 140px. Le
     mask-image fait disparaitre le flou progressivement vers le haut, sinon
     la zone floutee se termine par une arete franche en travers de l'ecran.
     Il agit aussi sur le gradient, mais dans le meme sens (les deux
     s'effacent vers le haut) : les stops ci-dessous integrent deja cette
     multiplication.
     Cout assume : contrairement au gradient seul, un backdrop-filter sur
     element fixe se recalcule a chaque image de defilement. C'est le
     compromis retenu apres arbitrage, le panneau du menu restant lui en
     aplat opaque pour ne pas cumuler les deux. Jamais anime. */
  .mnav-veil {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: 140px;
    z-index: 88;
    pointer-events: none;
    background: linear-gradient(
      to top,
      rgba(13, 8, 21, 0.95) 0%,
      rgba(13, 8, 21, 0.72) 38%,
      rgba(13, 8, 21, 0) 100%
    );
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    -webkit-mask-image: linear-gradient(to top, #000 0%, #000 55%, transparent 100%);
    mask-image: linear-gradient(to top, #000 0%, #000 55%, transparent 100%);
  }

  /* ---------- Voile ---------- */
  .mnav-scrim {
    position: fixed;
    inset: 0;
    z-index: 92;
    background: rgba(6, 4, 10, 0.62);
    opacity: 0;
    pointer-events: none;
    overscroll-behavior: contain;
    /* Promotion permanente : eviter que le passage sur son propre calque
       coincide avec la premiere image de l'animation (micro a-coup). */
    will-change: opacity;
    transition: opacity 0.3s var(--mnav-ease-close);
  }
  .mnav.is-open .mnav-scrim {
    opacity: 1;
    pointer-events: auto;
    transition: opacity 0.34s var(--mnav-ease-open);
  }

  /* ---------- Panneau ---------- */
  .mnav-sheet {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 94;
    padding: 8px 16px calc(var(--mnav-dock-clear) + 24px);
    background: rgba(23, 16, 34, 0.98);
    border-top: 1px solid var(--lavender-15);
    border-radius: 28px 28px 0 0;
    transform: translate3d(0, 100%, 0);
    pointer-events: none;
    overscroll-behavior: contain;
    will-change: transform;
    transition: transform 0.36s var(--mnav-ease-close);
  }
  .mnav.is-open .mnav-sheet {
    transform: translate3d(0, 0, 0);
    pointer-events: auto;
    /* Le geste de fermeture (glissement vers le bas) doit gagner sur toute
       interpretation de defilement par le navigateur. */
    touch-action: none;
    transition: transform 0.5s var(--mnav-ease-open);
  }
  /* Pendant le glissement : le doigt pilote, aucune transition ne doit
     s'interposer (le transform est pose en style inline par script.js). */
  .mnav.is-dragging .mnav-sheet,
  .mnav.is-dragging .mnav-scrim {
    transition: none;
  }
  /* Fermeture INSTANTANEE au tap sur un lien : la navigation cross-document
     (View Transitions) snapshoterait sinon un panneau a mi-course. */
  .mnav.is-instant .mnav-sheet,
  .mnav.is-instant .mnav-scrim {
    transition: none;
  }

  /* Poignee : 4px visibles, 28px de zone tactile. */
  .mnav-grabber {
    display: grid;
    place-items: center;
    height: 28px;
  }
  .mnav-grabber::before {
    content: "";
    display: block;
    width: 36px;
    height: 4px;
    border-radius: 999px;
    background: var(--lavender-30);
  }

  /* ---------- Liens ---------- */
  .mnav-links {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding-top: 8px;
  }
  .mnav-links a {
    position: relative;
    display: flex;
    align-items: center;
    min-height: 52px;
    padding: 0 20px;
    border-radius: 16px;
    color: var(--cream);
    text-decoration: none;
    font-weight: 600;
    font-size: 1.0625rem;
    letter-spacing: 0.01em;
    /* Pas d'etat :hover (il colle apres un tap sur tactile) : le retour est
       tactile, au doigt pose.
       Etat de depart du stagger "Hybride A" (choisi par l'operateur apres
       comparaison de 10 variantes, puis redemande sur ce nouveau menu) :
       decale vers le bas + legerement reduit. Cette regle est aussi la cible
       de la FERMETURE, d'ou sa duree courte : sortie rapide, entree posee. */
    opacity: 0;
    transform: translate3d(0, 20px, 0) scale(0.92);
    /* Sortie sur la courbe accelerante, et plus courte que la course du
       panneau : le contenu se dissipe pendant que le panneau descend, au
       lieu de partir avec lui sans qu'on voie rien. */
    transition: opacity 0.2s var(--mnav-ease-close), transform 0.26s var(--mnav-ease-close);
  }
  /* Doit surclasser .mnav.is-open .mnav-links a (3 classes + 1 element), qui
     pose maintenant un transform : sans ce selecteur au moins aussi
     specifique, le retour tactile au doigt pose ne s'appliquerait plus. */
  .mnav-links a:active,
  .mnav.is-open .mnav-links a:active {
    transform: translate3d(0, 0, 0) scale(0.97);
    transition: transform 0.1s var(--ease-out);
  }
  .mnav-links a[aria-current="page"] {
    background: var(--lavender-08);
  }
  .mnav-links a[aria-current="page"]::before {
    content: "";
    position: absolute;
    left: 8px;
    top: 50%;
    width: 3px;
    height: 20px;
    border-radius: 999px;
    background: var(--lavender);
    transform: translateY(-50%);
  }

  /* ---------- CTA ---------- */
  .mnav-cta {
    padding-top: 12px;
    /* Meme etat de depart que les liens (stagger "Hybride A"). Le :active du
       bouton vit sur .mnav-cta .btn, un autre element : aucun conflit de
       specificite avec le transform pose ici. */
    opacity: 0;
    transform: translate3d(0, 20px, 0) scale(0.92);
    transition: opacity 0.2s var(--mnav-ease-close), transform 0.26s var(--mnav-ease-close);
  }
  .mnav-cta .btn,
  .mnav-cta .btn:hover {
    display: flex;
    width: 100%;
    min-height: 52px;
    justify-content: center;
    background: #fff;
    color: #171022;
    border-color: transparent;
    /* Neutralise le scale(1.1) de survol de .btn-primary (le survol colle
       apres un tap sur tactile) ; le retour au doigt vit sur :active. */
    transform: none;
    transition: transform 0.1s var(--ease-out);
  }
  .mnav-cta .btn:active {
    transform: scale(0.97);
  }

  /* Stagger "Hybride A" : les cadences exactes de la variante que l'operateur
     avait retenue sur le comparateur (40/110/180/250 sur les liens, 320 sur
     la CTA), et ses courbes (--ease-spring, entree plus longue que la sortie).
     Le deplacement vertical + la reduction sont pris en charge par le
     compositeur (transform pur) : contrairement au flou de la variante
     d'origine, ils ne coutent pas de redessin par image. Les delais portent
     sur opacity ET transform, dans l'ordre de la transition ci-dessus. */
  .mnav.is-open .mnav-links a,
  .mnav.is-open .mnav-cta {
    opacity: 1;
    transform: translate3d(0, 0, 0) scale(1);
    transition: opacity 0.44s var(--ease-spring), transform 0.56s var(--ease-spring);
  }
  /* Cadences d'Hybride A etirees d'environ un quart (demande operateur :
     "ralentis les animations"). Les durees ont ete allongees plus que les
     delais : les liens se recouvrent davantage, ce qui donne une cascade
     plus posee sans que la sequence traine sur la fin. */
  .mnav.is-open .mnav-links a:nth-child(1) { transition-delay: 50ms; }
  .mnav.is-open .mnav-links a:nth-child(2) { transition-delay: 135ms; }
  .mnav.is-open .mnav-links a:nth-child(3) { transition-delay: 220ms; }
  .mnav.is-open .mnav-links a:nth-child(4) { transition-delay: 305ms; }
  .mnav.is-open .mnav-cta { transition-delay: 390ms; }
  /* Le retour tactile ne doit jamais heriter d'un delai de stagger : sinon un
     appui sur le 4e lien mettrait 250ms a reagir. */
  .mnav.is-open .mnav-links a:active { transition-delay: 0s; }

  /* ---------- Dock ---------- */
  .mnav-dock {
    position: fixed;
    left: 50%;
    bottom: var(--mnav-dock-bottom);
    z-index: 96;
    /* left + margin-left plutot que translateX(-50%) : le transform du dock
       reste libre pour le retour tactile, et rien ne l'anime en permanence. */
    margin-left: calc(var(--mnav-dock-w) / -2);
    width: var(--mnav-dock-w);
    height: var(--mnav-dock-h);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 0 4px;
    border-radius: 999px;
    background: rgba(10, 7, 16, 0.97);
    border: 1px solid var(--lavender-30);
    /* Persiste pendant les transitions de page cross-document (le contenu
       fond, le dock reste). Nomme uniquement sous le breakpoint : au-dessus,
       c'est .nav qui porte cmc-nav. */
    view-transition-name: cmc-mnav;
  }
  .mnav-dock-logo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    height: 44px;
    padding: 0 4px;
    color: #fff;
    text-decoration: none;
    font-weight: 800;
    font-size: 0.85rem;
    letter-spacing: 0.02em;
    transition: transform 0.1s var(--ease-out);
  }
  .mnav-dock-logo:active {
    transform: scale(0.94);
  }
  .mnav-dock-sep {
    flex: none;
    width: 1px;
    height: 20px;
    background: var(--lavender-30);
  }
  .mnav-toggle {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 44px;
    height: 44px;
    padding: 10px;
    background: none;
    border: none;
    border-radius: 999px;
    cursor: pointer;
    transition: transform 0.15s var(--ease-out);
  }
  .mnav-toggle:active {
    transform: scale(0.92);
  }
  .mnav-toggle span {
    display: block;
    height: 2px;
    background: var(--cream);
    border-radius: 2px;
    transition: transform 0.3s var(--ease-out), opacity 0.3s var(--ease-out);
  }
  /* Morph burger -> croix (repris tel quel de l'ancienne pilule). */
  .mnav.is-open .mnav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .mnav.is-open .mnav-toggle span:nth-child(2) { opacity: 0; }
  .mnav.is-open .mnav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

  /* ---------- Mouvement reduit : fondus seuls, aucun deplacement ---------- */
  @media (prefers-reduced-motion: reduce) {
    .mnav-sheet {
      transform: none;
      opacity: 0;
      transition: opacity 0.12s linear;
    }
    .mnav.is-open .mnav-sheet {
      transform: none;
      opacity: 1;
      transition: opacity 0.12s linear;
    }
    .mnav-scrim { transition: opacity 0.12s linear; }
    .mnav.is-open .mnav-scrim { transition: opacity 0.12s linear; }
    /* Le stagger "Hybride A" pose un translate + scale : les neutraliser ici,
       sinon les liens resteraient decales et reduits en mouvement reduit. */
    .mnav-links a,
    .mnav-cta { transform: none; transition: none; }
    .mnav.is-open .mnav-links a,
    .mnav.is-open .mnav-cta { transform: none; transition: none; transition-delay: 0s; }
    .mnav.is-open .mnav-links a:nth-child(1),
    .mnav.is-open .mnav-links a:nth-child(2),
    .mnav.is-open .mnav-links a:nth-child(3),
    .mnav.is-open .mnav-links a:nth-child(4),
    .mnav.is-open .mnav-cta { transition-delay: 0s; }
    .mnav-toggle,
    .mnav-toggle span,
    .mnav-dock-logo,
    .mnav-cta .btn { transition: none; }
  }
}

/* ==========================================================================
   Cibles tactiles du pied de page et des liens flechés (mobile)

   Mesure sur le site en ligne, iPhone 13 : les liens de navigation du pied de
   page font 19 px de haut, et les liens « Voir le site ↗ » entre 28 et 31 px.
   Le minimum du critere WCAG 2.5.8 est 24 px, la taille confortable 44. Un
   pouce sur un ecran en mouvement rate une cible de 19 px.

   On n'agrandit ni le texte ni l'interligne visible : c'est la surface
   touchable qui grandit, et la marge basse des <li> est reprise par le padding
   pour que l'espacement percu reste identique.
   ========================================================================== */
@media (max-width: 767.98px) {
  .footer-col a,
  .footer-legal a {
    display: inline-block;
    padding-block: 12px;
  }

  .footer-col li {
    margin-bottom: 0;
  }

  .link-arrow {
    display: inline-block;
    padding-block: 7px;
  }
}
