diff options
| author | Tyler Hoang <tyler@tylerhoang.xyz> | 2026-05-29 01:50:33 -0700 |
|---|---|---|
| committer | Tyler Hoang <tyler@tylerhoang.xyz> | 2026-05-29 01:50:33 -0700 |
| commit | 2ead51ef77c4872a188217cca8b82f5b02053ecd (patch) | |
| tree | 1755d5b644c32a913cb9d4a88a3038603b00a886 /aero.js | |
| parent | 41c352e939a3389b9c7a18065c1c25c005e98bfe (diff) | |
chrome: add moving shard background + CLAUDE.md
Implements the chrome theme's metallic shard ambient field from the
redesign handoff. Adds spawnShards() to aero.js, shard CSS (clip-path
polygon, chrome gradient, specular streak, shard-rise keyframes) to
aero.css, and wires up calls in index.js and enter.html. Shard field
is hidden by default; shown only when body[data-theme="chrome"].
Also adds prefers-reduced-motion guard for both fields.
Adds CLAUDE.md with architecture overview for future sessions.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'aero.js')
| -rw-r--r-- | aero.js | 26 |
1 files changed, 25 insertions, 1 deletions
@@ -17,6 +17,30 @@ function spawnBubbles(host, count = 22) { host.appendChild(f); } +function spawnShards(host, count = 30, kind = 'shard', speed = 1) { + const f = document.createElement('div'); + f.className = 'shard-field'; + for (let i = 0; i < count; i++) { + const s = document.createElement('div'); + s.className = 'chrome-shard ' + kind; + const w = kind === 'blade' ? 8 + Math.random() * 14 : 16 + Math.random() * 34; + const h = kind === 'blade' ? 64 + Math.random() * 130 : 36 + Math.random() * 92; + s.style.width = w + 'px'; + s.style.height = h + 'px'; + s.style.left = Math.random() * 100 + '%'; + s.style.setProperty('--drift', ((Math.random() - 0.5) * 170) + 'px'); + const rot0 = Math.round(Math.random() * 360); + const spin = (Math.random() < 0.5 ? -1 : 1) * (110 + Math.random() * 250); + s.style.setProperty('--rot0', rot0 + 'deg'); + s.style.setProperty('--rot1', (rot0 + spin) + 'deg'); + s.style.animationDuration = ((18 + Math.random() * 16) / speed) + 's'; + s.style.animationDelay = (-Math.random() * 30) + 's'; + f.appendChild(s); + } + host.appendChild(f); + return f; +} + function makeClouds(host) { const svg = `<svg viewBox="0 0 1440 900" preserveAspectRatio="xMidYMid slice" style="width:100%;height:100%;"> <defs> @@ -270,7 +294,7 @@ async function fetchReelMouthFeed(limit = 6) { } window.Aero = { - spawnBubbles, makeClouds, sparkleCursor, makeDraggable, makeResizable, + spawnBubbles, spawnShards, makeClouds, sparkleCursor, makeDraggable, makeResizable, counterHTML, nowPlayingHTML, animateEq, musicToggleHTML, // theme api getTheme, setTheme, mountThemeSwitcher, initTheme, THEMES, |
