/* ===== SoulKeeper - Level 2: Die Unterwelt (Höhle) =====================
   Übernommen aus test.html (finale Referenzversion der Höhle). Anders als
   Level 1 KEIN Parallax/Einfahr-Effekt - die Höhle ist eine statische
   Ebene, die direkt unter Level 1 liegt (siehe index.html: alles hier
   sitzt in einem einzigen Wrapper .level2-hoehle als Kind von
   #scene-unterwelt).

   Technik-Unterschied zu test.html: dort war jede Ebene "position:fixed"
   relativ zum Browser-Viewport (die Datei war eine eigenständige Seite
   ohne Kamerafahrt). Hier läuft die ganze Site über #story-track, das per
   transform:translateY bewegt wird - ein transformierter Vorfahre wird
   damit zum containing block für "position:fixed"-Nachfahren (CSS-Spec),
   wodurch fixed-Elemente an der falschen Stelle (oben an #story-track
   statt an der sichtbaren Szene) verankert würden. Deshalb überall
   "position:absolute" statt "position:fixed" - .level2-hoehle (inset:0)
   deckt exakt dieselbe 100vw x 100vh-Fläche ab wie vorher der Viewport,
   die Umrechnung ist 1:1.

   Farben: alle Höhlenfarben (Felswände, zentrales Höhlenlicht, Pilze)
   kommen aus Theme-Variablen (--level2-* in css/variables.css, je ein Satz
   pro Theme: Purple/Orange/Grey) statt fester Türkis-Werte. Abgestufte
   Zwischentöne (z.B. die vielen Farbstopps im zentralen Lichtschein)
   werden per color-mix() aus der jeweiligen Glow-Farbe berechnet, damit
   nirgends ein hartkodierter Zwischenwert stehen bleibt. Bewusst NICHT
   theme-abhängig bleiben: Ebene 5 + alle Schatten (tiefes Schwarz) und die
   Kristalle (eigene, feste Lila-Wirkung) - siehe jeweils dort. */

/* Gemeinsamer Wrapper für die komplette Höhlenkomposition - deckt die
   Szene exakt ab (inset:0 = 100vw x 100vh) und trägt die von mehreren
   Geschwister-Ebenen gemeinsam genutzten CSS-Variablen (Puls-Dauer, Naht-
   Position), damit sie nicht auf html/body liegen müssen. */
.level2-hoehle {
    position: absolute;
    inset: 0;
    z-index: 0;

    /* Gemeinsame Puls-Dauer für Ebene 1 (Grundlicht) + Ebene 1-Beam
       (Deckfläche/Lochschein) - eine Quelle, damit alle drei synchron
       pulsieren. */
    --level2-pulse-duration: 5.5s;

    /* Gemeinsame Kante: Start der schwarzen Deckfläche (.level2-cave-
       overlay). Wird auch von .level2-cave-ebene2 und .level2-cave-hole-
       glow verwendet, damit deren untere/obere Kante exakt hier andockt. */
    --level2-cave-start: 50%;

    /* Fallende Seelen (siehe .level2-soul weiter unten) - Start knapp
       oberhalb des sichtbaren Bereichs, Fallstrecke bis knapp UNTER die
       Unterkante von .level2-hoehle (die exakt die 100vh-Bildschirmfläche
       abdeckt, siehe Kopfkommentar) - anders als in Level 3 (dort endet die
       Fallstrecke an --river-mid, die Seele "landet" im Fluss) fallen sie
       hier komplett unter den Bildschirmrand hinaus. */
    --level2-soul-start: -60px;
    --level2-soul-fall-distance: calc(calc(100 * var(--uh)) - var(--level2-soul-start) + 60px);
}

/* ===== Puls-Animationen =====
   cave-pulse-base: kräftigeres Heller/Dunkler-Pulsieren der weit
   entfernten Grundebene (nur Helligkeit). cave-pulse-beam: zurück-
   haltenderes Pulsieren für Deckfläche + Lochschein (Helligkeit + minimales
   Skalieren) - wirkt, als würden beide vom selben, dahinterliegenden
   Leuchten mitgerissen. Beide nutzen --level2-pulse-duration und dieselben
   Keyframe-Prozentwerte, dadurch bleiben sie synchron. */
@keyframes level2-cave-pulse-base {
    0%, 100% { filter: brightness(0.35); }
    50%      { filter: brightness(1.15); }
}

@keyframes level2-cave-pulse-beam {
    0%, 100% { filter: brightness(0.12); transform: scale(1); }
    50%      { filter: brightness(1.06); transform: scale(1.015); }
}

/* ===== Ebene 1: Grundebene - radialer Lichtverlauf =====
   Zentrum unterhalb der Bildmitte (50% / 75%). Die Farbstopps gehen von
   fast-weiß im Kern über die volle Theme-Glow-Farbe bis zu Schwarz am
   Rand - color-mix() erzeugt die Zwischenstufen aus --level2-glow-color,
   damit hier kein fester Farbwert (Türkis oder sonst) hinterlegt ist. */
/* Hinweis: animation/filter dieser Regel werden weiter unten
   (".level2-cave-base { animation: none; ... }", Performance-Reduzierung)
   überschrieben - siehe dort für den aktuell tatsächlich wirksamen Wert. */
