/* ===== SoulKeeper - Level 3: Das Höllentor (Lava) ======================
   Übernommen aus test.html (finale Referenzversion des Hades-/Lava-Levels).
   Wie bei css/level2.css beschrieben: dort war jede Ebene "position:fixed"
   relativ zum Browser-Viewport (test.html 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 verankert würden. Deshalb
   überall "position:absolute" statt "position:fixed" - .level3-hoellentor
   (inset:0) deckt exakt dieselbe 100vw x 100vh-Fläche ab wie vorher der
   Viewport, die Umrechnung ist 1:1.

   Die in test.html auf :root liegenden CSS-Variablen sind hier auf
   .level3-hoellentor verschoben (gleiche Vererbung, da alle Ebenen
   Nachfahren dieses einen Wrappers sind) - dadurch bleiben sie auf die
   Szene beschränkt statt global auf :root zu liegen. Werte/Formeln
   unverändert aus test.html übernommen. */

.level3-hoellentor {
    position: absolute;
    inset: 0;
    z-index: 0;
    /* Entspricht dem html/body-Hintergrund aus test.html - liegt unter
       allen Ebenen, sichtbar an Stellen, die keine Ebene abdeckt. */
    background: #1a0806;

    --lava-band-vh: 30;

    /* ===== EBENE 3: TOR + ZÄUNE (hinteres Ufer) =====
       Global in :root, nicht mehr lokal auf .lava-gates, damit die
       Brücken-Formeln unten per var() darauf zugreifen können. */
    --gate-space: calc(160px * var(--stage-scale));
    --gate-overlap: calc(10px * var(--stage-scale));
    --gate-drop: calc(12px * var(--stage-scale));
    --fence-height: min(calc(120px * var(--stage-scale)), 200px);
    --gate-height: min(calc(200px * var(--stage-scale)), 440px);
    /* Zieht die GESAMTE Ebene 3 (Zaun+Gate UND Pufferbalken) nach unten.
       Wirkt sich direkt auf Ebene 4 aus (Brücken-Hinteranker + Fluss-Oberkante
       hängen an derselben Kante) - das ist gewollt, beide Ebenen sind
       aneinander verankert. */
    --back-drop: calc(140px * var(--stage-scale));
    /* Gemeinsamer Referenzpunkt: Oberkante des hinteren Pufferbalkens
       (= Unterkante von .lava-gates), inklusive --back-drop-Absenkung.
       Alles, was an "das hintere Ufer" andockt, nutzt diesen einen Wert. */
    --back-anchor: calc(var(--lava-band-vh) * calc(1 * var(--uh)) + var(--shore-height) - var(--back-drop));

    /* Dunkler "Ufer"-Streifen zwischen Lava-Oberkante und Zaun/Gate-Unterkante */
    --shore-height: min(calc(3 * var(--uh)), 36px);
    /* Wie tief die Ufer-Zacken (Ufer.svg) in die Lava eintauchen dürfen.
       Global, da auch Ebene 2 (Tor-Unterkante) sich daran ausrichtet. */
    --shore-overlap: calc(var(--shore-height) * 0.9);
    /* Unterkante von Ufer.svg selbst (tiefster Punkt der Zacken) */
    --shore-bottom: calc(var(--back-anchor) - var(--shore-height) - var(--shore-overlap));

    /* Fluss-Oberkante (= hinterer Ufer-Anker, Höhe der Lava-Oberkante) und
       Fluss-Mitte, jeweils als Abstand vom oberen Bildschirmrand. Die Seelen
       starten an --river-top (nicht ganz oben im Bild) und fallen bis
       --river-mid - bleiben damit immer zwischen Ebene 3 und Ebene 5,
       nie hinter Ebene 3 oder von ganz oben durchs Bild. */
    --river-top-from-bottom: calc(var(--back-anchor) - var(--shore-height));
    --river-bottom-from-bottom: calc(-1 * (var(--e5-drop) + var(--e5-shore-height)));
    --river-mid-from-bottom: calc((var(--river-top-from-bottom) + var(--river-bottom-from-bottom)) / 2);
    --river-top: calc(calc(100 * var(--uh)) - var(--river-top-from-bottom));
    --river-mid: calc(calc(100 * var(--uh)) - var(--river-mid-from-bottom));
    /* Seelen fallen vom Himmel (oberhalb des Bildschirms) bis in die
       Flussmitte. Fallstrecke als reine Distanz, für transform:translateY()
       statt top-Animation (Performance: kein Layout-Reflow pro Frame).
       Start ist an --e5-fence-height gekoppelt (nicht an vh), damit die
       Seelen bei jeder Fensterhöhe klar OBERHALB von Ebene5.svg starten
       und nicht mit ihr überlappen/"reinfliegen". */
    --soul-start: calc(-1 * (var(--e5-fence-height) + 60px));
    --soul-fall-distance: calc(var(--river-mid) - var(--soul-start));

    /* Feste Streckung der Lava-Steine (Breite = Faktor * Bandhöhe), IMMER,
       unabhängig von der Fensterbreite - kein Minimum, kein Maximum, konstant. */
    --lava-rock-min-stretch: 10;

    --lava-base:
        linear-gradient(
            to right,
            #000 0%,
            #f00 20%,
            #000 50%,
            #000 80%,
            #000 90%,
            #ffd500 100%
        );

    --lava-glow: #ff6200;

    /* Je höher, desto langsamer */
    --lava-speed: 120s;

    /* ===== EBENE 2 (HINTERGRUND: zentrales Tor + zwei Veins) ===== */
    /* Tor-Unterkante sitzt auf --shore-bottom (Unterkante von Ufer.svg) */
    --e2-gate-height: min(calc(450px * var(--stage-scale)), 980px);
    --e2-veins-width: calc(70 * var(--umin));
    /* Rissige Hintergrund-Ecken oben links/rechts - reichen vom oberen
       Bildrand bis zur Oberkante des hinteren Pufferbalkens (Ebene 3) */
    --bg-corner-size: calc(calc(100 * var(--uh)) - var(--back-anchor));

    /* ===== EBENE 5 (VORDERGRUND: nähere/größere Zaun+Tor-Reihe) ===== */
    --e5-gate-space: calc(320px * var(--stage-scale));
    --e5-gate-overlap: calc(14px * var(--stage-scale));
    --e5-gate-drop: calc(16px * var(--stage-scale));
    --e5-fence-height: min(calc(170px * var(--stage-scale)), 280px);
    --e5-gate-height: min(calc(280px * var(--stage-scale)), 620px);
    --e5-shore-height: min(calc(6 * var(--uh)), 70px);
    /* Wie weit Ebene5 (Zaun/Gate + Puffer) unter die sichtbare Unterkante rutscht.
       Klein genug, damit mindestens die Hälfte von --e5-fence-height sichtbar bleibt. */
    --e5-drop: calc(18px * var(--stage-scale));

    /* ===== BRÜCKE (spannt zwischen den Puffer-Oberkanten, X mittig zu den Gates) =====
       --gate-post-ratio: festes Breite:Höhe-Verhältnis des Tor-Pfostens in
       der Tor-Grafik selbst (49/462, aus der Bildvorlage vermessen) - an
       allen vier Stellen unten identisch, deshalb hier einmal benannt statt
       vierfach als unbenannte Magic Number wiederholt (siehe
       log/SK_SELF_CHECK_2026-08-23.md: SK-035). Ändert sich die Tor-Grafik,
       skalieren alle vier Stellen automatisch mit. */
    --gate-post-ratio: calc(49 / 462);
    --bridge-inset: calc(8px * var(--stage-scale));
    --bridge-x-back-left: calc(50% - (var(--gate-space) / 2) - (var(--gate-height) * var(--gate-post-ratio)));
    --bridge-x-back-right: calc(50% + (var(--gate-space) / 2) + (var(--gate-height) * var(--gate-post-ratio)));
    /* Ankert an --back-anchor (Oberkante des hinteren Pufferbalkens,
       inkl. --back-drop) - deckt damit den Balken-Verlauf im Brückenbereich ab */
    --bridge-y-back: calc(calc(100 * var(--uh)) - var(--back-anchor));
    --bridge-x-front-left: calc(50% - (var(--e5-gate-space) / 2) - (var(--e5-gate-height) * var(--gate-post-ratio)));
    --bridge-x-front-right: calc(50% + (var(--e5-gate-space) / 2) + (var(--e5-gate-height) * var(--gate-post-ratio)));
    /* Ankert an der OBERKANTE des Ebene5-Pufferbalkens (= Unterkante von
       .e5-gates) - selbe Logik wie hinten, für konsistenten Anker beidseitig */
    --bridge-y-front: calc(calc(100 * var(--uh)) + var(--e5-drop));
    --bridge-clip: polygon(
        var(--bridge-x-back-left) var(--bridge-y-back),
        var(--bridge-x-back-right) var(--bridge-y-back),
        var(--bridge-x-front-right) var(--bridge-y-front),
        var(--bridge-x-front-left) var(--bridge-y-front)
    );
    --bridge-clip-inset: polygon(
        calc(var(--bridge-x-back-left) + var(--bridge-inset)) calc(var(--bridge-y-back) + var(--bridge-inset)),
        calc(var(--bridge-x-back-right) - var(--bridge-inset)) calc(var(--bridge-y-back) + var(--bridge-inset)),
        calc(var(--bridge-x-front-right) - var(--bridge-inset)) calc(var(--bridge-y-front) - var(--bridge-inset)),
        calc(var(--bridge-x-front-left) + var(--bridge-inset)) calc(var(--bridge-y-front) - var(--bridge-inset))
    );
}

