/* ===== 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. */

#scene-hades {
    background: transparent;
    /* Ist der Fluch gebrochen, wächst diese Box per --soul-overflow
       (css/welt.css) um bis zu +200vh nach OBEN - reicht dann bis über die
       gesamte Oberwelt/den Himmel hinauf (fürs Aufsteigen der Seelen). Ohne
       pointer-events:none faengt diese riesige, an den meisten Stellen
       transparente Box (gleicher z-index:1 wie #scene-level1, aber SPAETER
       im DOM -> gewinnt bei Ueberlappung) dann saemtliche Klicks in der
       Oberwelt ab, z.B. den Button "Hinab in die Unterwelt" - obwohl dort
       optisch nichts zu sehen ist. .level3-hoellentor (der eigentliche,
       normal-grosse sichtbare Inhalt inkl. eingebetteter Wann&Wo-Links)
       bekommt pointer-events explizit zurueck. */
    pointer-events: none;
}

.level3-hoellentor {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: auto;
    /* Entspricht dem html/body-Hintergrund aus test.html - liegt unter
       allen Ebenen, sichtbar an Stellen, die keine Ebene abdeckt. */
    background: #1a0806;

    /* ===== TEST: Platz für eingebetteten Seiteninhalt (So war es 2025 /
       Wann & Wo, siehe css/hades-inhalt.css) =====
       --hades-extra wird von js/hades-inhalt.js gesetzt, sobald der
       eingebettete Inhalt mehr Platz braucht als bis zur Brückenmitte
       standardmäßig verfügbar ist (0px, solange er hineinpasst).
       --hades-box-hoehe ersetzt ab hier jedes "100vh", das bisher eine
       TOP-relative Distanz innerhalb dieser (bisher immer exakt 100vh
       hohen) Szene ausgedrückt hat (--bg-corner-size, --river-top,
       --river-mid, --bridge-y-back, --bridge-y-front) - dadurch wachsen
       diese Distanzen automatisch mit, wenn --hades-extra > 0 ist, und
       die davon abhängigen Elemente (Riss-Ecken, Fluss, Brücke) bleiben
       exakt an ihrer gewohnten Position relativ zu Tor/Ufer/Zäunen, die
       selbst per bottom:-Werten (siehe unten) automatisch mit nach unten
       rutschen, wenn die Szene wächst (siehe css/welt.css:
       #scene-hades/.level3-hoellentor für die dazu nötige Umstellung von
       bottom- auf top-Verankerung der gesamten Szene). */
    --hades-box-hoehe: calc(calc(100 * var(--uh)) + var(--hades-extra, 0px));

    --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: 160px;
    --gate-overlap: 10px;
    --gate-drop: 12px;
    --fence-height: clamp(120px, calc(10 * var(--uh)), 200px);
    --gate-height: clamp(200px, calc(24 * var(--uh)), 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.
       BUGFIX (TODO-20260901-025): war zuvor ein roher Pixelwert (140px),
       der nicht mit --stage-scale skalierte - dadurch wurde der Lavafluss
       bei sinkender Fensterhöhe überproportional schmaler (Formel dazu
       siehe --back-anchor unten), bis die Ufer sich berührten. 7.2px ist
       der Basiswert von --uh bei --stage-scale:1 (siehe js/buehne.js),
       140px / 7.2px * var(--uh) ergibt am Referenzgerät exakt wieder 140px,
       skaliert von dort aber proportional mit der Bühne. (7.2 bleibt hier
       bewusst ohne "px", da --uh selbst schon die Längeneinheit liefert -
       "px * px" wäre eine ungültige CSS-calc()-Einheit.) */
    --back-drop: calc((140 / 7.2) * var(--uh));
    /* 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: clamp(16px, 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(var(--hades-box-hoehe) - var(--river-top-from-bottom));
    --river-mid: calc(var(--hades-box-hoehe) - 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: clamp(450px, calc(56 * var(--uh)), 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(var(--hades-box-hoehe) - var(--back-anchor));

    /* ===== EBENE 5 (VORDERGRUND: nähere/größere Zaun+Tor-Reihe) ===== */
    --e5-gate-space: 320px;
    --e5-gate-overlap: 14px;
    --e5-gate-drop: 16px;
    --e5-fence-height: clamp(170px, calc(14 * var(--uh)), 280px);
    --e5-gate-height: clamp(280px, calc(34 * var(--uh)), 620px);
    --e5-shore-height: clamp(30px, 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.
       BUGFIX (TODO-20260901-025): war zuvor ein roher Pixelwert (18px), der
       nicht mit --stage-scale skalierte - lag direkt in der Formel für den
       Abstand .lava-shore/.e5-shore (Lavafluss-Höhe) und hat den Fluss bei
       sinkender Fensterhöhe zusätzlich unproportional schmaler gemacht.
       18px / 7.2px * var(--uh) ergibt am Referenzgerät exakt wieder 18px.
       (7.2 bleibt hier bewusst ohne "px", da --uh selbst schon die
       Längeneinheit liefert - "px * px" wäre eine ungültige CSS-calc()-
       Einheit.) */
    --e5-drop: calc((18 / 7.2) * var(--uh));

    /* ===== BRÜCKE (spannt zwischen den Puffer-Oberkanten, X mittig zu den Gates) ===== */
    --bridge-inset: 8px;
    --bridge-x-back-left: calc(50% - (var(--gate-space) / 2) - (var(--gate-height) * 49 / 462));
    --bridge-x-back-right: calc(50% + (var(--gate-space) / 2) + (var(--gate-height) * 49 / 462));
    /* Ankert an --back-anchor (Oberkante des hinteren Pufferbalkens,
       inkl. --back-drop) - deckt damit den Balken-Verlauf im Brückenbereich ab.
       TEST: über --hades-box-hoehe statt festem 100vh, damit die Brücke mit
       nach unten rutscht, wenn --hades-extra > 0 ist (siehe oben). */
    --bridge-y-back: calc(var(--hades-box-hoehe) - var(--back-anchor));
    /* TEST: dieselbe Formel, aber bewusst OHNE --hades-extra - reine
       Mess-Referenz für #hades-slot-marke (siehe css/hades-inhalt.css),
       damit js/hades-inhalt.js immer gegen denselben, unveränderten
       Bezugspunkt misst (sonst würde ein bereits gesetztes --hades-extra
       bei der nächsten Messung fälschlich mit "weggemessen"). */
    --bridge-y-back-basis: calc(calc(100 * var(--uh)) - var(--back-anchor));
    --bridge-x-front-left: calc(50% - (var(--e5-gate-space) / 2) - (var(--e5-gate-height) * 49 / 462));
    --bridge-x-front-right: calc(50% + (var(--e5-gate-space) / 2) + (var(--e5-gate-height) * 49 / 462));
    /* Ankert an der OBERKANTE des Ebene5-Pufferbalkens (= Unterkante von
       .e5-gates) - selbe Logik wie hinten, für konsistenten Anker beidseitig.
       TEST: siehe --bridge-y-back oben (--hades-box-hoehe statt 100vh). */
    --bridge-y-front: calc(var(--hades-box-hoehe) + var(--e5-drop));
    /* TEST: Mess-Referenz ohne --hades-extra, siehe --bridge-y-back-basis. */
    --bridge-y-front-basis: 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);
}

/* "Höllen"-Schein im Tordurchgang (das Loch in der Mitte) - bewusst
   statisch statt pulsierend: sitzt inzwischen größtenteils hinter den
   Höllentor-Karten (.hades-karte, siehe css/hades-inhalt.css) und war
   dadurch kaum noch sichtbar, kostete aber weiterhin Performance. */
.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;
}