.level2-cave-base {
    position: absolute;
    inset: 0;

    background-image: radial-gradient(
        circle at 50% 75%,
        color-mix(in srgb, white 88%, var(--level2-glow-color) 12%) 0%,
        color-mix(in srgb, white 55%, var(--level2-glow-color) 45%) 8%,
        var(--level2-glow-color) 22%,
        color-mix(in srgb, var(--level2-glow-color) 55%, black) 38%,
        color-mix(in srgb, var(--level2-glow-color) 25%, black) 55%,
        color-mix(in srgb, var(--level2-glow-color) 8%, black) 75%,
        #000000 100%
    );

    z-index: 1;
    animation: level2-cave-pulse-base var(--level2-pulse-duration) ease-in-out infinite;
}

/* ===== Ebene 2 (Beam): schwarze Deckfläche mit elliptischem Lichtschein =====
   Existiert nur unterhalb von --level2-cave-start - dadurch entsteht die
   harte Kante zu Ebene 1 automatisch, ganz ohne Verlauf. Die Ellipse
   darin ist erneut aus --level2-glow-color abgeleitet (dunklere Stufen via
   color-mix), letzter Stopp volles Schwarz. */
/* Hinweis: animation/filter dieser Regel werden weiter unten
   (".level2-cave-overlay, .level2-cave-hole-glow { animation: none; ... }",
   Performance-Reduzierung) überschrieben - siehe dort. */
.level2-cave-overlay {
    --level2-cave-cx: 50%;
    --level2-cave-cy: 12.5%;
    --level2-cave-rx: 35%;
    --level2-cave-ry: 54%;

    position: absolute;
    top: var(--level2-cave-start);
    left: 0;
    width: 100%;
    height: calc(100% - var(--level2-cave-start));
    transform-origin: 50% 0%;

    background-color: #000000;
    background-image: radial-gradient(
        ellipse var(--level2-cave-rx) var(--level2-cave-ry) at var(--level2-cave-cx) var(--level2-cave-cy),
        color-mix(in srgb, var(--level2-glow-color) 78%, black) 0%,
        color-mix(in srgb, var(--level2-glow-color) 65%, black) 25%,
        color-mix(in srgb, var(--level2-glow-color) 48%, black) 40%,
        color-mix(in srgb, var(--level2-glow-color) 30%, black) 55%,
        color-mix(in srgb, var(--level2-glow-color) 16%, black) 70%,
        #000000 88%,
        #000000 100%
    );

    z-index: 2;
    pointer-events: none;
    animation: level2-cave-pulse-beam var(--level2-pulse-duration) ease-in-out infinite;
}

/* ===== Felsformation (Ebene2.svg) =====
   mask-image + background-color statt der Original-Schwarz-Füllung, damit
   diese am nächsten am pulsierenden Licht liegende Ebene eine dunkle,
   theme-abhängige Grundfarbe bekommt statt reinem (mit Ebene 5
   verschmelzendem) Schwarz. */
.level2-cave-ebene2 {
    position: absolute;
    left: 0;
    bottom: calc(100% - var(--level2-cave-start));
    width: 100%;
    aspect-ratio: 1920 / 554;
    display: block;

    background-color: var(--level2-ebene2-color);
    -webkit-mask-image: url('../../sh/img/level2/Ebene2.svg');
    mask-image: url('../../sh/img/level2/Ebene2.svg');
    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;

    z-index: 3;
    pointer-events: none;
}

/* ===== Stalagmiten mit Schatten =====
   Drei Instanzen um die Loch-Position herum, Größe nimmt mit der Nähe zum
   Loch ab (Tiefen-/Perspektivillusion). Pro Instanz zwei eigenständige,
   NICHT verschachtelte Top-Level-Elemente (Schatten + Körper) - bewusst
   kein gemeinsamer Wrapper, siehe test.html-Kommentar zum Stacking-Bug bei
   verschachtelten Mask/Blur-Ebenen auf dieser Seite. Beide vollständig
   deckendes Schwarz, themeunabhängig, kein Glow. */
/* Kein mask-image hier (anders als Ebene2/4/5): die Zielfarbe ist fest
   #000000 und die SVG selbst hat bereits fill="black" - ein direktes
   background-image spart die Maskierung und vermeidet den bei sehr klein
   gerenderten, feingliedrigen Masken sichtbaren "durchscheinenden" Alpha-
   Verlauf, den die mask-Kompositierung an den vielen kleinen Kurven der
   Silhouette erzeugte. */
.level2-stalagmite-shadow {
    position: absolute;
    left: var(--x);
    bottom: var(--bottom);
    width: var(--w);
    aspect-ratio: 134 / 560;
    transform-origin: 50% 100%;
    transform: translateX(-50%) translateY(var(--shadow-lift, 0%)) rotate(var(--shadow-rotate)) scaleY(-1);
    background-image: url('../../sh/img/level2/Ebene3_Stalagmit.svg');
    background-size: 100% 100%;
    background-repeat: no-repeat;
    z-index: 4;
    pointer-events: none;
    opacity: 1;
    mix-blend-mode: normal;
}

.level2-stalagmite-body {
    position: absolute;
    left: var(--x);
    bottom: var(--bottom);
    width: var(--w);
    aspect-ratio: 134 / 560;
    transform: translateX(-50%);
    background-image: url('../../sh/img/level2/Ebene3_Stalagmit.svg');
    background-size: 100% 100%;
    background-repeat: no-repeat;
    z-index: 6;
    pointer-events: none;
    opacity: 1;
    mix-blend-mode: normal;
}

