/* ===== Einladung - Magische Verfluchung (Nebel + Hexen-Tiefenflug) ======
   Generisches Effekt-System: ein ".verflucht-bereich" liegt über seinem
   eigenen ".verflucht-inhalt" und legt zwei Nebelschichten darüber -
   dazwischen und davor kreist eine Hexe (".verfluchte-hexe"), die je
   nach Flugtiefe (--hexe-tiefe, von js/hexenflug.js pro Frame gesetzt)
   zwischen ".hexe-ebene--hinten" (hinter dem Nebel, kleiner/matter) und
   ".hexe-ebene--vorne" (vor dem Nebel, größer/klar) wechselt - Prinzip
   1:1 aus SoulKeepers Hexen-Tiefenflug übernommen (siehe
   SoulKeeper/js/level1-gameplay.js, Abschnitt "Hexen-Tiefenflug": Tiefe
   0..1 treibt dort ebenso kontinuierlich Größe/Container), nur auf den
   kleineren Maßstab dieser Seite herunterskaliert.

   Bewusst generisch benannt (nicht "oberwelt-*") statt fest an die
   Oberwelt gebunden - für spätere weitere verfluchte Bereiche
   (Unterwelt, Höllentor) reicht ein neuer ".verflucht-bereich" mit
   eigenen Kindern/eigenen Bildpfaden, ohne dieses Stylesheet ändern zu
   müssen. Die aktuelle Oberwelt-Instanz steht in index.php
   (#oberwelt-verflucht) und wird von js/hexenflug.js angesteuert.

   Ist der Fluch gebrochen (html.fluch-gebrochen, siehe
   js/fluch-status.js), verschwindet der Nebel komplett und die Hexe wird
   von js/hexenflug.js gar nicht erst gestartet (siehe dort) - hier reicht
   das Ausblenden der beiden Nebelschichten. */
html.fluch-gebrochen:not(.erloesung-laeuft) .nebel-schicht {
    display: none;
}

/* Farb-Tokens (--nebel-dunkel/--nebel-mittel/--nebel-hell) stehen jetzt
   PRO THEME in css/variables.css, nicht mehr fix hier - der Nebel soll
   im Lila-Theme lila+schwarz wirken, im Orange-Theme orange+schwarz, im
   Grey-Theme schwarz/grau/weiß, reagiert also auf den Theme-Umschalter
   wie --accent. Verwendung unten per color-mix() für die verschiedenen
   Deckkraft-Stufen (dieselbe Technik wie an anderer Stelle im Projekt,
   z.B. css/programm.css: color-mix(in srgb, var(--accent) ..., ...)). */

.verflucht-bereich {
    position: relative;
    /* Referenz laut Vorgabe: Notebook-Monitor 1920x1080 bei 100%
       Skalierung -> 225px/115px Hexenhöhe. 225/1920=11.7188vw,
       115/1920=5.9896vw, exakt getroffen bei 1920px Breite. Nur noch
       eine OBERE px-Grenze (90/225, 46/115) als Deckel gegen Übergröße -
       die frühere UNTERE px-Grenze wurde entfernt (TODO-20260901-039):
       sie verhinderte proportionales Mitskalieren bei breiten, aber
       niedrigen Fenstern (--stage-scale klein trotz großer Fensterbreite). */
    --hexe-groesse-min: min(calc(5.9896 * var(--uw)), 115px);
    --hexe-groesse-max: min(calc(11.7188 * var(--uw)), 225px);
}

.verflucht-inhalt {
    position: relative;
    z-index: 1;
}