/* =========================
   EBENE 2 (HINTERGRUND)
   ========================= */
.e2-gate {
    position: absolute;
    left: 50%;
    bottom: var(--shore-bottom);
    height: var(--e2-gate-height);
    width: auto;
    transform: translateX(-50%);
    z-index: 2;
    pointer-events: none;
    /* Statischer Rand-Schein um die gesamte Tor-Silhouette (nicht pulsierend) */
    filter:
        drop-shadow(0 0 22px #ff6a00)
        drop-shadow(0 0 50px #b32b00)
        drop-shadow(0 0 90px #7a1400);
}

/* Pulsierender "Höllen"-Schein im Tordurchgang (das Loch in der Mitte) */
.e2-gate-glow {
    position: absolute;
    left: 50%;
    /* Grob auf Höhe des Türspalts im Bild positioniert */
    bottom: calc(var(--shore-bottom) + var(--e2-gate-height) * 0.15);
    height: calc(var(--e2-gate-height) * 0.55);
    width: calc(var(--e2-gate-height) * 0.22);
    transform: translateX(-50%);
    z-index: 3;
    pointer-events: none;
    background: radial-gradient(
        ellipse at center,
        #ffdd88 0%,
        #ff8a00 25%,
        #ff3300 55%,
        rgba(255, 51, 0, 0) 75%
    );
    filter: blur(18px);
    mix-blend-mode: screen;
    animation: e2-gate-pulse 2.8s ease-in-out infinite;
}

@keyframes e2-gate-pulse {
    0%, 100% {
        opacity: 0.6;
        transform: translateX(-50%) scale(0.9);
    }
    50% {
        opacity: 1;
        transform: translateX(-50%) scale(1.08);
    }
}

.e2-veins {
    position: absolute;
    bottom: var(--back-anchor);
    width: var(--e2-veins-width);
    height: auto;
    z-index: 2;
    pointer-events: none;
    /* Erstmal ausgeblendet */
    display: none;
}
.e2-veins--left {
    right: calc(50% + var(--e2-gate-height) * 0.5);
}
.e2-veins--right {
    left: calc(50% + var(--e2-gate-height) * 0.5);
    transform: scaleX(-1);
}

/* Rissige Hintergrund-Ecken oben links/rechts - statischer Höllen-Schein
   liegt direkt an den Außenkanten der Riss-Linien (drop-shadow folgt der
   Linienform selbst), kein Puls mehr (auch Performance-Grund) */
.bg-corner {
    position: absolute;
    top: 0;
    /* SoulKeeper steht in Phase 2/3 immer VOR BackgroundLeft/-Right (siehe
       js/level3-gameplay.js) - 45% kleiner als die volle --bg-corner-size,
       damit sie trotzdem wie ein weiter entferntes Hintergrundelement
       wirken, statt zu groß/nah. */
    width: calc(var(--bg-corner-size) * 0.55);
    height: calc(var(--bg-corner-size) * 0.55);
    z-index: 1;
    pointer-events: none;
}
.bg-corner img {
    position: relative;
    display: block;
    width: 100%;
    height: 100%;
    filter:
        drop-shadow(0 0 10px #ff6a00)
        drop-shadow(0 0 24px #ff3300);
}
.bg-corner--left {
    left: 0;
}
.bg-corner--right {
    right: 0;
}

/* =========================
   SEELEN - fallen vom Himmel (oberhalb des Bildschirms) bis in die
   Flussmitte (Ebene 4), X-Position außerhalb der Brücke. Höherer z-index
   als Ebene 3 (Zaun/Gate), damit sie beim Durchfallen nicht dahinter
   verschwinden - sie sind ätherisch, dürfen ruhig "durch" den Zaun scheinen.
   ========================= */
.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(--soul-start);
    left: 50%;
    width: 26px;
    height: 42px;
    margin-left: -13px;
    z-index: 15;
    pointer-events: none;
    opacity: 0;
    animation: soul-fall linear infinite;
    will-change: transform, opacity;
}

/* Performance-Pause während des Bosskampfs gegen den Soulkeeper - Klasse
   wird per JS auf .level3-hoellentor umgeschaltet (js/level3-gameplay.js:
   zeigeSeelen). Gleiches Muster wie css/level2.css:
   .level2-hoehle--seelen-pause: display:none statt nur opacity, damit die
   Animation währenddessen tatsächlich ruht statt nur unsichtbar
   weiterzulaufen. Vor dem Kampf (Auftritt/Voice/Countdown) fallen die
   Seelen unverändert weiter. */
.level3-hoellentor--seelen-pause .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") - dieselbe Datei/Technik wie css/level2.css: .level2-soul::before
   (dort ursprünglich von HIER übernommen, siehe Kommentar dort - diese
   Stelle selbst war beim Umstieg auf das Bild übersehen worden). Kopf-oben
   ausgerichtetes Bild, beim Fallen zeigt der Kopf deshalb nach UNTEN
   (Sturz voran) - 180°-Drehung. */
.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;
    transform: rotate(180deg);
}

@keyframes soul-fall {
    0% {
        transform: translate(0, 0) scale(0.7);
        opacity: 0;
    }
    12% {
        opacity: 1;
    }
    80% {
        opacity: 0.85;
    }
    100% {
        transform: translate(var(--soul-drift, 0px), var(--soul-fall-distance)) scale(1.05);
        opacity: 0;
    }
}

/* =========================
   TOR + ZÄUNE
   ========================= */
.lava-gates {
    position: absolute;
    left: 0;
    /* Sitzt exakt auf --back-anchor (Oberkante Pufferbalken inkl. --back-drop) */
    bottom: var(--back-anchor);
    width: calc(100 * var(--uw));
    height: 0;
    z-index: 10;
    pointer-events: none;
}

/* =========================
   UFER (zwischen Lava und Zaun/Gate)
   ========================= */
.lava-shore {
    position: absolute;
    left: 0;
    /* Sinkt um --shore-overlap in die Lava ab (Zacken-Überhang) UND um
       --back-drop (folgt Ebene 3 nach unten, Oberkante bleibt bei --back-anchor) */
    bottom: calc(var(--lava-band-vh) * calc(1 * var(--uh)) - var(--shore-overlap) - var(--back-drop));
    width: calc(100 * var(--uw));
    /* Oben unverändert (Anschluss an Zaun/Gate), unten wächst es in die Lava hinein */
    height: calc(var(--shore-height) + var(--shore-overlap));
    z-index: 8;
    pointer-events: none;
    overflow: hidden;
}

/* Fester Balken - füllt den Abstand zwischen Zaun/Gate und Lava.
   Testweise reines Schwarz (Farbe raus), um im Zusammenspiel mit dem
   neuen Ufer.svg-Verlauf zu sehen, wie es wirkt. */
.lava-shore::after {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: var(--shore-height);
    background: #000000;
    z-index: 1;
}

/* Ufer.svg in Original-Ausrichtung (glatte Kante oben, Zacken unten) -
   beginnt erst UNTER dem Balken (nicht überlappend/anliegend am Zaun) und
   hängt mit den Zacken bis in die Lava. Silhouette als Maske, dahinter ein
   Verlauf von Schwarz (oben, Anschluss an den Balken) zu höllischen Farben
   (unten, Richtung Lava) - plus ein Schein nur nach unten per drop-shadow. */
.lava-shore::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: var(--shore-height);
    bottom: 0;
    -webkit-mask-image: url("../../sh/img/level3/Ufer.svg");
    mask-image: url("../../sh/img/level3/Ufer.svg");
    -webkit-mask-repeat: repeat-x;
    mask-repeat: repeat-x;
    -webkit-mask-position: bottom left;
    mask-position: bottom left;
    -webkit-mask-size: auto 100%;
    mask-size: auto 100%;
    -webkit-mask-mode: alpha;
    mask-mode: alpha;
    background: linear-gradient(
        to bottom,
        #000000 0%,
        #5a0f00 30%,
        #b32b00 55%,
        #ff6a00 80%,
        #ffcc66 100%
    );
    filter: drop-shadow(0 10px 6px #ff6a00);
    z-index: 2;
}

/* =========================
   SEITEN (Container)
   ========================= */
.lava-gate-side {
    position: absolute;
    bottom: 0;
    height: auto;
    top: 0;
    /* Container endet exakt an der Space-Grenze - keine Overlap-Zugabe mehr,
       sonst würde das Gate (das an dieser Kante andockt) in den Space ragen */
    width: calc(50% - (var(--gate-space) / 2));
}

/* =========================
   LINKE SEITE
   ========================= */
.lava-gate-side--left {
    left: 0;
}

/* =========================
   RECHTE SEITE
   ========================= */
.lava-gate-side--right {
    right: 0;
}

/* =========================
   ZAUN (BASIS)
   ========================= */
.lava-fence {
    position: absolute;
    bottom: 0;
    height: var(--fence-height);
    background-repeat: repeat-x;
    background-size: auto 100%;
    z-index: 1;
    /* Zaun endet gate-overlap vor der Container-/Space-Grenze,
       damit das (höher gestapelte) Gate das Zaunende sauber überdeckt */
    width: calc(100% - var(--gate-overlap));
}

/* =========================
   LINKER ZAUN
   ========================= */
.lava-fence--left {
    left: 0; /* Zaun dockt ganz links am Bildschirmrand an */
    background-image: url("../../sh/img/level3/FenceLeft.svg");
}

/* =========================
   RECHTER ZAUN
   ========================= */
.lava-fence--right {
    right: 0; /* Zaun dockt ganz rechts am Bildschirmrand an */
    background-image: url("../../sh/img/level3/FenceRight.svg");
}

/* =========================
   GATE (BASIS)
   ========================= */
.lava-gate {
    position: absolute;
    /* Sinkt etwas in den Ufer-Streifen ab, damit die unsauberen/transparenten
       Fußecken der Gate-Grafik nicht mehr sichtbar sind */
    bottom: calc(var(--gate-drop) * -1);
    width: auto;
    height: var(--gate-height);
    z-index: 20;
}

/* =========================
   LINKES GATE
   ========================= */
.lava-gate-side--left .lava-gate {
    /* Bündig mit der Space-Grenze (Container-Kante) - kein Hineinragen in den Space.
       Die Gate-Grafik selbst ist breiter als --gate-overlap und deckt damit
       automatisch das um --gate-overlap gekürzte Zaunende ab. */
    right: 0;
}

/* =========================
   RECHTES GATE
   ========================= */
.lava-gate-side--right .lava-gate {
    /* Bündig mit der Space-Grenze (Container-Kante) - kein Hineinragen in den Space */
    left: 0;
}

/* =========================
   BRÜCKE (zwischen Ebene5-Puffer vorne und Ufer-Puffer hinten)
   ========================= */
.bridge-layer {
    position: absolute;
    left: 0;
    top: 0;
    width: calc(100 * var(--uw));
    /* Reicht bewusst über die Viewport-Höhe hinaus, damit der vordere
       Brücken-Anker (liegt unterhalb des Sichtbaren) nicht am
       Element-Rand abgeschnitten wird */
    height: calc(calc(100 * var(--uh)) + var(--e5-drop) + var(--e5-shore-height) + 20px);
    pointer-events: none;
}

.bridge-frame {
    background: #000;
    clip-path: var(--bridge-clip);
    z-index: 22;
}

.bridge-texture {
    background-image: url("../../sh/img/level3/Bridge.svg");
    /* Echte Proportionen (1480x4440) statt Verzerrung - die Kachel wird auf
       die Deck-Höhe skaliert und dann so oft wie nötig nebeneinandergelegt */
    background-size: auto 100%;
    background-repeat: repeat-x;
    clip-path: var(--bridge-clip-inset);
    z-index: 23;
}

/* =========================
   EBENE 5 (VORDERGRUND) - PUFFERBALKEN
   ========================= */
.e5-shore {
    position: absolute;
    left: 0;
    /* Direkt unter Ebene5-Zaun/Gate, sinkt weiter unter die sichtbare Kante */
    bottom: calc(-1 * var(--e5-drop) - var(--e5-shore-height));
    width: calc(100 * var(--uw));
    /* War: nur var(--e5-shore-height) (siehe TODO-20260901-042, uebertragen
       aus TODO-20260901-038 in dev0/iv). #story schneidet hier per
       overflow:hidden exakt an der Unterkante von .scene ab (statt eines
       folgenden <footer> wie in dev0/iv) - mit der alten, kleineren Hoehe
       lag die KOMPLETTE Box dieses Puffers unterhalb dieser Schnittkante,
       also vollstaendig weggeschnitten und optisch wirkungslos: das
       Abdichten der Zaun-/Ufer-Zacken-Zwischenraeume gegen die
       dahinterliegende Lava fand nie sichtbar statt (per Playwright-Messung
       an mehreren Fenstergroessen bestaetigt - die Box begann IMMER exakt
       --e5-drop unterhalb der sichtbaren Unterkante). Die Unterkante bleibt
       unveraendert (s. oben), nur die Oberkante wandert dadurch um
       (--e5-drop + --e5-shore-height) nach oben - --e5-shore-height davon
       macht den Puffer oberhalb der Schnittkante sichtbar (deckt dort
       verbliebene transparente Luecken der Zaun-Silhouette ab), der Rest
       (--e5-drop) gleicht den bisher verschenkten Versatz aus. */
    height: calc(2 * var(--e5-shore-height) + var(--e5-drop));
    background: #000;
    z-index: 28;
    pointer-events: none;
    /* Vordergrund wirkt dadurch leicht unscharf/näher an der Kamera */
    filter: blur(3px);
}

/* Ebene5.svg - volle Breite, Seitenverhältnis bleibt erhalten (keine
   Verzerrung mehr). Die Unterkante (Tiefpunkt) ist an --e5-fence-height
   fixiert, wächst aber bei Bedarf über den oberen Bildschirmrand hinaus,
   statt gestaucht zu werden. GANZ VORNE (höchster z-index der Szene). */
.e5-top {
    position: absolute;
    left: 0;
    /* Fest an der Oberkante verankert (top:0), NICHT über bottom mit einer
       höhenabhängigen Formel - sonst wandert die Oberkante nach unten,
       sobald die (breitenabhängige, aspect-ratio-basierte) Höhe bei
       schmalem Fenster schrumpft, und reißt eine Lücke zum Bildrand auf. */
    top: 0;
    width: calc(100 * var(--uw));
    /* Neue, schmalere Version von Ebene5.svg (viewBox 1920x193) */
    aspect-ratio: 1920 / 193;
    height: auto;
    background-image: url("../../sh/img/level3/Ebene5.svg");
    background-size: 100% 100%;
    background-repeat: no-repeat;
    z-index: 50;
    pointer-events: none;
    /* Gleicher Schein-Effekt wie bei BackgroundLeft/Right.svg */
    filter:
        drop-shadow(0 0 10px #ff6a00)
        drop-shadow(0 0 24px #ff3300);
}

/* =========================
   EBENE 5 (VORDERGRUND) - ZAUN + TOR
   ========================= */
.e5-gates {
    position: absolute;
    left: 0;
    /* Unterkante rutscht unter den sichtbaren Bereich */
    bottom: calc(-1 * var(--e5-drop));
    width: calc(100 * var(--uw));
    height: 0;
    z-index: 30;
    pointer-events: none;
    /* Vordergrund wirkt dadurch leicht unscharf/näher an der Kamera */
    filter: blur(3px);
}

.e5-gate-side {
    position: absolute;
    bottom: 0;
    top: 0;
    height: auto;
    width: calc(50% - (var(--e5-gate-space) / 2));
}
.e5-gate-side--left {
    left: 0;
}
.e5-gate-side--right {
    right: 0;
}

.e5-fence {
    position: absolute;
    bottom: 0;
    height: var(--e5-fence-height);
    background-repeat: repeat-x;
    background-size: auto 100%;
    z-index: 1;
    width: calc(100% - var(--e5-gate-overlap));
}
.e5-fence--left {
    left: 0;
    background-image: url("../../sh/img/level3/Ebene5_FenceLeft.svg");
}
.e5-fence--right {
    right: 0;
    background-image: url("../../sh/img/level3/Ebene5_FenceRight.svg");
}

.e5-gate {
    position: absolute;
    bottom: calc(var(--e5-gate-drop) * -1);
    width: auto;
    height: var(--e5-gate-height);
    z-index: 20;
}
.e5-gate-side--left .e5-gate {
    right: 0;
}
.e5-gate-side--right .e5-gate {
    left: 0;
}

/* =========================
   LAVA
   ========================= */

.lava-flow {
    position: absolute;

    left: 0;
    /* Unterkante hängt jetzt am Ebene5-Puffer (wie der Ebene5-Puffer selbst
       unter den sichtbaren Rand rutschend) statt fix am Viewport-Boden.
       Oberkante bleibt unverändert an der hinteren Puffer-Unterkante
       (das war schon durch --lava-band-vh gegeben) - kein Trapez, volle
       100vw-Breite bleibt überall gleich. Die Lava-Steintextur staucht sich
       dadurch entsprechend in die neue (größere) Höhe. */
    bottom: calc(-1 * (var(--e5-drop) + var(--e5-shore-height)));

    width: calc(100 * var(--uw));
    /* Oberkante = --back-anchor - --shore-height (Pufferbalken-Unterkante,
       folgt also ebenfalls --back-drop) */
    height: calc(var(--back-anchor) - var(--shore-height) + var(--e5-drop) + var(--e5-shore-height));

    z-index: 5;

    pointer-events: none;

    overflow: hidden;
}

/* =========================
   LAVA-GRUNDFLÄCHE
   ========================= */

.lava-flow__base {
    position: absolute;

    inset: 0;

    background: var(--lava-base);

    clip-path: polygon(
        0% 0%,
        100% 0%,
        120% 100%,
        -20% 100%
    );
}

/* =========================
   SVG-FLÄCHE
   ========================= */

.lava-flow__surface {
    position: absolute;

    inset: 0;

    animation:
        lava-pulse 3.6s ease-in-out infinite;
}

.lava-flow__surface svg {
    display: block;

    position: absolute;
    left: 50%;
    top: 0;

    /* Breite folgt primär der Bandhöhe (Mindest-Streckfaktor), nicht dem
       Fenster - dadurch bleiben die Steine auch bei schmalem Fenster gestreckt.
       Bei breiten Fenstern gewinnt weiterhin 100%, falls das noch breiter ist. */
    width: max(100%, calc(var(--lava-rock-min-stretch) * var(--lava-band-vh) * calc(1 * var(--uh))));
    height: 100%;

    transform: translateX(-50%);
}

/* =========================
   LAVA-BEWEGUNG
   ========================= */

.lava-mover {
    transform: translateX(-1000px);

    animation:
        lava-scroll var(--lava-speed)
        linear infinite;
}

@keyframes lava-scroll {
    from {
        transform: translateX(-1000px);
    }

    to {
        transform: translateX(0);
    }
}

/* =========================
   GLOW
   ========================= */

@keyframes lava-pulse {
    0%,
    100% {
        filter:
            drop-shadow(
                0 0 8px
                var(--lava-glow)
            )
            drop-shadow(
                0 0 18px
                var(--lava-glow)
            );
    }

    50% {
        filter:
            drop-shadow(
                0 0 16px
                var(--lava-glow)
            )
            drop-shadow(
                0 0 38px
                var(--lava-glow)
            );
    }
}

/* =========================
   LAVA-PAUSE (Bosskampf)
   =========================
   Performance-Pause der Lava-/Fluss-Animationen während des Bosskampfs
   gegen den Soulkeeper - Klasse wird per JS auf .level3-hoellentor
   umgeschaltet (js/level3-gameplay.js: zeigeFluss), zu denselben
   Zeitpunkten wie die Seelen-Pause (.level3-hoellentor--seelen-pause
   weiter oben): an in beginneKampf(), aus am Ende des Kampfs.

   Anders als bei den Seelen darf hier NICHT display:none verwendet
   werden - die Lava ist die Bildmitte der Szene und muss sichtbar
   bleiben. Deshalb animation-play-state: paused - Aussehen, Position
   und Ebenenzuordnung bleiben unverändert, es ruhen nur die beiden
   endlos laufenden Animationen des Flusses an ihrer aktuellen Stelle:
   lava-scroll (Fließbewegung, .lava-mover) und lava-pulse (Glutpuls,
   .lava-flow__surface - animiert drop-shadow und muss den Schein daher
   jeden Frame neu rastern). */
.level3-hoellentor--fluss-pause .lava-flow__surface,
.level3-hoellentor--fluss-pause .lava-mover {
    animation-play-state: paused;
}
