/*
 * Animations « proposition 01 » partagées par tout le site vitrine (chantier anim7, docs/technique.md §34.4).
 * Moteur extrait de l'accueil (§33.7) : chargée par layouts/public.php sur toutes les pages en design p01 (accueil
 * compris, APRÈS home-p01.css et p01-pages.css) et par layouts/auth.php (connexion, inscription…). Le script
 * associé est assets/js/p01-anim.js.
 *
 * Règles communes :
 *  · tout est préfixé par html.p01-anim, classe posée avant le premier affichage (script en ligne des layouts) puis
 *    confirmée par p01-anim.js, seulement si le mouvement n'est pas réduit (système ou compte : data-motion) et
 *    qu'IntersectionObserver existe. Sans JavaScript, rien n'est masqué ni animé ;
 *  · seul ce qui est SOUS la ligne de flottaison est caché puis révélé (.p01-reveal, posée par le script) ; ce qui
 *    est visible au chargement n'est jamais retardé : les entrées du bandeau partent d'une opacité de .35 ;
 *  · seules transform, translate, scale et opacity sont animées (composition, aucun calcul de mise en page, pas de
 *    CLS) ; les apparitions emploient `translate`, les survols gardent `transform` ;
 *  · pages « sobres » (html.p01-sober : pages légales, panier, paiement) : ni halos animés, ni particules, ni
 *    révélation des blocs — seulement l'entrée du titre.
 */
@keyframes p01-rise{from{opacity:0;translate:0 18px}to{opacity:1;translate:0 0}}
@keyframes p01-enter{from{opacity:.35;translate:0 16px}to{opacity:1;translate:0 0}}
@keyframes p01-card-in{from{opacity:.6;translate:0 18px;scale:.985}to{opacity:1;translate:0 0;scale:1}}
@keyframes p01-float{0%,100%{translate:0 0}50%{translate:0 -10px}}
@keyframes p01-float-soft{0%,100%{translate:0 0}50%{translate:0 -6px}}
@keyframes p01-drift-a{0%,100%{transform:translate3d(0,0,0) scale(1);opacity:.33}50%{transform:translate3d(90px,-50px,0) scale(1.15);opacity:.42}}
@keyframes p01-drift-b{0%,100%{transform:translate3d(0,0,0) scale(1);opacity:.33}50%{transform:translate3d(-80px,60px,0) scale(.9);opacity:.24}}
@keyframes p01-drift-c{0%,100%{transform:translate3d(-60px,0,0) scale(.9);opacity:0}50%{transform:translate3d(80px,-70px,0) scale(1.1);opacity:.2}}
@keyframes p01-twinkle{0%,100%{opacity:.55;transform:scale(.85)}50%{opacity:1;transform:scale(1.15)}}
@keyframes p01-halo{0%,100%{opacity:.45;transform:scale(1)}50%{opacity:1;transform:scale(1.012)}}
@keyframes p01-particle{0%{opacity:0;transform:translate3d(0,0,0)}12%{opacity:.8}85%{opacity:.5}100%{opacity:0;transform:translate3d(24px,-240px,0)}}

/* ------------------------------------------------------------------ moteur générique */
/* Révélation au défilement : fondu + léger glissement, cascade via --p01-delay (posé en CSSOM par le script). */
.p01-anim .p01-reveal{opacity:0;translate:0 28px;transition:opacity .8s cubic-bezier(.2,.7,.2,1) var(--p01-delay,0s),translate .8s cubic-bezier(.2,.7,.2,1) var(--p01-delay,0s),transform .3s ease,box-shadow .3s ease,background-color .3s ease,border-color .3s ease}
.p01-anim .p01-reveal.is-in{opacity:1;translate:0 0}
/* Ancrage du défilement (Firefox) : un bloc qui glisse ne sert jamais d'ancre, sinon le navigateur compense son
   déplacement en faisant défiler la page — saut de ~20 px entre l'appui et le relâchement d'un clic en bas de page. */
.p01-anim .p01-reveal{overflow-anchor:none}
/* Déjà dans la fenêtre à l'arrivée (ancre #resultats, défilement restauré) : affiché sans transition. */
.p01-anim .p01-reveal.p01-instant{transition:none}
/* Zone hors de l'écran : animations continues suspendues (économie de batterie). */
.p01-anim .p01-paused,.p01-anim .p01-paused::before,.p01-anim .p01-paused::after,.p01-anim .p01-paused *,.p01-anim .p01-paused *::before,.p01-anim .p01-paused *::after{animation-play-state:paused}