/* ===== Nebelschichten =====
   Zwei Teile pro Schicht: das Element selbst ist der undurchsichtige
   "Kern" (volle Deckkraft, normale Blend-Art), ::before liefert darüber
   die bunten, weich ausblutenden Glow-Akzente (mix-blend-mode:screen).
   WICHTIG: opacity/mix-blend-mode dürfen NUR auf dem Glow (::before)
   stehen, nicht auf dem Kern-Element - eine opacity auf dem Eltern-
   Element würde sonst dessen GESAMTEN Nachfahren-Rendering (Kern +
   ::before zusammen als eine Gruppe) mit abblenden und die hohen
   rgba-Alphawerte im Kern wirkungslos machen (genau das war der Bug,
   durch den der Nebel trotz hoher Alpha-Werte blass blieb). Screen
   allein würde ohnehin nicht reichen: auf hellen Flächen (Countdown-
   Zahlen!) hellt es nur auf statt abzudunkeln (screen(Farbe, Weiß)
   bleibt praktisch Weiß) - der Kern übernimmt deshalb die eigentliche
   Verdeckung. Mehrere STARK überlappende Klumpen statt eines einzigen
   Flecks: die Deckkraft addiert sich in der Mitte auf praktisch 100%,
   einzelne Klumpen an den Rändern sorgen für Wolkentextur statt einer
   glatten Fläche - Mitte blickdicht, Ränder durchsichtig. */
.nebel-schicht {
    position: absolute;
    pointer-events: none;
    will-change: transform;
}

