/* =====================================================================
 * Ladevorhang und Seitenwechsel
 *
 * Beim Laden liegt ein schwarzer Vorhang mit der Bildmarke ueber der
 * Seite. Ist die Seite fertig, zieht sich das Schwarz von aussen als
 * Kreis auf die Bildmarke in der Mitte zusammen, die Marke schlaegt
 * einmal, dann wird alles durchsichtig.
 *
 * Beim Verlassen laeuft dieselbe Form rueckwaerts: der Kreis waechst
 * aus der Mitte nach aussen, bis der Bildschirm schwarz ist. Dann
 * wechselt die Seite.
 *
 * Ohne JavaScript ist der Vorhang nicht vorhanden. Der Inhalt darf nie
 * hinter einer Flaeche verschwinden, die niemand mehr wegnimmt.
 * ===================================================================== */

.fy-loader {
  display: none;
}

html.fy-js .fy-loader {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: grid;
  place-items: center;
  /* Bewusst der feste Markenwert, nicht die Variable: der Vorhang ist in
   * beiden Modi das Schwarz des Studios. */
  background-color: #0B0B0C;
  clip-path: circle(var(--fy-loader-full, 150%) at 50% 50%);
  will-change: clip-path, opacity;
  pointer-events: none;
}

/* Solange der Vorhang liegt, faengt er auch Klicks ab. */
html.fy-loading .fy-loader {
  pointer-events: auto;
}

/* Der Vorhang beim Seitenwechsel: aus der Mitte nach aussen. */
html.fy-js .fy-loader-out {
  clip-path: circle(0% at 50% 50%);
  animation: fy-loader-cover var(--fy-loader-cover, 460ms) var(--fy-ease, cubic-bezier(.22,.61,.24,1)) forwards;
}

@keyframes fy-loader-cover {
  from { clip-path: circle(0% at 50% 50%); }
  to   { clip-path: circle(var(--fy-loader-full, 150%) at 50% 50%); }
}

/* Das Zusammenziehen auf die Bildmarke. Der Endradius entspricht dem
 * halben Zeichen plus etwas Luft. */
html.fy-js .fy-loader-shrink {
  animation: fy-loader-shrink var(--fy-loader-shrink, 700ms) var(--fy-ease, cubic-bezier(.22,.61,.24,1)) forwards;
}

@keyframes fy-loader-shrink {
  from { clip-path: circle(var(--fy-loader-full, 150%) at 50% 50%); }
  to   { clip-path: circle(var(--fy-loader-r, 86px) at 50% 50%); }
}

/* Der Kreis bleibt beim Ausblenden klein.
 * Die Kurzform animation ersetzt die vorherige Animation, damit faellt
 * der Endwert des Zusammenziehens weg. Ohne diese feste Angabe wuerde
 * das Schwarz im letzten Moment wieder auf den ganzen Bildschirm
 * aufspringen. */
html.fy-js .fy-loader-done {
  clip-path: circle(var(--fy-loader-r, 86px) at 50% 50%);
  animation: fy-loader-fade var(--fy-loader-fade, 380ms) var(--fy-ease, cubic-bezier(.22,.61,.24,1)) forwards;
}

@keyframes fy-loader-fade {
  from { opacity: 1; }
  to   { opacity: 0; visibility: hidden; }
}

/* --- Die Bildmarke ---------------------------------------------------- */
.fy-loader-logo {
  display: block;
  width: auto;
  height: 92px;
  opacity: 0;
  animation: fy-loader-mark-in 420ms var(--fy-ease, cubic-bezier(.22,.61,.24,1)) 60ms forwards;
}

@keyframes fy-loader-mark-in {
  from { opacity: 0; transform: scale(0.94); }
  to   { opacity: 1; transform: scale(1); }
}

/* Ein einziger Schlag, sobald der Kreis die Marke erreicht hat. */
.fy-loader-pulse .fy-loader-logo {
  animation: fy-loader-beat var(--fy-loader-pulse, 420ms) var(--fy-ease, cubic-bezier(.22,.61,.24,1)) forwards;
}

@keyframes fy-loader-beat {
  0%   { opacity: 1; transform: scale(1); }
  42%  { opacity: 1; transform: scale(1.14); }
  100% { opacity: 1; transform: scale(1); }
}

/* Beim Verlassen bleibt der Kreis auf dem Telefon ganz im Bild. Mit
 * vollem Radius lief er nach wenigen Millisekunden ueber den Rand und war
 * nur noch eine schwarze Flaeche. Beim Laden gilt das nicht: dort ist der
 * Bildschirm wie auf dem Desktop erst ganz schwarz und zieht sich dann
 * auf die Bildmarke zusammen. */
@media (max-width: 767px) {
  .fy-loader-out {
    --fy-loader-full: 44vw;
  }
}

/* --- Bewegung respektieren --------------------------------------------
 * Wer weniger Bewegung eingestellt hat, bekommt keinen Vorhang. Die
 * Seite ist sofort da. Das ist die richtige Auslegung: der Vorhang ist
 * reine Inszenierung und traegt keine Information.                     */
@media (prefers-reduced-motion: reduce) {
  html.fy-js .fy-loader,
  html.fy-js .fy-loader-out {
    display: none;
    animation: none;
  }
}

/* Hat der Besucher Bewegung ausdruecklich eingeschaltet, gilt seine
 * Wahl. Die Media-Query oben bleibt die Voreinstellung. */
html.fy-js.fy-motion-on .fy-loader {
  display: grid;
}

html.fy-js.fy-motion-on .fy-loader-shrink {
  animation: fy-loader-shrink var(--fy-loader-shrink, 700ms) var(--fy-ease, cubic-bezier(.22,.61,.24,1)) forwards;
}

html.fy-js.fy-motion-on .fy-loader-done {
  animation: fy-loader-fade var(--fy-loader-fade, 380ms) var(--fy-ease, cubic-bezier(.22,.61,.24,1)) forwards;
}

html.fy-js.fy-motion-on .fy-loader-pulse .fy-loader-logo {
  animation: fy-loader-beat var(--fy-loader-pulse, 420ms) var(--fy-ease, cubic-bezier(.22,.61,.24,1)) forwards;
}

html.fy-js.fy-motion-on .fy-loader-out {
  display: grid;
  animation: fy-loader-cover var(--fy-loader-cover, 460ms) var(--fy-ease, cubic-bezier(.22,.61,.24,1)) forwards;
}