/* --shadow-lift schiebt NUR den Schatten (s.o.) nach oben, ohne den
   Körper zu berühren - bei Stalagmit 2 sonst eine sichtbare Lücke
   zwischen Schatten und Körper, da er (anders als 1/3) keinen Lift hatte. */
.level2-stalagmite-1 { --x: 32%; --w: calc(3.6 * var(--uw));  --bottom: 30%; --shadow-rotate: 30deg;  --shadow-lift: -12%; }
.level2-stalagmite-2 { --x: 48%; --w: calc(3.2 * var(--uw));  --bottom: 22%; --shadow-rotate: -10deg; --shadow-lift: -6%; }
.level2-stalagmite-3 { --x: 66%; --w: calc(2.25 * var(--uw)); --bottom: 35%; --shadow-rotate: -30deg; --shadow-lift: -12%; }


/* ===== Pilze (Ebene 3.5) =====
   z-index 5: zwischen Stalagmit-Schatten (4) und -Körper (6). Struktur pro
   Pilz: .level2-mushroom (nur Position/Größe) > .level2-mushroom-shadow
   (gespiegelte, rein schwarze Kopie als Schlagschatten, ZUERST im DOM,
   liegt also unten) + .level2-mushroom-glow (trägt NUR den drop-shadow-
   Glow, kein Mask - sonst greift der mask+filter-Clipping-Bug) mit dem
   eigentlichen .level2-mushroom-shape (Maske + theme-abhängige Farbe)
   darin. Farbe und Glow-Farbe sind bewusst getrennte Theme-Variablen
   (--level2-pilz-color / --level2-pilz-glow-color). Keine Animation
   (Performance für spätere Spiellogik). */
.level2-mushroom {
    position: absolute;
    aspect-ratio: 394 / 436;
    z-index: 5;
    pointer-events: none;
}

.level2-mushroom-glow {
    position: absolute;
    inset: 0;
    pointer-events: none;
    filter:
        drop-shadow(0 0 var(--mushroom-glow-blur) var(--mushroom-glow-color))
        drop-shadow(0 0 calc(var(--mushroom-glow-blur) * 2.2) var(--mushroom-glow-color));
}

.level2-mushroom-shape {
    position: absolute;
    inset: 0;
    background-color: var(--level2-pilz-color);
    -webkit-mask-image: url('../img/level2/Pilze.svg');
    mask-image: url('../img/level2/Pilze.svg');
    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
}

/* Schlagschatten: gespiegelte, rein schwarze Kopie derselben Maske, nur
   blur() zur Weichzeichnung - kein Glow/Farbe. skewX() verzieht ihn zur
   Seite, abhängig vom horizontalen Abstand zur zentrierten Lichtquelle. */
.level2-mushroom-shadow {
    position: absolute;
    inset: 0;
    background-color: rgba(0, 0, 0, var(--shadow-alpha));
    -webkit-mask-image: url('../img/level2/Pilze.svg');
    mask-image: url('../img/level2/Pilze.svg');
    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    transform-origin: 50% 100%;
    transform: scaleY(calc(-1 * var(--shadow-stretch))) skewX(calc((50 - var(--x)) * 0.33deg));
    filter: blur(var(--shadow-blur));
}

/* Tiefenstufen: Glow-Stärke + Schatten-Eigenschaften nehmen mit der
   Entfernung ab/zu. Glow-Farbe je Stufe per color-mix() aus der Theme-
   Pilz-Glow-Farbe abgeblendet, statt fixer Türkis-rgba-Werte. */
/* Hinweis: --mushroom-glow-blur/-color werden weiter unten auf 0px/
   transparent überschrieben (Glow testweise deaktiviert) - siehe dort. */
.level2-mushroom--front { --mushroom-glow-blur: 14px; --mushroom-glow-color: color-mix(in srgb, var(--level2-pilz-glow-color) 90%, transparent); --shadow-alpha: 0.55; --shadow-blur: 1.5px; --shadow-stretch: 1.15; }
.level2-mushroom--mid   { --mushroom-glow-blur: 9px;  --mushroom-glow-color: color-mix(in srgb, var(--level2-pilz-glow-color) 75%, transparent); --shadow-alpha: 0.4;  --shadow-blur: 2.5px; --shadow-stretch: 1; }
.level2-mushroom--back  { --mushroom-glow-blur: 5px;  --mushroom-glow-color: color-mix(in srgb, var(--level2-pilz-glow-color) 55%, transparent); --shadow-alpha: 0.25; --shadow-blur: 3.5px; --shadow-stretch: 0.85; }

/* 5 große Vordergrundpilze */
.level2-mushroom-1  { left: 9%;   bottom: 3%; height: 41px; --x: 9; }
.level2-mushroom-2  { left: 24%;  bottom: 1%; height: 40px; --x: 24; }
.level2-mushroom-3  { left: 52%;  bottom: 6%; height: 42px; --x: 52; }
.level2-mushroom-4  { left: 74%;  bottom: 2%; height: 40px; --x: 74; }
.level2-mushroom-5  { left: 79%;  bottom: 5%; height: 41px; --x: 79; }

/* 6 mittlere Pilze */
.level2-mushroom-6  { left: 5%;   bottom: 14%; height: 28px; --x: 5; }
.level2-mushroom-7  { left: 18%;  bottom: 20%; height: 33px; --x: 18; }
.level2-mushroom-8  { left: 35%;  bottom: 12%; height: 26px; --x: 35; }
.level2-mushroom-9  { left: 58%;  bottom: 22%; height: 31px; --x: 58; }
.level2-mushroom-10 { left: 63%;  bottom: 15%; height: 27px; --x: 63; }
.level2-mushroom-11 { left: 91%;  bottom: 18%; height: 34px; --x: 91; }

