/* Le site en mouvement — la feuille partagée par toutes les pages.
 *
 * LA RESPIRATION (refonte du 06.10.2026, qui remplace le fil à plomb). Plus
 * de tracé qui se déroule ni de laser : la page respire. Le haut de page se
 * lève — le sigle sort d'une brume, le carré orange se pose avec un léger
 * rebond, les halos de couleur dérivent lentement et une lueur suit le
 * pointeur. Plus bas, chaque bloc monte en fondu quand on y arrive ; les
 * cartes d'une grille arrivent en cascade, les titres de section mot à mot,
 * et les écrans de l'application flottent un peu plus lentement que la page,
 * ce qui leur donne de la profondeur.
 *
 * UNE SEULE FAÇON DE BOUGER. Une courbe (--mo-ease : départ franc, arrivée
 * très longue, sans rebond) pour tout ce qui apparaît, sa variante à rebond
 * léger (--mo-pose) pour ce qui se pose. Rien ne clignote ; seuls les halos
 * du haut de page dérivent, lentement, en boucle.
 *
 * Trois règles tiennent le fichier :
 *  1. RIEN NE DÉPEND DU SCRIPT POUR ÊTRE LU. Les entrées du haut de page sont
 *     des animations CSS qui finissent visibles d'elles-mêmes ; tout ce qui
 *     masque un bloc plus bas passe par une classe posée en JavaScript
 *     (`mo-entre`), retirée dès que le bloc est apparu.
 *  2. MOUVEMENT RÉDUIT OU INTERRUPTEUR = AUCUN MOUVEMENT. Toute animation vit
 *     dans `@media (prefers-reduced-motion: no-preference)` ET sous
 *     `:root:not([data-motion="non"])` (cf. l'en-tête de motion.js).
 *  3. ON N'ANIME QUE transform, translate, scale, opacity et filter : rien
 *     qui décale la mise en page — un bloc masqué garde sa place.
 */

:root {
  --mo-ease: cubic-bezier(.22, 1, .36, 1);
  --mo-pose: cubic-bezier(.34, 1.4, .64, 1);
  --mo-ombre-barre: 0 12px 30px -14px rgba(11, 25, 41, .30);
  --mo-lueur: rgba(249, 115, 22, .10);
  --mo-lueur-2: rgba(56, 189, 248, .08);
}
[data-theme="sombre"] {
  --mo-ombre-barre: 0 16px 34px -12px rgba(0, 0, 0, .75);
  --mo-lueur: rgba(249, 115, 22, .14);
  --mo-lueur-2: rgba(56, 189, 248, .10);
}

/* ── LE MOTIF, IMMOBILE ────────────────────────────────────────────────
   Le carré devant chaque étiquette de section : la forme du carré du sigle,
   à la taille du texte. Il existe sans script et sans mouvement. */
