/* motion.css — Ausgangszustände. Ohne JS bleibt alles sichtbar, weil die
   Zustände nur unter .js-on gesetzt werden (Klasse setzt motion.js sofort). */

.js-on .m-reveal { opacity: 0; transform: translateY(var(--shift)); }
.js-on .m-stagger > * { opacity: 0; transform: translateY(var(--shift)); }

/* Chart-Schema: Ebenen starten unsichtbar, Ebene 0 bleibt sichtbar */
.js-on #lyr-sessions,
.js-on #lyr-opens,
.js-on #lyr-ranges,
.js-on #lyr-gaps,
.js-on #lyr-preview { opacity: 0; }

/* Task 10, Schlussprüfung: Lighthouse (mobil, Standardviewport < 768px) meldete
   "color-contrast" als einzigen Accessibility-Fund auf der Produktseite (Score 96
   statt 100) — genau auf diesen fünf <li>/<b>. Ursache: unter 768px hebt der
   Mobilzweig eine Zeile erst hervor, wenn ihre Ebene beim Scrollen erscheint; beim
   Laden (Scroll 0) ist deshalb NOCH KEINE Zeile is-on, alle fünf stehen auf .28.
   Ink (#1A1A18) bei 28 % Deckkraft auf Ground (#FBFAF7) ergibt rechnerisch (WCAG-
   Formel, wie tokens.css' "16.70:1" für volle Deckkraft) nur ~1.84:1 — weit unter
   den geforderten 4.5:1 für normalen Fließtext. .62 ergibt ~4.8:1 (Rechnung siehe
   Bericht) und bleibt sichtbar gegenüber der hervorgehobenen Zeile (opacity 1)
   abgesetzt — die Choreografie selbst (welche Zeile wann aktiv wird) ist
   unverändert, nur der Ruhezustand der noch nicht aktiven Zeilen ist heller. */
.js-on .schema__labels li { opacity: .62; transition: opacity .35s var(--ease-out); }
.js-on .schema__labels li.is-on { opacity: 1; }

/* Review vor Livegang, Fund 1: In-Bühne-Beschriftung, nur ab 768px (dort wird
   gepinnt — siehe motion.js, gsap.matchMedia). Unter 768px bleibt der Block
   aus (site.css, display:none), weil dort kein Pin läuft und die Liste selbst
   schon immer im Bild ist. `display: grid` + `grid-area: 1 / 1` auf jeder
   Zeile stapelt alle fünf übereinander in derselben Zelle — die Zelle wird
   dadurch auf die höchste (am meisten umbrechende) Zeile bemessen, die Bühne
   springt beim Zeilenwechsel also nicht in der Höhe. Nur die aktive Zeile
   bekommt Deckkraft 1, exakt dieselbe mark()-Zuweisung wie .schema__labels
   li.is-on (siehe motion.js) — Versatz bleibt dadurch 0px in beide Richtungen. */
@media (min-width: 768px) {
  .js-on .schema__caption { display: grid; }
  .js-on .schema__caption span {
    grid-area: 1 / 1; opacity: 0; transition: opacity .35s var(--ease-out);
  }
  .js-on .schema__caption span.is-on { opacity: 1; }
}

/* Verbindlich: reduzierte Bewegung zeigt den vollständigen Endzustand. */
@media (prefers-reduced-motion: reduce) {
  .js-on .m-reveal,
  .js-on .m-stagger > * { opacity: 1 !important; transform: none !important; }
  .js-on #lyr-sessions, .js-on #lyr-opens, .js-on #lyr-ranges,
  .js-on #lyr-gaps, .js-on #lyr-preview { opacity: 1 !important; }
  .js-on .schema__labels li { opacity: 1 !important; }
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
