feat: synthwave fog rising above horizon

Five blurred elliptic wisps anchored at the horizon line, each drifting
upward at different speeds (8-15s) and delays for an organic breathing
effect. Color synced with the dominant album art color via applyTheme.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ltadeu6 2026-06-07 13:26:55 -03:00
parent 510e677c30
commit 775bad978d
No known key found for this signature in database
GPG key ID: FB9FDAB6B6F3418D

View file

@ -724,7 +724,41 @@ html, body {
50% { transform: rotate(5deg); }
}
/* ROBOT SHADOW (ellipse on the floor) */
/* ============================================================
FOG — synthwave atmospheric haze rising above horizon
============================================================ */
.fog-layer {
position: absolute;
bottom: 41.5%;
left: 0; right: 0;
height: 38%;
pointer-events: none;
overflow: visible;
}
.fog-wisp {
position: absolute;
bottom: -10px;
border-radius: 50%;
filter: blur(60px);
}
.fog-w1 { width: 70%; height: 140px; left: -8%; animation: fogDrift1 9s ease-in-out infinite alternate; }
.fog-w2 { width: 55%; height: 115px; left: 22%; animation: fogDrift2 13s ease-in-out infinite alternate; animation-delay: -4s; }
.fog-w3 { width: 48%; height: 105px; left: 52%; animation: fogDrift3 8s ease-in-out infinite alternate; animation-delay: -2s; }
.fog-w4 { width: 42%; height: 95px; left: 36%; animation: fogDrift1 15s ease-in-out infinite alternate; animation-delay: -8s; }
.fog-w5 { width: 52%; height: 125px; left: 8%; animation: fogDrift2 11s ease-in-out infinite alternate; animation-delay: -5s; }
@keyframes fogDrift1 {
from { transform: translateY(0) scaleX(1); opacity: 0.18; }
to { transform: translateY(-50px) scaleX(1.18); opacity: 0.34; }
}
@keyframes fogDrift2 {
from { transform: translateY(-12px) scaleX(0.93); opacity: 0.22; }
to { transform: translateY(-60px) scaleX(1.22); opacity: 0.30; }
}
@keyframes fogDrift3 {
from { transform: translateY(-6px) scaleX(1.06); opacity: 0.14; }
to { transform: translateY(-38px) scaleX(0.88); opacity: 0.26; }
}
</style>
</head>
@ -746,6 +780,15 @@ html, body {
<!-- Horizon glow -->
<div class="horizon"></div>
<!-- Dynamic fog above horizon -->
<div class="fog-layer" id="fogLayer">
<div class="fog-wisp fog-w1"></div>
<div class="fog-wisp fog-w2"></div>
<div class="fog-wisp fog-w3"></div>
<div class="fog-wisp fog-w4"></div>
<div class="fog-wisp fog-w5"></div>
</div>
<!-- Meteor layer (masked at horizon) -->
<div id="meteorLayer"></div>
@ -1029,9 +1072,13 @@ function applyTheme(rgb) {
bar.style.background = `rgb(${r},${g},${b})`;
bar.style.boxShadow = `0 0 4px rgba(${r},${g},${b},0.8)`;
});
fogWisps.forEach(w => {
w.style.background = `radial-gradient(ellipse, rgba(${r},${g},${b},0.55) 0%, transparent 70%)`;
});
}
const albumArtEl = document.getElementById('albumArt');
const fogWisps = document.querySelectorAll('.fog-wisp');
let lastArtUrl = '';