.nebel-schicht::before {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.nebel-schicht--hinten {
    inset: -55% -6% -12% -6%;
    z-index: 2;
    filter: blur(7px);
    background:
        radial-gradient(ellipse 44% 46% at 38% 32%, color-mix(in srgb, var(--nebel-dunkel) 94%, transparent) 0%, color-mix(in srgb, var(--nebel-dunkel) 86%, transparent) 46%, transparent 84%),
        radial-gradient(ellipse 42% 44% at 62% 34%, color-mix(in srgb, var(--nebel-dunkel) 94%, transparent) 0%, color-mix(in srgb, var(--nebel-dunkel) 86%, transparent) 46%, transparent 84%),
        radial-gradient(ellipse 46% 42% at 50% 58%, color-mix(in srgb, var(--nebel-mittel) 94%, transparent) 0%, color-mix(in srgb, var(--nebel-mittel) 86%, transparent) 46%, transparent 84%),
        radial-gradient(ellipse 40% 38% at 32% 74%, color-mix(in srgb, var(--nebel-mittel) 90%, transparent) 0%, color-mix(in srgb, var(--nebel-mittel) 80%, transparent) 46%, transparent 86%),
        radial-gradient(ellipse 40% 38% at 68% 76%, color-mix(in srgb, var(--nebel-mittel) 90%, transparent) 0%, color-mix(in srgb, var(--nebel-mittel) 80%, transparent) 46%, transparent 86%);
    animation: nebel-drift-hinten 18s ease-in-out infinite alternate;
}

.nebel-schicht--hinten::before {
    opacity: 0.55;
    mix-blend-mode: screen;
    filter: blur(16px);
    background:
        radial-gradient(ellipse 46% 30% at 50% 14%, var(--nebel-mittel) 0%, var(--nebel-mittel) 28%, transparent 74%),
        radial-gradient(ellipse 40% 34% at 28% 40%, var(--nebel-hell) 0%, var(--nebel-hell) 28%, transparent 72%),
        radial-gradient(ellipse 42% 38% at 72% 52%, var(--nebel-mittel) 0%, var(--nebel-mittel) 26%, transparent 74%),
        radial-gradient(ellipse 48% 40% at 50% 86%, var(--nebel-hell) 0%, var(--nebel-hell) 30%, transparent 76%);
}

.nebel-schicht--vorne {
    inset: -40% -5% -10% -5%;
    z-index: 3;
    filter: blur(7px);
    background:
        radial-gradient(ellipse 40% 40% at 55% 30%, color-mix(in srgb, var(--nebel-dunkel) 86%, transparent) 0%, color-mix(in srgb, var(--nebel-dunkel) 74%, transparent) 46%, transparent 84%),
        radial-gradient(ellipse 38% 40% at 32% 56%, color-mix(in srgb, var(--nebel-mittel) 86%, transparent) 0%, color-mix(in srgb, var(--nebel-mittel) 74%, transparent) 46%, transparent 84%),
        radial-gradient(ellipse 40% 36% at 62% 74%, color-mix(in srgb, var(--nebel-mittel) 82%, transparent) 0%, color-mix(in srgb, var(--nebel-mittel) 70%, transparent) 46%, transparent 86%);
    animation: nebel-drift-vorne 14s ease-in-out infinite alternate-reverse;
}

.nebel-schicht--vorne::before {
    opacity: 0.42;
    mix-blend-mode: screen;
    filter: blur(9px);
    background:
        radial-gradient(ellipse 38% 26% at 55% 12%, var(--nebel-hell) 0%, var(--nebel-hell) 26%, transparent 70%),
        radial-gradient(ellipse 36% 30% at 70% 34%, var(--nebel-hell) 0%, var(--nebel-hell) 24%, transparent 68%),
        radial-gradient(ellipse 38% 32% at 30% 60%, var(--nebel-hell) 0%, var(--nebel-hell) 26%, transparent 70%),
        radial-gradient(ellipse 42% 36% at 55% 84%, var(--nebel-mittel) 0%, var(--nebel-mittel) 28%, transparent 72%);
}

@keyframes nebel-drift-hinten {
    0%   { transform: translate(-5%, -3%) scale(1) rotate(-1.2deg); }
    50%  { transform: translate(6%, 4.5%) scale(1.14) rotate(1.5deg); }
    100% { transform: translate(-3%, 6%) scale(1.05) rotate(-0.6deg); }
}

@keyframes nebel-drift-vorne {
    0%   { transform: translate(5%, 3%) scale(1.1) rotate(1deg); }
    50%  { transform: translate(-7%, -4.5%) scale(1) rotate(-1.4deg); }
    100% { transform: translate(4%, -5.5%) scale(1.12) rotate(0.6deg); }
}

/* ===== Hexen-Tiefenflug =====
   Zwei Container statt einer Hexen-Instanz mit festem z-index: die Hexe
   wechselt tatsächlich die DOM-Ebene (siehe js/hexenflug.js). Reihenfolge
   von hinten nach vorne: hexe-hinten (0) -> verflucht-inhalt/Text (1) ->
   nebel-hinten (2) -> nebel-vorne (3) -> hexe-vorne (4) - dadurch kann
   sie wirklich HINTER Text UND Nebel verschwinden (nicht nur hinter dem
   Nebel, mit dem Text noch davor), und trotzdem VOR beiden auftauchen. */
.hexe-ebene {
    position: absolute;
    inset: 0;
    overflow: visible;
    pointer-events: none;
}

.hexe-ebene--hinten { z-index: 0; }
.hexe-ebene--vorne { z-index: 4; }

.verfluchte-hexe {
    position: absolute;
    left: var(--hexe-left, 50%);
    top: var(--hexe-top, 30%);
    width: calc(var(--hexe-groesse-min) + var(--hexe-tiefe, 0.5) * (var(--hexe-groesse-max) - var(--hexe-groesse-min)));
    aspect-ratio: 1 / 1;
    transform: translate(-50%, -50%);
}

@media (prefers-reduced-motion: reduce) {
    .nebel-schicht {
        animation: none;
    }
}

/* ===== Erlösungssequenz (?state=free, einmalige Rückkehr) =====
   Während die Sequenz läuft (html.erloesung-laeuft, siehe
   js/fluch-status.js), ist die Welt noch verflucht - der Nebel steht
   deshalb ohnehin da. Diese Regel ist für den Moment DANACH: am Satz "Sieh
   nur! ... der Nebel, er verschwindet." setzt js/verlorene-seele.js
   .fluch-gebrochen UND .erloesung-ausblenden. Die harte display:none-Regel
   ganz oben ist per :not(.erloesung-laeuft) so lange ausgesetzt (display
   kann nicht transitionieren, der Nebel würde sonst schlagartig
   verschwinden statt weich auszublenden) - erst erloesungAbgeschlossen()
   nimmt .erloesung-laeuft weg, ab dann greift wieder der normale
   Endzustand über .fluch-gebrochen allein.

   Dasselbe Muster nutzen die übrigen verfluchten Elemente in
   css/level2.css (Kastennebel/Netze/Kokon) und css/hoellentor-glut.css
   (Glut/Lavaschein) - alle blenden dadurch GEMEINSAM an diesem einen Satz
   aus. */
html.erloesung-laeuft .nebel-schicht {
    opacity: 1;
    transition: opacity 2.5s ease;
}

html.erloesung-laeuft.erloesung-ausblenden .nebel-schicht {
    opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
    html.erloesung-laeuft .nebel-schicht {
        transition: opacity 0.4s ease;
    }
}
