/* ═══════════════════════════════════════════════════════════════════
   KAÏROMOD - Transitions de page
   ---------------------------------------------------------------
   OBJECTIF : que le changement de page ne se remarque pas. Pas qu'il
   soit joli - qu'il soit invisible. Tout ce qui suit découle de là.

   ── CE QUI REND UN CHANGEMENT DE PAGE FLUIDE ──
   Ce n'est pas l'animation, c'est l'absence d'attente. Une page déjà
   prête s'affiche d'un coup et rien ne tremble ; une page qui se charge
   pendant qu'on l'anime tremble quoi qu'on fasse. Le vrai travail est
   donc dans js/page-transitions.js, qui prépare les pages à l'avance.
   Ici, on se contente de ne pas nuire.

   ── CE QUI A ÉTÉ ESSAYÉ PUIS RETIRÉ ──
   Un glissement directionnel : les pages entrant par la droite à
   l'aller, par la gauche au retour. Élégant sur le papier, sale à
   l'écran, pour deux raisons qui tiennent à la nature même du procédé :

     · une capture de page occupe exactement le cadre ; la décaler
       découvre une bande de fond sur le bord opposé ;
     · pendant le déplacement, les deux pages se superposent en
       transparence et on lit le texte de l'une à travers l'autre.

   Aucun réglage ne supprime ces deux effets - seul l'abandon du
   déplacement y parvient. Il ne reste donc AUCUNE transformation : ni
   glissement, ni zoom, ni échelle. Le seul mouvement est une variation
   d'opacité, la seule qui ne puisse rien découvrir.

   Une barre de navigation animée à part (view-transition-name) a été
   retirée pour la même raison : sortir un élément de la photo y laisse
   un trou que son calque doit recouvrir au pixel près. Un risque réel
   pour un gain nul dès lors que plus rien ne glisse dessous.

   Support : Chrome/Edge 126+, Safari 18.2+, Opera, Samsung Internet.
   Ailleurs le fichier est ignoré sans erreur.
   ═══════════════════════════════════════════════════════════════════ */

/* NOTE - pas de scrollbar-gutter:stable ici : la gouttière réservée reste
   visible quand la scrollbar disparaît (modale ouverte) et laisse voir le
   fond de <html>, blanc sur sa moitié haute → un liseré blanc le long du
   bord droit. La compensation du verrouillage se fait en padding-right
   (JS) + rattrapage des éléments en position:fixed dans chaque page. */

/* Activé ici, désactivé par js/page-transitions.js là où il ne peut pas
   être propre : mobile et webviews d'applications. */
@view-transition{ navigation: auto; }

/* Le navigateur fusionne par défaut les deux plans en mode additif
   (plus-lighter) : correct pour son crossfade natif, mais provoque un
   éclair blanc entre deux pages claires → fusion normale. */
::view-transition-image-pair(root){ isolation: auto; }
::view-transition-old(root),
::view-transition-new(root){ mix-blend-mode: normal; }

/* ── L'ANCIENNE PAGE NE BOUGE PAS ET NE S'EFFACE PAS ──────────────
   Elle reste immobile et pleinement opaque pendant toute la durée, et
   sert de fond à la nouvelle. C'est ce qui garantit qu'à aucun instant
   on ne puisse voir à travers : deux plans semi-transparents superposés
   laissent passer ce qu'il y a derrière, un plan opaque non. Elle
   disparaît d'un coup à la fin, quand la nouvelle la recouvre
   entièrement - donc invisiblement. */
::view-transition-old(root){ animation: none; }

/* ── LA NOUVELLE PAGE APPARAÎT, ET C'EST TOUT ─────────────────────
   160 ms : assez pour que l'œil ne perçoive pas de coupure franche,
   trop peu pour qu'il ait le temps de lire les deux pages à la fois.
   C'est ce dédoublement, et non la durée, qui se remarque - allonger
   pour « faire plus doux » produit exactement l'inverse.

   linear, et non une courbe d'accélération : sur une simple opacité, une
   courbe fait passer plus de temps dans les valeurs intermédiaires, donc
   dans le dédoublement. */
::view-transition-new(root){
  animation:
    km-vt-apparait 180ms linear both,
    km-vt-pose 420ms cubic-bezier(.16,1,.3,1) both;
}
@keyframes km-vt-apparait{
  from{ opacity: 0; }
  to{ opacity: 1; }
}
/* ── UNE POSE, PAS UN GLISSEMENT ──────────────────────────────────
   La nouvelle page monte de 14 px et reprend sa taille depuis 99 %,
   en décélérant longtemps. Ce n'est pas le glissement retiré plus
   haut : celui-ci déplaçait les DEUX pages, et découvrait le fond sur
   un bord. Ici l'ancienne page reste pleine et opaque dessous, le
   décalage ne peut donc découvrir qu'elle, et il est fini avant que
   l'opacité ait laissé le temps de lire deux textes à la fois : le
   mouvement se sent, il ne se voit pas. L'opacité reste linéaire et
   courte pour la raison donnée plus haut ; seule la pose s'étire. */
@keyframes km-vt-pose{
  from{ transform: translateY(14px) scale(.99); }
  to{ transform: none; }
}

/* Mouvement réduit : bascule instantanée. */
@media (prefers-reduced-motion: reduce){
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*){ animation: none !important; }
}

/* Blocs déjà présents à l'écran quand la page arrive par une transition :
   js/page-transitions.js les marque pour qu'ils soient photographiés en
   place, sans leur animation d'entrée. Sans cela la page arrive vide et
   son contenu monte à l'écran juste après - deux mouvements successifs là
   où l'œil en attend un. !important parce que les règles .reveal vivent
   dans le style de chaque page et sont plus spécifiques. */
.km-deja-la{
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
  animation: none !important;
}

/* ── Fondu de secours pour les retours (bouton « précédent ») ──
   Piloté par js/page-transitions.js, et PC uniquement : voile posé quand
   le navigateur ne joue PAS la transition native sur une navigation
   retour/avant (restauration bfcache, support partiel), puis levé en
   fondu.

   Volontairement absent du mobile : c'est ce voile, et non la transition
   native, qui pouvait rester bloqué sur un écran noir dans les webviews
   d'applications. */
html.km-return::after{
  content: ""; position: fixed; inset: 0; z-index: 2147483000;
  /* Couleur réglable par page : un voile noir qui se lève sur une page
     claire produit exactement l'éclair qu'il est censé masquer. Les pages
     dont le haut est clair redéfinissent --km-veil ; le noir reste le
     défaut, c'est la couleur du corps du site. */
  background: var(--km-veil, #080808); pointer-events: none;
}
html.km-return-lift::after{
  animation: km-return-lift .3s linear both;
}
@keyframes km-return-lift{ from{ opacity: 1; } to{ opacity: 0; } }