.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;
    /* Größe/z-index 1:1 an SoulKeeper angeglichen (SoulKeeper/css/level3.css:
       .bg-corner) - dort bewusst 45% kleiner als die volle --bg-corner-size,
       damit die Ecken wie ein weiter entferntes Hintergrundelement wirken. */
    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%;
    /* 1.3x der ursprünglichen 26x42px (Vorgabe: 1,2-1,4x größer). Referenz-
       anker 1920x1080, siehe css/programm.css: .programm-block fuer die
       Begruendung der /1.5-Korrektur. */
    width: calc(34px / 1.5 * var(--stage-scale));
    height: calc(55px / 1.5 * var(--stage-scale));
    margin-left: calc(-17px / 1.5 * var(--stage-scale));
    z-index: 15;
    pointer-events: none;
    opacity: 0;
    animation: soul-fall linear infinite;
    will-change: transform, opacity;
}
/* Reines Pixel-Art-Bild (img/Soul/DeadSoul_pixel.png) statt der früheren
   CSS-Tropfenform + Schweif (Vorgabe: "kein Schweif mehr, nur das Bild") -
   auf einem eigenen Pseudo-Element, damit die Kopf-oben/Kopf-unten-Drehung
   (siehe unten) unabhängig von der auf .soul selbst animierten
   translate/scale-Bewegung bleibt (zwei getrennte Elemente, keine
   Transform-Überlagerung nötig). */
