/*
  Transition zwischen Seiten.

  Der obere Block ist die Hauptsache: der Browser blendet selbst zwischen
  zwei Dokumenten ueber. Vier Zeilen, kein JavaScript, richtige
  Zurueck-Taste. Wo der Browser das noch nicht kann, springt transition.js
  mit einer einfachen Blende ein.

  Die Werte haengen an --tr-duration und --tr-ease. Stehen im Projekt eigene
  Tokens, kann man sie darauf zeigen lassen:
    :root { --tr-duration: var(--dauer); --tr-ease: var(--kurve); }
*/

:root {
  --tr-duration: .34s;
  --tr-ease: cubic-bezier(.22, 1, .36, 1);
  --tr-shift: 14px;
}

/* ---------------- 1. Der Browser macht es selbst ---------------- */

/* navigation: auto feuert auch bei Sprungmarken auf derselben Seite.
   Das sieht dann so aus: schwarze Balken von allen vier Seiten, und die
   Seite wird kurz zusammengeschoben. Es ist der Schnappschuss der alten
   Seite, der skaliert wird, und der Seitenhintergrund darunter.

   Ein Anker ist kein Seitenwechsel. Deshalb laeuft der Uebergang nur, wenn
   transition.js beim Klick bestaetigt hat, dass es wirklich einer ist. */
@view-transition { navigation: auto; }

html:not(.tr-going)::view-transition-old(root),
html:not(.tr-going)::view-transition-new(root) { animation: none; }

::view-transition-old(root) {
  animation: tr-out-anim var(--tr-duration) var(--tr-ease) both;
}
::view-transition-new(root) {
  animation: tr-in-anim var(--tr-duration) var(--tr-ease) both;
}

@keyframes tr-out-anim {
  to { opacity: 0; transform: translateY(calc(var(--tr-shift) * -.5)); }
}
@keyframes tr-in-anim {
  from { opacity: 0; transform: translateY(var(--tr-shift)); }
}

/* Was ueber den Wechsel hinweg stehenbleiben soll, bekommt einen Namen.
   Ein Kopf, der bei jedem Klick mitblendet, laesst die Seite flackern,
   obwohl er sich gar nicht aendert.

   ABER: nur waehrend des Wechsels. view-transition-name erzeugt einen
   eigenen Stapelkontext und Containment. Dauerhaft auf einem Kopf mit
   backdrop-filter und position: sticky gesetzt, laesst das die Leiste beim
   Scrollen flackern. Die Klasse setzt transition.js beim Klick, also genau
   dann, wenn der Name gebraucht wird. */
.tr-going .kopf,
.tr-going [data-persist] { view-transition-name: persist; }
::view-transition-group(persist) { animation-duration: var(--tr-duration); }

/* ---------------- 2. Ersatz, wo der Browser es nicht kann ---------------- */

.tr-fallback body {
  opacity: 0;
  transform: translateY(var(--tr-shift));
  transition: opacity var(--tr-duration) var(--tr-ease),
              transform var(--tr-duration) var(--tr-ease);
}
.tr-fallback.tr-in body { opacity: 1; transform: none; }
.tr-fallback.tr-out body {
  opacity: 0;
  transform: translateY(calc(var(--tr-shift) * -.5));
  /* Hinaus schneller als herein. Warten fuehlt sich laenger an als
     Ankommen, also dauert das Weggehen halb so lang. */
  transition-duration: calc(var(--tr-duration) * .55);
}

/* Ohne JavaScript bliebe die Seite unsichtbar stehen. Das ist der eine
   Fall, in dem eine Seite wirklich kaputt waere, deshalb blendet sie ohne
   JS gar nicht erst ab. */
.tr-fallback:not(.tr-in):not(.tr-out) body { animation: tr-failsafe 0s 1.2s forwards; }
@keyframes tr-failsafe { to { opacity: 1; transform: none; } }

/* ---------------- Ladezeichen, wenn gewuenscht ---------------- */
/* <body data-transition="lader"> */

[data-transition="lader"]::after {
  content: "";
  position: fixed;
  left: 0; top: 0;
  height: 2px; width: 0;
  z-index: 9999;
  background: var(--akzent, #ff4a17);
  pointer-events: none;
  opacity: 0;
}
.tr-out [data-transition="lader"]::after {
  width: 100%;
  opacity: 1;
  /* Laeuft schnell auf 90 Prozent und wartet dort. Ein Balken, der bis 100
     laeuft und dann stehenbleibt, sieht aus wie ein Fehler. */
  transition: width .5s cubic-bezier(.1, .9, .2, 1), opacity .12s;
}

/* ---------------- Ohne Motion ---------------- */

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
  .tr-fallback body,
  .tr-fallback.tr-out body { opacity: 1; transform: none; transition: none; }
  [data-transition="lader"]::after { display: none; }
}
