style(website): landing motion, interaction & layout polish

Feedback round (calmer, less "template/AI"):
- Dial back animated background motion globally (sway/leaf-drift halved,
  fewer falling leaves, gentler godrays/fireflies/light-sweep).
- Fire leaf confetti on click of real controls only (was pointerdown
  everywhere, which showered mobile users on every scroll).
- Remove hover lift/scale from non-interactive cards, screenshots and
  mascots so they no longer read as clickable.
- Fix mobile nav menu colours in the light theme (was a hard-coded dark
  panel with low-contrast links).
- Calm how-it-works steps 1-2 (no button pulse/shine/cursor bob); step 3
  keeps its lively sync animation. Remove the now-static "copied" toast
  from step 1 since it only made sense mid-animation.

UX audit follow-ups:
- Unify vertical rhythm with one section-padding scale; vertically centre
  the hero so space is balanced instead of pooling under the CTAs.
- Split the mixed "Why KoalaSync?" grid into use-case scenarios and a
  labelled "Features" subsection, and move the #features nav anchor there.
- Demote the hero GitHub CTA to a quiet text link (Chrome > Firefox >
  GitHub hierarchy); scale down oversized section mascots and give them a
  shared soft shadow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Timo
2026-07-13 02:42:19 +02:00
parent 63414bfcdd
commit af0da75d38
10 changed files with 127 additions and 143 deletions
+9 -9
View File
@@ -379,19 +379,19 @@ document.addEventListener('DOMContentLoaded', () => {
}
};
// Listen for `click`, not `pointerdown`: a click never fires while the
// page is being scrolled, so touch users no longer trigger a shower of
// leaves every time they swipe. Leaves are also only shed by actual
// interactive controls (links/buttons and the demo widgets), so a stray
// tap on plain text or an illustration stays quiet.
let lastBurst = 0;
document.addEventListener('pointerdown', (e) => {
if (e.button !== 0 || !e.isPrimary) return;
document.addEventListener('click', (e) => {
const control = e.target.closest('a, button, [role="button"], .btn, .mock-tab, select, .demo-progress');
if (!control) return;
const now = Date.now();
if (now - lastBurst < 180) return;
lastBurst = now;
const control = e.target.closest('button, [role="button"], .btn, .mock-tab, select, .demo-progress');
if (control) {
burstFromElement(control);
} else {
const count = 4 + Math.floor(Math.random() * 3);
for (let i = 0; i < count; i++) spawnLeaf(e.clientX, e.clientY);
}
burstFromElement(control);
}, { passive: true });
}