/* ══════════════════════════════════════════════════════════════════
   lbx-fx.css — Scroll-FX für Page-Builder-Blöcke (Lore UND Artworks)
   Wird von js/lbx-fx.js erzeugt, von js/lbx-anim.js scharf geschaltet.

   Aufbau des Wrappers:
     .lbx-fx-wrap.lbx-anim.lbx-anim-<preset>[.lbx-fx-on-<atmo>]
       └ .lbx-fx-layer        Partikel / Blitze  (z-index 5, vor dem Block)
       └ .lbx-fx-inner        wird animiert      (z-index 3)
           └ .lbx-fx-ghost    Farbkopien für Glitch
           └ .lbx-fx-body     der eigentliche Block
       └ .lbx-sound-toggle

   Alles bleibt im Block (overflow:hidden), nie Fullscreen.
   --lbx-fx-color steuert die Atmosphäre unabhängig von der Textfarbe.
   ══════════════════════════════════════════════════════════════════ */

/* ── Effect ──────────────────────────────────────────────────── */
.lbx-effect {
  padding: clamp(32px, 5vw, 64px) clamp(16px, 4vw, 48px);
  text-align: center;
  overflow: hidden;
}

/* BOOM — Impact / Haettenschweiler style */
.lbx-effect-boom .lbx-effect-text {
  font-family: Impact, 'Arial Narrow Bold', 'Haettenschweiler', 'Arial Black', sans-serif;
  font-size: clamp(4rem, 18vw, 14rem);
  font-weight: 900;
  text-transform: uppercase;
  line-height: .85;
  letter-spacing: -.02em;
  text-shadow: 6px 6px 0 rgba(0,0,0,.45);
  display: block;
}

/* FLASH — Monospace electric */
.lbx-effect-flash .lbx-effect-text {
  font-family: 'Courier New', 'Lucida Console', monospace;
  font-size: clamp(2rem, 8vw, 6rem);
  font-style: italic;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .12em;
  border-bottom: 3px solid currentColor;
  padding-bottom: 8px;
  display: inline-block;
  text-shadow: 0 0 18px currentColor, 0 0 40px currentColor;
}

