/* ============================================================
   Taverna am Fluss – Wasser
   Drei Zutaten, bewusst sparsam eingesetzt:
   eine Wellenkante am Übergang, Kaustik im Kontaktbereich
   und ein Tropfenring auf den Buttons.
   Eigene Datei, damit sich alles in einem Zug wieder
   entfernen lässt, ohne styles.css anzufassen.
   ============================================================ */

:root {
  /* Wassertöne zwischen Olivgrün und Fluss, kein Blau aus dem Nichts */
  --water-deep: #16281f;
  --water-mid:  #27473b;
  --water-lit:  #5f8f7c;
}

/* ============================================================
   Wellenkante
   Sichtbar sind 1440 Einheiten, gezeichnet werden 2880. Jede
   Ebene wandert um ein ganzes Vielfaches ihrer Wellenlänge,
   dadurch läuft die Kante endlos weiter, ohne dass rechts eine
   Lücke aufreißt.
   ============================================================ */
.wave-edge {
  display: block;
  width: 100%;
  height: clamp(70px, 8vw, 132px);
  margin-bottom: -2px;          /* keine Haarlinie zum nächsten Abschnitt */
  line-height: 0;
  pointer-events: none;
  background: var(--green-1000);
}
.wave-edge svg { width: 100%; height: 100%; display: block; }

@media (prefers-reduced-motion: no-preference) {
  .wave-edge .wave-1 { animation: wave-480 23s linear infinite; }
  .wave-edge .wave-2 { animation: wave-640 34s linear infinite; }
  .wave-edge .wave-3 { animation: wave-480 29s linear infinite; }
}
@keyframes wave-480 {
  from { transform: translateX(0); }
  to   { transform: translateX(-960px); }
}
@keyframes wave-640 {
  from { transform: translateX(0); }
  to   { transform: translateX(-1280px); }
}

/* ============================================================
   Kaustik
   Nicht die Spitzen des Rauschens werden hell, sondern die
   Höhenlinie in der Mitte. Daraus entsteht das zusammenhängende
   Lichtnetz, das man auf bewegtem Wasser sieht.
   ============================================================ */
/* Die Fläche reicht bewusst über den Abschnitt hinaus. Der Abschnitt
   schneidet selbst ab (overflow: hidden), dadurch liegt die weiche
   Kante der Maske außerhalb des Bildes und es bleibt keine Linie
   stehen, an der das Lichtnetz sichtbar aufhört. */
/* Diese Flaeche haeufte vier Dinge, bei denen Safari fuers Weissblitzen
   bekannt ist: mix-blend-mode in einem isolation-Kontext, ZWEI
   Maskenbilder mit mask-composite, ein SVG-Filter darin und will-change
   obendrauf. Weiss ist in Safari die Farbe einer Ebene, die noch nicht
   gezeichnet ist - muss sie neu aufgebaut werden, sieht man genau das.
   Chrome zeichnet stattdessen fortschreitend nach, deshalb war hier nie
   etwas zu messen.
   Geblieben ist eine einzige Maske und normales Ueberblenden. Screen
   hellt auf, statt zu decken; bei 16 % Deckkraft ist der Unterschied auf
   einem dunklen Foto minimal, also wird die Deckkraft leicht angehoben
   und die Farbe waermer genommen, damit das Netz gleich hell wirkt. */
.caustics {
  position: absolute;
  inset: -14%;
  z-index: 0;
  pointer-events: none;
  opacity: .2;

  /* Die Mitte bleibt ruhiger, damit der Text nicht im Netz verschwindet.
     Eine Maske statt zweier: der Verlauf nach unten steckt jetzt im
     radialen Verlauf selbst. */
  -webkit-mask-image: radial-gradient(72% 58% at 50% 44%, rgba(0, 0, 0, .28) 0%, rgba(0, 0, 0, .7) 58%, rgba(0, 0, 0, .95) 100%);
  mask-image: radial-gradient(72% 58% at 50% 44%, rgba(0, 0, 0, .28) 0%, rgba(0, 0, 0, .7) 58%, rgba(0, 0, 0, .95) 100%);
}
/* Die Flaeche ist groesser als ihr Kasten, damit die Drift nie eine
   Kante hereinzieht. Bewegt wird ausschliesslich per transform: das
   gefilterte Bild bleibt als fertige Rastergrafik liegen und wird vom
   Compositor nur verschoben, statt pro Frame neu gerechnet zu werden. */
.caustics svg {
  position: absolute;
  left: -8%;
  top: -8%;
  width: 116%;
  height: 116%;
  display: block;
  /* Kein will-change: eine dauerhaft reservierte Ebene fuer eine
     gefilterte Flaeche ist genau die Kombination, die Safari beim
     Wiederaufbau weiss zeigt. Die Drift ist ein transform, das promotet
     der Browser fuer die Dauer der Animation von selbst. */
  animation: kaustik-drift 34s ease-in-out infinite alternate;
}

/* Licht, das ueber bewegtem Wasser wandert: leichtes Ziehen plus
   minimales Atmen. Beides sind reine Compositor-Eigenschaften. */
