/* ===========================================================================
   KONZEPT "SOUL" — Bewegungsschicht, Teil 1 von 2 (das Aussehen)
   Gehoert zu _soul-bewegung.js. Ohne das Skript passiert hier fast nichts:
   jede Regel, die etwas versteckt, haengt an .hat-js — und diese Klasse
   setzt ausschliesslich das Skript. Faellt es aus oder ist JavaScript
   abgeschaltet, steht die Seite vollstaendig lesbar da.

   Eingeblendet wird mit ANIMATIONEN, nicht mit Uebergaengen. Zwei Gruende:
   1. _soul.css setzt bei prefers-reduced-motion "*{transition-duration:
      .001ms!important}" — das wuerde jeden Uebergang toeten, auch den
      erzwungenen Pruefbetrieb.
   2. Nach der Animation nimmt das Skript die Klasse .bw-fertig dazu.
      Dann greift von hier gar keine Regel mehr, und die eigenen
      Uebergaenge der Bauteile (z. B. .karte:hover) laufen unberuehrt weiter.
   =========================================================================== */

:root{
  --bw-weg:26px;                            /* Weg von unten, Standard      */
  --bw-dauer:.72s;
  --bw-dauer-zeile:.9s;
  --bw-kurve:cubic-bezier(.22,.62,.24,1);   /* satt gebremst, kein Federn   */
  --bw-zeile-weg:140%;                      /* Zeile startet unter der Maske */
}

/* ---------------------------------------------------------------------------
   Kopfbild: die Leinwand ist hoeher als ihr Rahmen.
   Nur so kann sie beim Scrollen zurueckbleiben, ohne unten eine Luecke zu
   reissen. Die Regel steht bewusst NICHT hinter .hat-js: _soul.js misst die
   Leinwand beim Zeichnen, und die Groesse muss vor dem ersten Bild stehen.
   Ohne Skript ist die Leinwand schlicht 26 % zu hoch — .oben schneidet ab,
   das Schindelmuster ist ueberall gleich, man sieht keinen Unterschied.
   --------------------------------------------------------------------------- */
#wand{height:126%;bottom:auto;will-change:translate}

/* ---------------------------------------------------------------------------
   Weiches Scrollen
   Das Skript setzt die Rollposition Bild fuer Bild selbst. Das native
   "scroll-behavior:smooth" aus _soul.css wuerde dagegenhalten und sich
   aufschaukeln. .weich-an setzt das Skript nur dann, wenn es die Fuehrung
   wirklich uebernimmt (Zeigegeraet mit feiner Spitze, keine Ruhe verlangt).
   --------------------------------------------------------------------------- */
.weich-an{scroll-behavior:auto}

/* ---------------------------------------------------------------------------
   Einblendungen
   --------------------------------------------------------------------------- */
/* Bewegt wird ueber die eigenstaendige Eigenschaft "translate", nicht ueber
   "transform". Der Unterschied ist hier entscheidend: mehrere Bauteile
   bringen ihr eigenes transform mit (die Wortmarke steht mit
   translateX(-50%) mittig, der Hinweis "Weiter" ebenso, Karten heben sich
   beim Zeigen). transform wuerde das ueberschreiben und die Marke waehrend
   der Einblendung nach rechts werfen. translate legt sich davor, beides
   gilt gleichzeitig. */
@keyframes bw-auf{
  from{opacity:0;translate:0px var(--bw-weg)}
  to{opacity:1;translate:none}
}
@keyframes bw-blende{
  from{opacity:0}
  to{opacity:1}
}
@keyframes bw-zeile{
  from{translate:0px var(--bw-zeile-weg)}
  to{translate:none}
}

/* -- einzeln: das Element selbst steigt auf ------------------------------- */
.hat-js [data-auf-modus="einzeln"]:not(.bw-fertig){
  opacity:0;translate:0px var(--bw-weg);
  will-change:opacity,translate;
}
.hat-js [data-auf-modus="einzeln"].ist-da:not(.bw-fertig){
  animation:bw-auf var(--bw-dauer) var(--bw-kurve) var(--bw-verzug,0ms) both;
}