/* WOW — Gradient glam */
.lbx-effect-wow .lbx-effect-text {
  font-size: clamp(3rem, 12vw, 10rem);
  font-weight: 900;
  text-transform: uppercase;
  line-height: .9;
  background: linear-gradient(135deg, var(--lbx-effect-color, #ff6b00) 0%, #ffd700 50%, #ff6b00 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  display: block;
  letter-spacing: -.03em;
}

/* ATTACK — Aggressive italic */
.lbx-effect-attack .lbx-effect-text {
  font-family: 'Arial Black', Impact, sans-serif;
  font-size: clamp(3rem, 10vw, 8rem);
  font-weight: 900;
  font-style: italic;
  text-transform: uppercase;
  letter-spacing: .06em;
  line-height: .9;
  display: block;
  text-shadow: 3px 0 0 rgba(0,0,0,.5);
  transform: skewX(-6deg);
  display: inline-block;
}

.lbx-effect-subtext {
  display: block;
  font-size: .78rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  opacity: .5;
  margin-top: 14px;
}


/* ══ FX-SYSTEM für Effect-Blöcke ══════════════════════════════════
   Zwei unabhängige, kombinierbare Ebenen:
     1. Textanimation   .lbx-anim-<preset>   (pop, slam, glitch, …)
     2. Atmosphäre      .lbx-fx-<preset>     (rain, snow, ash, storm, …)
   js/lbx-anim.js setzt .is-in beim Reinscrollen.
   Alles bleibt im Block (overflow:hidden), nie Fullscreen.
   --lbx-fx-color steuert die Atmosphäre unabhängig von der Textfarbe. */

.lbx-fx-wrap { position: relative; isolation: isolate; display: block; overflow: hidden; }
.lbx-fx-inner { position: relative; z-index: 3; }
.lbx-fx-body  { position: relative; }

/* Startzustand: Text unsichtbar, bis gescrollt wurde */
.lbx-anim .lbx-fx-inner { opacity: 0; will-change: transform, opacity, filter; }
.lbx-anim.is-in .lbx-fx-inner { opacity: 1; }

/* ─────────────────────────────────────────────────────────────────
   1. TEXTANIMATIONEN
   ───────────────────────────────────────────────────────────────── */

/* POP — bloppt auf, Druckwelle + Splitter fliegen raus */
.lbx-anim-pop.is-in .lbx-fx-inner { animation: lbxPop .55s cubic-bezier(.2,1.7,.3,1) both; }
.lbx-anim-pop .lbx-fx-body::before,
.lbx-anim-pop .lbx-fx-body::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 12px; height: 12px; margin: -6px 0 0 -6px; border-radius: 50%;
  border: 4px solid var(--lbx-anim-color, currentColor); opacity: 0; pointer-events: none; z-index: -1;
}
.lbx-anim-pop.is-in .lbx-fx-body::before { animation: lbxShockwave .8s cubic-bezier(.1,.7,.3,1) .04s both; }
.lbx-anim-pop.is-in .lbx-fx-body::after  { animation: lbxShockwave 1.1s cubic-bezier(.1,.7,.3,1) .16s both; }
@keyframes lbxPop {
  0%   { opacity: 0; transform: scale(.2) rotate(-4deg); filter: blur(10px); }
  50%  { opacity: 1; transform: scale(1.15) rotate(1.5deg); filter: blur(0); }
  68%  { transform: scale(.94) rotate(-.5deg); }
  84%  { transform: scale(1.04); }
  100% { opacity: 1; transform: scale(1) rotate(0); }
}
@keyframes lbxShockwave {
  0%   { opacity: .9; transform: scale(1); border-width: 8px; }
  100% { opacity: 0; transform: scale(60); border-width: 0.5px; }
}

/* SLAM — knallt aus der Tiefe rein, Nachbeben, Staubring */
.lbx-anim-slam.is-in .lbx-fx-inner { animation: lbxSlam .45s cubic-bezier(.2,.85,.15,1) both, lbxShake .38s .42s both; }
@keyframes lbxSlam {
  0%   { opacity: 0; transform: scale(3.2) translate3d(0,-8%,0); filter: blur(20px); }
  60%  { opacity: 1; filter: blur(2px); }
  100% { opacity: 1; transform: scale(1) translate3d(0,0,0); filter: blur(0); }
}

/* SHAKE */
.lbx-anim-shake.is-in .lbx-fx-inner { animation: lbxShake .5s cubic-bezier(.36,.07,.19,.97) both; }
@keyframes lbxShake {
  0%, 100% { transform: translate3d(0,0,0); }
  10% { transform: translate3d(-11px, 3px, 0) rotate(-.8deg); }
  22% { transform: translate3d(10px, -4px, 0) rotate(.7deg); }
  34% { transform: translate3d(-8px, 2px, 0) rotate(-.4deg); }
  46% { transform: translate3d(6px, -2px, 0); }
  62% { transform: translate3d(-4px, 1px, 0); }
  80% { transform: translate3d(2px, 0, 0); }
}

/* GLITCH — echter Kanaltrenner: zwei Geisterkopien + Slice-Versatz + Scanlines */
.lbx-anim-glitch .lbx-fx-ghost {
  position: absolute; inset: 0; pointer-events: none; opacity: 0;
  mix-blend-mode: screen; will-change: transform, clip-path;
}
.lbx-anim-glitch .lbx-fx-ghost * { color: inherit !important; -webkit-text-fill-color: currentColor !important; background: none !important; }
.lbx-anim-glitch .lbx-fx-ghost img,
.lbx-anim-glitch .lbx-fx-ghost video,
.lbx-anim-glitch .lbx-fx-ghost iframe { opacity: .35; filter: saturate(0); }
.lbx-anim-glitch .lbx-fx-ghost-a { color: #00e9ff; }
.lbx-anim-glitch .lbx-fx-ghost-b { color: #ff0052; }
.lbx-anim-glitch.is-in .lbx-fx-body { animation: lbxGlitchBody 1.15s steps(1, end) both; }
.lbx-anim-glitch.is-in .lbx-fx-ghost-a  { animation: lbxGlitchA 1.15s steps(1, end) both; }
.lbx-anim-glitch.is-in .lbx-fx-ghost-b  { animation: lbxGlitchB 1.15s steps(1, end) both; }
.lbx-anim-glitch .lbx-fx-inner::after {
  content: ''; position: absolute; inset: -10%; pointer-events: none; opacity: 0;
  background: repeating-linear-gradient(to bottom,
    rgba(255,255,255,.10) 0 1px, transparent 1px 3px);
  mix-blend-mode: overlay;
}
.lbx-anim-glitch.is-in .lbx-fx-inner::after { animation: lbxScanlines 1.15s linear both; }
@keyframes lbxGlitchBody {
  0%   { opacity: 0; clip-path: inset(45% 0 45% 0); transform: translate3d(0,0,0); }
  6%   { opacity: 1; clip-path: inset(0 0 0 0); }
  12%  { clip-path: inset(12% 0 62% 0); transform: translate3d(-22px,0,0); }
  16%  { clip-path: inset(0 0 0 0);    transform: translate3d(0,0,0); }
  24%  { clip-path: inset(68% 0 8% 0); transform: translate3d(18px,0,0); }
  28%  { clip-path: inset(0 0 0 0);    transform: translate3d(0,0,0); }
  38%  { clip-path: inset(34% 0 40% 0); transform: translate3d(-12px,2px,0); }
  42%  { clip-path: inset(0 0 0 0);    transform: none; }
  55%  { opacity: .25; }
  57%  { opacity: 1; }
  70%  { clip-path: inset(6% 0 78% 0); transform: translate3d(9px,-2px,0); }
  73%  { clip-path: inset(0 0 0 0);    transform: none; }
  100% { opacity: 1; clip-path: inset(0 0 0 0); transform: none; }
}
@keyframes lbxGlitchA {
  0%   { opacity: 0; }
  6%   { opacity: .9; transform: translate3d(-14px,-3px,0); clip-path: inset(10% 0 55% 0); }
  14%  { opacity: .8; transform: translate3d(12px,2px,0);  clip-path: inset(58% 0 18% 0); }
  22%  { opacity: .9; transform: translate3d(-20px,0,0);   clip-path: inset(25% 0 45% 0); }
  30%  { opacity: .6; transform: translate3d(8px,-4px,0);  clip-path: inset(72% 0 4% 0); }
  44%  { opacity: .8; transform: translate3d(-9px,3px,0);  clip-path: inset(38% 0 38% 0); }
  58%  { opacity: .5; transform: translate3d(5px,0,0);     clip-path: inset(2% 0 82% 0); }
  72%  { opacity: .3; transform: translate3d(-3px,0,0);    clip-path: inset(0 0 0 0); }
  88%, 100% { opacity: 0; transform: none; clip-path: inset(0 0 0 0); }
}
@keyframes lbxGlitchB {
  0%   { opacity: 0; }
  6%   { opacity: .9; transform: translate3d(15px,3px,0);  clip-path: inset(55% 0 12% 0); }
  14%  { opacity: .8; transform: translate3d(-13px,-2px,0);clip-path: inset(16% 0 60% 0); }
  22%  { opacity: .9; transform: translate3d(21px,0,0);    clip-path: inset(44% 0 26% 0); }
  30%  { opacity: .6; transform: translate3d(-7px,4px,0);  clip-path: inset(6% 0 70% 0); }
  44%  { opacity: .8; transform: translate3d(10px,-3px,0); clip-path: inset(36% 0 40% 0); }
  58%  { opacity: .5; transform: translate3d(-6px,0,0);    clip-path: inset(80% 0 2% 0); }
  72%  { opacity: .3; transform: translate3d(3px,0,0);     clip-path: inset(0 0 0 0); }
  88%, 100% { opacity: 0; transform: none; clip-path: inset(0 0 0 0); }
}
@keyframes lbxScanlines {
  0%   { opacity: .9; transform: translate3d(0,0,0); }
  60%  { opacity: .5; transform: translate3d(0,14px,0); }
  100% { opacity: 0; transform: translate3d(0,26px,0); }
}

/* WIPE */
.lbx-anim-wipe.is-in .lbx-fx-inner { animation: lbxWipe .85s cubic-bezier(.72,0,.16,1) both; }
@keyframes lbxWipe {
  0%   { opacity: 1; clip-path: inset(0 100% 0 0); transform: translate3d(-30px,0,0); }
  100% { opacity: 1; clip-path: inset(0 0 0 0);    transform: none; }
}

/* RISE */
.lbx-anim-rise.is-in .lbx-fx-inner { animation: lbxRise .8s cubic-bezier(.16,1,.3,1) both; }
@keyframes lbxRise {
  0%   { opacity: 0; transform: translate3d(0,48px,0); letter-spacing: .22em; filter: blur(6px); }
  100% { opacity: 1; transform: none; filter: blur(0); }
}

/* SHATTER — Text zerspringt herein */
.lbx-anim-shatter.is-in .lbx-fx-inner { animation: lbxShatter .9s cubic-bezier(.19,1,.22,1) both; }
@keyframes lbxShatter {
  0%   { opacity: 0; transform: scale(1.6) skewX(22deg); filter: blur(18px) contrast(3); }
  35%  { opacity: 1; transform: scale(.97) skewX(-7deg); filter: blur(2px) contrast(1.4); }
  55%  { transform: scale(1.02) skewX(3deg); filter: blur(0) contrast(1); }
  72%  { transform: scale(.995) skewX(-1deg); }
  100% { opacity: 1; transform: none; filter: none; }
}

/* BURN — brennt sich von unten ein */
.lbx-anim-burn.is-in .lbx-fx-inner { animation: lbxBurn 1.1s cubic-bezier(.3,.8,.2,1) both; }
@keyframes lbxBurn {
  0%   { opacity: 0; clip-path: inset(0 0 100% 0); filter: brightness(4) blur(8px); }
  30%  { opacity: 1; filter: brightness(2.4) blur(2px); }
  100% { opacity: 1; clip-path: inset(0 0 0 0); filter: none; }
}

/* ─────────────────────────────────────────────────────────────────
   2. ATMOSPHÄRE — Partikel- und Wetterebenen
   ───────────────────────────────────────────────────────────────── */

.lbx-fx-layer {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 5;
  opacity: 0; transition: opacity .6s ease;
  color: var(--lbx-fx-color, #9fd0ff);
}
.is-in > .lbx-fx-layer { opacity: 1; }
.lbx-fx-layer i {
  position: absolute; top: -14%; display: block;
  animation-iteration-count: infinite; animation-timing-function: linear;
  animation-play-state: paused;
}
.is-in > .lbx-fx-layer i { animation-play-state: running; }

/* REGEN — drei Tiefenebenen, schräg, mit Aufschlag am Boden */
.lbx-fx-rain i {
  width: 1.5px; height: clamp(28px, 6vh, 60px);
  background: linear-gradient(to bottom, transparent, currentColor 55%, #fff);
  opacity: .5; border-radius: 2px;
  animation-name: lbxRainFall;
}
.lbx-fx-rain i:nth-child(3n)   { opacity: .22; width: 1px;   filter: blur(1.2px); }
.lbx-fx-rain i:nth-child(3n+1) { opacity: .75; width: 2px; }
.lbx-fx-rain::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to bottom, transparent 55%, color-mix(in srgb, currentColor 22%, transparent));
  mix-blend-mode: screen;
}
@keyframes lbxRainFall {
  0%   { top: -22%; transform: translate3d(0, 0, 0) scaleY(var(--lbx-p-scale,1)); }
  100% { top: 118%; transform: translate3d(28px, 0, 0) scaleY(var(--lbx-p-scale,1)); }
}

/* SCHNEE — größer, weich, seitlich treibend, drei Größen */
.lbx-fx-snow i {
  width: 9px; height: 9px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #fff 0%, currentColor 60%, transparent 72%);
  opacity: .9; animation-name: lbxSnowDrift;
}
.lbx-fx-snow i:nth-child(3n)   { width: 5px;  height: 5px;  opacity: .55; filter: blur(.6px); }
.lbx-fx-snow i:nth-child(4n+1) { width: 14px; height: 14px; opacity: .5;  filter: blur(2.4px); }
@keyframes lbxSnowDrift {
  0%   { top: -14%; transform: translate3d(0,0,0) scale(var(--lbx-p-scale,1)) rotate(0deg); }
  25%  {            transform: translate3d(22px,0,0) scale(var(--lbx-p-scale,1)) rotate(90deg); }
  55%  {            transform: translate3d(-18px,0,0) scale(var(--lbx-p-scale,1)) rotate(200deg); }
  80%  {            transform: translate3d(14px,0,0) scale(var(--lbx-p-scale,1)) rotate(290deg); }
  100% { top: 114%; transform: translate3d(-6px,0,0) scale(var(--lbx-p-scale,1)) rotate(360deg); }
}

/* ASCHE / GLUT — Funken steigen auf, glühen, flackern */
.lbx-fx-ash i {
  top: auto; bottom: -12%;
  width: 6px; height: 6px; border-radius: 50%;
  background: radial-gradient(circle, #fff2c2 0%, currentColor 45%, transparent 70%);
  box-shadow: 0 0 14px 3px currentColor;
  opacity: 0; animation-name: lbxEmberRise;
}
.lbx-fx-ash i:nth-child(3n)   { width: 3px;  height: 3px; box-shadow: 0 0 8px 1px currentColor; }
.lbx-fx-ash i:nth-child(5n+2) { width: 10px; height: 10px; filter: blur(2px); }
@keyframes lbxEmberRise {
  0%   { bottom: -12%; opacity: 0;   transform: translate3d(0,0,0) scale(var(--lbx-p-scale,1)); }
  12%  {               opacity: 1; }
  45%  {               opacity: .85; transform: translate3d(-28px,0,0) scale(calc(var(--lbx-p-scale,1) * .8)); }
  70%  {               opacity: .5;  transform: translate3d(20px,0,0)  scale(calc(var(--lbx-p-scale,1) * .6)); }
  100% { bottom: 122%; opacity: 0;   transform: translate3d(-12px,0,0) scale(calc(var(--lbx-p-scale,1) * .35)); }
}

/* NEBEL — träge Schwaden */
.lbx-fx-fog i {
  top: auto; bottom: -30%;
  width: 62%; height: 62%; border-radius: 50%;
  background: radial-gradient(ellipse at center, currentColor 0%, transparent 68%);
  opacity: 0; filter: blur(30px); animation-name: lbxFogDrift;
}
@keyframes lbxFogDrift {
  0%   { bottom: -30%; opacity: 0;   transform: translate3d(-45%, 0, 0) scale(var(--lbx-p-scale,1)); }
  25%  {               opacity: .4; }
  75%  {               opacity: .32; }
  100% { bottom: 55%;  opacity: 0;   transform: translate3d(65%, 0, 0) scale(calc(var(--lbx-p-scale,1) * 1.5)); }
}

/* GEWITTER — Regen + Blitzschlag + Aufhellung des ganzen Blocks */
.lbx-fx-storm i {
  width: 1.5px; height: clamp(34px, 7vh, 72px);
  background: linear-gradient(to bottom, transparent, currentColor 50%, #fff);
  opacity: .6; animation-name: lbxRainFall;
}
.lbx-fx-storm i:nth-child(3n) { opacity: .25; filter: blur(1.4px); }
.lbx-bolt {
  position: absolute; top: -6%; width: 42%; height: 116%;
  opacity: 0; pointer-events: none; z-index: 2;
  filter: drop-shadow(0 0 14px #cfe6ff) drop-shadow(0 0 40px #79b6ff);
}
.lbx-bolt path { fill: none; stroke: #eaf4ff; stroke-width: 3; stroke-linejoin: miter; }
.is-in .lbx-bolt { animation: lbxBolt 7s steps(1, end) infinite; }
.is-in .lbx-bolt-2 { animation-delay: 3.4s; animation-duration: 9s; }
@keyframes lbxBolt {
  0%, 3%   { opacity: 0; }
  4%       { opacity: 1; }
  5%       { opacity: 0; }
  6%       { opacity: .85; }
  8%       { opacity: 0; }
  9%       { opacity: 1; }
  12%,100% { opacity: 0; }
}
.lbx-flash {
  position: absolute; inset: 0; pointer-events: none; z-index: 2; opacity: 0;
  background: radial-gradient(ellipse at 50% 0%, rgba(226,240,255,.85) 0%, rgba(150,190,255,.28) 42%, transparent 72%);
  mix-blend-mode: screen;
}
.is-in .lbx-flash { animation: lbxFlash 7s steps(1, end) infinite; }
.is-in .lbx-flash-2 { animation-delay: 3.4s; animation-duration: 9s; }
@keyframes lbxFlash {
  0%, 3%   { opacity: 0; }
  4%       { opacity: 1; }
  5%       { opacity: .1; }
  6%       { opacity: .7; }
  8%       { opacity: 0; }
  9%       { opacity: .9; }
  13%,100% { opacity: 0; }
}

/* Ohne eigene Textanimation sollen Atmosphären-Blöcke trotzdem sanft kommen */
.lbx-anim-none.is-in .lbx-fx-inner { animation: lbxRise .8s cubic-bezier(.16,1,.3,1) both; }

/* Sound-Schalter — ein kleiner Lautsprecher unten rechts im Block */
.lbx-sound-toggle {
  position: absolute; right: 12px; bottom: 10px; z-index: 6;
  width: 30px; height: 30px; padding: 0; cursor: pointer;
  display: grid; place-items: center; font-size: 14px; line-height: 1;
  border: 1px solid rgba(255,255,255,.28); border-radius: 50%;
  background: rgba(0,0,0,.42); color: #fff; opacity: .38;
  transition: opacity .25s ease, transform .25s ease, background .25s ease;
}
.lbx-sound-toggle:hover { opacity: 1; transform: scale(1.12); background: rgba(0,0,0,.7); }
.lbx-sound-toggle:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .lbx-anim .lbx-fx-inner,
  .lbx-anim.is-in .lbx-fx-inner,
  .lbx-anim.is-in .lbx-fx-body,
  .lbx-anim.is-in .lbx-fx-ghost { animation: none !important; opacity: 1; }
  .lbx-anim-glitch .lbx-fx-ghost { display: none; }
  .lbx-fx-layer { display: none; }
}