/* 9 kleine, ferne Pilze */
.level2-mushroom-12 { left: 3%;   bottom: 30%; height: 24px; --x: 3; }
.level2-mushroom-13 { left: 15%;  bottom: 42%; height: 27px; --x: 15; }
.level2-mushroom-14 { left: 27%;  bottom: 33%; height: 22px; --x: 27; }
.level2-mushroom-15 { left: 39%;  bottom: 45%; height: 29px; --x: 39; }
.level2-mushroom-16 { left: 46%;  bottom: 29%; height: 20px; --x: 46; }
.level2-mushroom-17 { left: 60%;  bottom: 38%; height: 26px; --x: 60; }
.level2-mushroom-18 { left: 71%;  bottom: 44%; height: 31px; --x: 71; }
.level2-mushroom-19 { left: 83%;  bottom: 31%; height: 24px; --x: 83; }
.level2-mushroom-20 { left: 95%;  bottom: 41%; height: 27px; --x: 95; }

/* ===== Ebene 4: Ebene4_1 / Ebene4_2 / Ebene4_3 =====
   Liegt vor Ebene 1-3, hinter Ebene 5. Theme-abhängige Fels-Grundfarbe,
   kein Schein-Effekt. */
.level2-cave-ebene4-1-wrap {
    position: absolute;
    top: 0;
    right: 5%;
    width: calc(45 * var(--uw));
    aspect-ratio: 929 / 265;
    z-index: 7;
    pointer-events: none;
}

.level2-cave-ebene4-2-wrap {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    width: auto;
    aspect-ratio: 518 / 1080;
    z-index: 7;
    pointer-events: none;
}

.level2-cave-ebene4-3-wrap {
    --level2-ebene4-3-x: 25%;

    position: absolute;
    bottom: 0;
    left: var(--level2-ebene4-3-x);
    width: calc(20 * var(--uw));
    aspect-ratio: 510 / 369;
    z-index: 7;
    pointer-events: none;
}

.level2-cave-ebene4-1-wrap .level2-cave-ebene4-shape,
.level2-cave-ebene4-2-wrap .level2-cave-ebene4-shape,
.level2-cave-ebene4-3-wrap .level2-cave-ebene4-shape {
    position: absolute;
    inset: 0;
    background-color: var(--level2-ebene4-color);
    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
}

.level2-cave-ebene4-1-wrap .level2-cave-ebene4-shape {
    -webkit-mask-image: url('../../sh/img/level2/Ebene4_1.svg');
    mask-image: url('../../sh/img/level2/Ebene4_1.svg');
}

.level2-cave-ebene4-2-wrap .level2-cave-ebene4-shape {
    -webkit-mask-image: url('../../sh/img/level2/Ebene4_2.svg');
    mask-image: url('../../sh/img/level2/Ebene4_2.svg');
}

.level2-cave-ebene4-3-wrap .level2-cave-ebene4-shape {
    -webkit-mask-image: url('../../sh/img/level2/Ebene4_3.svg');
    mask-image: url('../../sh/img/level2/Ebene4_3.svg');
}

/* ===== Ebene 5: Ebene5_1 / Ebene5_2 / Ebene5_3 =====
   Vordergrund - liegt vor Ebene2/4, hinter dem Lochschein. Bewusst
   themeunabhängiges, deckendes Schwarz (siehe Vorgabe: Ebene 5 bleibt
   immer #000000, unabhängig vom Theme). */
.level2-cave-ebene5-1-wrap {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    aspect-ratio: 1920 / 161;
    z-index: 8;
    pointer-events: none;
}

.level2-cave-ebene5-2-wrap {
    --level2-corner-w: calc(33 * var(--uw));

    position: absolute;
    left: 0;
    bottom: 0;
    width: var(--level2-corner-w);
    aspect-ratio: 829 / 325;
    z-index: 8;
    pointer-events: none;
}

.level2-cave-ebene5-3-wrap {
    --level2-corner-w: calc(24.5 * var(--uw));

    position: absolute;
    right: 0;
    bottom: 0;
    width: var(--level2-corner-w);
    aspect-ratio: 483 / 723;
    z-index: 8;
    pointer-events: none;
}

.level2-cave-ebene5-1-wrap .level2-cave-ebene5-shape,
.level2-cave-ebene5-2-wrap .level2-cave-ebene5-shape,
.level2-cave-ebene5-3-wrap .level2-cave-ebene5-shape {
    position: absolute;
    inset: 0;
    background-color: #000000;
    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
}

.level2-cave-ebene5-1-wrap .level2-cave-ebene5-shape {
    -webkit-mask-image: url('../../sh/img/level2/Ebene5_1.svg');
    mask-image: url('../../sh/img/level2/Ebene5_1.svg');
}

.level2-cave-ebene5-2-wrap .level2-cave-ebene5-shape {
    -webkit-mask-image: url('../img/level2/Ebene5_2.svg');
    mask-image: url('../img/level2/Ebene5_2.svg');
}

.level2-cave-ebene5-3-wrap .level2-cave-ebene5-shape {
    -webkit-mask-image: url('../../sh/img/level2/Ebene5_3.svg');
    mask-image: url('../../sh/img/level2/Ebene5_3.svg');
}

