/* ═══════════════════════════════════════════════════════════════
   Alle @keyframes an einem Ort.

   Regel für alles hier drin: nur transform und opacity. Beides
   läuft auf der Grafikeinheit und ruckelt auch auf einem alten
   Android nicht. Sobald hier width, top oder filter animiert
   würde, wäre die Show auf dem Handy nicht mehr flüssig.
   ═══════════════════════════════════════════════════════════════ */

/* ─── Dauerbewegung: das leichte Leben in der Zeichnung ──────── */

@keyframes knopf-wippt {
  0%, 100% { transform: rotate(-1.2deg) translateY(0); }
  50%      { transform: rotate(1.2deg) translateY(-3px); }
}

@keyframes schweben {
  0%, 100% { transform: translateY(0) rotate(-1deg); }
  50%      { transform: translateY(-10px) rotate(1deg); }
}

@keyframes wackeln {
  0%, 100% { transform: rotate(-2deg); }
  50%      { transform: rotate(2deg); }
}

@keyframes zappeln {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  20%      { transform: translate(-2px, 1px) rotate(-1.5deg); }
  40%      { transform: translate(2px, -1px) rotate(1.5deg); }
  60%      { transform: translate(-1px, -2px) rotate(-1deg); }
  80%      { transform: translate(1px, 2px) rotate(1deg); }
}

@keyframes huepfen {
  0%, 100% { transform: translateY(0)     scaleY(1); }
  15%      { transform: translateY(0)     scaleY(.9) scaleX(1.06); }
  45%      { transform: translateY(-22px) scaleY(1.05) scaleX(.96); }
  75%      { transform: translateY(0)     scaleY(.94) scaleX(1.04); }
}

@keyframes pulsieren {
  0%, 100% { transform: scale(1);    opacity: 1;   }
  50%      { transform: scale(1.06); opacity: .82; }
}

/* ─── „Boiling Line" ──────────────────────────────────────────────
   Der klassische Trick aus der Handzeichnung: zwei minimal
   verschiedene Fassungen derselben Figur wechseln sich mit rund
   8 Bildern pro Sekunde ab. Die Konturen scheinen zu kochen, die
   Zeichnung wirkt lebendig — ohne dass sich irgendetwas bewegt.

   steps() ist hier wichtig: Es soll hart umspringen wie im
   Daumenkino, nicht weich überblenden.                           */

.kocht > .fassung        { animation: kochen-a .25s steps(1) infinite; }
.kocht > .fassung + .fassung { animation: kochen-b .25s steps(1) infinite; }

@keyframes kochen-a { 0%, 49.9% { opacity: 1; } 50%, 100% { opacity: 0; } }
@keyframes kochen-b { 0%, 49.9% { opacity: 0; } 50%, 100% { opacity: 1; } }

/* ─── Sich selbst zeichnen ────────────────────────────────────────
   stroke-dashoffset von der Pfadlänge auf 0. Die Pfadlänge wird
   per pathLength="1" im SVG normiert, damit hier überall
   dieselben Zahlen stehen können.                                */

.zeichnet {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: strich-zieht var(--zeichen-dauer, .9s) ease-out forwards;
  animation-delay: var(--zeichen-start, 0s);
}

@keyframes strich-zieht { to { stroke-dashoffset: 0; } }

/* Flächen werden nicht gezeichnet, sondern „ausgemalt": sie
   blenden kurz nach ihrer Kontur ein.

   Der Keyframe hat absichtlich nur ein from und kein to. Dann
   nimmt der Browser als Ziel den eigenen berechneten Wert des
   Elements — und die Flächen landen bei ihrer jeweiligen
   Deckkraft (.88 aus draw.css, bei manchen .5 oder .7) statt alle
   stumpf bei 1. Mit fill-mode backwards gilt vor dem Start der
   from-Zustand und danach wieder das normale Stylesheet. */
.malt-aus {
  /* Ohne fill-box bezöge sich das scale() im Keyframe auf die
     Mitte der gesamten viewBox — jede Fläche würde beim Einblenden
     quer über das Bild rutschen statt an Ort und Stelle zu wachsen. */
  transform-box: fill-box;
  transform-origin: center;
  animation: ausmalen .5s ease-out backwards;
  animation-delay: var(--zeichen-start, 0s);
}

@keyframes ausmalen {
  from { opacity: 0; transform: scale(.94); }
}

/* ─── Auftritte ──────────────────────────────────────────────── */

@keyframes ploppt-rein {
  0%   { opacity: 0; transform: scale(.4) rotate(-12deg); }
  70%  { opacity: 1; transform: scale(1.12) rotate(3deg); }
  100% { opacity: 1; transform: scale(1) rotate(0deg); }
}