/* Particules décoratives des zones sombres (10 points, 14-22 s) ; le conteneur n'existe qu'animé. */
.p01-particles{display:none}
.p01-anim .p01-particles{position:absolute;inset:0;z-index:1;display:block;overflow:hidden;pointer-events:none}
.p01-particles i{position:absolute;bottom:-12px;width:5px;height:5px;border-radius:50%;background:rgba(255,255,255,.75);box-shadow:0 0 10px rgba(124,235,255,.8);animation:p01-particle 16s linear infinite}
.p01-particles i:nth-child(1){inset-inline-start:6%;animation-delay:-2s}
.p01-particles i:nth-child(2){inset-inline-start:15%;width:3px;height:3px;animation-duration:19s;animation-delay:-11s}
.p01-particles i:nth-child(3){inset-inline-start:26%;animation-duration:14s;animation-delay:-6s;background:rgba(214,160,255,.8)}
.p01-particles i:nth-child(4){inset-inline-start:37%;width:4px;height:4px;animation-duration:21s;animation-delay:-15s}
.p01-particles i:nth-child(5){inset-inline-start:48%;width:3px;height:3px;animation-delay:-9s}
.p01-particles i:nth-child(6){inset-inline-start:58%;animation-duration:18s;animation-delay:-4s;background:rgba(255,160,245,.8)}
.p01-particles i:nth-child(7){inset-inline-start:67%;width:4px;height:4px;animation-duration:15s;animation-delay:-12s}
.p01-particles i:nth-child(8){inset-inline-start:76%;width:3px;height:3px;animation-duration:20s;animation-delay:-7s}
.p01-particles i:nth-child(9){inset-inline-start:86%;animation-duration:17s;animation-delay:-1s;background:rgba(214,160,255,.8)}
.p01-particles i:nth-child(10){inset-inline-start:94%;width:4px;height:4px;animation-duration:22s;animation-delay:-17s}

/* Cartes de formation (accueil et partials/course_card) : soulevées, inclinées sous le pointeur (--p01-rx/--p01-ry,
   posées par le script, souris seulement) et traversées d'un reflet. */
.p01-anim .p01-course-card:hover,.p01-anim .p01-page .p01-card:hover{transform:perspective(900px) rotateX(var(--p01-rx,0deg)) rotateY(var(--p01-ry,0deg)) translateY(-8px);box-shadow:0 28px 56px rgba(26,42,82,.18)}
.p01-anim .p01-course-card::before,.p01-anim .p01-page .p01-card::before{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;background:linear-gradient(110deg,transparent 35%,rgba(255,255,255,.34) 50%,transparent 65%);transform:translateX(-110%);transition:transform .9s cubic-bezier(.2,.7,.2,1)}
.p01-anim .p01-course-card:hover::before,.p01-anim .p01-page .p01-card:hover::before{transform:translateX(110%)}
.p01-anim .p01-page .p01-card:hover .p01c-symbol{transform:rotate(0deg) scale(1.08)}
.p01-anim .p01-page .p01c-symbol{transition:transform .5s cubic-bezier(.3,1.5,.5,1)}

/* Boutons : reflet qui traverse au survol et au focus clavier (sous le texte grâce à isolation). */
.p01-anim .p01-main .p01-button,.p01-anim .p01-page .p01-button,.p01-anim .p01-page .btn-primary:not(.btn-ai),.p01-anim .p01-auth .auth-card .btn-primary:not(.btn-ai){position:relative;overflow:hidden;isolation:isolate}
.p01-anim .p01-main .p01-button::after,.p01-anim .p01-page .p01-button::after,.p01-anim .p01-page .btn-primary:not(.btn-ai)::after,.p01-anim .p01-auth .auth-card .btn-primary:not(.btn-ai)::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;background:linear-gradient(110deg,transparent 30%,rgba(255,255,255,.38) 50%,transparent 70%);transform:translateX(-120%)}
.p01-anim .p01-main .p01-button:hover::after,.p01-anim .p01-main .p01-button:focus-visible::after,.p01-anim .p01-page .p01-button:hover::after,.p01-anim .p01-page .p01-button:focus-visible::after,.p01-anim .p01-page .btn-primary:not(.btn-ai):hover::after,.p01-anim .p01-page .btn-primary:not(.btn-ai):focus-visible::after,.p01-anim .p01-auth .auth-card .btn-primary:not(.btn-ai):hover::after,.p01-anim .p01-auth .auth-card .btn-primary:not(.btn-ai):focus-visible::after{transform:translateX(120%);transition:transform .8s cubic-bezier(.2,.7,.2,1)}
.p01-anim .p01-main .p01-button--white::after,.p01-anim .p01-page .p01-button--white::after{background:linear-gradient(110deg,transparent 30%,rgba(124,60,255,.14) 50%,transparent 70%)}

/* Menu mobile : sous la charge des animations composées, la visibilité du panneau ouvert bascule sans transition
   (le focus du premier lien ne tombe jamais sur un lien encore « hidden ») ; l'opacité garde son fondu. */
.p01-anim .p01-primary-nav.open{transition:opacity .2s ease,visibility 0s}

/* Compteurs : chiffres à chasse fixe pendant l'incrément. */
[data-p01-countup]{display:inline-block;font-variant-numeric:tabular-nums}

/* ------------------------------------------------------------------ pages intérieures (§34.4) */
/* Bandeau bleu nuit : entrée du surtitre, du titre et de l'introduction dès le premier affichage (opacité ≥ .35 :
   jamais retardés), halos qui dérivent lentement, particules. Recherche, formulaires et boutons ne bougent pas. */