@keyframes kaustik-drift {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  50%  { transform: translate3d(1.8%, -1.4%, 0) scale(1.045); }
  100% { transform: translate3d(-1.6%, 1.6%, 0) scale(1.02); }
}

/* Der Abschnitt mit Kaustik braucht eine eigene Stapelebene,
   sonst blendet das Netz über die Nachbarabschnitte hinaus. */
.has-caustics { position: relative; isolation: isolate; }

/* Hier stand display:none, sobald der Abschnitt aus dem Bild lief - und
   genau das war der Fehler. Der Turbulenz-Filter rechnet NICHT pro Bild:
   er wird einmal in eine Rastergrafik gelegt, deshalb steht ja auch kein
   <animate> auf baseFrequency. display:none wirft diese Rastergrafik weg.
   Beim Zurueckscrollen musste der Browser das komplette Lichtnetz neu
   rechnen, und der Abschnitt zeigte erst das nackte Foto und dann mit
   sichtbarer Verzoegerung das Netz darueber - bei jedem Hoch und Runter
   aufs Neue. Das Raster bleibt jetzt liegen, angehalten wird nur die
   Drift. Die kostet als reine Compositor-Animation ohnehin nichts, soll
   aber nicht unbemerkt weiterlaufen. */
.has-caustics:not(.in-view) .caustics svg { animation-play-state: paused; }

/* Dasselbe Prinzip fuer die uebrigen Dauerschleifen: ausserhalb des
   Bildes anhalten statt abbauen. Nichts wird verworfen, es laeuft nur
   nichts weiter, was niemand sieht. */
.wave-edge:not(.in-view) g { animation-play-state: paused; }
.hero:not(.in-view) .hero-media { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .caustics { display: none; }
}

/* ============================================================
   Tropfenring
   Ein einzelner Ring, der ausläuft, kein Material-Splash.
   ============================================================ */
.btn-primary, .btn-hero, .btn-glass { position: relative; overflow: hidden; isolation: isolate; }
.drop-ring {
  position: absolute;
  width: 12px; height: 12px;
  margin: -6px 0 0 -6px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  opacity: .5;
  pointer-events: none;
  transform: scale(0);
  animation: drop-ring 760ms var(--ease) forwards;
}
@keyframes drop-ring {
  0%   { transform: scale(0);  opacity: .45; }
  70%  { opacity: .14; }
  100% { transform: scale(20); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .drop-ring { display: none; }
}

/* ============================================================
   Wasserschrift
   Die Wasseroberfläche steht in den Buchstaben und wandert beim
   Scrollen durch. Jedes Wort trägt seine eigene Kachel, weil die
   Wörter einzeln aufgedeckt werden; wasser.js rechnet den Versatz
   so aus, dass die Textur trotzdem als eine Fläche durchläuft.
   ============================================================ */
/* Positioniert, damit die Wortversätze für die Textur unabhängig von
   der Scroll-Skalierung berechnet werden können. */
.statement-text { position: relative; transform-origin: 50% 45%; }
@media (prefers-reduced-motion: reduce) {
  .statement-text { transform: none !important; }
}

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .statement-text.wasser-bereit .fill-line,
  .statement-text.wasser-bereit .accent { color: transparent; }

  .statement-text.wasser-bereit .w {
    background-image: url("assets/wasser-textur.jpg");
    background-repeat: no-repeat;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}

/* Solange die Kacheln noch nicht ausgerichtet sind, bleibt die
   Schrift in ihren normalen Farben. Sonst zeigt jedes Wort für
   einen Frame dieselbe Ecke der Textur. */
.statement-text .w { transition: opacity .35s var(--ease); }

/* ============================================================
   Teller: Auftauchen aus der Tiefe
   Skalierung und Versatz hängen an der Scrollposition, nicht an
   einem Timer. Die drei laufen leicht versetzt, damit die Reihe
   nicht wie ein Block kippt.
   ============================================================ */
.plate { will-change: transform; }
@media (prefers-reduced-motion: reduce) {
  .plate { transform: none !important; }
}

/* Der Turbulenz-Filter rechnet jede Bildzeile pro Frame neu. Auf dem Handy
   kostet das mehr, als der Effekt auf der kleinen Fläche bringt. */
@media (max-width: 720px) {
  .caustics { display: none; }
}

/* ============================================================
   Telefon: Ebenen sparen
   ------------------------------------------------------------
   Die Wellenkante laeuft in drei endlosen Transform-Animationen. Jede
   liegt auf einer eigenen Compositor-Ebene, und weil sie ueber den
   angrenzenden Abschnitten liegen, muessen die Abschnitte selbst mit auf
   eigene Ebenen - gemessen sechs Ebenen, nur damit sich am Rand etwas
   bewegt, das auf einem Telefon 70 px hoch ist. Die Kante bleibt, sie
   steht nur still.
   .plate steht hier, weil diese Datei NACH styles.css geladen wird und
   die dortige Mobil-Regel sonst ueberstimmt wuerde.
   ============================================================ */
@media (max-width: 760px) {
  .wave-edge .wave-1,
  .wave-edge .wave-2,
  .wave-edge .wave-3 { animation: none; }
  .plate { will-change: auto; }
}
