/* ══════════════════════════════════════════════════════════════════════════
   Der Seitenhintergrund: Partikelwelle
   Gehoert zu static/js/hintergrund.js und templates/includes/hintergrund.html.
   ══════════════════════════════════════════════════════════════════════════

   Adrian hat diesen Hintergrund selbst als Prototyp gebaut. Diese Datei ist
   seine Uebersetzung ins Produkt, keine Neufassung. Was hier anders ist als im
   Prototyp, ist es aus einem technischen Grund, und der steht dabei.

   ── Die vier Ebenen, von hinten nach vorn ────────────────────────────────

     z -4   .hg-grund      der Grund. Radiale Verlaeufe statt einer Farbe.
     z -4   .hg-grund-zwei derselbe Grund in den Originalfarben, per Deckkraft
                           eingeblendet. Das JavaScript wandert zwischen beiden.
     z -3   .hg-leinwand   die WebGL-Punktwolke.
     z -2   .hg-dunst      weiche Schlieren ueber den Kaemmen.
     z -2   .hg-dunst-zwei dasselbe in den Originalfarben.
     z -1   .hg-vignette   zieht den Blick in die Mitte.

   ── Warum negative z-Werte und keine eigene Ebene ────────────────────────

   Die Malreihenfolge im Wurzel-Stapel ist: Wurzelhintergrund, dann alles mit
   negativem z-index, DANN die Hintergruende der Bloecke. Genau deshalb steht
   der Grundton am <html> und nicht am <body> (siehe seiten-grund.css und den
   Kopf von base_public.html). Eine Farbe auf dem <body> uebermalt die Leinwand
   vollstaendig - schwarzer Schirm, kein Fehler in der Konsole.

   ── Diese Datei traegt das Bild ALLEIN, wenn kein Shader laeuft ──────────

   Drei Faelle, und in allen dreien bleibt es bei dem, was hier steht:

     kein JavaScript    die Leinwand bleibt leer und durchsichtig
     kein WebGL         hintergrund.js entfernt die Leinwand
     keine Importkarte  (Safari unter 16.4) das Modul laedt gar nicht erst
     reduzierte Bew.    hintergrund.js zeichnet EIN Bild, dann Ruhe

   Deshalb ist der Auslieferungszustand hier vollstaendig: .hg-grund traegt die
   Aurora-Farben mit voller Deckkraft, .hg-grund-zwei liegt bei 0. Wer nichts
   ausfuehrt, sieht die Aurora-Fassung - und die sieht fuer sich schon gut aus.

   ── Hell und dunkel ──────────────────────────────────────────────────────

     dunkel = KEIN Attribut am <html>.  Der Auslieferungszustand.
     hell   = <html data-theme="hell">.

   `prefers-color-scheme` wird bewusst NICHT ausgewertet. Der Grund steht im
   Kopf von heller-modus.css und ist eine Produktentscheidung.

   Wird von base_public.html geladen, NACH tailwind.css und heller-modus.css.
   Die Reihenfolge ist unkritisch: jede helle Regel traegt
   `:root[data-theme="hell"]` und schlaegt ihr Gegenstueck ueber die
   Spezifitaet.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Gemeinsame Lage ──────────────────────────────────────────────────────
   Alle Ebenen liegen fest im Sichtfeld und fangen keinen Zeigerklick ab. Das
   ist Flaeche, kein Inhalt - `pointer-events: none` ist hier Pflicht, sonst
   liegt eine unsichtbare Scheibe ueber jedem Knopf der Seite. */
.hg-grund,
.hg-grund-zwei,
.hg-leinwand,
.hg-dunst,
.hg-dunst-zwei,
.hg-vignette {
  position: fixed;
  pointer-events: none;
  display: block;
}

/* ── Ebene 1: der Grund ───────────────────────────────────────────────────
   Zwei radiale Lichter auf einem senkrechten Verlauf. Die Werte stammen
   unveraendert aus Adrians Prototyp. */