/* ===== Kristalle: Kristall01.svg (Kontur) + Kristall02.svg (Grundform) =====
   Bewusst OHNE Theme-Variablen - Vorgabe: "Kristalle bleiben unverändert
   und behalten ihre eigene Wirkung", unverändert aus test.html übernommen,
   unabhängig vom gewählten Theme. Struktur: .level2-crystal-wrap (Position
   /Größe) > .level2-crystal-body (Grundform, statisch) +
   .level2-crystal-outline-wrap (Kontur, trägt Glow-Puls-Animation).

   STATUS: Das zugehörige HTML (index.html: .level2-crystal-wrap-Blöcke) ist
   testweise auskommentiert - der Ambient-/Outline-Glow führte beim Scrollen
   durch die Unterwelt zu Rucklern. Ersetzt durch das deutlich billigere
   .level2-crystal-rock-tint (siehe weiter unten). Dieses CSS bleibt bewusst
   bestehen, um das Feature bei Bedarf wieder aktivieren zu können (siehe
   log/SK_SELF_CHECK_2026-08-23.md: SK-030). */
@keyframes level2-crystal-pulse {
    0%, 100% {
        opacity: var(--crystal-outline-op-min);
        filter:
            drop-shadow(0 0 var(--crystal-glow-min) var(--crystal-outline-color))
            drop-shadow(0 0 calc(var(--crystal-glow-min) * 2.5) var(--crystal-outline-color))
            drop-shadow(0 0 calc(var(--crystal-glow-min) * 5) var(--crystal-outline-color));
    }
    50% {
        opacity: var(--crystal-outline-op-max);
        filter:
            drop-shadow(0 0 var(--crystal-glow-max) var(--crystal-outline-color))
            drop-shadow(0 0 calc(var(--crystal-glow-max) * 2.5) var(--crystal-outline-color))
            drop-shadow(0 0 calc(var(--crystal-glow-max) * 5) var(--crystal-outline-color));
    }
}

/* Ambienter Halo: weich verwaschener Lichtschein um den Kristall herum,
   mix-blend-mode:screen hellt den Fels darunter tatsächlich auf. */
.level2-crystal-ambient-wrap {
    position: absolute;
    inset: -20%;
    border-radius: 50%;
    background: radial-gradient(circle, var(--crystal-ambient-color) 0%, transparent 55%);
    filter: blur(var(--crystal-ambient-blur));
    mix-blend-mode: screen;
    animation: level2-crystal-pulse var(--crystal-pulse-duration) ease-in-out var(--crystal-pulse-delay) infinite;
}

/* Hinweis: --crystal-ambient-color/-glow-min/-glow-max werden weiter unten
   auf transparent/0px überschrieben (Glow testweise deaktiviert, siehe auch
   SK-030-Kommentar oben im Kristall-Abschnitt) - siehe dort. */
.level2-crystal-wrap {
    --crystal-body-bottom: #D9B8FF;
    --crystal-body-top: #3A1F5C;
    --crystal-body-opacity: 0.55;
    --crystal-outline-color: rgba(191, 102, 255, 0.95);
    --crystal-ambient-color: rgba(180, 110, 255, 0.45);
    --crystal-ambient-blur: 20px;
    --crystal-outline-op-min: 0.65;
    --crystal-outline-op-max: 0.95;
    --crystal-glow-min: 4px;
    --crystal-glow-max: 14px;
    --crystal-pulse-duration: 6.5s;
    --crystal-pulse-delay: 0s;

    position: absolute;
    aspect-ratio: 1097 / 1095;
    pointer-events: none;
}

.level2-crystal-body {
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, var(--crystal-body-bottom), var(--crystal-body-top));
    opacity: var(--crystal-body-opacity);
    -webkit-mask-image: url('../img/level2/Kristall02.svg');
    mask-image: url('../img/level2/Kristall02.svg');
    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
}

.level2-crystal-outline-wrap {
    position: absolute;
    inset: 0;
    animation: level2-crystal-pulse var(--crystal-pulse-duration) ease-in-out var(--crystal-pulse-delay) infinite;
}

.level2-crystal-outline-shape {
    position: absolute;
    inset: 0;
    background-color: var(--crystal-outline-color);
    -webkit-mask-image: url('../img/level2/Kristall01.svg');
    mask-image: url('../img/level2/Kristall01.svg');
    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
}

.level2-crystal--glow-medium { --crystal-glow-min: 4px;  --crystal-glow-max: 14px; --crystal-ambient-blur: 24px; }

/* Instanz #1: auf dem Eckstein von Ebene 5 (Ebene5_3). Position/Breite in
   % relativ zur Box des Steins - bleibt so exakt auf dem Stein, egal wie
   sich Fenster-/Steingröße ändert. */
.level2-crystal-1 {
    --crystal-pulse-duration: 7s;
    --crystal-pulse-delay: -2.3s;
    left: 34.7%;
    top: 53.7%;
    width: 40.8%;
}

/* Instanz #2: mittig auf dem Stein von Ebene 4 (Ebene4_3). */
.level2-crystal-2 {
    --crystal-pulse-duration: 6s;
    --crystal-pulse-delay: -4s;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 34.7%;
}