.soul::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image: url('../../sh/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. Sobald der Fluch
       gebrochen ist, fliegen sie stattdessen nach oben (siehe
       html.fluch-gebrochen .soul unten) - dort bleibt die Kopf-oben-
       Ausrichtung unverändert, keine Drehung mehr. */
    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;
    }
}

/* Ist der Fluch gebrochen (html.fluch-gebrochen, siehe js/fluch-status.js),
   fallen die Seelen nicht mehr in den Lavafluss - sie steigen stattdessen
   vom Fluss auf und sind frei, in den Himmel zu gelangen (siehe Dialogtext
   der verlorenen Seele: "Endlich können die verlorenen Seelen wieder
   ruhen."). Dieselben Zeit-/Delay-Werte wie beim Fallen (siehe index.php,
   inline style je .soul), aber NICHT dieselbe (kurze) Fallstrecke rückwärts -
   --soul-fall-distance wird bei gebrochenem Fluch selbst länger (css/welt.css:
   html.fluch-gebrochen #scene-hades vergrößert --soul-overflow zusätzlich um
   Oberwelt- und Himmel-Höhe), die Seelen steigen dadurch durch die gesamte
   Oberwelt hindurch bis in den Himmel auf, statt nur bis zur Unterwelt-
   Oberkante. Ohne die 180°-Drehung, da Kopf-oben jetzt schon die richtige
   Flugrichtung ist. */
html.fluch-gebrochen .soul {
    animation-name: soul-rise;
    /* Die Aufstiegsstrecke ist deutlich laenger als die urspruengliche
       Fallstrecke (steigt durch die GESAMTE Oberwelt bis in den Himmel,
       siehe --soul-overflow-Vergroesserung in css/welt.css), lief mit der
       unveraenderten Falldauer (--soul-basis-dauer, inline je .soul in
       index.php) dadurch spuerbar zu schnell. !important noetig, da eine
       Inline-style-Deklaration (animation-duration auf .soul selbst) sonst
       IMMER gewinnt, unabhaengig von Selektor-Spezifitaet. Multiplikator
       (statt fester Sekundenwert) erhaelt die bestehende Staffelung
       zwischen den 5 Seelen (unterschiedlicher Start-Zeitpunkt/-Tempo). */
    animation-duration: calc(var(--soul-basis-dauer, 15s) * 3.2) !important;
}

html.fluch-gebrochen .soul::before {
    transform: none;
}

