/* Banco de efectos de fondo (lib/fx.js): lo usan todas las vistas. Se carga en el CSS global (index.html) y también
   dentro del Shadow DOM de Clima. El cielo (.fx-sky) es un fondo fijo detrás del contenido; --t = duración y
   --ph = fase del reloj de cada animación (los pone fx.js inline: un repintado no las reinicia). */
.fx-sky { position: fixed; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }
.fx-sky { isolation: isolate; }
.fx-sky > * { position: absolute; inset: 0; }

.fx-ctl { position: relative; z-index: 30; } /* sobre las tarjetas (con efecto activo tienen backdrop-filter y crean su propio contexto de apilado) */
.fx-toggle {
  display: flex; align-items: center; gap: 7px; height: var(--fxh, 30px); width: var(--fx-btn-w, auto);
  padding: 0 11px; border: 1px solid var(--border); border-radius: 999px;
  background: color-mix(in srgb, var(--surface) 84%, transparent);
  color: color-mix(in srgb, var(--text) 84%, transparent);
  font: inherit; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.01em;
  backdrop-filter: blur(12px) saturate(1.1); -webkit-backdrop-filter: blur(12px) saturate(1.1);
  box-shadow: 0 6px 20px -12px rgba(0,0,0,.45);
  cursor: pointer; transition: transform .18s ease, background .18s ease, border-color .18s ease, color .18s ease;
}
.fx-toggle::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--fx-accent, var(--accent, var(--seq-fill, #2a78d6))); box-shadow: 0 0 0 4px color-mix(in srgb, var(--fx-accent, var(--accent, var(--seq-fill, #2a78d6))) 18%, transparent); }
.fx-toggle:hover { transform: translateY(-1px); background: color-mix(in srgb, var(--surface) 90%, transparent); color: var(--text); }
.fx-toggle:active { transform: translateY(0) scale(.98); }
.fx-toggle:focus-visible, .fx-opt:focus-visible { outline: 2px solid var(--seq-fill, #2a78d6); outline-offset: 2px; }
.fx-caret { color: var(--text-2); font-size: 0.75rem; margin-left: auto; }
.fx-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fx-menu {
  position: absolute; right: 0; top: calc(100% + 6px); min-width: 170px; max-height: max(160px, min(440px, calc(100vh - 200px))); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin;
  display: flex; flex-direction: column; padding: 5px; border: 1px solid var(--border); border-radius: 16px;
  background: color-mix(in srgb, var(--surface) 94%, transparent);
  backdrop-filter: blur(14px) saturate(1.1); -webkit-backdrop-filter: blur(14px) saturate(1.1);
  box-shadow: 0 14px 34px -14px rgba(0,0,0,.6);
}
.fx-opt {
  display: flex; align-items: center; gap: 9px; padding: 8px 11px; border: 0; border-radius: 11px; background: transparent;
  color: var(--text-2); font: inherit; font-size: 0.8125rem; font-weight: 500; text-align: left; white-space: nowrap; cursor: pointer;
}
.fx-opt::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: transparent; border: 1px solid var(--muted); flex: none; }
.fx-opt:hover { color: var(--text); background: color-mix(in srgb, var(--text) 8%, transparent); }
.fx-opt.on { color: var(--text); }
.fx-grp { padding: 10px 11px 4px; font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.fx-grp:not(:first-child) { margin-top: 4px; border-top: 1px solid var(--border); }
.fx-opt.on::before { background: var(--fx-accent, var(--accent, var(--seq-fill, #2a78d6))); border-color: var(--fx-accent, var(--accent, var(--seq-fill, #2a78d6))); }

/* Atmósferas con identidad propia. Los contenedores (.fx-sky > *) ocupan todo el cielo; las capas internas se posicionan solas.
   --t = duración y --ph = fase del reloj (inline desde views/clima.js: el repintado no reinicia la animación). */

/* Atardecer: cielo violeta -> rosa -> naranja, sol bajo que late y rayos que giran */
.fx-dusk { background: linear-gradient(180deg, rgba(88,52,170,.26) 0%, rgba(235,92,128,.18) 52%, rgba(255,150,64,.30) 100%); }
.fx-sun { inset: auto; left: 50%; bottom: -46vmin; width: 118vmin; height: 118vmin; margin-left: -59vmin; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,226,150,.60) 0%, rgba(255,140,80,.34) 34%, rgba(255,80,110,.12) 56%, transparent 70%);
  animation: fx-sun-pulse var(--t) ease-in-out infinite alternate; animation-delay: var(--ph); }
@keyframes fx-sun-pulse { from { transform: scale(.94); opacity: .8; } to { transform: scale(1.06); opacity: 1; } }
.fx-rays { inset: auto; left: 50%; bottom: -80vmax; width: 160vmax; height: 160vmax; margin-left: -80vmax; border-radius: 50%;
  background: repeating-conic-gradient(from 0deg, rgba(255,205,140,.20) 0 5deg, transparent 5deg 15deg);
  -webkit-mask-image: radial-gradient(circle, #000 0%, transparent 62%); mask-image: radial-gradient(circle, #000 0%, transparent 62%);
  animation: fx-spin var(--t) linear infinite; animation-delay: var(--ph); }
@keyframes fx-spin { to { transform: rotate(360deg); } }

/* Océano: agua profunda, olas festoneadas que se deslizan y burbujas */
.fx-sea { background: linear-gradient(180deg, rgba(10,50,120,.10) 0%, rgba(12,110,160,.22) 55%, rgba(10,150,170,.30) 100%); }
.fx-wave { inset: auto; left: 0; width: calc(100% + var(--tile)); height: calc(var(--wh) + 60vh); bottom: calc(var(--wb) - 60vh);
  background: radial-gradient(ellipse calc(var(--tile) / 2) var(--wh) at 50% 100%, var(--wc) 0 96%, transparent 100%) repeat-x 0 0 / var(--tile) var(--wh),
              linear-gradient(var(--wc), var(--wc)) 0 var(--wh) / 100% 60vh no-repeat; /* la ola + el agua debajo en un solo elemento: sin costura */
  animation: fx-wave-x var(--t) linear infinite; animation-delay: var(--ph); }
.fx-wave.w1 { --tile: 360px; --wh: 70px; --wc: rgba(20,110,170,.22); --wb: 6vh; }
.fx-wave.w2 { --tile: 260px; --wh: 54px; --wc: rgba(30,170,200,.20); --wb: 2vh; animation-direction: reverse; }
.fx-wave.w3 { --tile: 180px; --wh: 40px; --wc: rgba(120,225,235,.18); --wb: -3vh; }
@keyframes fx-wave-x { to { transform: translateX(calc(var(--tile) * -1)); } }
.fx-bubbles i { position: absolute; left: var(--x); bottom: -14px; width: var(--s); height: var(--s); border-radius: 50%; border: 1px solid rgba(170,235,255,.6); background: rgba(170,235,255,.08); animation: fx-rise-mote var(--d) linear infinite; will-change: transform; }

/* Bosque: dosel verde, haces de luz inclinados que oscilan y hojas que caen girando */
.fx-canopy { background: linear-gradient(180deg, rgba(18,120,64,.26) 0%, rgba(40,150,80,.10) 55%, rgba(120,200,90,.10) 100%); }
.fx-beam { inset: auto; top: -12vh; left: var(--x); width: var(--w); height: 135vh; transform-origin: top center; filter: blur(9px);
  background: linear-gradient(180deg, rgba(205,255,160,.34), rgba(130,225,120,.12) 55%, transparent);
  animation: fx-beam-sway var(--t) ease-in-out infinite alternate; animation-delay: var(--ph); }
@keyframes fx-beam-sway { from { transform: rotate(16deg); opacity: .35; } to { transform: rotate(23deg); opacity: 1; } }
.fx-leaves i { position: absolute; left: var(--x); top: -18px; width: var(--s); height: calc(var(--s) * 1.7); border-radius: 0 100% 0 100%; background: linear-gradient(135deg, rgba(150,225,95,.85), rgba(40,150,70,.75)); opacity: calc(var(--o) + .3); animation: fx-leaf var(--d) linear infinite; will-change: transform; }
@keyframes fx-leaf { 0% { transform: translate3d(0,0,0) rotate(0); opacity: 0; } 10% { opacity: 1; } 50% { transform: translate3d(calc(var(--sw) * 2.2), 55vh, 0) rotate(200deg); } 90% { opacity: 1; } 100% { transform: translate3d(calc(var(--sw) * -1.4), 112vh, 0) rotate(420deg); opacity: 0; } }

/* Nebulosa: remolinos cónicos difusos que giran en sentidos opuestos */
.fx-swirl { inset: auto; width: 120vmax; height: 120vmax; border-radius: 50%; filter: blur(46px);
  -webkit-mask-image: radial-gradient(circle, #000 0%, transparent 66%); mask-image: radial-gradient(circle, #000 0%, transparent 66%);
  animation: fx-spin var(--t) linear infinite; animation-delay: var(--ph); }
.fx-swirl.s1 { left: -45vmax; top: -50vmax; background: conic-gradient(from 0deg, transparent, rgba(160,80,255,.40), rgba(70,200,255,.22), transparent 55%, rgba(255,80,190,.30), transparent); }
.fx-swirl.s2 { right: -50vmax; bottom: -55vmax; background: conic-gradient(from 90deg, transparent, rgba(255,80,190,.34), rgba(120,90,255,.30), transparent 50%, rgba(60,210,255,.26), transparent); animation-direction: reverse; }

/* Efectos "solos" sobre el fondo plano */
.fx-snow i, .fx-rain i, .fx-fly i, .fx-stars i { position: absolute; left: var(--x); will-change: transform, opacity; }
.fx-snow i { top: -12px; width: var(--s); height: var(--s); border-radius: 50%; background: color-mix(in srgb, var(--text) calc(var(--o) * 100% + 25%), transparent); animation: fx-fall-mote var(--d) linear infinite; }
.fx-rain i { top: -30px; width: 1px; height: var(--s); background: linear-gradient(transparent, color-mix(in srgb, var(--s1) 80%, var(--text))); opacity: calc(var(--o) + .15); animation: fx-rain-drop var(--d) linear infinite; }
@keyframes fx-rain-drop { from { transform: translate3d(0,0,0); } to { transform: translate3d(-4vh, 115vh, 0); } }
.fx-fly i { top: var(--y); width: var(--s); height: var(--s); border-radius: 50%; background: #d9ff8a; box-shadow: 0 0 10px 3px rgba(190,255,100,.55); animation: fx-wander var(--d) ease-in-out infinite alternate, fx-blink calc(var(--d) / 2.3) ease-in-out infinite alternate; }
@keyframes fx-wander { from { transform: translate3d(calc(var(--sw) * -1.6), 0, 0); } to { transform: translate3d(calc(var(--sw) * 1.6), -9vh, 0); } }
@keyframes fx-blink { from { opacity: .1; } to { opacity: 1; } }
.fx-stars i { top: var(--y); width: var(--s); height: var(--s); border-radius: 50%; background: var(--text); animation: fx-twinkle var(--d) ease-in-out infinite alternate; }
@keyframes fx-twinkle { from { opacity: .12; transform: scale(.7); } to { opacity: calc(var(--o) + .5); transform: scale(1.25); } }

/* Paleta atmosférica por estado */
.fx-sky {
  --sky-c1: rgba(82, 215, 160, .24);
  --sky-c2: rgba(66, 153, 225, .20);
  --sky-c3: rgba(16, 185, 129, .14);
  --glow-main: rgba(84, 208, 154, .18);
  --glow-side: rgba(76, 145, 245, .14);
  --heat-a: rgba(255, 197, 112, .18);
  --heat-b: rgba(255, 137, 78, .10);
}
.fx-sky[data-fx-theme="hot"] {
  --sky-c1: rgba(255, 183, 96, .26);
  --sky-c2: rgba(255, 120, 79, .18);
  --sky-c3: rgba(255, 230, 168, .12);
  --glow-main: rgba(255, 186, 104, .22);
  --glow-side: rgba(255, 122, 86, .16);
  --heat-a: rgba(255, 212, 135, .24);
  --heat-b: rgba(255, 138, 82, .14);
}
.fx-sky[data-fx-theme="cold"] {
  --sky-c1: rgba(86, 147, 255, .20);
  --sky-c2: rgba(124, 200, 255, .18);
  --sky-c3: rgba(139, 92, 246, .10);
  --glow-main: rgba(74, 143, 246, .16);
  --glow-side: rgba(110, 198, 255, .14);
  --heat-a: rgba(173, 223, 255, .10);
  --heat-b: rgba(115, 175, 255, .06);
}
.fx-sky[data-fx-theme="alert"] {
  --sky-c1: rgba(245, 95, 95, .16);
  --sky-c2: rgba(255, 163, 96, .14);
  --sky-c3: rgba(166, 35, 58, .12);
  --glow-main: rgba(239, 92, 92, .16);
  --glow-side: rgba(255, 173, 102, .10);
  --heat-a: rgba(255, 154, 112, .16);
  --heat-b: rgba(226, 74, 74, .10);
}
.fx-sky[data-fx-theme="off"] {
  --sky-c1: rgba(128, 137, 161, .10);
  --sky-c2: rgba(107, 114, 128, .08);
  --sky-c3: rgba(86, 93, 111, .06);
  --glow-main: rgba(148, 163, 184, .10);
  --glow-side: rgba(107, 114, 128, .08);
  --heat-a: rgba(255,255,255,.04);
  --heat-b: rgba(255,255,255,.02);
}

/* Aurora ambiental */
.fx-aurora { opacity: .92; mix-blend-mode: screen; }
.fx-aurora span {
  position: absolute; display: block; width: min(54vw, 540px); height: min(54vw, 540px);
  border-radius: 50%; filter: blur(52px); opacity: .9;
  animation: fx-aurora-drift var(--d, 36s) ease-in-out infinite alternate;
  animation-delay: var(--delay, 0s); transform: translate3d(0,0,0) scale(1);
  will-change: transform, opacity;
}
.fx-aurora span:nth-child(1) { left: -7vw; top: -10vh; background: radial-gradient(circle at 35% 35%, var(--sky-c1) 0%, rgba(255,255,255,0) 68%); --d: 34s; --delay: var(--ph1); }
.fx-aurora span:nth-child(2) { right: -12vw; top: 6vh; background: radial-gradient(circle at 55% 45%, var(--sky-c2) 0%, rgba(255,255,255,0) 70%); --d: 44s; --delay: var(--ph2); }
.fx-aurora span:nth-child(3) { left: 18vw; top: 30vh; width: min(44vw, 460px); height: min(44vw, 460px); background: radial-gradient(circle at 50% 50%, var(--sky-c3) 0%, rgba(255,255,255,0) 72%); --d: 40s; --delay: calc(var(--ph1) * .55); }
@keyframes fx-aurora-drift {
  0% { transform: translate3d(-2vw, -1vh, 0) scale(1); opacity: .72; }
  50% { transform: translate3d(2vw, 2vh, 0) scale(1.06); opacity: .92; }
  100% { transform: translate3d(4vw, -2vh, 0) scale(1.12); opacity: .78; }
}

/* Luz ambiental reactiva */
.fx-glow { opacity: .95; }
.fx-glow::before, .fx-glow::after { content: ""; position: absolute; inset: 0; transition: opacity .35s ease; }
.fx-glow::before { background: radial-gradient(ellipse 62% 42% at 50% 16%, var(--glow-main) 0%, rgba(255,255,255,0) 72%); }
.fx-glow::after { background: radial-gradient(ellipse 36% 28% at 85% 18%, var(--glow-side) 0%, rgba(255,255,255,0) 75%); opacity: .9; }

/* Calor / distorsión térmica sutil */
.fx-heat { opacity: .32; mix-blend-mode: screen; }
.fx-heat::before {
  content: ""; position: absolute; inset: -10% -6% 16%;
  background:
    radial-gradient(ellipse 58% 42% at 50% 14%, var(--heat-a) 0%, rgba(255,255,255,0) 68%),
    repeating-linear-gradient(180deg, rgba(255,255,255,0) 0 22px, rgba(255,255,255,.026) 22px 34px, rgba(255,255,255,0) 34px 48px),
    linear-gradient(90deg, rgba(255,255,255,0) 0%, var(--heat-b) 50%, rgba(255,255,255,0) 100%);
  filter: blur(16px);
  animation: fx-heat-wave 11s ease-in-out infinite alternate;
  transform-origin: center top;
}
@keyframes fx-heat-wave {
  0% { transform: translate3d(-1%, 0, 0) scaleY(1); opacity: .22; }
  50% { transform: translate3d(1%, 1.8%, 0) scaleY(1.03); opacity: .36; }
  100% { transform: translate3d(2%, -1.2%, 0) scaleY(1.06); opacity: .28; }
}

.fx-particles i { position: absolute; left: var(--x); bottom: -12px; width: var(--s); height: var(--s); border-radius: 50%; background: color-mix(in srgb, var(--text) calc(var(--o) * 100%), transparent); animation: fx-rise-mote var(--d) linear infinite; will-change: transform; }
@keyframes fx-rise-mote { 0% { transform: translate3d(0,0,0); opacity: 0; } 10% { opacity: 1; } 50% { transform: translate3d(var(--sw),-55vh,0); } 90% { opacity: 1; } 100% { transform: translate3d(calc(var(--sw) * -1),-112vh,0); opacity: 0; } }
.fx-sky[data-fx-theme="hot"] .fx-particles i { background: rgba(255,214,150,var(--o)); box-shadow: 0 0 10px rgba(255,170,90,0.6); }
.fx-sky[data-fx-theme="cold"] .fx-particles i { bottom: auto; top: -12px; animation-name: fx-fall-mote; }
@keyframes fx-fall-mote { 0% { transform: translate3d(0,0,0); opacity: 0; } 10% { opacity: 1; } 50% { transform: translate3d(var(--sw),55vh,0); } 90% { opacity: 1; } 100% { transform: translate3d(calc(var(--sw) * -1),112vh,0); opacity: 0; } }
.fx-sky[data-fx-theme="alert"] { animation: fx-alert 2.6s ease-in-out infinite; }
@keyframes fx-alert { 50% { filter: brightness(1.18) saturate(1.2); } }

/* ---- Partículas nuevas ---- */
.fx-night { background: linear-gradient(180deg, rgba(12,16,52,.34), transparent 70%); }
.fx-meteors i { position: absolute; left: var(--x); top: calc(var(--y) * .6); width: var(--s); height: 2px; border-radius: 2px; transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--text), transparent); opacity: 0; animation: fx-meteor var(--d) linear infinite; will-change: transform, opacity; }
@keyframes fx-meteor { 0% { transform: translate3d(0,0,0) rotate(-35deg); opacity: 0; } 3% { opacity: 1; } 13% { transform: translate3d(-42vmin, 29vmin, 0) rotate(-35deg); opacity: 0; } 100% { transform: translate3d(-42vmin, 29vmin, 0) rotate(-35deg); opacity: 0; } }

.fx-forge { background: linear-gradient(0deg, rgba(255,100,30,.30), rgba(255,160,60,.08) 38%, transparent 62%); }
.fx-embers i { position: absolute; left: var(--x); bottom: -10px; width: var(--s); height: var(--s); border-radius: 50%; background: #ffb347; box-shadow: 0 0 8px 2px rgba(255,120,40,.7); animation: fx-rise-mote var(--d) ease-in infinite; will-change: transform; }

.fx-petals i { position: absolute; left: var(--x); top: -20px; width: var(--s); height: calc(var(--s) * .7); border-radius: 100% 0 100% 0; background: linear-gradient(135deg, #ffd6e6, #ff8fb8); opacity: calc(var(--o) + .45); animation: fx-petal var(--d) linear infinite; will-change: transform; }
@keyframes fx-petal {
  0% { transform: translate3d(0,0,0) rotate(0); opacity: 0; } 8% { opacity: 1; }
  25% { transform: translate3d(calc(var(--sw) * 1.6), 28vh, 0) rotate(110deg); }
  50% { transform: translate3d(calc(var(--sw) * -1.2), 56vh, 0) rotate(230deg); }
  75% { transform: translate3d(calc(var(--sw) * 1.4), 84vh, 0) rotate(340deg); opacity: 1; }
  100% { transform: translate3d(0, 112vh, 0) rotate(450deg); opacity: 0; }
}

.fx-soap i { position: absolute; left: var(--x); bottom: -50px; width: var(--s); height: var(--s); border-radius: 50%; border: 1px solid rgba(130,150,210,.45);
  background: radial-gradient(circle at 30% 26%, rgba(255,255,255,.7), transparent 34%), conic-gradient(from 0deg, rgba(255,120,200,.20), rgba(120,200,255,.22), rgba(160,255,190,.20), rgba(255,120,200,.20));
  animation: fx-rise-mote var(--d) ease-in-out infinite; will-change: transform; }

.fx-matrix b { position: absolute; left: var(--x); top: 0; font: 600 14px/16px ui-monospace, Menlo, Consolas, monospace; white-space: pre; text-align: center; color: #2fe872; opacity: .8;
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 70%); mask-image: linear-gradient(180deg, transparent, #000 70%);
  animation: fx-matrix-fall var(--d) linear infinite; will-change: transform; }
.fx-matrix u { text-decoration: none; color: #e6ffee; text-shadow: 0 0 8px #2fe872; }
@keyframes fx-matrix-fall { from { transform: translate3d(0, -100%, 0); } to { transform: translate3d(0, 100vh, 0); } }

.fx-storm { background: linear-gradient(180deg, rgba(24,34,70,.42), rgba(24,34,70,.16) 55%, transparent); }
.fx-flash { background: rgba(225,235,255,.85); opacity: 0; animation: fx-flash var(--t) linear infinite; animation-delay: var(--ph); }
@keyframes fx-flash { 0%, 91% { opacity: 0; } 92% { opacity: .5; } 93% { opacity: .05; } 94.5% { opacity: .35; } 97%, 100% { opacity: 0; } }

/* ---- Atmósferas nuevas ---- */
/* Niebla: bancos difusos que se desplazan; el color sale del texto del tema (blanquecina en oscuro, grisácea en claro) */
.fx-fogbank { inset: auto; left: -40%; width: 180%; height: 42vh; filter: blur(28px);
  background: radial-gradient(ellipse 34% 50% at 26% 50%, color-mix(in srgb, var(--text) 20%, transparent), transparent 70%), radial-gradient(ellipse 30% 44% at 72% 56%, color-mix(in srgb, var(--text) 16%, transparent), transparent 70%);
  animation: fx-fog var(--t) ease-in-out infinite alternate; animation-delay: var(--ph); }
.fx-fogbank.f1 { bottom: -4vh; } .fx-fogbank.f2 { top: 22vh; opacity: .8; } .fx-fogbank.f3 { top: -6vh; opacity: .65; }
@keyframes fx-fog { from { transform: translate3d(-8%, 0, 0); } to { transform: translate3d(8%, -2vh, 0); } }

/* Lámpara de lava: manchas que suben y bajan cambiando de forma */
.fx-blob { inset: auto; left: var(--x); bottom: -20vmin; width: var(--sz); height: var(--sz); border-radius: 50%; filter: blur(18px); opacity: .5;
  background: radial-gradient(circle at 38% 36%, var(--c), color-mix(in srgb, var(--c) 40%, transparent) 70%, transparent);
  animation: fx-lava var(--t) ease-in-out infinite alternate; animation-delay: var(--ph); will-change: transform, border-radius; }
@keyframes fx-lava {
  0% { transform: translate3d(0, 0, 0) scale(.85); border-radius: 50% 50% 46% 54% / 54% 46% 54% 46%; }
  50% { transform: translate3d(5vw, -62vh, 0) scale(1.15); border-radius: 42% 58% 55% 45% / 60% 40% 60% 40%; }
  100% { transform: translate3d(-4vw, -105vh, 0) scale(.9); border-radius: 56% 44% 40% 60% / 46% 54% 46% 54%; }
}

/* Aurora boreal: cortinas verticales que ondulan */
.fx-polar { background: linear-gradient(180deg, rgba(6,20,52,.42), transparent 62%); }
.fx-curtain { inset: auto; top: 0; left: var(--x); width: var(--w); height: 64vh; filter: blur(14px); transform-origin: top center;
  background: linear-gradient(180deg, rgba(80,255,170,.0), rgba(80,255,170,.42) 22%, rgba(60,200,230,.30) 55%, rgba(150,90,255,.0));
  -webkit-mask-image: linear-gradient(180deg, #000 55%, transparent); mask-image: linear-gradient(180deg, #000 55%, transparent);
  animation: fx-curtain var(--t) ease-in-out infinite alternate; animation-delay: var(--ph); }
@keyframes fx-curtain { from { transform: skewX(var(--k)) scaleY(.82); opacity: .45; } to { transform: skewX(calc(var(--k) * -1)) scaleY(1.08); opacity: 1; } }

/* Polvo de luz: haces tibios en diagonal + motas */
.fx-shaft { inset: auto; top: -15vh; width: 34vw; height: 140vh; filter: blur(14px); transform-origin: top center;
  background: linear-gradient(180deg, rgba(255,232,160,.40), rgba(255,220,140,.14) 60%, transparent); }
.fx-shaft.a { left: 18%; transform: rotate(22deg); }
.fx-shaft.b { left: 52%; width: 20vw; transform: rotate(22deg); opacity: .7; }
.fx-dust i { position: absolute; left: calc(14% + var(--x) * .6); top: var(--y); width: var(--s); height: var(--s); border-radius: 50%; background: rgba(255,238,185,.95); box-shadow: 0 0 5px rgba(255,225,150,.8);
  animation: fx-wander var(--d) ease-in-out infinite alternate, fx-blink calc(var(--d) / 2) ease-in-out infinite alternate; will-change: transform, opacity; }

@media (prefers-reduced-motion: reduce) {
  .fx-sky *, .fx-sky *::before, .fx-sky *::after { animation: none !important; transition: none !important; }
  .fx-particles i, .fx-snow i, .fx-rain i, .fx-fly i, .fx-bubbles i, .fx-leaves i, .fx-meteors i, .fx-embers i, .fx-petals i, .fx-soap i, .fx-dust i, .fx-matrix b, .fx-flash { display: none; }
}

/* Botón del menú: punto lleno con algo activo, hueco sin nada; el texto se corta si la combinación es larga */
.fx-toggle { max-width: 260px; }
.fx-toggle:not(.is-on)::before { background: transparent; box-shadow: none; border: 1px solid var(--muted); }
