.light-effects{position:absolute;inset:0;z-index:0;pointer-events:none;mix-blend-mode:screen;--fx-color:#ffbc62;opacity:var(--brightness,.75);transition:opacity .25s}.light-effects svg{display:block;width:100%;height:100%;overflow:visible}.light-effects path{fill:none;stroke:var(--fx-color);stroke-linecap:round}.light-effects::before{content:'';position:absolute;inset:8% 7% 7%;border-radius:48% 48% 9% 9%;box-shadow:0 0 4cqw 1cqw var(--fx-color),inset 0 0 3cqw var(--fx-color);opacity:.12;filter:blur(1.8cqw)}.light-effects::after{content:'';position:absolute;left:17%;right:17%;bottom:1.2%;height:5%;background:radial-gradient(ellipse,var(--fx-color),transparent 70%);opacity:.23;filter:blur(1cqw)}.tube-halo{stroke-width:3.4;opacity:.4;filter:url(#tubeGlow)}.tube-line{stroke-width:.55;opacity:.65}.speaker-glow{fill:var(--fx-color);opacity:.06;filter:url(#tubeGlow)}.speaker-bars{opacity:.15}.led-bar{transform-box:view-box;transform-origin:50px 129px;transform:scaleY(calc(.08 + var(--level,0)*.92));opacity:calc(.12 + var(--level,0)*.88);stroke-width:1.8}.disco-orbits{display:none;fill:none;stroke:url(#partySpectrum);stroke-width:.6;transform-origin:50px 117px}.disco-orbits ellipse:nth-child(2){stroke:#8beafa;stroke-dasharray:4 5}.disco-orbits ellipse:nth-child(3){stroke:#ffbcf0}.machine[data-light=aurora] .light-effects{--fx-color:#58e5da;animation:aurora-shift 14s ease-in-out infinite}.machine[data-light=aurora] .tube-halo,.machine[data-light=aurora] .tube-line{stroke:url(#auroraSpectrum)!important}.machine[data-light=party] .light-effects{--fx-color:#e67aeb;animation:party-shift 12s linear infinite}.machine[data-light=party] .tube-halo,.machine[data-light=party] .tube-line{stroke:url(#partySpectrum)!important}.machine[data-light=party] .led-bar{stroke:url(#partySpectrum)!important}.machine.audio-reactive[data-light=party] .tube-halo{opacity:calc(.2 + var(--bass,0)*.65);stroke-width:calc(2px + var(--bass,0)*3px)}.machine.audio-reactive[data-light=party] .speaker-glow{opacity:calc(.02 + var(--bass,0)*.2)}.machine.audio-reactive[data-light=party] .disco-orbits{display:block;opacity:calc(.05 + var(--bass,0)*.45);transform:scale(calc(.7 + var(--bass,0)*.5))}.machine.audio-reactive[data-light=party] .speaker-bars{opacity:.4}.speaker-vibration{position:absolute;inset:0;z-index:0;pointer-events:none;background:url('/jukeboks/cabinet.png') center/100% 100% no-repeat;mask-image:radial-gradient(ellipse 29% 11% at 50% 77%,#000 60%,transparent 100%);-webkit-mask-image:radial-gradient(ellipse 29% 11% at 50% 77%,#000 60%,transparent 100%);transform-origin:50% 77%;opacity:0}.machine.audio-reactive[data-state=playing] .speaker-vibration{opacity:1;transform:scale(calc(1 + var(--bass,0)*.023));will-change:transform}.machine.lights-off .light-effects{visibility:hidden;opacity:0}.machine.lights-off .speaker-vibration{filter:brightness(.64) saturate(.75)}@keyframes aurora-shift{0%,100%{filter:hue-rotate(0deg)}50%{filter:hue-rotate(55deg)}}@keyframes party-shift{to{filter:hue-rotate(360deg)}}@media(prefers-reduced-motion:reduce){.light-effects,.light-effects *{animation:none!important}.speaker-vibration{opacity:0!important;transform:none!important}.disco-orbits{transform:none!important}}
/* Twenty coordinated palettes and movement patterns. No rapid flashing. */
.machine[data-pattern] .light-effects{--fx-color:var(--mode-color);animation:none}
.machine[data-pattern] .tube-halo,.machine[data-pattern] .tube-line{stroke:var(--mode-color)!important}
.machine[data-pattern=wave] .tube-halo{animation:palette-wave var(--mode-speed) ease-in-out infinite}
.machine[data-pattern=wave] .tube-line{stroke:var(--mode-accent)!important}
.machine[data-pattern=breathe] .tube-halo{animation:soft-breath var(--mode-speed) ease-in-out infinite}
.machine[data-light=christmas] .tube-line{stroke:var(--mode-accent)!important}
.machine[data-pattern=rainbow] .light-effects{animation:party-shift var(--mode-speed) linear infinite}
.machine[data-pattern=rainbow] .tube-halo,.machine[data-pattern=rainbow] .tube-line{stroke:url(#partySpectrum)!important}
.machine[data-pattern=pulse] .tube-halo{opacity:calc(.25 + var(--bass,0)*.7);stroke-width:calc(2px + var(--bass,0)*4px)}
.machine[data-pattern=pulse] .speaker-glow{opacity:calc(.04 + var(--bass,0)*.35)}
.machine[data-pattern=pulse] .speaker-bars{opacity:.7}
.machine[data-pattern=pulse] .disco-orbits{display:block;stroke:var(--mode-accent);opacity:calc(.08 + var(--bass,0)*.55);transform:scale(calc(.75 + var(--bass,0)*.4))}
@keyframes palette-wave{0%,100%{opacity:.25;stroke-width:2.5}50%{opacity:.65;stroke-width:4.5}}
@keyframes soft-breath{0%,100%{opacity:.2;stroke-width:2.5}50%{opacity:.65;stroke-width:4.2}}
@media(prefers-reduced-motion:reduce){.machine[data-pattern] .light-effects,.machine[data-pattern] .light-effects *{animation:none!important}}

/* Stationary glow animation only: no travelling dots or highlights. */
.machine[data-pattern=bloom] .tube-halo{animation:soft-breath var(--mode-speed) ease-in-out infinite}
.machine[data-pattern=bloom] .tube-line{stroke:var(--mode-accent)!important}
.machine[data-pattern=calm] .tube-halo{animation:soft-breath var(--mode-speed) ease-in-out infinite}
.machine[data-pattern=sparkle] .tube-halo{animation:stationary-shimmer var(--mode-speed) ease-in-out infinite}
@keyframes stationary-shimmer{0%,100%{opacity:.25}35%{opacity:.55}65%{opacity:.35}}
@media(prefers-reduced-motion:reduce){.machine[data-pattern] .light-effects *{animation:none!important}}

/* Visible stationary animation in every preset, including bass mode at rest. */
.machine[data-pattern=pulse]:not(.audio-reactive) .tube-halo{animation:soft-breath var(--mode-speed) ease-in-out infinite}
.machine[data-pattern=rainbow] .tube-halo{animation:soft-breath var(--mode-speed) ease-in-out infinite}
.machine.audio-reactive[data-state=playing] .speaker-vibration{transform:scale(calc(1 + var(--bass,0)*.045))}
.machine.audio-reactive[data-state=playing] .tube-line{opacity:calc(.45 + var(--bass,0)*.5);stroke-width:calc(.55px + var(--bass,0)*1.1px)}
/* Embedded video does not expose its audio spectrum; this is ambient motion. */
.machine[data-source=youtube][data-state=playing] .speaker-vibration{opacity:1;animation:ambient-speaker .7s ease-in-out infinite;will-change:transform}
.machine[data-source=youtube][data-state=playing] .speaker-glow{animation:ambient-speaker-glow 2.4s ease-in-out infinite}
.machine[data-source=youtube][data-state=playing] .tube-halo{animation:soft-breath var(--mode-speed) ease-in-out infinite}
@keyframes ambient-speaker{0%,100%{transform:scale(1)}35%{transform:scale(1.018)}65%{transform:scale(1.007)}}
@keyframes ambient-speaker-glow{0%,100%{opacity:.06}50%{opacity:.25}}
@media(prefers-reduced-motion:reduce){.machine .speaker-vibration{animation:none!important;opacity:0!important;transform:none!important}.machine .light-effects *{animation:none!important}}
/* Paused, buffering and unavailable media leave steady light, with no motion. */
.machine:not([data-state=playing]) .light-effects *,.machine:not([data-state=playing]) .speaker-vibration{animation:none!important;transition:none!important}
.machine:not([data-state=playing]) .speaker-vibration{transform:none!important;opacity:0!important}
.machine:not([data-state=playing]) .speaker-glow{opacity:0!important}