.p01-anim .p01p-hero__content > .p01p-eyebrow,.p01-anim .p01p-hero__content > .p01p-hero__title,.p01-anim .p01p-hero__content > .p01p-hero__lead,.p01-anim .p01p-error__code,
.p01-anim .p01p-hero > .container .kicker,.p01-anim .p01p-hero > .container h1,.p01-anim .course-hero h1,.p01-anim .course-hero .lead,
.p01-anim .p01-auth .auth-side-content > *{animation:p01-enter .7s cubic-bezier(.2,.7,.2,1) both}
.p01-anim .p01p-hero__content > .p01p-hero__title,.p01-anim .p01p-hero > .container h1,.p01-anim .course-hero h1,.p01-anim .p01-auth .auth-side-content > :nth-child(2){animation-delay:.08s}
.p01-anim .p01p-hero__content > .p01p-hero__lead,.p01-anim .course-hero .lead,.p01-anim .p01-auth .auth-side-content > :nth-child(3){animation-delay:.16s}
.p01-anim .p01-auth .auth-side-content > :nth-child(4){animation-delay:.24s}
.p01-anim .p01p-hero__glow{will-change:transform}
.p01-anim:not(.p01-sober) .p01p-hero__glow--cyan,.p01-anim .p01-auth .auth-orb.o2{animation:p01-drift-a 22s ease-in-out infinite}
.p01-anim:not(.p01-sober) .p01p-hero__glow--violet,.p01-anim .p01-auth .auth-orb.o1{animation:p01-drift-b 26s ease-in-out infinite}
.p01-anim .p01p-eyebrow__icon .ic{animation:p01-twinkle 4s ease-in-out infinite}

/* Carte de connexion : entrée douce (translation et échelle, opacité ≥ .6 : le formulaire est lisible et
   utilisable dès le premier affichage). */
.p01-anim .p01-auth .auth-card{animation:p01-card-in .6s cubic-bezier(.2,.7,.2,1) .05s both}

/* Zones sombres : particules sous le contenu (et sous la découpe blanche inclinée du bandeau). */
.p01-anim .p01p-cta{position:relative;overflow:hidden}
.p01-anim .p01p-cta__inner{position:relative;z-index:2}
.p01-anim .p01p-hero .p01-particles,.p01-anim .p01p-cta .p01-particles,.p01-anim .p01p-navy .p01-particles,.p01-anim .p01p-panel > .p01-particles,.p01-anim .course-hero .p01-particles,.p01-anim .p01-auth .auth-side .p01-particles{z-index:0}

/* Abonnements : formules visibles au chargement en cascade (entrée sans masquage, opacité ≥ .35 ; celles sous la ligne
   de flottaison sont révélées au défilement par le script), formule recommandée avec un halo qui respire (ombre
   portée par un calque transparent : rien ne couvre le contenu). */
.p01-anim .p01-page .pricing-grid > .plan:not(.p01-reveal){animation:p01-enter .7s cubic-bezier(.2,.7,.2,1) both}
.p01-anim .p01-page .pricing-grid > .plan:not(.p01-reveal):nth-child(2){animation-delay:.08s}
.p01-anim .p01-page .pricing-grid > .plan:not(.p01-reveal):nth-child(3){animation-delay:.16s}
.p01-anim .p01-page .pricing-grid > .plan:not(.p01-reveal):nth-child(n+4){animation-delay:.24s}
.p01-anim .p01-page .plan.recommended::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;box-shadow:0 0 0 1px rgba(124,235,255,.3),0 0 46px 6px rgba(124,60,255,.42),0 0 90px 14px rgba(238,32,220,.16);animation:p01-halo 5s ease-in-out infinite}

/* Devenir formateur : la carte inclinée du panneau flotte (translate ; sa rotation reste en transform). */
.p01-anim .p01p-panel__card{animation:p01-float 8s ease-in-out infinite}

/* FAQ : la réponse glisse à l'ouverture. */
.p01-anim .p01-page .p01p-accordion details[open] > p{animation:p01-rise .45s cubic-bezier(.2,.7,.2,1)}

/* Cartes de fonctionnalités : pictogramme qui pivote au survol. */
.p01-anim .p01-page .feature .pill-icon{transition:transform .35s cubic-bezier(.3,1.6,.5,1)}
.p01-anim .p01-page .feature:hover .pill-icon{transform:rotate(-8deg) scale(1.08)}
[dir="rtl"].p01-anim .p01-page .feature:hover .pill-icon{transform:rotate(8deg) scale(1.08)}

/* ------------------------------------------------------------------ mouvement réduit et impression */
/* Si la préférence change en cours de visite, le script retire aussi p01-anim : tout redevient statique et visible. */
@media (prefers-reduced-motion:reduce){
  .p01-anim .p01-reveal{opacity:1;translate:none}
  .p01-anim .p01-page .p01-card:hover,.p01-anim .p01-course-card:hover{transform:none}
  .p01-anim *,.p01-anim *::before,.p01-anim *::after{animation:none!important}
  .p01-particles,.p01-anim .p01-particles{display:none}
}
@media print{.p01-anim .p01-reveal,.p01-anim .p01-reveal *{opacity:1!important;translate:none!important}.p01-particles{display:none!important}}
