/* ==========================================================================
   EatMe — Globales Grundgerüst
   Enthält NUR: Reset, Basis-Layout, Hintergrund-Layer-Grundgerüst.
   Sektions-spezifisches Styling gehört in die jeweilige Sektions-Datei
   unter /sections, nicht hierher — siehe ARCHITECTURE.md.
   ========================================================================== */

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* ---- Globale Bild-Convention ----
   Kein Bild auf der Seite soll sich per Drag-and-Drop aus dem Browser
   ziehen lassen -- weder Bandfotos noch reine Deko-Grafiken (Vögel,
   Tropfen etc.). Zentral hier statt pro Sektion/Element, damit jedes
   neue <img> in jeder künftigen Sektion automatisch geschützt ist.
   Ersetzt die bisherigen Einzel-Regeln in section-02/section-05 (dort
   auf .bird-blue-*/.tropfen beschränkt) -- die dortigen Deklarationen
   bleiben unschädlich (Kaskade greift ohnehin), sind aber ab jetzt
   redundant. Hinweis: verhindert nur das Draggen, nicht "Bild speichern
   unter" per Rechtsklick -- das lässt sich browserseitig nicht
   zuverlässig blocken. */
img {
  -webkit-user-drag: none;
  user-select: none;
}

/* ---- Globale Text-Auswahl-Convention (::selection) ----
   Custom Markier-Farbe statt Browser-Standard-Blau, referenziert
   ausschließlich Werte aus tokens.css (keine neuen Hex-Codes, siehe
   tokens-notes.md-Konvention): Hintergrund = --color-blue-05,
   Vordergrund/Textfarbe = --color-grey-50. ::-moz-selection zusätzlich
   für ältere Firefox-Versionen, die das unpräfixte ::selection noch
   nicht unterstützen (moderne Firefox-Versionen brauchen es nicht mehr,
   schadet aber nicht). */
::selection {
  background-color: var(--color-blue-05);
  color: var(--color-grey-50);
}
::-moz-selection {
  background-color: var(--color-blue-05);
  color: var(--color-grey-50);
}

