/* ===================================================================
   STATEMENT

   The opening paragraph, centred, filling in word by word as you
   scroll. Words start pale and reach full ink in reading order, so the
   fill travels from top-left to bottom-right on its own.

   GEPINNT WIRD HIER NICHT MEHR ÜBER GSAP, sondern über position:
   sticky und eine Scroll-Strecke am Abschnitt.

   Zur Vorgeschichte, damit das nicht wieder zurückgedreht wird: Der
   ScrollTrigger-Pin setzte auf dem Absatzcontainer jeden Frame ein
   transform: translate(0, Ypx) mit gebrochenem Y. Ein Textblock, der
   um Bruchteile eines Pixels verschoben wird, wird bei jedem neuen
   Versatz neu gerastert — und genau das sieht man beim langsamen
   Scrollen als Zittern. Dazu kam GSAPs scrub-Glättung, die den Absatz
   der Scrollposition hinterherziehen liess.

   position: sticky wird vom Browser zusammen mit dem Scrollen
   verrechnet, nicht per JavaScript-Transform pro Frame. Der Absatz
   steht damit so ruhig wie jeder andere Text auf der Seite.

   Der zweite Teil der Kur steht unten bei .statement__word: die
   Deckkraft hängt nicht mehr an der Scrollposition, sondern schaltet
   pro Wort einmal um und läuft dann auf der eigenen Uhr.
   =================================================================== */

.statement {
  background: var(--bg);
  color: var(--fg);
  /* Die Strecke, über die der Absatz stehen bleibt und sich füllt.
     Danach gibt er von selbst frei und scrollt normal weg. */
  --statement-lauf: 90vh;
  min-height: calc(100svh + var(--statement-lauf));
  /* Polsterung liegt am klebenden Kind: min-height rechnet mit
     border-box, und Polsterung am Abschnitt läge ausserhalb seiner
     Inhaltsbox — dorthin kann ein klebendes Kind nicht wandern. */
  padding-block: 0;
}

/* Before the script runs — and forever, if JS is off or motion is
   reduced — this is a plain, fully legible centred paragraph. Nothing
   here hides the text. */
.statement__inner {
  position: sticky;
  top: 0;
  min-height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-block: var(--space-l);
}

/* Ist der Lauf einmal durch, hält der Abschnitt nicht mehr fest (Wunsch
   vom 04.10.: beim zweiten Besuch blockierte die Klebe-Strecke das
   Scrollen, obwohl längst alles gefüllt war). Ohne Strecke und ohne
   sticky ist es ein gewöhnlicher Abschnitt mit dem fertigen Absatz.
   html.statement-frei setzt index.html schon vor dem ersten Bild;
   .statement--frei setzt statement.js, wenn der Lauf in diesem Besuch
   endet und der Abschnitt oben aus dem Bild ist. */
.statement-frei .statement, .statement.statement--frei { min-height: 0; }
.statement-frei .statement__inner, .statement--frei .statement__inner {
  position: relative;
  min-height: 0;
  padding-block: var(--space-2xl);
}

.statement__text {
  max-width: 26ch;
  margin-inline: auto;
  text-align: center;
  text-wrap: balance;
  /* Larger than the old --size-lede: this is the one paragraph on the
     homepage that asks to be read, and the fill needs room to read as
     a movement across lines rather than a flicker. */
  font-size: clamp(1.5rem, 0.9rem + 2.1vw, 3rem);
  font-weight: var(--w-semibold);
  /* deliberately no font-stretch: this paragraph is running text set
     large, not display type, so it keeps the site's single width */
  line-height: 1.18;
  letter-spacing: var(--tracking-display);
}
.statement__text p + p { margin-top: 0.6em; }

/* One word.

   KEIN display: inline-block. Das war die Ursache des
   Safari-Alignments, am 17.09. in Safari 1440x900 isoliert gemessen:

     mit    inline-block   17 Zeilen: 1,1,1,1,1,1,1,1,1,4,3,3,3,2,3,5,4
     ohne   inline-block    9 Zeilen: 5,4,4,3,4,3,3,5,5

   Der Absatz ist in beiden Fällen 667px breit. WebKit bricht nach
   einem inline-block-Wort fast immer um und stapelt so die erste
   Hälfte des Absatzes ein Wort pro Zeile. Gegengeprüft: text-wrap:
   balance abzuschalten änderte NICHTS (ebenfalls 17 Zeilen, exakt
   dieselbe Verteilung), es lag also nie am Balancing.

   Die Deckkraft schaltet pro Wort EINMAL um, statt an der
   Scrollposition zu hängen.

   Das ist der eigentliche Grund, warum der Text vorher zitterte: 43
   Wörter bekamen bei jedem Scroll-Frame einen neuen Zwischenwert
   zwischen 0.16 und 1. Deckkraft auf einem nicht-atomaren
   Inline-Element lässt sich nicht auf eine Compositing-Ebene heben,
   jeder Zwischenwert ist also ein Neuzeichnen des Wortes — und Text,
   der mit wechselnder Deckkraft neu gezeichnet wird, verändert dabei
   sein Antialiasing. Das ist das Flimmern.

   Jetzt kennt ein Wort nur zwei Zustände. Der Übergang dazwischen
   läuft über eine CSS-Transition auf der eigenen Uhr, unabhängig
   davon, wie ruckartig die Scroll-Deltas hereinkommen. Beim langsamen
   Scrollen sind zu jedem Zeitpunkt ein bis zwei Wörter in Bewegung,
   nicht dreiundvierzig. */
.statement__word {
  opacity: 0.16;
  transition: opacity 280ms linear;
}
.statement__word.is-an { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  /* kein Kleben, kein Lauf — der Absatz steht einfach da, in voller Tinte */
  .statement { min-height: 0; --statement-lauf: 0px; }
  .statement__inner { position: static; min-height: 60svh; }
  .statement__word { opacity: 1; transition: none; }
}
