/* =========================================================================
   anim.css — phase animations finale (liquid glass, DESIGN-SPEC §Plan).
   3 registres : AMBIANT (lent, seules boucles autorisées) · APPARITIONS
   (une passe, jamais en boucle) · INTERACTIONS (vives, 150–200 ms).
   GPU only (transform/opacity) sauf exceptions notées. Tout l'ambiant et
   les reveals vivent sous @media (prefers-reduced-motion: no-preference) ;
   en mouvement réduit : ambiant coupé, reveals instantanés, transitions
   ≤ 120 ms, bulles cachées. Les classes .view-in / .view-out sont posées
   par le router (core.js) ; .pop / .star-pop / .copy-done / .dropped /
   .gate-halo / .lock-open par les vues.
   ========================================================================= */

:root{ --dur-amb:8s; --dur-in:.6s; --dur-hov:.16s; }

/* ---------- Toujours actifs (pilotés par l'utilisateur, pas des boucles) --- */

/* Barre S0 : progression de lecture de la fiche (transform piloté au scroll) */
.scroll-progress{position:fixed;top:0;left:0;width:100%;height:2px;z-index:95;
  background:linear-gradient(90deg,var(--accent),var(--accent2));
  transform-origin:0 50%;transform:scaleX(0);pointer-events:none}

/* Voile de modale : blur STATIQUE — le fondu d'opacité fait percevoir le blur
   sans animer backdrop-filter (animation réservée à ⌘K, seule autorisée). */
.modal-backdrop{backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}

/* Morph copie → ✓ : la couleur bascule toujours, l'animation est plus bas. */
.copy-done .ic{color:var(--ok)}

/* (S12 supprimé — MISSION2 2.1 : le header de fiche n'est plus sticky, la
   densification .dense n'existe plus ; la mini-barre gère sa propre transition.) */

/* Vague décorative réutilisée hors Suivi (Santé des sources) : plus petite. */
.act-card-head .pipe-wave{height:13px;margin-left:6px;gap:2px}
.act-card-head .pipe-wave i{width:3px}

/* =========================================================================
   MOUVEMENT COMPLET — uniquement si l'utilisateur accepte les animations
   ========================================================================= */