/* -- blende: nur Deckkraft, kein Weg (fuer grosse Flaechen und Laufbaender) */
.hat-js [data-auf-modus="blende"]:not(.bw-fertig){
  opacity:0;will-change:opacity;
}
.hat-js [data-auf-modus="blende"].ist-da:not(.bw-fertig){
  animation:bw-blende var(--bw-dauer) var(--bw-kurve) var(--bw-verzug,0ms) both;
}

/* -- kinder: die direkten Kindelemente steigen gestaffelt auf ------------- */
.hat-js [data-auf-modus="kinder"] > *:not(.bw-fertig){
  opacity:0;translate:0px var(--bw-weg);
  will-change:opacity,translate;
}
.hat-js [data-auf-modus="kinder"].ist-da > *:not(.bw-fertig){
  animation:bw-auf var(--bw-dauer) var(--bw-kurve) var(--bw-verzug,0ms) both;
}

/* -- schnitt: an <br> zerlegte Zeilen steigen hinter einer Maske hoch -----
   Geschnitten wird mit clip-path, nicht mit overflow:hidden. Anton laeuft
   bei line-height .86 oben und unten aus seinem Zeilenkasten heraus
   (Umlautpunkte, Komma); ein harter Kasten wuerde sie abschneiden. Die
   negativen Werte machen das Fenster genau so viel groesser, ohne am
   Satzspiegel etwas zu aendern — Polster und Aussenabstaende wuerden das
   nicht schaffen, weil benachbarte Aussenabstaende verschmelzen. */
.hat-js [data-auf-modus="schnitt"] > .zeile{
  display:block;
  clip-path:inset(-.18em -.5em -.24em);
}
.hat-js [data-auf-modus="schnitt"] > .zeile.bw-fertig{clip-path:none}
.hat-js [data-auf-modus="schnitt"] .zeileninhalt{display:block}
.hat-js [data-auf-modus="schnitt"] .zeileninhalt:not(.bw-fertig){
  translate:0px var(--bw-zeile-weg);
  will-change:translate;
}
.hat-js [data-auf-modus="schnitt"].ist-da .zeileninhalt:not(.bw-fertig){
  animation:bw-zeile var(--bw-dauer-zeile) var(--bw-kurve) var(--bw-verzug,0ms) both;
}

/* -- fertig: keine Regel von hier greift mehr ----------------------------- */
.hat-js .bw-fertig{will-change:auto}

/* ---------------------------------------------------------------------------
   Laufbaender
   Sobald das Skript sie fuehrt, wird die CSS-Animation aus _soul.css
   abgeschaltet — sonst liefen zwei Bewegungen uebereinander.
   --------------------------------------------------------------------------- */
.band-js .bandlauf,
.band-js .parolelauf{animation:none;will-change:translate}

/* ---------------------------------------------------------------------------
   Absperrung
   Doppelter Boden: sollte .hat-js jemals gesetzt sein, obwohl das System
   Ruhe verlangt, ist trotzdem alles sichtbar. Ausgenommen ist nur der
   erzwungene Pruefbetrieb (window.HR_ZWANG, Klasse .zwang).
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  html:not(.zwang) [data-auf-modus],
  html:not(.zwang) [data-auf-modus] > *,
  html:not(.zwang) .zeileninhalt{
    opacity:1!important;translate:none!important;animation:none!important;
    will-change:auto!important;
  }
  html:not(.zwang) .zeile{clip-path:none!important}
  html:not(.zwang) #wand{translate:none!important}
}

/* ---------------------------------------------------------------------------
   Die Fussleiste beim Lesen aus dem Weg
   Sie steht fest ueber dem Text und verdeckt beim Herunterscrollen genau die
   Zeilen, die man gerade liest. Deshalb schiebt sie sich beim Lesen nach
   unten weg und kommt zurueck, sobald jemand hochscrollt - dann sucht er
   ohnehin nach Preis oder Telefonnummer.

   Ohne Skript passiert nichts: die Klasse .weg setzt nur das Skript.
   --------------------------------------------------------------------------- */
.leiste{
  transition:transform .38s cubic-bezier(.2,.7,.3,1);
  will-change:transform;
}
.leiste.weg{
  transform:translateY(calc(100% + clamp(10px,1.5vw,20px)));
}
@media(prefers-reduced-motion:reduce){
  .leiste{transition:none}
}