/* ===== Gesteins-Tönung =====
   Färbt den jeweiligen Stein selbst an (radial-gradient, per Stein-SVG
   maskiert, mix-blend-mode:screen) statt nur einen Lichtfleck darüber zu
   legen. Bewusst dieselben festen Lila-Töne wie die Kristalle (siehe
   oben) - gehört zur unveränderten Kristallwirkung, nicht zum Theme. */
@keyframes level2-crystal-tint-pulse {
    0%, 100% { opacity: 0.55; }
    50%      { opacity: 1; }
}

.level2-crystal-rock-tint {
    position: absolute;
    inset: 0;
    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    mix-blend-mode: screen;
    pointer-events: none;
}

.level2-crystal-rock-tint--ebene5-3 {
    background: radial-gradient(
        circle at 34.7% 53.7%,
        rgba(190, 120, 255, 0.95) 0%,
        rgba(170, 90, 255, 0.55) 22%,
        transparent 55%
    );
    -webkit-mask-image: url('../../sh/img/level2/Ebene5_3.svg');
    mask-image: url('../../sh/img/level2/Ebene5_3.svg');
    animation: level2-crystal-tint-pulse 7s ease-in-out -2.3s infinite;
}

.level2-crystal-rock-tint--ebene4-3 {
    background: radial-gradient(
        circle at 50% 50%,
        rgba(190, 120, 255, 0.95) 0%,
        rgba(170, 90, 255, 0.55) 22%,
        transparent 55%
    );
    -webkit-mask-image: url('../../sh/img/level2/Ebene4_3.svg');
    mask-image: url('../../sh/img/level2/Ebene4_3.svg');
    animation: level2-crystal-tint-pulse 6s ease-in-out -4s infinite;
}

/* ===== Partikel: schwebender Staub/Magie-Funken =====
   Zwei Tiefen-Ebenen (--far liegt hinter Ebene4/5, --near liegt vor
   wirklich allem). Farbe bewusst gedämpftes Weiß/Theme-Glow statt fixer
   Türkis-rgba - .level2-particle--crystal nutzt --level2-glow-color. */
@keyframes level2-particle-drift {
    0%   { transform: translate(0, 0); opacity: 0; }
    12%  { opacity: var(--particle-opacity); }
    38%  { transform: translate(var(--particle-drift-a), calc(32 * var(--uh))); }
    64%  { transform: translate(var(--particle-drift-b), calc(63 * var(--uh))); }
    88%  { opacity: var(--particle-opacity); }
    100% { transform: translate(var(--particle-drift-c), calc(104 * var(--uh))); opacity: 0; }
}

/* Hinweis: diese Regel wird weiter unten per "display: none;" komplett
   ausgeblendet (Partikel testweise deaktiviert) - siehe dort. */
.level2-particle {
    position: absolute;
    top: calc(-4 * var(--uh));
    border-radius: 50%;
    pointer-events: none;
    filter: blur(var(--particle-blur, 0px));
    animation: level2-particle-drift var(--particle-duration) ease-in-out var(--particle-delay) infinite;
}

.level2-particle--dust {
    background: radial-gradient(circle, rgba(216, 232, 234, 0.9) 0%, rgba(216, 232, 234, 0) 72%);
}

.level2-particle--crystal {
    background: radial-gradient(circle, color-mix(in srgb, var(--level2-glow-color) 65%, transparent) 0%, transparent 72%);
}

.level2-particle--highlight {
    background: radial-gradient(circle, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0) 65%);
    filter: blur(var(--particle-blur, 0px)) drop-shadow(0 0 2px rgba(255, 255, 255, 0.55));
}

.level2-particle--far {
    z-index: 6;
}

.level2-particle--near {
    z-index: 10;
}

/* Staub zwischen den Höhlenebenen: klein, kaum/kein Blur */
.level2-particle-1  { left: 11%; top: calc(-6 * var(--uh));  width: 3px; height: 3px; --particle-blur: 0px;   --particle-opacity: 0.6;  --particle-duration: 19s; --particle-delay: -3s;  --particle-drift-a: 10px;  --particle-drift-b: -6px;  --particle-drift-c: 14px; }
.level2-particle-2  { left: 21%; top: calc(-2 * var(--uh));  width: 2px; height: 2px; --particle-blur: 0.3px; --particle-opacity: 0.5;  --particle-duration: 24s; --particle-delay: -9s;  --particle-drift-a: -8px;  --particle-drift-b: 12px;  --particle-drift-c: -10px; }
.level2-particle-3  { left: 33%; top: calc(-8 * var(--uh));  width: 4px; height: 4px; --particle-blur: 0px;   --particle-opacity: 0.65; --particle-duration: 17s; --particle-delay: -5s;  --particle-drift-a: 14px;  --particle-drift-b: -10px; --particle-drift-c: 8px; }
.level2-particle-4  { left: 45%; top: calc(-4 * var(--uh));  width: 2px; height: 2px; --particle-blur: 0px;   --particle-opacity: 0.8;  --particle-duration: 26s; --particle-delay: -14s; --particle-drift-a: -6px;  --particle-drift-b: 9px;   --particle-drift-c: -12px; }
.level2-particle-5  { left: 57%; top: calc(-10 * var(--uh)); width: 5px; height: 5px; --particle-blur: 0.4px; --particle-opacity: 0.55; --particle-duration: 21s; --particle-delay: -2s;  --particle-drift-a: 16px;  --particle-drift-b: -14px; --particle-drift-c: 10px; }
.level2-particle-6  { left: 68%; top: calc(-3 * var(--uh));  width: 3px; height: 3px; --particle-blur: 0px;   --particle-opacity: 0.5;  --particle-duration: 27s; --particle-delay: -11s; --particle-drift-a: -12px; --particle-drift-b: 8px;   --particle-drift-c: -9px; }
.level2-particle-7  { left: 79%; top: calc(-7 * var(--uh));  width: 2px; height: 2px; --particle-blur: 0px;   --particle-opacity: 0.6;  --particle-duration: 18s; --particle-delay: -7s;  --particle-drift-a: 9px;   --particle-drift-b: -11px; --particle-drift-c: 13px; }
.level2-particle-8  { left: 90%; top: calc(-5 * var(--uh));  width: 4px; height: 4px; --particle-blur: 0.3px; --particle-opacity: 0.65; --particle-duration: 23s; --particle-delay: -16s; --particle-drift-a: -14px; --particle-drift-b: 10px;  --particle-drift-c: -8px; }

