Polish animated forest background

This commit is contained in:
KoalaDev
2026-07-10 20:42:54 +02:00
parent 9cddac47ef
commit 21383b8b9c
15 changed files with 402 additions and 91 deletions
+14 -6
View File
@@ -123,6 +123,8 @@
<span class="bamboo-stalk far-1"></span>
<span class="bamboo-stalk far-2"></span>
<span class="bamboo-stalk far-3"></span>
<span class="bamboo-stalk far-4"></span>
<span class="bamboo-stalk far-5"></span>
</div>
<div id="bamboo-near">
<div class="bamboo-stalk near-1">
@@ -138,6 +140,12 @@
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
<div class="bamboo-stalk near-3">
<i class="bamboo-node node-1"></i>
<i class="bamboo-node node-2"></i>
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
</div>
<span class="fall-leaf fall-leaf-1"><i></i></span>
<span class="fall-leaf fall-leaf-2"><i></i></span>
@@ -155,12 +163,12 @@
<div class="bg-mist bg-mist-1"></div>
<div class="bg-mist bg-mist-2"></div>
<div class="bg-horizon"></div>
<span class="firefly firefly-1"></span>
<span class="firefly firefly-2"></span>
<span class="firefly firefly-3"></span>
<span class="firefly firefly-4"></span>
<span class="firefly firefly-5"></span>
<span class="firefly firefly-6"></span>
<span class="firefly-wrap fw-1"><span class="firefly"></span></span>
<span class="firefly-wrap fw-2"><span class="firefly"></span></span>
<span class="firefly-wrap fw-3"><span class="firefly"></span></span>
<span class="firefly-wrap fw-4"><span class="firefly"></span></span>
<span class="firefly-wrap fw-5"><span class="firefly"></span></span>
<span class="firefly-wrap fw-6"><span class="firefly"></span></span>
</div>
<div class="bg-light-sweep"></div>
<div class="bg-grain"></div>
+14 -6
View File
@@ -129,6 +129,8 @@
<span class="bamboo-stalk far-1"></span>
<span class="bamboo-stalk far-2"></span>
<span class="bamboo-stalk far-3"></span>
<span class="bamboo-stalk far-4"></span>
<span class="bamboo-stalk far-5"></span>
</div>
<div id="bamboo-near">
<div class="bamboo-stalk near-1">
@@ -144,6 +146,12 @@
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
<div class="bamboo-stalk near-3">
<i class="bamboo-node node-1"></i>
<i class="bamboo-node node-2"></i>
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
</div>
<span class="fall-leaf fall-leaf-1"><i></i></span>
<span class="fall-leaf fall-leaf-2"><i></i></span>
@@ -161,12 +169,12 @@
<div class="bg-mist bg-mist-1"></div>
<div class="bg-mist bg-mist-2"></div>
<div class="bg-horizon"></div>
<span class="firefly firefly-1"></span>
<span class="firefly firefly-2"></span>
<span class="firefly firefly-3"></span>
<span class="firefly firefly-4"></span>
<span class="firefly firefly-5"></span>
<span class="firefly firefly-6"></span>
<span class="firefly-wrap fw-1"><span class="firefly"></span></span>
<span class="firefly-wrap fw-2"><span class="firefly"></span></span>
<span class="firefly-wrap fw-3"><span class="firefly"></span></span>
<span class="firefly-wrap fw-4"><span class="firefly"></span></span>
<span class="firefly-wrap fw-5"><span class="firefly"></span></span>
<span class="firefly-wrap fw-6"><span class="firefly"></span></span>
</div>
<div class="bg-light-sweep"></div>
<div class="bg-grain"></div>
+14 -6
View File
@@ -129,6 +129,8 @@
<span class="bamboo-stalk far-1"></span>
<span class="bamboo-stalk far-2"></span>
<span class="bamboo-stalk far-3"></span>
<span class="bamboo-stalk far-4"></span>
<span class="bamboo-stalk far-5"></span>
</div>
<div id="bamboo-near">
<div class="bamboo-stalk near-1">
@@ -144,6 +146,12 @@
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
<div class="bamboo-stalk near-3">
<i class="bamboo-node node-1"></i>
<i class="bamboo-node node-2"></i>
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
</div>
<span class="fall-leaf fall-leaf-1"><i></i></span>
<span class="fall-leaf fall-leaf-2"><i></i></span>
@@ -161,12 +169,12 @@
<div class="bg-mist bg-mist-1"></div>
<div class="bg-mist bg-mist-2"></div>
<div class="bg-horizon"></div>
<span class="firefly firefly-1"></span>
<span class="firefly firefly-2"></span>
<span class="firefly firefly-3"></span>
<span class="firefly firefly-4"></span>
<span class="firefly firefly-5"></span>
<span class="firefly firefly-6"></span>
<span class="firefly-wrap fw-1"><span class="firefly"></span></span>
<span class="firefly-wrap fw-2"><span class="firefly"></span></span>
<span class="firefly-wrap fw-3"><span class="firefly"></span></span>
<span class="firefly-wrap fw-4"><span class="firefly"></span></span>
<span class="firefly-wrap fw-5"><span class="firefly"></span></span>
<span class="firefly-wrap fw-6"><span class="firefly"></span></span>
</div>
<div class="bg-light-sweep"></div>
<div class="bg-grain"></div>
+14 -6
View File
@@ -129,6 +129,8 @@
<span class="bamboo-stalk far-1"></span>
<span class="bamboo-stalk far-2"></span>
<span class="bamboo-stalk far-3"></span>
<span class="bamboo-stalk far-4"></span>
<span class="bamboo-stalk far-5"></span>
</div>
<div id="bamboo-near">
<div class="bamboo-stalk near-1">
@@ -144,6 +146,12 @@
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
<div class="bamboo-stalk near-3">
<i class="bamboo-node node-1"></i>
<i class="bamboo-node node-2"></i>
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
</div>
<span class="fall-leaf fall-leaf-1"><i></i></span>
<span class="fall-leaf fall-leaf-2"><i></i></span>
@@ -161,12 +169,12 @@
<div class="bg-mist bg-mist-1"></div>
<div class="bg-mist bg-mist-2"></div>
<div class="bg-horizon"></div>
<span class="firefly firefly-1"></span>
<span class="firefly firefly-2"></span>
<span class="firefly firefly-3"></span>
<span class="firefly firefly-4"></span>
<span class="firefly firefly-5"></span>
<span class="firefly firefly-6"></span>
<span class="firefly-wrap fw-1"><span class="firefly"></span></span>
<span class="firefly-wrap fw-2"><span class="firefly"></span></span>
<span class="firefly-wrap fw-3"><span class="firefly"></span></span>
<span class="firefly-wrap fw-4"><span class="firefly"></span></span>
<span class="firefly-wrap fw-5"><span class="firefly"></span></span>
<span class="firefly-wrap fw-6"><span class="firefly"></span></span>
</div>
<div class="bg-light-sweep"></div>
<div class="bg-grain"></div>
+14 -6
View File
@@ -129,6 +129,8 @@
<span class="bamboo-stalk far-1"></span>
<span class="bamboo-stalk far-2"></span>
<span class="bamboo-stalk far-3"></span>
<span class="bamboo-stalk far-4"></span>
<span class="bamboo-stalk far-5"></span>
</div>
<div id="bamboo-near">
<div class="bamboo-stalk near-1">
@@ -144,6 +146,12 @@
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
<div class="bamboo-stalk near-3">
<i class="bamboo-node node-1"></i>
<i class="bamboo-node node-2"></i>
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
</div>
<span class="fall-leaf fall-leaf-1"><i></i></span>
<span class="fall-leaf fall-leaf-2"><i></i></span>
@@ -161,12 +169,12 @@
<div class="bg-mist bg-mist-1"></div>
<div class="bg-mist bg-mist-2"></div>
<div class="bg-horizon"></div>
<span class="firefly firefly-1"></span>
<span class="firefly firefly-2"></span>
<span class="firefly firefly-3"></span>
<span class="firefly firefly-4"></span>
<span class="firefly firefly-5"></span>
<span class="firefly firefly-6"></span>
<span class="firefly-wrap fw-1"><span class="firefly"></span></span>
<span class="firefly-wrap fw-2"><span class="firefly"></span></span>
<span class="firefly-wrap fw-3"><span class="firefly"></span></span>
<span class="firefly-wrap fw-4"><span class="firefly"></span></span>
<span class="firefly-wrap fw-5"><span class="firefly"></span></span>
<span class="firefly-wrap fw-6"><span class="firefly"></span></span>
</div>
<div class="bg-light-sweep"></div>
<div class="bg-grain"></div>
+14 -6
View File
@@ -129,6 +129,8 @@
<span class="bamboo-stalk far-1"></span>
<span class="bamboo-stalk far-2"></span>
<span class="bamboo-stalk far-3"></span>
<span class="bamboo-stalk far-4"></span>
<span class="bamboo-stalk far-5"></span>
</div>
<div id="bamboo-near">
<div class="bamboo-stalk near-1">
@@ -144,6 +146,12 @@
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
<div class="bamboo-stalk near-3">
<i class="bamboo-node node-1"></i>
<i class="bamboo-node node-2"></i>
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
</div>
<span class="fall-leaf fall-leaf-1"><i></i></span>
<span class="fall-leaf fall-leaf-2"><i></i></span>
@@ -161,12 +169,12 @@
<div class="bg-mist bg-mist-1"></div>
<div class="bg-mist bg-mist-2"></div>
<div class="bg-horizon"></div>
<span class="firefly firefly-1"></span>
<span class="firefly firefly-2"></span>
<span class="firefly firefly-3"></span>
<span class="firefly firefly-4"></span>
<span class="firefly firefly-5"></span>
<span class="firefly firefly-6"></span>
<span class="firefly-wrap fw-1"><span class="firefly"></span></span>
<span class="firefly-wrap fw-2"><span class="firefly"></span></span>
<span class="firefly-wrap fw-3"><span class="firefly"></span></span>
<span class="firefly-wrap fw-4"><span class="firefly"></span></span>
<span class="firefly-wrap fw-5"><span class="firefly"></span></span>
<span class="firefly-wrap fw-6"><span class="firefly"></span></span>
</div>
<div class="bg-light-sweep"></div>
<div class="bg-grain"></div>
+14 -6
View File
@@ -129,6 +129,8 @@
<span class="bamboo-stalk far-1"></span>
<span class="bamboo-stalk far-2"></span>
<span class="bamboo-stalk far-3"></span>
<span class="bamboo-stalk far-4"></span>
<span class="bamboo-stalk far-5"></span>
</div>
<div id="bamboo-near">
<div class="bamboo-stalk near-1">
@@ -144,6 +146,12 @@
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
<div class="bamboo-stalk near-3">
<i class="bamboo-node node-1"></i>
<i class="bamboo-node node-2"></i>
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
</div>
<span class="fall-leaf fall-leaf-1"><i></i></span>
<span class="fall-leaf fall-leaf-2"><i></i></span>
@@ -161,12 +169,12 @@
<div class="bg-mist bg-mist-1"></div>
<div class="bg-mist bg-mist-2"></div>
<div class="bg-horizon"></div>
<span class="firefly firefly-1"></span>
<span class="firefly firefly-2"></span>
<span class="firefly firefly-3"></span>
<span class="firefly firefly-4"></span>
<span class="firefly firefly-5"></span>
<span class="firefly firefly-6"></span>
<span class="firefly-wrap fw-1"><span class="firefly"></span></span>
<span class="firefly-wrap fw-2"><span class="firefly"></span></span>
<span class="firefly-wrap fw-3"><span class="firefly"></span></span>
<span class="firefly-wrap fw-4"><span class="firefly"></span></span>
<span class="firefly-wrap fw-5"><span class="firefly"></span></span>
<span class="firefly-wrap fw-6"><span class="firefly"></span></span>
</div>
<div class="bg-light-sweep"></div>
<div class="bg-grain"></div>
+89 -2
View File
@@ -60,6 +60,9 @@ document.addEventListener('DOMContentLoaded', () => {
}
};
// Populated by the forest renderer further down (no-op until then)
let forestGreet = null;
// Theme toggle (saved preference wins; otherwise follows system preference,
// pre-paint class is applied by lang-init.js to avoid a flash)
const themeToggle = document.getElementById('theme-toggle');
@@ -108,6 +111,14 @@ document.addEventListener('DOMContentLoaded', () => {
applyTheme(nextTheme);
safeSetLocalStorage(themeStorageKey, nextTheme);
syncThemeMeta();
// Switching into light mode flares the horizon once (sunrise)
const scene = document.querySelector('.bg-nature');
if (nextTheme === 'light' && scene && !window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
scene.classList.remove('sunrise');
void scene.offsetWidth;
scene.classList.add('sunrise');
setTimeout(() => scene.classList.remove('sunrise'), 1700);
}
});
}
@@ -200,6 +211,7 @@ document.addEventListener('DOMContentLoaded', () => {
entries.forEach(entry => {
if (entry.isIntersecting) {
history.replaceState(null, null, '#' + entry.target.id);
if (forestGreet) forestGreet();
}
});
}, { threshold: 0.3 });
@@ -220,11 +232,18 @@ document.addEventListener('DOMContentLoaded', () => {
// pointer devices the layers tilt slightly toward the cursor.
const bambooFar = document.getElementById('bamboo-far');
const bambooNear = document.getElementById('bamboo-near');
if (bambooFar && bambooNear && !window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
const forestScene = document.querySelector('.bg-nature');
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (bambooFar && bambooNear && !prefersReducedMotion) {
const depthDay = document.querySelector('.bg-depth-day');
const depthDusk = document.querySelector('.bg-depth-dusk');
const duskTint = document.querySelector('.bg-dusk-tint');
const fireflies = Array.from(document.querySelectorAll('.firefly-wrap'), (el) => ({ el, x: 0, y: 0 }));
const canHover = window.matchMedia('(hover: hover)').matches;
let mouseX = 0;
let pointerX = -9999;
let pointerY = -9999;
let depthStep = '';
let framePending = false;
const renderForest = () => {
@@ -238,6 +257,39 @@ document.addEventListener('DOMContentLoaded', () => {
if (depthDay) depthDay.style.opacity = (1 - depth * 0.75).toFixed(3);
if (depthDusk) depthDusk.style.opacity = (0.35 + depth * 0.65).toFixed(3);
if (duskTint) duskTint.style.opacity = (depth * 0.85).toFixed(3);
// Depth of field: step the far layer's blur on threshold crossings
// only (filter changes are too expensive to run per frame)
if (forestScene) {
const step = depth < 0.33 ? '' : depth < 0.66 ? 'depth-mid' : 'depth-deep';
if (step !== depthStep) {
forestScene.classList.remove('depth-mid', 'depth-deep');
if (step) forestScene.classList.add(step);
depthStep = step;
}
}
// Fireflies shy away from the cursor and drift back once it leaves
let settling = false;
for (const fly of fireflies) {
const cx = fly.el.offsetLeft + 2;
const cy = fly.el.offsetTop + 2;
const dx = cx - pointerX;
const dy = cy - pointerY;
const dist = Math.hypot(dx, dy);
let tx = 0;
let ty = 0;
if (dist < 130 && dist > 0.001) {
const push = ((130 - dist) / 130) * 46;
tx = (dx / dist) * push;
ty = (dy / dist) * push;
}
fly.x += (tx - fly.x) * 0.14;
fly.y += (ty - fly.y) * 0.14;
if (Math.abs(tx - fly.x) > 0.4 || Math.abs(ty - fly.y) > 0.4) settling = true;
fly.el.style.transform = `translate(${fly.x.toFixed(1)}px, ${fly.y.toFixed(1)}px)`;
}
if (settling) requestForestFrame();
};
const requestForestFrame = () => {
@@ -246,16 +298,51 @@ document.addEventListener('DOMContentLoaded', () => {
requestAnimationFrame(renderForest);
}
};
// Let one firefly greet newly reached sections (used by the section
// observer below; index rotates so it is not always the same one)
let helloIndex = 0;
forestGreet = () => {
if (!fireflies.length) return;
const wrap = fireflies[helloIndex % fireflies.length].el;
helloIndex += 1;
wrap.classList.remove('firefly-hello');
void wrap.offsetWidth;
wrap.classList.add('firefly-hello');
setTimeout(() => wrap.classList.remove('firefly-hello'), 1300);
};
window.addEventListener('scroll', requestForestFrame, { passive: true });
window.addEventListener('resize', requestForestFrame, { passive: true });
if (window.matchMedia('(hover: hover)').matches) {
if (canHover) {
window.addEventListener('pointermove', (e) => {
mouseX = (e.clientX / window.innerWidth - 0.5) * 2;
pointerX = e.clientX;
pointerY = e.clientY;
requestForestFrame();
}, { passive: true });
window.addEventListener('pointerleave', () => {
pointerX = -9999;
pointerY = -9999;
requestForestFrame();
});
}
renderForest();
// Wind gusts: every 12-24s the sway variables ramp up for ~3s. The
// custom properties are registered via @property, so they transition
// smoothly inside the running keyframes instead of jumping.
if (forestScene) {
const scheduleGust = () => {
setTimeout(() => {
forestScene.classList.add('gusting');
setTimeout(() => {
forestScene.classList.remove('gusting');
scheduleGust();
}, 3000);
}, 12000 + Math.random() * 12000);
};
scheduleGust();
}
}
// Invite Detection & Bridge
+14 -6
View File
@@ -67,6 +67,8 @@
<span class="bamboo-stalk far-1"></span>
<span class="bamboo-stalk far-2"></span>
<span class="bamboo-stalk far-3"></span>
<span class="bamboo-stalk far-4"></span>
<span class="bamboo-stalk far-5"></span>
</div>
<div id="bamboo-near">
<div class="bamboo-stalk near-1">
@@ -82,6 +84,12 @@
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
<div class="bamboo-stalk near-3">
<i class="bamboo-node node-1"></i>
<i class="bamboo-node node-2"></i>
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
</div>
<span class="fall-leaf fall-leaf-1"><i></i></span>
<span class="fall-leaf fall-leaf-2"><i></i></span>
@@ -99,12 +107,12 @@
<div class="bg-mist bg-mist-1"></div>
<div class="bg-mist bg-mist-2"></div>
<div class="bg-horizon"></div>
<span class="firefly firefly-1"></span>
<span class="firefly firefly-2"></span>
<span class="firefly firefly-3"></span>
<span class="firefly firefly-4"></span>
<span class="firefly firefly-5"></span>
<span class="firefly firefly-6"></span>
<span class="firefly-wrap fw-1"><span class="firefly"></span></span>
<span class="firefly-wrap fw-2"><span class="firefly"></span></span>
<span class="firefly-wrap fw-3"><span class="firefly"></span></span>
<span class="firefly-wrap fw-4"><span class="firefly"></span></span>
<span class="firefly-wrap fw-5"><span class="firefly"></span></span>
<span class="firefly-wrap fw-6"><span class="firefly"></span></span>
</div>
<div class="bg-light-sweep"></div>
<div class="bg-grain"></div>
+14 -6
View File
@@ -67,6 +67,8 @@
<span class="bamboo-stalk far-1"></span>
<span class="bamboo-stalk far-2"></span>
<span class="bamboo-stalk far-3"></span>
<span class="bamboo-stalk far-4"></span>
<span class="bamboo-stalk far-5"></span>
</div>
<div id="bamboo-near">
<div class="bamboo-stalk near-1">
@@ -82,6 +84,12 @@
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
<div class="bamboo-stalk near-3">
<i class="bamboo-node node-1"></i>
<i class="bamboo-node node-2"></i>
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
</div>
<span class="fall-leaf fall-leaf-1"><i></i></span>
<span class="fall-leaf fall-leaf-2"><i></i></span>
@@ -99,12 +107,12 @@
<div class="bg-mist bg-mist-1"></div>
<div class="bg-mist bg-mist-2"></div>
<div class="bg-horizon"></div>
<span class="firefly firefly-1"></span>
<span class="firefly firefly-2"></span>
<span class="firefly firefly-3"></span>
<span class="firefly firefly-4"></span>
<span class="firefly firefly-5"></span>
<span class="firefly firefly-6"></span>
<span class="firefly-wrap fw-1"><span class="firefly"></span></span>
<span class="firefly-wrap fw-2"><span class="firefly"></span></span>
<span class="firefly-wrap fw-3"><span class="firefly"></span></span>
<span class="firefly-wrap fw-4"><span class="firefly"></span></span>
<span class="firefly-wrap fw-5"><span class="firefly"></span></span>
<span class="firefly-wrap fw-6"><span class="firefly"></span></span>
</div>
<div class="bg-light-sweep"></div>
<div class="bg-grain"></div>
+14 -6
View File
@@ -67,6 +67,8 @@
<span class="bamboo-stalk far-1"></span>
<span class="bamboo-stalk far-2"></span>
<span class="bamboo-stalk far-3"></span>
<span class="bamboo-stalk far-4"></span>
<span class="bamboo-stalk far-5"></span>
</div>
<div id="bamboo-near">
<div class="bamboo-stalk near-1">
@@ -82,6 +84,12 @@
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
<div class="bamboo-stalk near-3">
<i class="bamboo-node node-1"></i>
<i class="bamboo-node node-2"></i>
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
</div>
<span class="fall-leaf fall-leaf-1"><i></i></span>
<span class="fall-leaf fall-leaf-2"><i></i></span>
@@ -99,12 +107,12 @@
<div class="bg-mist bg-mist-1"></div>
<div class="bg-mist bg-mist-2"></div>
<div class="bg-horizon"></div>
<span class="firefly firefly-1"></span>
<span class="firefly firefly-2"></span>
<span class="firefly firefly-3"></span>
<span class="firefly firefly-4"></span>
<span class="firefly firefly-5"></span>
<span class="firefly firefly-6"></span>
<span class="firefly-wrap fw-1"><span class="firefly"></span></span>
<span class="firefly-wrap fw-2"><span class="firefly"></span></span>
<span class="firefly-wrap fw-3"><span class="firefly"></span></span>
<span class="firefly-wrap fw-4"><span class="firefly"></span></span>
<span class="firefly-wrap fw-5"><span class="firefly"></span></span>
<span class="firefly-wrap fw-6"><span class="firefly"></span></span>
</div>
<div class="bg-light-sweep"></div>
<div class="bg-grain"></div>
+14 -6
View File
@@ -52,6 +52,8 @@
<span class="bamboo-stalk far-1"></span>
<span class="bamboo-stalk far-2"></span>
<span class="bamboo-stalk far-3"></span>
<span class="bamboo-stalk far-4"></span>
<span class="bamboo-stalk far-5"></span>
</div>
<div id="bamboo-near">
<div class="bamboo-stalk near-1">
@@ -67,6 +69,12 @@
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
<div class="bamboo-stalk near-3">
<i class="bamboo-node node-1"></i>
<i class="bamboo-node node-2"></i>
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
</div>
<span class="fall-leaf fall-leaf-1"><i></i></span>
<span class="fall-leaf fall-leaf-2"><i></i></span>
@@ -84,12 +92,12 @@
<div class="bg-mist bg-mist-1"></div>
<div class="bg-mist bg-mist-2"></div>
<div class="bg-horizon"></div>
<span class="firefly firefly-1"></span>
<span class="firefly firefly-2"></span>
<span class="firefly firefly-3"></span>
<span class="firefly firefly-4"></span>
<span class="firefly firefly-5"></span>
<span class="firefly firefly-6"></span>
<span class="firefly-wrap fw-1"><span class="firefly"></span></span>
<span class="firefly-wrap fw-2"><span class="firefly"></span></span>
<span class="firefly-wrap fw-3"><span class="firefly"></span></span>
<span class="firefly-wrap fw-4"><span class="firefly"></span></span>
<span class="firefly-wrap fw-5"><span class="firefly"></span></span>
<span class="firefly-wrap fw-6"><span class="firefly"></span></span>
</div>
<div class="bg-light-sweep"></div>
<div class="bg-grain"></div>
+14 -6
View File
@@ -67,6 +67,8 @@
<span class="bamboo-stalk far-1"></span>
<span class="bamboo-stalk far-2"></span>
<span class="bamboo-stalk far-3"></span>
<span class="bamboo-stalk far-4"></span>
<span class="bamboo-stalk far-5"></span>
</div>
<div id="bamboo-near">
<div class="bamboo-stalk near-1">
@@ -82,6 +84,12 @@
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
<div class="bamboo-stalk near-3">
<i class="bamboo-node node-1"></i>
<i class="bamboo-node node-2"></i>
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
</div>
<span class="fall-leaf fall-leaf-1"><i></i></span>
<span class="fall-leaf fall-leaf-2"><i></i></span>
@@ -99,12 +107,12 @@
<div class="bg-mist bg-mist-1"></div>
<div class="bg-mist bg-mist-2"></div>
<div class="bg-horizon"></div>
<span class="firefly firefly-1"></span>
<span class="firefly firefly-2"></span>
<span class="firefly firefly-3"></span>
<span class="firefly firefly-4"></span>
<span class="firefly firefly-5"></span>
<span class="firefly firefly-6"></span>
<span class="firefly-wrap fw-1"><span class="firefly"></span></span>
<span class="firefly-wrap fw-2"><span class="firefly"></span></span>
<span class="firefly-wrap fw-3"><span class="firefly"></span></span>
<span class="firefly-wrap fw-4"><span class="firefly"></span></span>
<span class="firefly-wrap fw-5"><span class="firefly"></span></span>
<span class="firefly-wrap fw-6"><span class="firefly"></span></span>
</div>
<div class="bg-light-sweep"></div>
<div class="bg-grain"></div>
+131 -11
View File
@@ -115,6 +115,30 @@ body {
}
/* --- Animated Bamboo Forest Background (v3 Greens Update) --- */
/* Registered so wind gusts can TRANSITION these instead of jumping */
@property --sway {
syntax: '<angle>';
initial-value: 1.2deg;
inherits: true;
}
@property --leaf-drift {
syntax: '<length>';
initial-value: 26px;
inherits: true;
}
.bg-nature {
--sway: 1.2deg;
--leaf-drift: 26px;
transition: --sway 1.6s ease-in-out, --leaf-drift 1.6s ease-in-out;
}
.bg-nature.gusting {
--sway: 3.4deg;
--leaf-drift: 68px;
}
.bg-nature {
position: fixed;
top: 0;
@@ -143,12 +167,37 @@ body {
height: 140%;
border-radius: 999px;
filter: blur(5.5px);
transition: filter 1.2s ease;
background: linear-gradient(180deg, oklch(0.32 0.05 145 / 0.35), oklch(0.24 0.04 140 / 0.15));
}
#bamboo-far .far-1 { left: 2%; width: 26px; }
#bamboo-far .far-2 { left: 7.5%; width: 18px; }
#bamboo-far .far-3 { right: 4%; width: 30px; }
#bamboo-far .far-4 { left: 13%; width: 20px; }
#bamboo-far .far-5 { right: 10.5%; width: 16px; }
/* Two barely-there trunks break up the empty middle without competing with
the content. They share the far layer's single parallax transform. */
#bamboo-far::before,
#bamboo-far::after {
content: '';
position: absolute;
top: -20%;
height: 140%;
border-radius: 999px;
filter: blur(8px);
opacity: 0.28;
background: linear-gradient(180deg, oklch(0.34 0.05 145 / 0.3), oklch(0.23 0.04 140 / 0.1));
}
#bamboo-far::before { left: 24%; width: 13px; }
#bamboo-far::after { right: 25%; width: 17px; }
/* Depth of field: the far layer blurs further as you descend (stepped by
JS on threshold crossings, never per frame) */
.bg-nature.depth-mid #bamboo-far .bamboo-stalk { filter: blur(6.5px); }
.bg-nature.depth-deep #bamboo-far .bamboo-stalk { filter: blur(8px); }
/* (b) Near bamboo layer: sharp stalks with nodes and leaves, gentle sway */
#bamboo-near {
@@ -169,6 +218,7 @@ body {
#bamboo-near .near-1 { left: 4.5%; width: 13px; animation-duration: 9.2s; }
#bamboo-near .near-2 { right: 7%; width: 11px; animation-duration: 11s; animation-delay: -3.5s; }
#bamboo-near .near-3 { left: 10%; width: 9px; animation-duration: 12.5s; animation-delay: -6s; opacity: 0.75; }
#bamboo-near .bamboo-node {
position: absolute;
@@ -194,10 +244,11 @@ body {
#bamboo-near .near-1 .leaf-1 { top: 27.5%; left: 10px; transform: rotate(18deg); }
#bamboo-near .near-1 .leaf-2 { top: 47.5%; left: -28px; transform: rotate(-160deg); width: 22px; height: 10px; }
#bamboo-near .near-2 .leaf-1 { top: 44%; left: -26px; transform: rotate(-155deg); }
#bamboo-near .near-3 .leaf-1 { top: 33%; left: 7px; transform: rotate(24deg); width: 18px; height: 9px; }
@keyframes bambooSway {
0%, 100% { transform: rotate(0); }
50% { transform: rotate(1.2deg); }
50% { transform: rotate(var(--sway, 1.2deg)); }
}
/* (d) Falling leaves: outer element falls + rotates, inner leaf sways */
@@ -245,7 +296,7 @@ body {
@keyframes leafSway {
0%, 100% { margin-left: 0; }
50% { margin-left: 26px; }
50% { margin-left: var(--leaf-drift, 26px); }
}
/* Scroll journey: JS drives the opacity of these two groups so the page
@@ -377,11 +428,32 @@ body {
50% { opacity: 0.85; }
}
/* (i) Fireflies */
.firefly {
/* Theme switch to light: the horizon flares up once like a sunrise */
.bg-nature.sunrise .bg-horizon {
animation:
horizonBreathe 10s ease-in-out infinite,
sunriseFlash 1.6s ease-out;
}
@keyframes sunriseFlash {
0% { opacity: 0.5; }
30% { opacity: 1; }
100% { opacity: 0.5; }
}
/* (i) Fireflies: the wrapper holds the base position and is what the JS
pushes away from the cursor; the inner dot pulses (transform) and
wanders (translate) independently. */
.firefly-wrap {
position: absolute;
width: 4px;
height: 4px;
}
.firefly {
display: block;
width: 4px;
height: 4px;
border-radius: 50%;
background: oklch(0.68 0.13 150);
box-shadow: 0 0 8px oklch(0.68 0.13 150);
@@ -390,19 +462,38 @@ body {
fireflyWander 21s ease-in-out infinite alternate;
}
.firefly:nth-child(even) {
.fw-2 .firefly,
.fw-4 .firefly,
.fw-6 .firefly {
width: 3px;
height: 3px;
background: oklch(0.62 0.14 45);
box-shadow: 0 0 8px oklch(0.62 0.14 45);
}
.firefly-1 { top: 32%; left: 12%; animation-delay: -0.4s, -4s; }
.firefly-2 { top: 58%; left: 22%; animation-duration: 4.4s, 26s; animation-delay: -2.1s, -11s; }
.firefly-3 { top: 44%; left: 46%; animation-duration: 3.4s, 18s; animation-delay: -1.2s, -7s; }
.firefly-4 { top: 70%; left: 64%; animation-duration: 4.1s, 29s; animation-delay: -3s, -19s; }
.firefly-5 { top: 26%; left: 78%; animation-duration: 3.6s, 23s; animation-delay: -1.8s, -14s; }
.firefly-6 { top: 62%; left: 90%; animation-duration: 4.2s, 17s; animation-delay: -0.9s, -2s; }
.fw-1 { top: 32%; left: 12%; }
.fw-2 { top: 58%; left: 22%; }
.fw-3 { top: 44%; left: 46%; }
.fw-4 { top: 70%; left: 64%; }
.fw-5 { top: 26%; left: 78%; }
.fw-6 { top: 62%; left: 90%; }
.fw-1 .firefly { animation-delay: -0.4s, -4s; }
.fw-2 .firefly { animation-duration: 4.4s, 26s; animation-delay: -2.1s, -11s; }
.fw-3 .firefly { animation-duration: 3.4s, 18s; animation-delay: -1.2s, -7s; }
.fw-4 .firefly { animation-duration: 4.1s, 29s; animation-delay: -3s, -19s; }
.fw-5 .firefly { animation-duration: 3.6s, 23s; animation-delay: -1.8s, -14s; }
.fw-6 .firefly { animation-duration: 4.2s, 17s; animation-delay: -0.9s, -2s; }
/* One firefly greets you when a new section scrolls into view */
.firefly-wrap.firefly-hello {
animation: fireflyHello 1.2s ease-out;
}
@keyframes fireflyHello {
0%, 100% { transform: scale(1); filter: brightness(1); }
35% { transform: scale(2.4); filter: brightness(1.7); }
}
@keyframes fireflyPulse {
0%, 100% { opacity: 0.2; transform: scale(1); }
@@ -443,6 +534,22 @@ body {
background-size: 160px 160px;
}
@media (max-width: 768px) {
/* Half the leaves, no god rays / light sweep / extra stalks: the scene
stays recognisable while the animation count roughly halves. */
.fall-leaf-5,
.fall-leaf-6,
.fall-leaf-7,
.fall-leaf-8,
.bg-godrays,
.bg-light-sweep,
#bamboo-far .far-4,
#bamboo-far .far-5,
#bamboo-near .near-3 {
display: none;
}
}
@media (prefers-reduced-motion: reduce) {
.bg-nature *,
.bg-nature *::before,
@@ -5265,6 +5372,19 @@ header[id] {
box-shadow: 0 0 8px var(--accent-glow);
}
.scroll-progress-bar::after {
content: '';
position: absolute;
right: -3px;
top: 50%;
width: 10px;
height: 7px;
border-radius: 0 70% 0 70%;
background: var(--accent-green);
box-shadow: 0 0 6px var(--accent-glow);
transform: translateY(-50%) rotate(24deg);
}
/* Navigation logo pop & spin */
.nav-logo-img {
animation: logo-entrance 1.2s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
+14 -6
View File
@@ -232,6 +232,8 @@
<span class="bamboo-stalk far-1"></span>
<span class="bamboo-stalk far-2"></span>
<span class="bamboo-stalk far-3"></span>
<span class="bamboo-stalk far-4"></span>
<span class="bamboo-stalk far-5"></span>
</div>
<div id="bamboo-near">
<div class="bamboo-stalk near-1">
@@ -247,6 +249,12 @@
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
<div class="bamboo-stalk near-3">
<i class="bamboo-node node-1"></i>
<i class="bamboo-node node-2"></i>
<i class="bamboo-node node-3"></i>
<i class="bamboo-leaf leaf-1"></i>
</div>
</div>
<span class="fall-leaf fall-leaf-1"><i></i></span>
<span class="fall-leaf fall-leaf-2"><i></i></span>
@@ -264,12 +272,12 @@
<div class="bg-mist bg-mist-1"></div>
<div class="bg-mist bg-mist-2"></div>
<div class="bg-horizon"></div>
<span class="firefly firefly-1"></span>
<span class="firefly firefly-2"></span>
<span class="firefly firefly-3"></span>
<span class="firefly firefly-4"></span>
<span class="firefly firefly-5"></span>
<span class="firefly firefly-6"></span>
<span class="firefly-wrap fw-1"><span class="firefly"></span></span>
<span class="firefly-wrap fw-2"><span class="firefly"></span></span>
<span class="firefly-wrap fw-3"><span class="firefly"></span></span>
<span class="firefly-wrap fw-4"><span class="firefly"></span></span>
<span class="firefly-wrap fw-5"><span class="firefly"></span></span>
<span class="firefly-wrap fw-6"><span class="firefly"></span></span>
</div>
<div class="bg-light-sweep"></div>
<div class="bg-grain"></div>