/* =============================================================================
   scroll-reveal V2 — Einblenden beim Sichtbarwerden (Sweep-Schleife)
   =============================================================================
   V2, Rückfluss aus den Realbauten (Sektions-Ernte 2026-09-01, recfX55otwCPVGo4Z).
   Die V1 (IntersectionObserver, Guard-Klasse .sr-ready auf <html>, Opacity-
   Übergang) war die älteste und riskanteste der drei im Bestand gebauten
   Fassungen (BEFUND-lp-components-Lieferweg-2026-08-06.md, Abschnitt 3).
   Diese V2 übernimmt die gehärtete Mechanik des Engpass-Funnels
   (projekte/wos-selbstmarketing/setup/build/dist/engpass-*.html, 54 Vorkommen).

   DIE DREI HÄRTUNGEN, alle am Artefakt begründet:

   1) Guard-Klasse auf dem SCOPE-Element, nie auf <html>. Das JS setzt .js-reveal
      auf .sr-scope als erste Handlung; ohne JS greift der Versteck-Zustand nie
      (Falle 12, Guard-Klassen-Dreiklang). Nebeneffekt: kein Vorfahren-Selektor
      mehr, die Komponente passiert das Emitter-Gate (V1 wurde abgewiesen).

   2) BEWUSST KEINE Deckkraft-Animation, nur Bewegung. Gemessen 2026-08-03 im
      Perspective-iFrame: ein opacity-Übergang bleibt auf Elementen hängen, die
      beim Klassenwechsel nicht gerendert werden, und zwar dauerhaft. Die Sektion
      bleibt dann unsichtbar. Mit reiner Bewegung ist der schlimmste Fall ein
      Element, das ein Stück tiefer sitzt, und das sieht niemand.
      Deshalb entfällt auch die V1-Variante data-reveal="fade" (opacity-only).

   3) Die Sichtbar-Regel (.is-in) trägt höhere Spezifität als die Versteck-Regel
      (0,4,1 gegen 0,3,1). Bei Gleichstand entschiede die Stylesheet-Reihenfolge,
      ein stiller Kipppunkt bei jedem Umbau (Falle 12, Teil 2).

   TOKEN-PUR: enthält KEINE Farben (nur Transform/Timing). Die --sr-* sind
   komponenten-lokale Motion-Konstanten, an keine Marke gekettet
   (rules/lp-components-token-disziplin.md).

   Lade-Reihenfolge: _tokens/_base.css -> <brand>.css -> diese Datei -> scroll-reveal.js
   ============================================================================ */

[data-reveal] {
  --sr-distance: 20px;                              /* Start-Versatz */
  --sr-duration: 0.7s;                              /* Einblend-Dauer */
  --sr-easing:   cubic-bezier(0.22, 1, 0.36, 1);   /* weiches Aus-Schwingen */
  --sr-delay:    0s;                                /* optionaler Stagger pro Element */
}

/* Versteckter Startzustand NUR aktiv, wenn das JS läuft und .js-reveal auf dem
   Scope gesetzt hat. Ohne JS ist alles sofort sichtbar, die Seite kann durch
   einen Script-Ausfall nie leer werden. */
.sr-scope.js-reveal [data-reveal] {
  transform: translateY(var(--sr-distance));
}

/* Richtungs-Varianten (optional via Attribut-Wert). "fade" gibt es nicht mehr,
   siehe Härtung 2 im Kopf. */
.sr-scope.js-reveal [data-reveal="up"]    { transform: translateY(var(--sr-distance)); }
.sr-scope.js-reveal [data-reveal="down"]  { transform: translateY(calc(-1 * var(--sr-distance))); }
.sr-scope.js-reveal [data-reveal="left"]  { transform: translateX(var(--sr-distance)); }
.sr-scope.js-reveal [data-reveal="right"] { transform: translateX(calc(-1 * var(--sr-distance))); }

/* Eingeblendeter Endzustand. Der Übergang hängt bewusst HIER und nicht am
   Startzustand: so animiert nur der Weg nach vorn, nie ein Rücksprung. */
.sr-scope.js-reveal [data-reveal].is-in {
  transform: none;
  transition: transform var(--sr-duration) var(--sr-easing);
  transition-delay: var(--sr-delay);
}

/* Schon vorbeigescrollt (Sweep-Befund r.bottom < 0): Endzustand ohne Übergang,
   sonst bleibt eine unsichtbar abgelaufene Animation hängen. */
.sr-scope.js-reveal [data-reveal].no-anim {
  transition: none;
}

/* Reduced-Motion: kein Versteck-/Bewegungs-Zustand, alles sofort sichtbar. */
@media (prefers-reduced-motion: reduce) {
  .sr-scope.js-reveal [data-reveal] {
    transform: none;
    transition: none;
  }
}