/* Vordergrund-Staub: nah an der Kamera, größer, weich verschwommen */
.level2-particle-9  { left: 18%; top: calc(-8 * var(--uh));  width: 18px; height: 18px; --particle-blur: 4px;   --particle-opacity: 0.3;  --particle-duration: 34s; --particle-delay: -6s;  --particle-drift-a: 26px;  --particle-drift-b: -18px; --particle-drift-c: 22px; }
.level2-particle-10 { left: 39%; top: calc(-4 * var(--uh));  width: 22px; height: 22px; --particle-blur: 5px;   --particle-opacity: 0.22; --particle-duration: 40s; --particle-delay: -18s; --particle-drift-a: -22px; --particle-drift-b: 16px;  --particle-drift-c: -20px; }
.level2-particle-11 { left: 61%; top: calc(-10 * var(--uh)); width: 16px; height: 16px; --particle-blur: 3.5px; --particle-opacity: 0.28; --particle-duration: 31s; --particle-delay: -10s; --particle-drift-a: 20px;  --particle-drift-b: -24px; --particle-drift-c: 18px; }
.level2-particle-12 { left: 76%; top: calc(-3 * var(--uh));  width: 14px; height: 14px; --particle-blur: 3px;   --particle-opacity: 0.32; --particle-duration: 44s; --particle-delay: -25s; --particle-drift-a: -18px; --particle-drift-b: 14px;  --particle-drift-c: -16px; }
.level2-particle-13 { left: 86%; top: calc(-6 * var(--uh));  width: 20px; height: 20px; --particle-blur: 6px;   --particle-opacity: 0.25; --particle-duration: 37s; --particle-delay: -14s; --particle-drift-a: 24px;  --particle-drift-b: -20px; --particle-drift-c: 19px; }

/* ===== Lochschein: pulsierendes Licht an der Öffnung in Ebene2.svg =====
   Sitzt auf derselben Naht wie Ebene 1-Beam (--level2-cave-start). Nutzt
   dieselbe cave-pulse-beam-Animation wie diese -> exakt synchrones
   Pulsieren, als käme es von derselben Lichtquelle. Bewusst helle,
   gesättigte Stufe der Theme-Glow-Farbe statt festem Türkis-rgba. */
/* Hinweis: animation/filter dieser Regel werden weiter unten überschrieben
   (Performance-Reduzierung, zusammen mit .level2-cave-overlay) - siehe dort. */
.level2-cave-hole-glow {
    --level2-hole-cx: 54.2%;
    --level2-hole-w: calc(62 * var(--uw));
    --level2-hole-h: calc(24 * var(--uw));

    position: absolute;
    left: calc(var(--level2-hole-cx) - (var(--level2-hole-w) / 2));
    bottom: calc(100% - var(--level2-cave-start));
    width: var(--level2-hole-w);
    height: var(--level2-hole-h);
    transform-origin: 50% 100%;

    background: radial-gradient(
        ellipse 50% 100% at 50% 100%,
        color-mix(in srgb, white 30%, var(--level2-glow-color) 70%) 0%,
        color-mix(in srgb, var(--level2-glow-color) 60%, transparent) 35%,
        color-mix(in srgb, var(--level2-glow-color) 20%, transparent) 65%,
        transparent 100%
    );
    mix-blend-mode: screen;

    /* Korrektur: war z-index:9 - höher als jeder Kreaturen-Layer (6/7),
       dadurch lag der screen-geblendete Lichtschein VOR Skeletten/
       Fledermäusen/Spinne und ließ sie ausgeblendet/transparent wirken
       (Vorgabe: Kreaturen müssen immer ÜBER diesem Verlauf liegen). Jetzt
       auf derselben Stufe wie Ebene 1-Beam (.level2-cave-overlay, z:2) -
       "Sitzt auf derselben Naht", siehe Kommentar oben - beide sitzen
       damit (wie schon cave-base, z:1) HINTER der Felswand (Ebene2.svg,
       z:3), passend zum Effekt "Licht scheint durch eine Öffnung in der
       Wand", statt wie zuvor über allem inklusive der Kreaturen zu liegen. */
    z-index: 2;
    pointer-events: none;
    animation: level2-cave-pulse-beam var(--level2-pulse-duration) ease-in-out infinite;
}

