/* Page transitions. Only <main> changes; header and footer keep their place.
   Each page's data-effect picks one of the animations below; router.js sets html[data-vt] and html[data-vt-dir].
   Every effect animates opacity and transform only, so it stays on the compositor (smooth on iPhone too). */

.page[hidden] {
  display: none;
}

/* Header and footer are excluded from the page swap. */
.site-header {
  view-transition-name: site-header;
}

.site-footer {
  view-transition-name: site-footer;
}

::view-transition-group(site-header),
::view-transition-new(site-header),
::view-transition-group(site-footer),
::view-transition-new(site-footer) {
  animation: none;
}

/* Only the live new header shows: the old snapshot would keep a closing menu frozen open underneath. */
::view-transition-old(site-header),
::view-transition-old(site-footer) {
  display: none;
}

/* The outgoing page always leaves the same way: a quick fade with a slight drift back. */
html[data-vt]::view-transition-old(root) {
  animation: fx-leave calc(var(--dur) * 0.5) var(--ease-in-out) both;
}

html[data-vt]::view-transition-new(root) {
  animation-duration: calc(var(--dur) * 1.1);
  animation-timing-function: var(--ease-out);
  animation-delay: calc(var(--dur) * 0.12);
  animation-fill-mode: both;
}

html[data-vt="rise"]::view-transition-new(root) { animation-name: fx-rise-in; }
html[data-vt="zoom"]::view-transition-new(root) { animation-name: fx-zoom-in; }
html[data-vt="lift"]::view-transition-new(root) { animation-name: fx-lift-in; }
html[data-vt="slide"][data-vt-dir="forward"]::view-transition-new(root) { animation-name: fx-slide-in-right; }
html[data-vt="slide"][data-vt-dir="back"]::view-transition-new(root) { animation-name: fx-slide-in-left; }

/* Fallback for browsers without View Transitions: the entering page plays the same effect. */
.page.is-entering {
  animation-duration: calc(var(--dur) * 1.1);
  animation-timing-function: var(--ease-out);
  animation-fill-mode: both;
}

.page.is-entering[data-effect="rise"] { animation-name: fx-rise-in; }
.page.is-entering[data-effect="zoom"] { animation-name: fx-zoom-in; }
.page.is-entering[data-effect="lift"] { animation-name: fx-lift-in; }
html[data-vt-dir="forward"] .page.is-entering[data-effect="slide"] { animation-name: fx-slide-in-right; }
html[data-vt-dir="back"] .page.is-entering[data-effect="slide"] { animation-name: fx-slide-in-left; }

@keyframes fx-leave {
  to { opacity: 0; transform: scale(0.985) translateY(-0.75rem); }
}

@keyframes fx-rise-in {
  from { opacity: 0; transform: translateY(2.5rem); }
  to { opacity: 1; transform: none; }
}

@keyframes fx-zoom-in {
  from { opacity: 0; transform: scale(1.04); }
  to { opacity: 1; transform: none; }
}

@keyframes fx-lift-in {
  from { opacity: 0; transform: translateY(1.5rem) scale(0.985); }
  to { opacity: 1; transform: none; }
}

@keyframes fx-slide-in-right {
  from { opacity: 0; transform: translateX(3rem); }
  to { opacity: 1; transform: none; }
}

@keyframes fx-slide-in-left {
  from { opacity: 0; transform: translateX(-3rem); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root),
  .page.is-entering {
    animation: none !important;
  }
}
