/* Transition entre les vues du menu.

   Deux calques identiques se relaient autour d'un changement de page :
   - le composant React PageTransition recouvre l'écran au clic sur un lien de la
     sidebar, puis lance la navigation une fois l'écran couvert : le chargement
     de la vue se fait donc derrière le calque ;
   - le calque rendu par partials/_page_transition.html.twig arrive déjà couvert
     dans le HTML de la page suivante, et se retire au chargement.
   Le raccord est donc invisible même si la navigation est un rechargement
   complet de page. */

/* Le scintillement blanc entre deux pages est l'image que le navigateur peint
   entre l'abandon de l'ancien document et le premier rendu du suivant. Les
   transitions de vue inter-documents suppriment cette image : le navigateur
   garde l'ancien écran (déjà recouvert) jusqu'à ce que le suivant soit prêt.
   Ignoré par les navigateurs qui ne les gèrent pas encore. */
@view-transition {
    navigation: auto;
}

/* Le fondu par défaut dure 0,25 s, trop long ici : les deux écrans sont déjà
   identiques (panneau plein + icône), un raccord court suffit. */
::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: 0.15s;
}

:root {
    --pt-panneau-premier: var(--primary-color, #EA0069);
    --pt-panneau-second: var(--Blue, #121432);
    /* Le recouvrement doit suivre le clic : court, et couvrant dès le début de
       sa course. Le dévoilement peut être plus posé. */
    --pt-duree-couverture: 0.42s;
    --pt-duree-devoilement: 0.5s;
    --pt-easing-couverture: cubic-bezier(0.22, 1, 0.36, 1);
    --pt-easing-devoilement: cubic-bezier(0.65, 0, 0.35, 1);
    --pt-taille-icone: clamp(72px, 9vw, 120px);
}

.page-transition {
    position: fixed;
    inset: 0;
    /* La sidebar monte à 9999 : le calque doit passer au-dessus. */
    z-index: 10000;
    pointer-events: none;
}

.page-transition__panel {
    position: absolute;
    inset: 0;
    transform: scaleX(0);
    transform-origin: left;
}

.page-transition__panel--premier {
    background: var(--pt-panneau-premier);
}

.page-transition__panel--second {
    background: var(--pt-panneau-second);
}

.page-transition__icon {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #FFFFFF;
    opacity: 0;
}

.page-transition__icon svg {
    width: var(--pt-taille-icone);
    height: var(--pt-taille-icone);
    stroke-width: 1.5;
}

.page-transition__icon img {
    width: auto;
    height: var(--pt-taille-icone);
}

/* Même traitement que dans la sidebar : les icônes SVG monochromes sont
   teintées en blanc par filtre, le logo (PNG couleur) reste tel quel. */
.page-transition__icon img[src$=".svg"] {
    filter: brightness(0) saturate(100%) invert(100%);
}

/* --- Recouvrement, joué au clic sur un lien du menu --- */

.page-transition--cover {
    visibility: hidden;
}

.page-transition--cover.is-covering {
    visibility: visible;
}

.is-covering .page-transition__panel--premier {
    animation: pt-panneau-entre var(--pt-duree-couverture) var(--pt-easing-couverture) forwards;
}

.is-covering .page-transition__panel--second {
    animation: pt-panneau-entre var(--pt-duree-couverture) var(--pt-easing-couverture) 0.06s forwards;
}

/* L'icône finit sa course avant le panneau : la dernière image de la page
   quittée est alors exactement la première de la page d'arrivée. Elle respire
   ensuite tant que la vue suivante se charge, pour que l'attente reste vivante. */
.is-covering .page-transition__icon {
    animation:
        pt-icone-entre 0.3s var(--pt-easing-couverture) 0.12s forwards,
        pt-icone-respire 1.4s ease-in-out 0.5s infinite;
}

@keyframes pt-panneau-entre {
    from { transform: scaleX(0); }
    to { transform: scaleX(1); }
}

@keyframes pt-icone-entre {
    from { opacity: 0; transform: translate3d(-8vw, 0, 0); }
    to { opacity: 1; transform: translate3d(0, 0, 0); }
}

@keyframes pt-icone-respire {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.07); }
}

/* --- Dévoilement, joué quand la vue d'arrivée est rendue --- */

/* Le calque reste en place tant que le composant PageTransition n'a pas posé
   « is-revealing » : sans cette attente, il se retirerait sur une zone de
   contenu encore vide, et la page clignoterait en blanc le temps que React
   monte la vue. */
.page-transition--reveal .page-transition__panel--second {
    transform: scaleX(1);
    transform-origin: right;
}

.page-transition--reveal .page-transition__icon {
    opacity: 1;
    animation: pt-icone-respire 1.4s ease-in-out infinite;
}

.page-transition--reveal.is-revealing .page-transition__panel--second {
    animation: pt-panneau-sort var(--pt-duree-devoilement) var(--pt-easing-devoilement) forwards;
}

/* L'icône s'efface avant que le bord du panneau ne la dépasse, sinon elle
   flotterait un instant au-dessus de la page déjà découverte. Elle continue de
   respirer pendant qu'elle s'efface, sinon sa pulsation s'arrêterait net. */
.page-transition--reveal.is-revealing .page-transition__icon {
    animation:
        pt-icone-respire 1.4s ease-in-out infinite,
        pt-icone-sort 0.18s var(--pt-easing-devoilement) forwards;
}

/* Filet pour les navigateurs sans transition de vue : si le nouveau document est
   peint avant que son contenu ne soit posé, le fond de page est déjà celui du
   calque, jamais du blanc. Le body occupe alors toute la hauteur visible pour
   que ce fond ne déborde plus une fois la page découverte. */
html:has(.page-transition--reveal) {
    background: var(--pt-panneau-second);
}

html:has(.page-transition--reveal) body {
    min-height: 100vh;
}

/* Filet : le balayage dépend du JS, pas l'effacement du calque. Si le bundle ne
   se charge jamais, l'écran se libère quand même. Dans le cas normal, le calque
   est déjà transparent bien avant. */
.page-transition--reveal {
    animation: pt-calque-masque 0.01s linear 4s forwards;
}

@keyframes pt-panneau-sort {
    from { transform: scaleX(1); }
    to { transform: scaleX(0); }
}

@keyframes pt-icone-sort {
    from { opacity: 1; }
    to { opacity: 0; }
}

@keyframes pt-calque-masque {
    to { visibility: hidden; }
}

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

    /* Le raccord entre documents reste utile (il évite l'image blanche), mais
       sans fondu. */
    ::view-transition-old(root),
    ::view-transition-new(root) {
        animation: none;
    }
}