.s-label::before {
  content: ""; display: inline-block; width: .62em; height: .62em;
  margin-right: .65em; vertical-align: .02em;
  background: var(--orange, #ea6a0c);
}

/* La cote sous le titre des tarifs : un trait bleu entre deux butées, le
   carré en son milieu. */
.hero > .wrap.s-center::after {
  content: ""; display: block; width: min(320px, 60%); height: 9px; margin: 8px auto 0;
  background:
    linear-gradient(var(--orange), var(--orange)) 50% 0 / 9px 9px no-repeat,
    linear-gradient(var(--blue-lt), var(--blue-lt)) 0 4px / 100% 1px no-repeat,
    linear-gradient(var(--blue-lt), var(--blue-lt)) 0 0 / 1px 9px no-repeat,
    linear-gradient(var(--blue-lt), var(--blue-lt)) 100% 0 / 1px 9px no-repeat;
  opacity: .85;
}

/* Un bloc pas encore apparu tient ses démos sur leur première image. */
.demo-attente, .demo-attente * { animation-play-state: paused !important; }
/* Un bloc sorti de l'écran arrête ses démos et ses halos en boucle : une
   trentaine d'animations tournaient sans fin sur l'accueil, à chaque image du
   défilement, même loin de la vue (27.10.2026). */
.mo-hors-ecran, .mo-hors-ecran * { animation-play-state: paused !important; }

/* La lueur qui suit le pointeur dans le haut de page (posée par motion.js). */
.mo-lueur {
  position: absolute; left: 0; top: 0; width: 640px; height: 640px; margin: -320px 0 0 -320px;
  border-radius: 50%; pointer-events: none; opacity: 0;
  background: radial-gradient(circle, var(--mo-lueur) 0%, var(--mo-lueur-2) 35%, transparent 68%);
  transition: opacity .8s ease; will-change: transform;
}
.mo-lueur.on { opacity: 1; }

/* ── LA JAUGE DE LECTURE (pages longues) ───────────────────────────── */
.mo-progression {
  position: fixed; top: 0; left: 0; right: 0; z-index: 200;
  height: 2px; pointer-events: none;
  transform: scaleX(0); transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--blue-lt, #0284c7), var(--orange, #ea6a0c));
  will-change: transform;
}

/* ── LA BARRE QUI SE DÉTACHE ─────────────────────────────────────────── */
body > nav { transition: box-shadow .4s ease, border-color .4s ease; }
body > nav.mo-replie { box-shadow: var(--mo-ombre-barre); border-bottom-color: transparent; }
.wordmark .dot { display: inline-block; }

/* ── LES BOUTONS : un reflet au survol, un appui qui cède ─────────────── */
:is(.btn-primary, .nav-cta, .form-submit, .pay-btn:not(.card-btn):not(:disabled)) {
  background-image: linear-gradient(110deg, transparent 38%, rgba(255, 255, 255, .28) 50%, transparent 62%);
  background-size: 260% 100%;
  background-position: 130% 0;
  background-repeat: no-repeat;
  transition: opacity .15s, transform .25s var(--mo-ease), scale .15s ease, box-shadow .25s, background-position .9s var(--mo-ease);
}
:is(.btn-primary, .btn-ghost, .nav-cta, .nav-login, .form-submit, .pay-btn,
    .rc-btn, .theme-bascule, .bouton, .btn-imprimer, .btn-reset-mdp, .copy-btn):active:not(:disabled) {
  scale: .965;
}

@media (prefers-reduced-motion: no-preference) {
  :root:not([data-motion="non"]) {
    scroll-behavior: smooth;

    /* ── L'ENTRÉE DE CHAQUE PAGE ─────────────────────────────────────── */
    & body > nav { animation: mo-descend .8s var(--mo-ease) backwards; }
    .annonce { animation: mo-fondu .9s ease backwards; }

    /* Inscription, paiement : le titre, puis la phrase. */
    .hero > .wrap > h1 { animation: mo-leve 1s .12s var(--mo-ease) backwards; }
    .hero > .wrap > p { animation: mo-leve 1s .26s var(--mo-ease) backwards; }
    .hero::before { animation: mo-fondu 1.4s ease backwards; translate: 0 var(--mo-y, 0px); }

    /* Pages légales : l'en-tête entre, le texte du contrat ne bouge jamais. */
    .cgv-tete > *, main > h1, main > .maj { animation: mo-leve .9s var(--mo-ease) backwards; }
    .cgv-tete > :nth-child(2), main > .maj { animation-delay: .1s; }
    .cgv-somm { animation: mo-fondu 1s .2s ease backwards; }
    & body > .actions { animation: mo-descend .6s var(--mo-ease) backwards; }

    /* ── L'ACCUEIL : LE SIGLE SE LÈVE ───────────────────────────────────
         0,15 s  GEO sort de la brume, VIO le suit ;
         0,55 s  le carré orange tombe à sa place, rebondit à peine, s'allume ;
         0,85 s  la signature monte mot à mot (motion.js la découpe) ;
         1,10 s  la promesse, puis le bouton.
       Ensuite, seuls les halos dérivent, lentement. */
    .hero .hero-grid { animation: mo-fondu 1.8s ease backwards; }
    .hero-glow-top { animation: mo-fondu 1.8s .2s ease backwards, mo-respire 14s 2s ease-in-out infinite alternate; }
    .hero-glow-l { animation: mo-fondu 1.8s .3s ease backwards, mo-derive-l 18s 2s ease-in-out infinite alternate; }
    .hero-glow-r { animation: mo-fondu 1.8s .4s ease backwards, mo-derive-r 21s 2s ease-in-out infinite alternate; }

    .lg-mot { display: inline-block; animation: mo-brume .9s var(--mo-ease) backwards; }
    .lg-mot:last-child { animation-delay: .12s; }
    .hero-logo .carre { animation: mo-chute .9s .55s var(--mo-pose) backwards, mo-allume 1.6s .9s ease backwards; }

    .hero > .wrap > h1.hero-signature { animation: mo-leve 1s .85s var(--mo-ease) backwards; }
    .hero > .wrap > p.hero-sous { animation: mo-leve 1s 1.1s var(--mo-ease) backwards; }
    .hero .hero-actions { animation: mo-leve 1s 1.25s var(--mo-ease) backwards; }

    /* Tarifs : le titre mot à mot, puis la cote se trace dessous. */
    .hero > .wrap.s-center > h1 { animation: mo-leve 1s .2s var(--mo-ease) backwards; }
    .hero > .wrap.s-center::after { animation: mo-cote 1.2s .6s var(--mo-ease) backwards; }

    /* ── L'APPARITION (classes posées par motion.js) ─────────────────────
       Un bloc attend sous `mo-entre`, invisible et un peu plus bas ; il
       monte à sa place quand on y arrive (`mo-vu`), après son délai
       (`--mo-delai`, la cascade d'une grille). Un écran de l'application
       vient de plus loin, légèrement réduit. Le script retire les deux
       classes une fois l'apparition finie : le bloc rend son propre style. */
    .mo-entre { opacity: 0; transform: translateY(28px); }
    .mo-entre.mo-carte { transform: translateY(34px) scale(.97); }
    .mo-entre.mo-media { transform: translateY(56px) scale(.94); }
    .mo-entre.mo-titre { transform: none; }
    .mo-entre.mo-vu {
      opacity: 1; transform: none;
      transition: opacity .9s ease var(--mo-delai, 0s), transform 1.2s var(--mo-ease) var(--mo-delai, 0s);
    }
    .mo-entre.mo-media.mo-vu { transition-duration: 1.1s, 1.6s; }
    .s-label.mo-vu::before { animation: mo-pose .8s calc(var(--mo-delai, 0s) + .15s) var(--mo-pose) backwards; }
    .mo-vu .p-circle { animation: mo-pose .7s calc(var(--mo-delai, 0s) + .2s) var(--mo-pose) backwards; }

    /* Mots découpés : chacun sort d'une fente qui le rogne. */
    .mo-decoupe, .mo-fait { animation: none !important; }
    .mo-mot { display: inline-block; overflow: hidden; vertical-align: top; padding: 0 .04em .14em; margin: 0 -.04em -.14em; }
    .mo-mot > i { display: inline-block; font-style: inherit; animation: mo-mot 1s var(--mo-ease) backwards; }

    /* ── LES TITRES DES PAGES LÉGALES (classes posées par motion.js) ────
       Jamais invisibles : un titre de contrat se lit tout le temps. */
    .mo-ancre { opacity: .35; transform: translateX(-8px); transition: opacity .6s ease, transform .8s var(--mo-ease); }
    .mo-ancre.mo-vu { opacity: 1; transform: none; }

    .mo-compte { font-variant-numeric: tabular-nums; }
  }
}

/* ── AU POINTEUR SEULEMENT ─────────────────────────────────────────────
   Sur un écran tactile, un « survol » reste collé après le toucher. Les
   cartes se soulèvent sous le pointeur, les liens se soulignent. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  :root:not([data-motion="non"]) {
    :is(.btn-primary, .nav-cta, .form-submit, .pay-btn:not(.card-btn):not(:disabled)):hover { background-position: -30% 0; }
    .btn-primary:hover { transform: translateY(-2px); }
    :is(.mod-tuile, .atout, .code-carte, .lct-carte, .eq-groupe, .offre, .roi-card, .chaine-etape):not(.mo-entre) {
      transition: translate .5s var(--mo-ease), box-shadow .5s var(--mo-ease), border-color .3s ease;
    }
    :is(.mod-tuile, .atout, .code-carte, .lct-carte, .eq-groupe, .offre, .roi-card, .chaine-etape):not(.mo-entre):hover {
      translate: 0 -4px; box-shadow: 0 18px 40px -22px rgba(11, 25, 41, .35);
    }
    .nav-links a, .footer-links a {
      text-decoration: underline; text-decoration-color: transparent;
      text-decoration-thickness: 1.5px; text-underline-offset: .6em;
      transition: color .15s, text-decoration-color .3s ease, text-underline-offset .35s var(--mo-ease);
    }
    .nav-links a:hover, .footer-links a:hover, .nav-links a.active { text-decoration-color: var(--orange); text-underline-offset: .3em; }
    .wordmark:hover .dot { animation: mo-pose .5s var(--mo-pose); }
  }
}

/* ── LE CHANGEMENT DE THÈME (theme.js, View Transitions) ─────────────── */
::view-transition-old(root), ::view-transition-new(root) { animation: none; mix-blend-mode: normal; }

/* ── MOUVEMENT RÉDUIT, INTERRUPTEUR : le filet de sûreté ───────────────
   Les scripts ne posent déjà rien dans ces cas ; ces règles couvrent la
   préférence changée pendant que la page est ouverte. */
@media (prefers-reduced-motion: reduce) {
  .mo-ancre, .mo-entre { opacity: 1 !important; transform: none !important; transition: none !important; }
  .mo-lueur { display: none !important; }
}
:root[data-motion="non"] .mo-lueur, :root[data-motion="non"] .mo-progression { display: none !important; }
:root[data-motion="non"] .mo-entre { opacity: 1 !important; transform: none !important; }

/* ── IMPRESSION ──────────────────────────────────────────────────────── */
@media print {
  .mo-ancre, .mo-entre { opacity: 1 !important; transform: none !important; }
  .mo-progression, .mo-lueur { display: none !important; }
}

@keyframes mo-fondu { from { opacity: 0; } }
@keyframes mo-leve { from { opacity: 0; transform: translateY(18px); } }
@keyframes mo-descend { from { opacity: 0; transform: translateY(-10px); } }
/* Le sigle est le plus grand élément du haut de page : Google mesure l'affichage
   du site sur lui (LCP). Parti invisible, il le retardait de 4 s sur mobile
   (Lighthouse, 14.10.2026) ; il part désormais visible, à peine flou. */
@keyframes mo-brume { from { opacity: .6; transform: translateY(.08em) scale(.985); filter: blur(5px); } }
@keyframes mo-chute { from { opacity: 0; transform: translateY(-1.4em) rotate(-45deg) scale(.4); } 40% { opacity: 1; } }
@keyframes mo-allume { 0% { filter: brightness(1); } 35% { filter: brightness(1.8) drop-shadow(0 0 .35em rgba(249, 115, 22, .9)); } 100% { filter: brightness(1); } }
@keyframes mo-respire { to { scale: 1.12; opacity: .8; } }
@keyframes mo-derive-l { to { transform: translate(60px, 40px) scale(1.15); } }
@keyframes mo-derive-r { to { transform: translate(-70px, 30px) scale(1.1); } }
@keyframes mo-cote { from { opacity: 0; transform: scaleX(0); } }
@keyframes mo-mot { from { transform: translateY(105%); opacity: .2; } }
@keyframes mo-pose { 0% { transform: scale(0) rotate(-90deg); } 100% { transform: none; } }
