/*
 * Animations et micro-interactions (V2, `Plan design/UX` v1.1 §17).
 *
 * Principes :
 * - une animation accompagne un changement réel (arrivée sur un écran,
 *   survol d'un élément cliquable, apparition d'un message, ouverture d'un
 *   panneau) — jamais un mouvement décoratif en boucle ;
 * - durées courtes (150 à 450 ms), courbes de décélération douces ;
 * - seules `opacity` et `transform` sont animées (fluide même sur un
 *   téléphone modeste, aucune relayout) ;
 * - `prefers-reduced-motion: reduce` neutralise tout mouvement (en fin de
 *   fichier) : l'interface reste entièrement utilisable, simplement sans
 *   animation.
 */

:root {
    --duree-rapide: 0.15s;
    --duree-moyenne: 0.28s;
    --duree-lente: 0.45s;
    --courbe-sortie: cubic-bezier(0.22, 1, 0.36, 1);
    --courbe-rebond: cubic-bezier(0.34, 1.56, 0.64, 1);
    --decalage-cascade: 45ms;
}

@keyframes apparition-montee {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes apparition-fondu {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

@keyframes apparition-glisse {
    from {
        opacity: 0;
        transform: translateY(-8px) scale(0.98);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes pastille-apparition {
    0% {
        opacity: 0;
        transform: scale(0.4);
    }
    100% {
        opacity: 1;
        transform: scale(1);
    }
}

@keyframes remplissage-barre {
    from {
        transform: scaleX(0);
    }
    to {
        transform: scaleX(1);
    }
}

@keyframes halo-etape {
    0%, 100% {
        box-shadow: 0 0 0 0 rgba(22, 199, 185, 0.45);
    }
    50% {
        box-shadow: 0 0 0 7px rgba(22, 199, 185, 0);
    }
}

/* Arrivée sur un écran : le contenu principal monte légèrement en fondu,
   bloc par bloc (cascade limitée aux premiers blocs, les suivants
   apparaissent ensemble). */
.app-contenu > *,
.ps-contenu > * {
    animation: apparition-montee var(--duree-lente) var(--courbe-sortie) both;
}

.app-contenu > *:nth-child(2),
.ps-contenu > *:nth-child(2) { animation-delay: calc(var(--decalage-cascade) * 1); }
.app-contenu > *:nth-child(3),
.ps-contenu > *:nth-child(3) { animation-delay: calc(var(--decalage-cascade) * 2); }
.app-contenu > *:nth-child(4),
.ps-contenu > *:nth-child(4) { animation-delay: calc(var(--decalage-cascade) * 3); }
.app-contenu > *:nth-child(5),
.ps-contenu > *:nth-child(5) { animation-delay: calc(var(--decalage-cascade) * 4); }
.app-contenu > *:nth-child(n+6),
.ps-contenu > *:nth-child(n+6) { animation-delay: calc(var(--decalage-cascade) * 5); }

/* Cascade dans une grille de cartes ou une liste de tâches. */
.cartes-grille > *,
.taches > *,
.anime-cascade > * {
    animation: apparition-montee var(--duree-lente) var(--courbe-sortie) both;
}

.cartes-grille > *:nth-child(2), .taches > *:nth-child(2), .anime-cascade > *:nth-child(2) { animation-delay: 60ms; }
.cartes-grille > *:nth-child(3), .taches > *:nth-child(3), .anime-cascade > *:nth-child(3) { animation-delay: 120ms; }
.cartes-grille > *:nth-child(4), .taches > *:nth-child(4), .anime-cascade > *:nth-child(4) { animation-delay: 180ms; }
.cartes-grille > *:nth-child(5), .taches > *:nth-child(5), .anime-cascade > *:nth-child(5) { animation-delay: 240ms; }
.cartes-grille > *:nth-child(n+6), .taches > *:nth-child(n+6), .anime-cascade > *:nth-child(n+6) { animation-delay: 300ms; }

/* Messages flash : glissent depuis le haut. */
.succes:not(.tache):not(.badge), .erreur:not(.tache):not(.badge), .info:not(.tache):not(.badge), .attention:not(.tache):not(.badge) {
    animation: apparition-glisse var(--duree-moyenne) var(--courbe-sortie) both;
}

/* Onglets : le panneau affiché apparaît en fondu plutôt que brutalement. */
.onglet-panneau {
    animation: apparition-fondu var(--duree-moyenne) ease both;
}

/* Volets repliables (`<details>`) : le contenu révélé apparaît en fondu. */
details[open] > :not(summary) {
    animation: apparition-montee var(--duree-moyenne) var(--courbe-sortie) both;
}

/* Étape en cours du parcours : léger halo pulsé, deux fois seulement —
   attire l'œil sans clignoter en permanence. */
.parcours-etape.actuelle .parcours-puce {
    animation: halo-etape 1.6s ease-out 0.4s 2;
}

/* Transitions de page (Turbo Drive + View Transitions API, voir
   base.html.twig) : fondu enchaîné court ; la sidebar et le header restent
   fixes pendant la transition. */
::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: 0.22s;
}

.app-sidebar {
    view-transition-name: navigation-principale;
}

.app-header {
    view-transition-name: entete-principal;
}

/* Blocage du défilement pendant l'ouverture du menu mobile. */
html.menu-mobile-ouvert {
    overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        animation-delay: 0ms !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    ::view-transition-group(*),
    ::view-transition-old(*),
    ::view-transition-new(*) {
        animation: none !important;
    }
}

@media print {
    *,
    *::before,
    *::after {
        animation: none !important;
        transition: none !important;
    }
}
