/* Rhythmus und Bewegung.
 *
 * WAS HIER DRINSTEHT und was nicht:
 *
 * Hier steht, WIE sich etwas bewegt. In bewegung.js steht nur, WIE WEIT es
 * ist (--p am Element, --h an einem haltenden Abschnitt). Diese Trennung ist
 * der ganze Punkt: Wer die Bewegung aendern will, aendert eine CSS-Zeile und
 * nicht ein Skript, und wer das Skript liest, findet dort keine
 * Gestaltungsentscheidung.
 *
 * DIE ZWEI PROBLEME, gegen die das hier gebaut ist
 *
 * 1. STILLSTAND ZWISCHEN DEN EINBLENDUNGEN. Die Seite kannte nur "Element
 *    kommt ins Bild, Element blendet ein, fertig". Dazwischen - und das sind
 *    die meisten Pixel - stand alles. Jetzt haengt ein Teil der Bewegung am
 *    Scrollbalken selbst.
 *
 * 2. DAS LOCH IN DER MITTE. section#features war 2101 Pixel hoch, seine
 *    Inhalte zusammen 1481. Sechshundert Pixel Nichts, verteilt auf die
 *    Abstaende zwischen vier Zeilen. Auf dem Bildschirm sah das nicht nach
 *    Luft aus, sondern nach einem Fehler.
 *
 * DIE MASSE kommen aus dem Haus und sind nicht neu erfunden: die Kurve
 * cubic-bezier(.2,.7,.2,1) und die 0.75s stehen schon an .reveal in
 * styles-light.css. Was hier dazukommt, benutzt dieselben Werte - eine
 * zweite Zeitsprache neben der ersten waere genau der Fehler, den das
 * Stylesheet an .reveal schon einmal beschrieben hat.
 */

:root {
  /* Eine Kurve, ein Takt - fuer alles, was hier steht. */
  --bogen: cubic-bezier(.2, .7, .2, 1);
  --takt: .75s;
  --takt-kurz: .42s;
  /* Der senkrechte Grundabstand. Alle Abschnitte rechnen damit, statt jeder
     mit einer eigenen Zahl - dadurch bleibt der Rhythmus gleich, auch wenn
     einer dazukommt. */
  --luft: clamp(72px, 9vw, 132px);
}

/* ══ 1. Das Loch in der Mitte ═══════════════════════════════════════════════
   Die vier Zeilen in #features standen rund zweihundert Pixel auseinander.
   Zweihundert Pixel Leere zwischen zwei Zeilen, die zusammengehoeren, liest
   man nicht als Ruhe, sondern als Abbruch: Man glaubt, der Abschnitt sei zu
   Ende, und scrollt weiter, ohne den Rest gesehen zu haben.

   Jetzt tragen die Zeilen den Abstand selbst, alle denselben, und er ist
   knapp genug, dass die naechste Zeile beim Lesen der vorigen schon
   angeschnitten ist. Genau das haelt einen im Abschnitt. */
/* Der Abstand steht jetzt in system.css an .zeilen: Er ist eine Eigenschaft
   des Grundrisses und keine der Bewegung. Diese Datei rechnet nur noch mit
   --p. */

/* ══ 2. Bewegung am Scrollbalken ════════════════════════════════════════════
   --p geht von 0 auf 1, waehrend das Element von unten in die Bildmitte
   wandert. Was hier damit gerechnet wird, ist absichtlich klein: Eine Seite,
   auf der sich beim Scrollen alles bewegt, ist ein Jahrmarkt. Was sie teuer
   aussehen laesst, ist, dass sich WENIGES bewegt, dieses aber genau. */

/* Karten steigen die letzten Pixel heran und legen sich ab. 18 Pixel, mehr
   nicht - man soll es spueren und nicht sehen. */
[data-lauf] {
  --hub: 18px;
  transform: translate3d(0, calc((1 - var(--p, 1)) * var(--hub)), 0);
  will-change: transform;
}
/* Ist das Skript aus oder noch nicht gelaufen, steht --p nicht - dann greift
   der Vorgabewert 1 oben, und alles steht an seinem Platz. Eine Seite, die
   ohne JavaScript leer bleibt, ist kaputt und nicht zurueckhaltend. */

/* Der Schatten waechst mit: Was heranschwebt, wirft weiter; was liegt, wirft
   knapp. Das ist der Unterschied zwischen "eingeblendet" und "abgelegt". */
[data-lauf].hebt {
  box-shadow:
    0 calc((1 - var(--p, 1)) * 26px + 2px) calc((1 - var(--p, 1)) * 40px + 8px)
    rgba(12, 12, 16, calc((1 - var(--p, 1)) * .12 + .04));
}

