/* ==========================================================================
   transitions.css — transiciones entre páginas.
   Usa la View Transitions API entre documentos: navegación real, sin router.
   Los navegadores que no la soportan usan el fallback de page-transitions.js,
   que reproduce el mismo movimiento.
   ========================================================================== */

@view-transition { navigation: auto; }

:root {
  --fx-ease-out: cubic-bezier(.23, 1, .32, 1);
}

/* --------------------------------------------------------------------------
   El "chrome" persiste. Al darle identidad propia, la cabecera queda fuera
   del crossfade del root y no parpadea: se mantiene fija mientras el
   contenido barre por debajo. Es lo que evita que parezca un fundido genérico.
   -------------------------------------------------------------------------- */
.site-header { view-transition-name: site-header; }
main         { view-transition-name: page-main; }

/* OJO con `animation:none`: no borra la instantánea VIEJA, la deja pintada
   toda la transición debajo de la nueva. Mientras la nueva sea opaca no se
   nota, pero la cabecera móvil es transparente y el menú vive dentro de ella:
   por ahí se colaba la página anterior entera —la lámina naranja del menú y su
   logo flotando sobre el logo de la página entrante—. Lo que no se anima se
   OCULTA en su versión vieja; la nueva es la buena y se pinta ya en su sitio. */
::view-transition-old(root) { display: none; }
::view-transition-new(root) { animation: none; mix-blend-mode: normal; }

/* La cabecera persiste: ni se funde ni se desplaza. `group` va aparte porque
   es quien interpola posición y tamaño entre las dos instantáneas, y sin
   silenciarlo la barra se estiraba sola cuando la página saliente estaba
   scrolleada (`is-scrolled`) y la entrante no. */
::view-transition-group(site-header) { animation: none; }
::view-transition-old(site-header) { display: none; }
::view-transition-new(site-header) { animation: none; }

/* --------------------------------------------------------------------------
   La página entrante se descubre con la MISMA diagonal que las imágenes del
   sitio: el borde que avanza va inclinado, adelantado por arriba.
   -------------------------------------------------------------------------- */
@keyframes fx-sweep-from-left {
  from { clip-path: polygon(0% 0%, 0% 0%, -28% 100%, -28% 100%); }
  to   { clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%); }
}
@keyframes fx-sweep-from-right {
  from { clip-path: polygon(100% 0%, 100% 0%, 128% 100%, 128% 100%); }
  to   { clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%); }
}

/* La saliente no se desvanece: retrocede en profundidad. */
@keyframes fx-page-recede {
  from { transform: none;                              filter: blur(0);    opacity: 1; }
  to   { transform: scale(.955) translate3d(0,-2%,0);  filter: blur(7px);  opacity: 0; }
}

::view-transition-old(page-main) {
  animation: fx-page-recede .40s var(--fx-ease-out) both;
  will-change: transform, filter, opacity;
}
::view-transition-new(page-main) {
  animation: fx-sweep-from-left .58s var(--fx-ease-out) both;
  will-change: clip-path;
}

/* Dirección: hacia atrás en el orden del menú, la diagonal se invierte. */
:root[data-vt-dir="back"] ::view-transition-new(page-main) {
  animation-name: fx-sweep-from-right;
}

/* --------------------------------------------------------------------------
   PERFIL BAJO — `html.fx-low`
   (equipos con <=4 GB de RAM, <=4 nucleos o "ahorro de datos" activo; la
   clase la pone el snippet en linea del <head> de cada pagina).

   Por que hace falta: el barrido anima `clip-path` y el retroceso anima
   `filter:blur()`. Ninguna de las dos las resuelve el compositor, asi que el
   navegador vuelve a rasterizar la PANTALLA ENTERA en cada cuadro — unos 35
   rasterizados seguidos por transicion. En una maquina holgada no se nota; en
   una justa es exactamente la sensacion de trabado.

   Aqui no se quita la transicion: se conserva el mismo gesto (la entrante
   llega desde el lado que marca la direccion, la saliente cede terreno) con
   `translate3d` + `opacity`, que van enteras en el compositor. Es el mismo
   criterio que mobile-perf.css aplica en telefonos, ahora tambien para
   equipos de gama baja.

   Los fotogramas viven fuera de cualquier media query a proposito: los usan
   este bloque y mobile-perf.css, y un @keyframes declarado dentro de un
   @media solo existe mientras esa condicion se cumple.
   -------------------------------------------------------------------------- */
@keyframes fx-shift-in-right{
  from{opacity:0;transform:translate3d(14%,0,0)}
  to  {opacity:1;transform:translate3d(0,0,0)}
}
@keyframes fx-shift-in-left{
  from{opacity:0;transform:translate3d(-14%,0,0)}
  to  {opacity:1;transform:translate3d(0,0,0)}
}
@keyframes fx-shift-out-left{
  from{opacity:1;transform:translate3d(0,0,0)}
  to  {opacity:0;transform:translate3d(-8%,0,0)}
}
@keyframes fx-shift-out-right{
  from{opacity:1;transform:translate3d(0,0,0)}
  to  {opacity:0;transform:translate3d(8%,0,0)}
}

:root.fx-low::view-transition-new(page-main){
  animation:fx-shift-in-right .3s cubic-bezier(.22,.61,.36,1) both;
}
:root.fx-low::view-transition-old(page-main){
  animation:fx-shift-out-left .2s cubic-bezier(.4,0,1,1) both;
}
:root.fx-low[data-vt-dir="back"]::view-transition-new(page-main){
  animation-name:fx-shift-in-left;
}
:root.fx-low[data-vt-dir="back"]::view-transition-old(page-main){
  animation-name:fx-shift-out-right;
}

/* --------------------------------------------------------------------------
   Fallback (Firefox y Safari antiguos): mismo movimiento con clases.
   -------------------------------------------------------------------------- */
/* OJO: aqui NO va `will-change`. Esta regla aplica durante TODA la sesion en
   los navegadores sin View Transitions, asi que la pista promocionaria <main>
   —la pagina entera— a su propia capa de forma permanente y penalizaria el
   scroll de principio a fin. En los pseudo-elementos de arriba si vale: solo
   existen mientras dura la transicion. */
.vt-fallback main { animation: fx-sweep-from-left .58s var(--fx-ease-out) both; }
.vt-fallback[data-vt-dir="back"] main { animation-name: fx-sweep-from-right; }
.vt-fallback.vt-leaving main { animation: fx-page-recede .26s var(--fx-ease-out) both; will-change: transform, filter, opacity; }

/* Mismo relevo para el fallback en perfil bajo. */
.fx-low.vt-fallback main { animation: fx-shift-in-right .3s cubic-bezier(.22,.61,.36,1) both; }
.fx-low.vt-fallback[data-vt-dir="back"] main { animation-name: fx-shift-in-left; }
.fx-low.vt-fallback.vt-leaving main { animation: fx-shift-out-left .2s cubic-bezier(.4,0,1,1) both; }
.fx-low.vt-fallback[data-vt-dir="back"].vt-leaving main { animation-name: fx-shift-out-right; }

/* -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
  .vt-fallback main,
  .vt-fallback.vt-leaving main { animation: none !important; }
}