.hg-grund,
.hg-grund-zwei {
  inset: 0;
  z-index: -4;
}

.hg-grund {
  background:
    radial-gradient(115% 85% at 80% 6%,  #2b1a6e 0%, rgba(43,26,110,0) 58%),
    radial-gradient(100% 80% at 14% 96%, #0b2f52 0%, rgba(11,47,82,0) 62%),
    linear-gradient(180deg, #100b2e 0%, #070a1c 58%, #04060f 100%);
}

/* Die Originalfarben liegen als eigene Schicht darueber und werden ueber ihre
   Deckkraft eingeblendet. Als Klasse liesse sich das nicht ueberblenden - eine
   Klasse ist an oder aus, und der langsame Wechsel (90 s) lebt genau davon,
   dass er dazwischen stehen bleiben kann. Den Wert setzt hintergrund.js. */
.hg-grund-zwei {
  opacity: 0;
  background:
    radial-gradient(115% 85% at 80% 6%,  #5e0f4a 0%, rgba(94,15,74,0) 58%),
    radial-gradient(100% 80% at 14% 96%, #101a4e 0%, rgba(16,26,78,0) 62%),
    linear-gradient(180deg, #1a0a30 0%, #0b0619 58%, #050310 100%);
}

:root[data-theme="hell"] .hg-grund {
  background:
    radial-gradient(115% 85% at 80% 6%,  #e3f4f0 0%, rgba(227,244,240,0) 58%),
    radial-gradient(100% 80% at 14% 96%, #e4e6fb 0%, rgba(228,230,251,0) 62%),
    linear-gradient(180deg, #fbfaff 0%, #f0f0fc 58%, #e6e6f7 100%);
}

:root[data-theme="hell"] .hg-grund-zwei {
  background:
    radial-gradient(115% 85% at 80% 6%,  #f7e0ef 0%, rgba(247,224,239,0) 58%),
    radial-gradient(100% 80% at 14% 96%, #e2e6fb 0%, rgba(226,230,251,0) 62%),
    linear-gradient(180deg, #fcf9ff 0%, #f2edfc 58%, #e7e2f7 100%);
}

/* ── Ebene 2: die Leinwand ────────────────────────────────────────────────
   100vw/100vh statt inset:0, damit sie exakt so gross ist, wie der Renderer
   sie in Bildpunkten aufzieht (`renderer.setSize(innerWidth, innerHeight)`).
   Ein Groessenunterschied zwischen CSS-Kasten und Zeichenpuffer streckt das
   Bild, ohne dass irgendetwas meldet.

   ── Im hellen Modus ist sie aus ──────────────────────────────────────────

   Nicht durchsichtig gerechnet, sondern wirklich aus: hintergrund.js haelt die
   Schleife an und nimmt sie nach der Blende aus dem Baum. Wer die Seite hell
   oeffnet, laedt three.js gar nicht erst.

   Die Deckkraft steht trotzdem HIER und nicht dort, aus zwei Gruenden. Ohne
   JavaScript ist die Leinwand sonst eine leere Scheibe, die zwar nichts malt,
   aber im hellen Modus auch nichts zu suchen hat. Und die Blende in beide
   Richtungen kostet so keine einzige Zeile Zeitrechnung im Skript - sie
   haengt am selben Attribut wie der ganze Rest der Seite.

   Die 0,45 s muessen zu BLENDE_MS in hintergrund.js passen: so lange wartet
   das Skript, bevor es abschaltet. */
.hg-leinwand {
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: -3;
  opacity: 1;
  transition: opacity 0.45s ease;
}

:root[data-theme="hell"] .hg-leinwand {
  opacity: 0;
}

/* ── Ebene 3: der Dunst ───────────────────────────────────────────────────
   Weiche Schlieren, die den Kaemmen Tiefe geben. `inset: -12%` gibt der
   Weichzeichnung Rand zum Ausfransen - sonst zieht `blur(38px)` die Kante des
   Elements als helle Naht ins Bild. */
.hg-dunst,
.hg-dunst-zwei {
  inset: -12%;
  z-index: -2;
  filter: blur(38px);
  animation: hg-treiben 46s ease-in-out infinite alternate;
}

.hg-dunst {
  background:
    radial-gradient(38% 22% at 30% 46%, rgba(60,220,200,0.16) 0%, rgba(60,220,200,0) 70%),
    radial-gradient(46% 18% at 68% 40%, rgba(150,110,255,0.18) 0%, rgba(150,110,255,0) 72%),
    radial-gradient(30% 26% at 84% 62%, rgba(60,150,255,0.14) 0%, rgba(60,150,255,0) 70%);
}

.hg-dunst-zwei {
  opacity: 0;
  background:
    radial-gradient(38% 22% at 30% 46%, rgba(255,130,80,0.22) 0%, rgba(255,120,90,0) 70%),
    radial-gradient(46% 18% at 68% 40%, rgba(190,110,255,0.18) 0%, rgba(190,110,255,0) 72%),
    radial-gradient(30% 26% at 84% 62%, rgba(255,80,140,0.12) 0%, rgba(255,80,140,0) 70%);
}

/* Im Hellen bleibt der Dunst zurueckhaltender, sonst wird er auf dem fast
   weissen Grund zu einem farbigen Schleier statt zu Tiefe. */
:root[data-theme="hell"] .hg-dunst {
  opacity: 0.5;
}

/* Im Prototyp stand hier noch `body.hell #dunst2 { opacity: 0 }`. Die Regel
   ist bei uns ersatzlos weg, und zwar weil sie nie gegriffen hat: den Wert
   setzt der Palettenwechsel als style-Attribut, und ein style-Attribut
   schlaegt jede Stylesheet-Regel, auch die spezifischere.

   Was stattdessen gilt: sobald der Modus auf hell geht, gibt hintergrund.js
   die beiden "Zwei"-Ebenen ans Stylesheet zurueck (`loesen()`), und dann greift
   die Grundregel oben - beide auf 0. Der helle Modus hat damit EINEN festen
   Zustand statt eines eingefrorenen Zwischenwerts. Das ist die Bedingung
   dafuer, dass man ihn ueberhaupt messen kann. */

@keyframes hg-treiben {
  from { transform: translate3d(-2.5%, 1.5%, 0) scale(1.04); }
  to   { transform: translate3d( 3%,  -2%,  0) scale(1.12); }
}

/* ── Ebene 4: die Vignette ────────────────────────────────────────────────
   Im Dunkeln dunkelt sie den Rand ab, im Hellen legt sie einen kuehlen Ton
   darauf. Nicht gespiegelt: Weiss auf Weiss waere nichts. */
.hg-vignette {
  inset: 0;
  z-index: -1;
  background: radial-gradient(78% 62% at 50% 46%, rgba(0,0,0,0) 42%, rgba(0,0,0,.42) 100%);
}

:root[data-theme="hell"] .hg-vignette {
  background: radial-gradient(78% 62% at 50% 46%, rgba(255,255,255,0) 40%, rgba(120,110,150,.22) 100%);
}

/* ── Reduzierte Bewegung: kein Treiben ────────────────────────────────────
   Reduziert heisst KEINE Bewegung, nicht "weniger Animation". Der Dunst steht
   dann in seinem unverschobenen Zustand (kein transform, scale 1) - `inset:
   -12%` deckt das Sichtfeld auch dort vollstaendig ab, es entsteht kein Rand.

   Die JavaScript-Haelfte dieser Zusage steht in hintergrund.js: die
   Medienabfrage erreicht ein `requestAnimationFrame` nicht, sie muss dort
   getrennt geprueft werden. Der Shader zeichnet dann ein einziges Bild. */
@media (prefers-reduced-motion: reduce) {
  .hg-dunst,
  .hg-dunst-zwei {
    animation: none;
  }
  .hg-leinwand {
    transition: none;
  }
}