/* ===== Leuchten Pilze + Kristall: vorübergehend deaktiviert =====
   Auf Wunsch ausgeschaltet - überschreibt hier NUR die Glow-bezogenen
   Custom Properties der Originalregeln weiter oben (.level2-mushroom--*/
   .level2-crystal-wrap), löscht/ändert dort nichts. Reaktivieren = diesen
   Block einfach wieder entfernen/auskommentieren, dann gelten wieder die
   ursprünglichen Werte von oben. Form (Pilz-Maske, Kristall-Körper/-Kontur)
   bleibt unangetastet sichtbar, nur der Leucht-/Pulsier-Effekt verschwindet. */
.level2-mushroom--front,
.level2-mushroom--mid,
.level2-mushroom--back {
    --mushroom-glow-blur: 0px;
    --mushroom-glow-color: transparent;
}

.level2-crystal-wrap {
    --crystal-ambient-color: transparent;
    --crystal-glow-min: 0px;
    --crystal-glow-max: 0px;
}

/* ===== Partikel + Hintergrund-Pulsieren: vorübergehend deaktiviert =====
   Auf Wunsch ausgeschaltet, nach demselben Prinzip wie der Glow-Block oben -
   überschreibt/ergänzt hier nur, ändert die Originalregeln weiter oben
   nicht. Reaktivieren = diesen Block entfernen/auskommentieren.
   - Partikel (Staub/Funken vor den Höhlenebenen): komplett ausgeblendet.
   - Grundebene/Deckfläche/Lochschein pulsieren nicht mehr (animation:none),
     bleiben aber als statisches Licht auf ihrer "Mitte"-Helligkeit stehen
     (dieselbe filter:brightness(), die die Pulsanimation ohnehin bei 50%
     Fortschritt durchläuft) statt komplett ohne Filter (das wäre heller/
     dunkler als der bisherige Durchschnittseindruck der Szene). */
.level2-particle {
    display: none;
}

.level2-cave-base {
    animation: none;
    filter: brightness(0.75);
}

.level2-cave-overlay,
.level2-cave-hole-glow {
    animation: none;
    filter: brightness(0.55);
}

/* =========================
   SEELEN - übernommen aus Level 3 (css/level3.css: .soul/@keyframes
   soul-fall), eigener Klassenname (level2-*) statt Wiederverwendung, da
   .level2-hoehle NICHT derselbe Vorfahre wie .level3-hoellentor ist und die
   dortigen --soul-*-Variablen hier nicht greifen würden. Unterschied zu
   Level 3 (Vorgabe): dort "landen" die Seelen in der Flussmitte
   (--river-mid) und verschwinden, bevor sie ankommen - hier fallen sie
   komplett unter den unteren Bildschirmrand hinaus (siehe
   --level2-soul-fall-distance auf .level2-hoehle oben). Bewegung läuft
   ausschließlich über transform (kein top-Layout pro Frame, GPU-
   kompositierbar) - identisches Performance-Prinzip wie Level 3.
   ========================= */
.level2-soul {
    /* top/left setzen nur die RUHEPOSITION (einmalig, kein Layout pro
       Frame) - die eigentliche Fallbewegung läuft über transform (GPU,
       kein Reflow). */
    position: absolute;
    top: var(--level2-soul-start);
    left: 50%;
    /* 1.3x der nativen Bildgröße (img/Soul/DeadSoul_pixel.png, 22x32px) -
       Vorgabe: 1.2-1.4x. */
    width: 29px;
    height: 42px;
    margin-left: -14.5px;
    z-index: 11;
    pointer-events: none;
    opacity: 0;
    animation: level2-soul-fall linear infinite;
    will-change: transform, opacity;
}

/* Performance-Pause während des Kampfes (Phase 1 + Bossphase) - Klasse wird
   per JS auf .level2-hoehle umgeschaltet (js/level2-gameplay.js:
   zeigeSeelen). display:none statt nur opacity, damit die Animation
   währenddessen tatsächlich ruht statt nur unsichtbar weiterzulaufen. */
.level2-hoehle--seelen-pause .level2-soul {
    display: none;
}

/* Reines Pixel-Art-Bild (img/Soul/DeadSoul_pixel.png) statt der früheren
   CSS-Tropfenform + Schweif-Glow (Vorgabe: "kein Schweif mehr, nur das
   Bild") - identisches Muster wie invitation/css/level3.css: eigenes
   Pseudo-Element, damit die Kopf-oben/Kopf-unten-Drehung unabhängig von
   der auf .level2-soul selbst animierten translate/scale-Bewegung bleibt. */
.level2-soul::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image: url('../img/Soul/DeadSoul_pixel.png');
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    image-rendering: pixelated;
    image-rendering: -moz-crisp-edges;
    /* Das Bild ist Kopf-oben ausgerichtet - beim Fallen zeigt der Kopf
       deshalb nach UNTEN (Sturz voran), 180°-Drehung. In Level 2 gibt es
       aktuell keinen Aufstiegs-Zustand (Seelen fallen ausschließlich, siehe
       js/level2-gameplay.js: zeigeSeelen) - falls das je ergänzt wird, dort
       KEINE Drehung setzen (Kopf-oben ist für Aufwärtsflug schon richtig). */
    transform: rotate(180deg);
}

@keyframes level2-soul-fall {
    0% {
        transform: translate(0, 0) scale(0.7);
        opacity: 0;
    }
    12% {
        opacity: 1;
    }
    80% {
        opacity: 0.85;
    }
    100% {
        transform: translate(var(--level2-soul-drift, 0px), var(--level2-soul-fall-distance)) scale(1.05);
        opacity: 0;
    }
}