@media (prefers-reduced-motion: no-preference){

  /* ======================= 1. AMBIANT (lent) ============================= */

  /* Orbe du héros + anneau de score : flottement 8 s, amplitude 6 px. */
  .hero-orb,.fiche-head .ring-wrap{animation:sfaFloat var(--dur-amb) ease-in-out infinite}

  /* Stat-cards : respiration scale 1→1.008, déphasées de 1,5 s. */
  .statcard{animation:sfaBreathe 6s ease-in-out infinite}
  .statcards>:nth-child(2){animation-delay:1.5s}
  .statcards>:nth-child(3){animation-delay:3s}

  /* Bulles de verre : 7 cercles 24–90 px, montée 26–44 s, dérive sinusoïdale
     ±30 px, opacité ≤ .14, régénérées en haut (boucle infinie + délais
     négatifs pour une répartition immédiate). z-index : entre scrim et vue. */
  .bubble{display:block;position:absolute;bottom:-100px;border-radius:50%;opacity:0;
    background:radial-gradient(circle at 32% 30%,rgba(255,255,255,.18),rgba(255,255,255,.05) 46%,rgba(255,255,255,0) 62%);
    border:1px solid rgba(255,255,255,.12);
    box-shadow:inset 0 -6px 12px rgba(255,255,255,.05);
    will-change:transform,opacity;
    animation:sfaBulleA 34s linear infinite}
  .bubble:nth-child(1){left:8%;width:34px;height:34px;--bo:.11;animation-duration:31s;animation-delay:-4s}
  .bubble:nth-child(2){left:19%;width:72px;height:72px;--bo:.08;animation-duration:44s;animation-delay:-19s;animation-name:sfaBulleB}
  .bubble:nth-child(3){left:33%;width:24px;height:24px;--bo:.14;animation-duration:26s;animation-delay:-11s}
  .bubble:nth-child(4){left:52%;width:48px;height:48px;--bo:.09;animation-duration:37s;animation-delay:-27s;animation-name:sfaBulleB}
  .bubble:nth-child(5){left:66%;width:90px;height:90px;--bo:.07;animation-duration:42s;animation-delay:-8s}
  .bubble:nth-child(6){left:79%;width:28px;height:28px;--bo:.13;animation-duration:28s;animation-delay:-16s;animation-name:sfaBulleB}
  .bubble:nth-child(7){left:90%;width:56px;height:56px;--bo:.09;animation-duration:39s;animation-delay:-31s}

  /* Dot du bandeau relances : pulse 2 s — n'existe dans le DOM QUE si retard. */
  .rel-banner .status-dot.warn{animation:sfaPulse 2s ease-in-out infinite}

  /* Vague : header du Suivi + « Santé des sources » quand tout est vert. */
  .pipe-wave i{transform-origin:50% 100%;animation:sfaWave 1.9s ease-in-out infinite}
  .pipe-wave i:nth-child(2){animation-delay:.22s}
  .pipe-wave i:nth-child(3){animation-delay:.44s}
  .pipe-wave i:nth-child(4){animation-delay:.66s}
  .pipe-wave i:nth-child(5){animation-delay:.88s}

  /* ================== 2. APPARITIONS (une passe) ========================= */

  /* Transition de vue : sortie fade 120 ms (classe posée par le router)
     puis entrée reveal 250 ms + translateY 8 px. */
  #view.view-out{opacity:0;transition:opacity .12s ease}
  #view.view-in{animation:sfaViewIn .25s ease-out}

  /* Reveal S1 des stat-cards : stagger 80 ms — combiné à la respiration
     (délai de la 2ᵉ animation > fin du reveal pour éviter le conflit de
     transform). fill backwards : rien ne « colle » après la passe. */
  #view.view-in .statcard{
    animation:sfaReveal var(--dur-in) cubic-bezier(.22,.7,.3,1) backwards,
              sfaBreathe 6s ease-in-out infinite;
    animation-delay:0s,1.8s}
  #view.view-in .statcards>:nth-child(2){animation-delay:.08s,3.3s}
  #view.view-in .statcards>:nth-child(3){animation-delay:.16s,4.8s}
  /* Le survol (lift liste.css) reprend la main sur le transform. */
  #view .statcard:hover{animation:none}

  /* Reveal des 8 premières lignes de liste : stagger 40 ms, instantané après. */
  #view.view-in .liste-panel .lgrow{animation:sfaReveal .45s cubic-bezier(.22,.7,.3,1) backwards}
  #view.view-in .liste-panel .lgrow:nth-child(1){animation-delay:.05s}
  #view.view-in .liste-panel .lgrow:nth-child(2){animation-delay:.09s}
  #view.view-in .liste-panel .lgrow:nth-child(3){animation-delay:.13s}
  #view.view-in .liste-panel .lgrow:nth-child(4){animation-delay:.17s}
  #view.view-in .liste-panel .lgrow:nth-child(5){animation-delay:.21s}
  #view.view-in .liste-panel .lgrow:nth-child(6){animation-delay:.25s}
  #view.view-in .liste-panel .lgrow:nth-child(7){animation-delay:.29s}
  #view.view-in .liste-panel .lgrow:nth-child(8){animation-delay:.33s}
  #view.view-in .liste-panel .lgrow:nth-child(n+9){animation:none}

  /* Shimmer A2 : UNE passe diagonale sur stat-cards + listbar à l'entrée.
     ::before (le kit réserve ::after au spéculaire), au-dessus du lg-content. */
  #view.view-in .statcard::before,
  #view.view-in .listbar::before{content:"";position:absolute;inset:0;z-index:4;
    border-radius:inherit;pointer-events:none;
    background:linear-gradient(105deg,transparent 40%,rgba(255,255,255,.13) 50%,transparent 60%);
    background-size:220% 100%;background-repeat:no-repeat;background-position:130% 0;
    animation:sfaShimmer .9s ease-out .25s 1 backwards}

  /* Anneau de score : l'arc conic se dessine 0→valeur en 900 ms (fiche.js pose
     dasharray 0 puis la valeur au double-rAF ; en mouvement réduit le JS écrit
     la valeur finale directement, sans passer par cette transition). */
  .ring-val{transition:stroke-dasharray .9s cubic-bezier(.25,.6,.3,1)}

  /* Jelly de la lettre de note à la fin du tracé de l'anneau (classe JS). */
  .ring-note.pop{animation:sfaJelly .38s ease}

  /* ================== 3. INTERACTIONS (150–200 ms) ======================= */

  /* B1 : jelly au clic. B4/B22/boutons de carte : press scale .96 (120 ms,
     la transition transform .14s du kit fait le retour). */
  .btn.b1:active{animation:sfaJelly .38s ease}
  .btn.b4:active,.btn.b22:active,.kc-btn:active,.fchip:active{transform:scale(.96)}

  /* Étoile « suivre » : rotation + pop 250 ms (classe .star-pop posée au clic). */
  .star-pop .ic{animation:sfaStar .25s ease}

  /* Morph copie → ✓ : pop de la coche (couleur déjà gérée hors media). */
  .copy-done .ic{animation:sfaPopIn .3s ease}

  /* Dock : icône scale 1.15 au survol (180 ms). */
  .dock-item .ic{transition:transform .18s ease}
  .dock-item:hover .ic{transform:scale(1.15)}

  /* Kanban : atterrissage translate + squash après un drop (classe JS). */
  .kcard.dropped{animation:sfaDrop .35s cubic-bezier(.34,1.4,.64,1)}
  /* Halo accent UNE passe sur la colonne garde-fou à la confirmation. */
  .kcol-gate.gate-halo{animation:sfaHalo 1s ease-out 1}

  /* Modale garde-fou : voile en fondu 250 ms (blur statique), panneau .96→1. */
  .modal-backdrop{animation:sfaFadeIn .25s ease-out}
  .modal-panel{animation:sfaModalIn .25s cubic-bezier(.22,.9,.3,1)}
  /* Cadenas qui pivote et s'ouvre 400 ms à la confirmation (classe core.js). */
  .modal-title .ic.lock-open{color:var(--ok);animation:sfaLock .4s ease}

  /* ⌘K : le fond se floute 250 ms — SEULE animation autorisée sur
     backdrop-filter — et la palette descend avec un léger rebond. */
  .search-backdrop{backdrop-filter:blur(0px);-webkit-backdrop-filter:blur(0px);
    transition:backdrop-filter .25s ease,-webkit-backdrop-filter .25s ease}
  .search-overlay.show .search-backdrop{backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}
  .search-overlay .search-panel{transform:translate(-50%,-12px)}
  .search-overlay.show .search-panel{transform:translate(-50%,0);
    transition:transform .25s cubic-bezier(.34,1.45,.64,1)}

  /* Toast : entrée slide-up 220 ms avec micro-rebond, sortie 180 ms. */
  .app-toast{transition:opacity .18s ease,transform .18s ease}
  .app-toast.show{transition:opacity .22s cubic-bezier(.22,.9,.3,1.15),
    transform .22s cubic-bezier(.22,.9,.3,1.15)}

  /* ======================= Keyframes ===================================== */
  @keyframes sfaFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}
  @keyframes sfaBreathe{0%,100%{transform:scale(1)}50%{transform:scale(1.008)}}
  @keyframes sfaBulleA{
    0%{transform:translate3d(0,0,0);opacity:0}
    6%{opacity:var(--bo,.1)}
    25%{transform:translate3d(22px,-27vh,0)}
    50%{transform:translate3d(-14px,-54vh,0)}
    75%{transform:translate3d(26px,-81vh,0)}
    94%{opacity:var(--bo,.1)}
    100%{transform:translate3d(4px,-108vh,0);opacity:0}
  }
  @keyframes sfaBulleB{
    0%{transform:translate3d(0,0,0);opacity:0}
    6%{opacity:var(--bo,.1)}
    25%{transform:translate3d(-26px,-27vh,0)}
    50%{transform:translate3d(16px,-54vh,0)}
    75%{transform:translate3d(-22px,-81vh,0)}
    94%{opacity:var(--bo,.1)}
    100%{transform:translate3d(-4px,-108vh,0);opacity:0}
  }
  @keyframes sfaPulse{0%,100%{box-shadow:0 0 0 0 rgba(255,159,10,.55)}50%{box-shadow:0 0 0 9px rgba(255,159,10,0)}}
  @keyframes sfaWave{0%,100%{transform:scaleY(.45)}50%{transform:scaleY(1)}}
  @keyframes sfaViewIn{from{opacity:0;transform:translateY(8px)}}
  @keyframes sfaReveal{from{opacity:0;transform:translateY(14px)}}
  @keyframes sfaShimmer{from{background-position:130% 0}to{background-position:-130% 0}}
  @keyframes sfaJelly{0%{transform:scale(1)}30%{transform:scale(1.12,.88)}55%{transform:scale(.94,1.06)}75%{transform:scale(1.03,.98)}100%{transform:scale(1)}}
  @keyframes sfaStar{0%{transform:scale(.6) rotate(-20deg)}60%{transform:scale(1.3) rotate(8deg)}100%{transform:scale(1) rotate(0)}}
  @keyframes sfaPopIn{0%{transform:scale(.4);opacity:0}100%{transform:scale(1);opacity:1}}
  @keyframes sfaDrop{0%{transform:translateY(-6px) scale(1.02,.96)}60%{transform:translateY(0) scale(.985,1.01)}100%{transform:scale(1)}}
  @keyframes sfaHalo{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--accent) 55%,transparent)}
    100%{box-shadow:0 0 0 22px transparent}}
  @keyframes sfaFadeIn{from{opacity:0}}
  @keyframes sfaModalIn{from{opacity:0;transform:scale(.96)}}
  @keyframes sfaLock{0%{transform:rotate(0)}40%{transform:rotate(-18deg) translateY(-2px)}70%{transform:rotate(10deg)}100%{transform:rotate(0)}}
}

/* =========================================================================
   MOUVEMENT RÉDUIT : ambiant coupé (kit.css annule déjà les animations),
   bulles cachées, transitions plafonnées à 120 ms, reveals instantanés.
   ========================================================================= */
@media (prefers-reduced-motion: reduce){
  .bubble{display:none!important}
  .scroll-progress{display:none}
  *,*::before,*::after{transition-duration:.12s!important}
}