html {
  scroll-behavior: smooth;
  /* Verhindert automatisches Hochskalieren der Schriftgröße durch den
     Browser (iOS Safari/Chrome "Text Autosizing"), das bei langen
     Textblöcken in schmalen Spalten auf Mobile greift und die per CSS
     gesetzte font-size ignoriert. War die Ursache für den zu großen
     Privacy-Text auf Mobil (imprint-and-privacy.html): die Privacy-Spalte
     ist deutlich länger als die Imprint-Spalte und wurde deshalb vom
     Browser automatisch hochskaliert, obwohl beide dieselbe
     .text-copy-s-Klasse nutzen. Global hier gesetzt, damit künftige
     lange Textblöcke in anderen Sektionen nicht denselben Bug bekommen. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  font-family: var(--font-display);
  color: var(--color-black);
  background: var(--color-white);
  position: relative;
  overflow-x: hidden;
}

/* ---- Hintergrund-Layer ----
   Liegt fixed hinter dem gesamten Seiteninhalt, erstreckt sich über die
   komplette Scroll-Höhe. Enthält den durchgehenden Himmel-Hintergrund
   (Cloud + Footer-Bild), siehe Abschnitt weiter unten. */
.page-background {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  background: var(--color-white);
  pointer-events: none;
  overflow: hidden; /* Crop-Container fuer den Mobile-Anschnitt links/rechts, siehe unten */
}

/* ==========================================================================
   Sitewide Himmel-Hintergrund — Cloud (WebGL-Shader) + Footer (Bild) Layer
   .bg-cloud enthaelt ein <canvas> statt eines <img> (siehe initCloudShader()
   in script.js) -- .bg-footer bleibt unveraendert ein <img>.
   - Cloud: der weiche Alpha-Fade oben/unten, den das alte clouds.webp
     bereits eingebaut hatte, wird IM SHADER selbst erzeugt (siehe
     script.js, uEdgeFade im Fragment-Shader) -- kein CSS-Fade noetig.
   - WICHTIG (der eigentliche Perf-Fix, 2. Anlauf): Erst hatten wir .bg-cloud
     wie .bg-footer als absolute/document-flow-Element mit einem einmalig
     gesetzten .style.top (siehe CLOUD_ANCHOR_FRACTION) belassen und nur
     den Scroll-Parallax in den Shader verlagert. Problem dabei: das
     Element bewegte sich beim Scrollen weiterhin GANZ NORMAL (nativ, vom
     Compositor-Thread gesteuert), waehrend der Shader-Inhalt GLEICHZEITIG
     per JS/rAF (Main-Thread) gegensteuerte, um die langsamere Drift zu
     simulieren -- zwei unabhaengige "Antriebe" fuer dieselbe Bewegung,
     die bei schnellem/Momentum-Scrollen leicht auseinanderlaufen (sichtbares
     Ruckeln/Springen, exakt in der Vertikalen). Jetzt: .bg-cloud ist
     position:fixed und bewegt sich UEBERHAUPT NICHT MEHR -- die komplette
     Bewegung (Drift + simulierter Parallax) passiert ausschliesslich als
     Shader-Uniform, ein einziger Antrieb, exakt wie beim section-01-Stage-
     Cloud-Shader (der von Anfang an sauber lief). Bonus: der Canvas
     rendert nur noch Viewport-Groesse statt der kompletten, oft weit
     ausserhalb sichtbaren Bild-Hoehe.
   - Footer (assets/images/eatme-image-footer.jpg): unveraendert ein <img>
     mit echter mask-image (JPG hat keinen Alpha-Kanal). Kein Parallax,
     daher unproblematisch fuer Performance, bleibt document-flow/absolute.
   Sichtbarkeit der Cloud: reine opacity, pro Frame in script.js
   (parallaxLoop()) berechnet -- Fade-in ab section-03, Fade-out ab der
   Footer-Sektion (jeweils ueber CLOUD_FADE_DISTANCE_PX). Kein
   display:none/.is-visible-Toggle mehr (siehe Kommentar an .bg-cloud
   unten) -- das GPU-Sparen beim Nicht-Sichtbar-Sein passiert stattdessen
   rein in JS (der teure Shader-Render-Call wird uebersprungen), ohne die
   DOM-Sichtbarkeit anzufassen.
   ========================================================================== */

.bg-footer {
  position: absolute;
  left: 50%;
  width: 100%;
  overflow: hidden;
  pointer-events: none;
}

.bg-cloud canvas {
  display: block;
  width: 100%;
  height: 100%;
}

.bg-footer img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Footer: echte Alpha-Maske (JPG hat keinen eigenen Alpha-Kanal).
   object-position: die Gesichter auf dem Bandfoto sitzen bei ca. 40-49%
   der Bildhoehe (nicht im oberen Drittel, wie zunaechst angenommen) --
   36% als Kompromisswert, der den sichtbaren Ausschnitt ueber den
   gesamten Cropping-Bereich (1080px bis Ultra-Wide) mittig auf die
   Gesichter haelt. */
.bg-footer img {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 220px);
  mask-image: linear-gradient(to bottom, transparent 0, #000 220px);
  object-position: center 36%;
}

/* .bg-cloud: position: fixed statt absolute/document-flow -- BEWUSSTE
   Architektur-Aenderung (war zuerst absolute + aspect-ratio-Hoehe wie
   .bg-footer, siehe Chat-Verlauf). Grund: Bei absolute/document-flow
   bewegte sich das Element beim Scrollen ganz normal (nativ, vom
   Compositor-Thread gesteuert), WAEHREND der Shader-Inhalt gleichzeitig
   per JS/rAF (Main-Thread) gegengesteuert wurde, um die langsamere
   Parallax-Drift zu simulieren -- zwei unabhaengige "Antriebe" fuer
   dieselbe Bewegung, die bei schnellem/Momentum-Scrolling leicht
   auseinanderlaufen (sichtbares Ruckeln/Springen, genau in der
   Vertikalen). Mit position:fixed bewegt sich das Element UEBERHAUPT
   NICHT MEHR -- die komplette Bewegung passiert ausschliesslich als
   Shader-Uniform (ein einziger Antrieb, exakt wie beim section-01-Stage-
   Cloud-Shader, der von Anfang an sauber lief). Bonus: der Canvas
   rendert jetzt nur noch Viewport-Groesse statt der kompletten,
   oft weit ausserhalb sichtbaren Bild-Hoehe -> weniger GPU-Last pro
   Frame. Sichtbarkeit (erst unterhalb section-02) wird jetzt per
   Show/Hide in script.js gesteuert (parallaxLoop()), nicht mehr ueber
   die Dokumentposition. */
.bg-cloud {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  /* Opacity wird per JS/rAF gesetzt (parallaxLoop() in script.js), inkl.
     dieser kurzen Transition als Sicherheitsnetz gegen Sprung-Artefakte
     bei sehr schnellem Momentum-Scrolling. KEIN display:none -- das
     erforderte einen resync()-Sonderfall genau an der Stelle, an der
     Scroll-Spruenge am wahrscheinlichsten auftreten; die Groesse ist von
     Anfang an korrekt, kein Sonderfall noetig.

     FRUEHER stand hier zusaetzlich eine native CSS-Scroll-Timeline
     (animation-timeline: view() + @property + calc()) als vermeintlich
     off-main-thread-Loesung fuers Fade-in/-out. Per Web-Inspector-
     Timeline-Aufnahme (Til, 23.08.2026) widerlegt: die echten Zahlen
     zeigten ~260 Style-Neuberechnungen/Sekunde bei nur ~19 tatsaechlichen
     rAF-Aufrufen/Sekunde und Frame-Zeiten bis 700ms (Ziel: 16ms) -- die
     Funktion ist in Safari erst seit Version 26 verfuegbar und hat in
     dieser Kombination (@property + calc() + view-timeline) offenbar
     einen Style-Recalculation-Sturm ausgeloest, der den Main-Thread
     abgewuergt hat. Ersatzlos entfernt, zurueck zur reinen JS-Loesung.
     KEIN translateZ(0)/will-change mehr -- ebenfalls getestet (siehe
     Chat), keine messbare Wirkung. */
  transition: opacity 0.15s linear;
}

/* Footer: Hoehe eingefroren ab Referenzbreite 1080px. 1080 * 1.172
   (= 2344/2000, das Bildverhaeltnis) = 1265.76 =~ 1266px. Bis 1080px
   Viewport-Breite unveraendert (volle Aspect-Ratio, komplettes Foto wie
   im Original-Design). Darueber waechst nur noch die Breite weiter, die
   Hoehe bleibt bei 1266px stehen -> Bild wird angeschnitten statt endlos
   hoeher zu werden (was auf grossen Screens sonst die Gesichter aus dem
   sichtbaren Bereich schieben wuerde), object-position (oben) haelt die
   Gesichter dabei im Blick. */
.bg-footer {
  bottom: 0;
  height: min(117.2vw, 1266px);
  transform: translate3d(-50%, 0, 0);
  z-index: 1; /* liegt ueber der Cloud */
}

/* ---- Mobile (768px-Breakpoint, siehe tokens-notes.md) ----
   Beide Bilder schrumpfen NICHT unter die Groesse, die sie bei exakt
   768px Viewport-Breite haetten -- stattdessen bleibt die Breite auf
   768px fixiert und wird links/rechts angeschnitten (Crop passiert
   automatisch durch .page-background { overflow:hidden } + zentrierte
   Position). Footer-Hoehe wird hier explizit auf den 768px-Aspect-Ratio-
   Wert gesetzt (768 * 1.172 = 900px), weil der vw-basierte min()-Wert
   oben sich auf die echte Viewport-Breite bezieht, nicht auf die hier
   fixierte 768px-Elementbreite. */
@media (max-width: 768px) {
  .bg-footer {
    width: 768px;
    max-width: none;
    height: 900px;
  }
}

/* ---- Globale Link-Convention ----
   Browser-Standard für <a> (blau, unterstrichen) wird zurückgesetzt, damit
   Links immer die Textfarbe/den Font aus den tokens.css-Utility-Klassen
   übernehmen, statt auf den User-Agent-Style zurückzufallen. Zentral hier,
   damit jeder neue Link in jeder Sektion automatisch richtig aussieht. */
a {
  color: inherit;
  text-decoration: none;
}

/* ---- Globale Hover-Convention: Buttons ----
   Einfaches Opacity-Hover, unverändert seit section-01 (Sound-Toggle). */
button {
  transition: opacity 0.2s ease;
}
button:hover {
  opacity: 0.6;
}

/* ---- Globale Hover-Convention: Links ----
   Verlauf: erst 1:1 wie Buttons (Opacity 0.2s), auf Wunsch dann um einen
   Blur ergänzt, verlangsamt (0.6s) und verstärkt (4px) -- final an der
   eatme-navigation getestet und hier als Standard für ALLE Links auf der
   Seite festgehalten (nicht nur Nav).

   - display: inline-block statt inline: verhindert, dass der Blur am
     Text-Bounding-Box-Rand des inline-Fragments abgeschnitten wird.
   - padding + exakt gegengleiches negatives margin: reiner Safari-Fix.
     Safari bemisst die Filter-"Leinwand" nach der Element-Box statt
     großzügig für den Blur-Radius -> ohne diesen Puffer zeigt der Blur
     dort eine harte Kante statt weich auszulaufen. Das negative Margin
     macht die Padding-Verschiebung layoutmäßig wieder rückgängig -- der
     Text steht optisch exakt da, wo er ohne das Padding stünde.
   - will-change: filter: Hinweis an den Browser, früh eine eigene
     Compositing-Layer für den Filter anzulegen.

   Faustregel für neue Sektionen mit engem Link-Abstand: horizontales
   Padding + negatives Margin zusammen sollten unter der Hälfte des
   tatsächlichen Link-Gaps bleiben, sonst überlappen sich die (unsichtbaren)
   Hover-/Klick-Flächen benachbarter Links. Bei 16px Gap (wie in der Nav)
   sind 6px pro Seite die getestete, sichere Größe. */
a {
  display: inline-block;
  padding: 10px 6px;
  margin: -10px -6px;
  will-change: filter;
  transition: opacity 0.6s ease, filter 0.6s ease;
}
a:hover {
  opacity: 0.6;
  filter: blur(4px);
}

/* ---- Globale Scroll-Fade-In-Convention (für Texte) ----
   DEAKTIVIERT (25.08.2026, siehe Chat): Til hat nach mehreren
   Web-Inspector-Aufnahmen entschieden, den kompletten Blur/Opacity-Fade
   sitewide zu entfernen (Texte + Songtext-Module), da Paint/Composite-
   Kosten fuer Blur-Uebergaenge auf Safari weiterhin spuerbar waren.
   Elemente mit der Klasse .fade-in-text sind jetzt einfach permanent
   sichtbar -- kein Blur, keine Transition, kein laufender Kostenfaktor
   mehr. Die Klasse selbst (und initFadeInText()/der IntersectionObserver
   in script.js) bleiben im Code stehen, tun aber nichts mehr -- falls das
   Fade-in spaeter in einer leichtgewichtigeren Form zurueckkommen soll,
   ist der Anschlusspunkt noch da. */
.fade-in-text {
  opacity: 1;
  filter: none;
  transition: none;
}

.fade-in-text.is-visible {
  opacity: 1;
  filter: none;
}

/* ---- Layout-Grundgerüst ---- */
main {
  position: relative;
  z-index: 1;
}

.section {
  position: relative;
  width: 100%;
  margin: 0 auto;
}

#site-nav {
  position: relative;
  z-index: 10;
}

/* ---- Globaler Breakpoint ----
   Siehe tokens-notes.md: 768px ist verbindlich für ALLE Sektionen.
   CSS-Variablen funktionieren nicht in @media-Queries, daher hier als
   fest verdrahtete Zahl — exakt so in jeder Sektions-Datei übernehmen. */
@media (max-width: 768px) {
  .section {
    /* Sektionsspezifische Mobile-Anpassungen passieren in den jeweiligen
       Sektions-Dateien, nicht hier. Dieser Block ist nur Referenz/Anker. */
  }
}