@keyframes soul-rise {
    0% {
        transform: translate(0, var(--soul-fall-distance)) scale(0.7);
        opacity: 0;
    }
    12% {
        opacity: 1;
    }
    80% {
        opacity: 0.85;
    }
    100% {
        transform: translate(var(--soul-drift, 0px), 0) 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. MUSS + --hades-extra enthalten:
       --bridge-y-back/--bridge-y-front (siehe --bridge-clip oben) hängen
       an --hades-box-hoehe, die --hades-extra einschließt - fehlt es HIER,
       bleibt die eigene Box des Elements kürzer als die Clip-Path-Koordinaten
       und die komplette Brücke landet außerhalb ihrer eigenen (zu kurzen)
       Box, wird also gar nicht mehr gezeichnet (nicht falsch positioniert,
       sondern komplett unsichtbar). Fiel auf invitation/index.html nie auf,
       da dort --hades-extra immer 0 ist (kein eingebetteter Inhalt). */
    height: calc(calc(100 * var(--uh)) + var(--hades-extra, 0px) + var(--e5-drop) + var(--e5-shore-height) + 20px);
    pointer-events: none;
}

/* z-index zwischen .lava-shore (8) und .lava-gates (10, enthält Zaun+Gate) -
   die Brücke deckt damit weiterhin den Pufferbalken-Verlauf ab, wird aber
   selbst von Zaun+Gate überdeckt (analog zu .e5-gates, deren z-index 30
   bewusst ÜBER der Brücke liegt). So bleibt die Brücke optisch an den
   Gate-Anschlussstellen "aufgehängt" statt sie zu überdecken. */
.bridge-frame {
    background: #000;
    clip-path: var(--bridge-clip);
    z-index: 9;
}

.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: 9;
}

/* =========================
   EBENE 5 (VORDERGRUND) - PUFFERBALKEN
   ========================= */
.e5-shore {
    position: absolute;
    left: 0;
    /* Direkt unter Ebene5-Zaun/Gate, sinkt weiter unter die sichtbare Kante.
       UNVERÄNDERT gelassen (siehe BUGFIX-20260901-006): --e5-drop/
       --e5-shore-height bestimmen zusammen mit --hades-box-hoehe (welt.css:
       #scene-hades .level3-hoellentor) exakt, wo die Unterkante dieses
       Puffers endet - identisch mit der Unterkante von .lava-flow (beide
       nutzen dieselbe Formel), das darf so bleiben. */
    bottom: calc(-1 * var(--e5-drop) - var(--e5-shore-height));
    width: calc(100 * var(--uw));
    /* War: nur var(--e5-shore-height). <footer class="site-footer"> ist das
       nächste Geschwisterelement von #scene-hades und beginnt (normaler
       Dokumentfluss, kein eigener Stacking-Context-Konflikt) GENAU an der
       Unterkante von .level3-hoellentor. Mit der alten, kleineren Höhe lag
       die KOMPLETTE Box dieses Puffers unterhalb dieser Kante, also
       vollständig hinter dem <footer> versteckt und optisch wirkungslos -
       das eigentliche Abdichten der Zaun-/Ufer-Zacken-Zwischenräume gegen
       die dahinterliegende Lava fand nie sichtbar statt (per Playwright-
       Live-Messung an mehreren Fenstergrößen bestätigt: die Box begann
       IMMER exakt --e5-drop unterhalb der Footer-Oberkante). Die Unterkante
       bleibt unverändert (s. oben), nur die Oberkante wandert dadurch um
       (--e5-drop + --e5-shore-height) nach oben - --e5-shore-height davon
       macht den Puffer oberhalb der Footer-Oberkante sichtbar (deckt dort
       verbliebene transparente Lücken der Zaun-Silhouette ab), der Rest
       (--e5-drop) gleicht exakt den bisher verschenkten Versatz aus. Beide
       Anteile bestehen bereits aus --uh-basierten Variablen, die neue Höhe
       skaliert dadurch automatisch mit --stage-scale mit. */
    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)
            );
    }
}

/* ===== Bewegung reduzieren (siehe css/welt.css für dasselbe Muster) =====
   Schaltet die dauerhaften Endlosschleifen-Animationen des Höllentors ab
   (Lavafluss-Scroll, Lava-Glow-Puls, fallende/aufsteigende Seelen). */
@media (prefers-reduced-motion: reduce) {
    .lava-mover,
    .lava-flow__surface,
    .soul {
        animation: none;
    }
}