@keyframes faellt-rein {
  0%   { opacity: 0; transform: translateY(-40px) rotate(-8deg); }
  60%  { opacity: 1; transform: translateY(6px) rotate(2deg); }
  100% { opacity: 1; transform: translateY(0) rotate(0deg); }
}

@keyframes steigt-auf {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes verschwindet {
  from { opacity: 1; transform: scale(1); }
  to   { opacity: 0; transform: scale(.85); }
}

.ploppt      { animation: ploppt-rein .5s cubic-bezier(.2, 1.5, .5, 1) both; }
.faellt      { animation: faellt-rein .6s cubic-bezier(.3, 1.3, .6, 1) both; }
.steigt      { animation: steigt-auf .55s ease-out both; }
.verschwindet{ animation: verschwindet .35s ease-in forwards; }

/* Einzelne Buchstaben im Titel. Die Anfangs- und Endwerte müssen
   die Kritzel-Variablen mitführen, sonst würde die Animation die
   Neigung aus draw.css wieder plattbügeln. */
.buchstabe { opacity: 0; }

.buchstabe.kommt {
  animation: buchstabe-kritzelt .38s cubic-bezier(.2, 1.4, .5, 1) both;
}

@keyframes buchstabe-kritzelt {
  0% {
    opacity: 0;
    transform: translateY(calc(var(--hoch, 0px) + 20px))
               rotate(calc(var(--kipp, 0deg) - 16deg)) scale(.45);
  }
  70% {
    opacity: 1;
    transform: translateY(var(--hoch, 0)) rotate(var(--kipp, 0deg))
               scale(calc(var(--gross, 1) * 1.18));
  }
  100% {
    opacity: 1;
    transform: translateY(var(--hoch, 0)) rotate(var(--kipp, 0deg))
               scale(var(--gross, 1));
  }
}

/* ─── Ballons ────────────────────────────────────────────────── */

@keyframes ballon-steigt {
  0%   { opacity: 0; transform: translateY(30dvh) rotate(-6deg); }
  12%  { opacity: 1; }
  100% { opacity: 1; transform: translateY(0) rotate(4deg); }
}

@keyframes ballon-treibt {
  0%, 100% { transform: translateX(0) rotate(-4deg); }
  50%      { transform: translateX(12px) rotate(4deg); }
}

/* ─── Sonne ──────────────────────────────────────────────────── */

@keyframes sonne-dreht {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ─── Kuh ────────────────────────────────────────────────────── */

@keyframes schwanz-pendelt {
  0%, 100% { transform: rotate(-14deg); }
  50%      { transform: rotate(16deg); }
}

@keyframes ohr-zuckt {
  0%, 88%, 100% { transform: rotate(0deg); }
  92%           { transform: rotate(-16deg); }
  96%           { transform: rotate(9deg); }
}

@keyframes blinzeln {
  0%, 92%, 100% { transform: scaleY(1); }
  95%           { transform: scaleY(.08); }
}

@keyframes kauen {
  0%, 100% { transform: translateY(0) scaleX(1); }
  50%      { transform: translateY(1.5px) scaleX(1.05); }
}

@keyframes glocke-schwingt {
  0%, 100% { transform: rotate(-9deg); }
  50%      { transform: rotate(9deg); }
}

@keyframes kuh-steigt-aus-karton {
  0%   { opacity: 0; transform: translateY(90px) scale(.6); }
  55%  { opacity: 1; transform: translateY(-14px) scale(1.06); }
  75%  { transform: translateY(6px) scale(.98); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

/* ─── Metzger ─────────────────────────────────────────────────────
   Die Beine sind ein Zweibild-Daumenkino, genau wie die
   Boiling Line — steps(1), damit es hart umspringt.              */

@keyframes metzger-laeuft {
  from { transform: translateX(-58vw); }
  to   { transform: translateX(0); }
}

@keyframes beine-wechseln {
  0%, 49.9% { opacity: 1; } 50%, 100% { opacity: 0; }
}
@keyframes beine-wechseln-b {
  0%, 49.9% { opacity: 0; } 50%, 100% { opacity: 1; }
}

@keyframes koerper-wippt {
  0%, 100% { transform: translateY(0) rotate(-1deg); }
  50%      { transform: translateY(-5px) rotate(1deg); }
}

@keyframes messer-holt-aus {
  0%   { transform: rotate(0deg); }
  55%  { transform: rotate(-72deg); }
  70%  { transform: rotate(-80deg); }
  100% { transform: rotate(38deg); }
}

/* ─── Der Schnitt ────────────────────────────────────────────── */

@keyframes blitzt {
  0%   { opacity: 0; }
  8%   { opacity: .95; }
  100% { opacity: 0; }
}

@keyframes buehne-bebt {
  0%, 100% { transform: translate(0, 0); }
  10% { transform: translate(-9px, 5px) rotate(-.6deg); }
  25% { transform: translate(8px, -6px) rotate(.5deg); }
  40% { transform: translate(-6px, -4px) rotate(-.4deg); }
  55% { transform: translate(5px, 5px) rotate(.3deg); }
  70% { transform: translate(-3px, -2px); }
  85% { transform: translate(2px, 1px); }
}

@keyframes wolke-quillt {
  0%   { opacity: 0; transform: scale(.2) rotate(-20deg); }
  22%  { opacity: 1; transform: scale(1.14) rotate(6deg); }
  45%  { transform: scale(1) rotate(-4deg); }
  70%  { opacity: 1; transform: scale(1.05) rotate(3deg); }
  100% { opacity: 0; transform: scale(1.3) rotate(-6deg); }
}

@keyframes wolke-rumpelt {
  0%, 100% { transform: rotate(-3deg) scale(1); }
  33%      { transform: rotate(4deg) scale(1.04); }
  66%      { transform: rotate(-2deg) scale(.97); }
}

@keyframes zack-knallt {
  0%   { opacity: 0; transform: scale(.2) rotate(-25deg); }
  35%  { opacity: 1; transform: scale(1.3) rotate(8deg); }
  55%  { transform: scale(1) rotate(-6deg); }
  80%  { opacity: 1; transform: scale(1.05) rotate(-9deg); }
  100% { opacity: 0; transform: scale(1.15) rotate(-12deg); }
}

/* ─── Engel-Kuh ──────────────────────────────────────────────── */

@keyframes engel-schwebt-hoch {
  0%   { opacity: 0; transform: translateY(30px) scale(.85); }
  18%  { opacity: .9; transform: translateY(0) scale(1); }
  70%  { opacity: .8; }
  100% { opacity: 0; transform: translateY(-72dvh) scale(.62); }
}

@keyframes fluegel-schlagen {
  0%, 100% { transform: rotate(-16deg) scaleY(1); }
  50%      { transform: rotate(14deg) scaleY(.82); }
}

@keyframes winken {
  0%, 100% { transform: rotate(-22deg); }
  50%      { transform: rotate(18deg); }
}

@keyframes heiligenschein-glimmt {
  0%, 100% { opacity: .75; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.07); }
}

/* ─── Das Finale mit der Fleischbox ──────────────────────────── */

@keyframes blendet-auf {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Die Vorderwand kommt von unten. Dadurch wirkt es, als werde die
   Kiste um den fertigen Stapel herum gebaut — und nicht, als sei
   der Stapel schon immer darin gewesen. */
@keyframes kiste-schiebt-hoch {
  0%   { opacity: 0; transform: translateY(38px); }
  70%  { opacity: 1; transform: translateY(-4px); }
  100% { opacity: 1; transform: translateY(0); }
}

@keyframes glanz-wandert {
  0%   { transform: translateX(-140%) skewX(-18deg); opacity: 0; }
  18%  { opacity: .9; }
  75%  { opacity: .9; }
  100% { transform: translateX(240%) skewX(-18deg); opacity: 0; }
}

/* ─── Die Gitarre ────────────────────────────────────────────────
   Drei Bewegungen im selben Takt, aber nicht im Gleichschritt: die
   Schlaghand schrammelt doppelt so schnell wie der Kopf nickt, und
   das Haar hinkt dem Kopf hinterher (die Verzögerung steht in
   scenes.css). Zusammen ergibt das den Eindruck von Musik.       */

@keyframes schrammelt {
  0%, 100% { transform: rotate(-13deg); }
  50%      { transform: rotate(11deg); }
}

@keyframes headbangt {
  0%, 100% { transform: rotate(-4deg)  translateY(0); }
  45%      { transform: rotate(9deg)   translateY(3px); }
}

@keyframes haar-schwingt {
  0%, 100% { transform: rotate(-5deg); }
  50%      { transform: rotate(6deg); }
}

/* ═══════════════════════════════════════════════════════════════
   Bewegung reduzieren.

   Nicht alles abschalten — dann stünde die Show still und man
   käme nicht mehr durch. Stattdessen: Dauerschleifen aus (das
   sind die, die stören), Auftritte auf ein kurzes Einblenden
   zusammengestrichen. Bedienbar bleibt alles.
   ═══════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {

  /* Dauerschleifen komplett still */
  .kocht > .fassung,
  .kocht > .fassung + .fassung {
    animation: none;
  }
  .kocht > .fassung           { opacity: 1; }
  .kocht > .fassung + .fassung { opacity: 0; }

  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .1s !important;
  }

  /* Diese vier müssen ihren Endzustand trotzdem erreichen,
     sonst bleibt die Bühne leer. */
  .zeichnet    { stroke-dashoffset: 0; }
  .malt-aus,
  .ploppt, .faellt, .steigt { opacity: 1; transform: none; }
}