/* Ueberschriften ziehen ein Stueck langsamer nach als ihr Abschnitt. Der
   Versatz ist winzig und macht den Unterschied zwischen "die Seite scrollt"
   und "die Seite bewegt sich". */
[data-lauf].zieht { --hub: 34px; }

/* AUF SCHMALEN SCHIRMEN ZIEHT DIE UEBERSCHRIFT NICHT.
 *
 * Der Versatz schiebt die Ueberschrift nach UNTEN, solange --p unter 1 steht,
 * und niemand reserviert dafuer Platz. Auf dem Schreibtisch faellt das nicht
 * auf, dort liegen zwischen Ueberschrift und Absatz genug Punkte. Auf dem
 * Telefon sind es sechzehn, und die Ueberschrift schob sich vierunddreissig
 * Punkte tief in ihren eigenen Absatz. Gemessen an vier Ueberschriften der
 * Startseite: achtzehn Punkte Ueberlappung, jedes Mal.
 *
 * Sie steht jetzt still, wo es eng ist. Sichtbar bleibt sie trotzdem: Die
 * Einblendung laeuft weiter, nur ohne den Versatz. Die Karten drueber und
 * drunter ziehen weiter ihre achtzehn, die haben ihren Platz.
 *
 * 900 und nicht 720: Das ist dieselbe Grenze, an der die Kopfzeile zum
 * Burger wird. Eine zweite Grenze waere eine zweite Wahrheit. */
@media (max-width: 900px) {
  [data-lauf].zieht { --hub: 0px; }
}

/* ══ 3. Staffeln ════════════════════════════════════════════════════════════
   --stufe kommt aus bewegung.js und zaehlt die Kinder durch. Damit
   verschwinden .d1 .d2 .d3 aus dem HTML: Die gab es nur dreimal, und beim
   Umsortieren stimmte die Reihenfolge nicht mehr, weil die Klasse am Element
   klebte statt an seiner Stelle. */
[data-staffel] > * { animation-delay: var(--stufe, 0ms) !important; }

/* ══ 4. Haltende Abschnitte ═════════════════════════════════════════════════
   --h laeuft von 0 bis 1, waehrend man an dem festgehaltenen Abschnitt
   vorbeiscrollt. Sparsam: EINER auf der Startseite. Ein zweiter waere kein
   Erzaehlmittel mehr, sondern ein Hindernis zwischen dem Kunden und dem
   Preis. */
[data-halt] { position: relative; }
[data-halt] > .halt-buehne {
  position: sticky;
  top: 0;
  min-height: 100vh;
  display: grid;
  place-items: center;
  overflow: clip;
}

/* ══ 5. Was beim Ueberfahren passiert ═══════════════════════════════════════
   Eine Karte, die sich beim Zeigen NICHT bewegt, fuehlt sich an wie ein Bild.
   Zwei Pixel reichen; wer vier nimmt, bekommt eine Seite, die wackelt. */
.pr-card, .frcard, .ae-card {
  transition: transform var(--takt-kurz) var(--bogen),
              box-shadow var(--takt-kurz) var(--bogen);
}
/* Hier stand: .pr-card:hover { transform: translate3d(0,-2px,0) }.
   Raus, und der Grund ist nicht Geschmack. Diese Datei wird NACH system.css
   geladen - die zwei Pixel haben also die ganze Karten-Bewegung ueberfahren,
   die dort steht (sechs Pixel anheben, Preis groesser, Lichtstreifen), und
   zwar auch dann, wenn jemand gar keine Bewegung will: Die Abschaltung in
   system.css konnte gegen eine spaetere Datei nichts ausrichten.

   Wie sich eine Karte beim Zeigen verhaelt, gehoert dorthin, wo die Karte
   definiert ist. Diese Datei rechnet mit --p und sonst nichts. */

/* ══ 6. Und wer keine Bewegung will ═════════════════════════════════════════
   Zum zweiten Mal, nach bewegung.js. Doppelt gemoppelt ist hier richtig: Die
   eine Stelle wird beim naechsten Umbau vergessen, und dann ist es eine
   Einstellung, die jemand gesetzt hat und die nichts mehr tut. */
@media (prefers-reduced-motion: reduce) {
  [data-lauf], [data-lauf].hebt, [data-lauf].zieht {
    transform: none !important;
    box-shadow: none;
    will-change: auto;
  }
  [data-staffel] > * { animation-delay: 0ms !important; }
  [data-halt] > .halt-buehne { position: static; min-height: 0; }
  .pr-card, .frcard, .ae-card { transition: none; }
}
