diff options
| author | Tyler Hoang <tyler@tylerhoang.xyz> | 2026-05-26 19:28:43 -0700 |
|---|---|---|
| committer | Tyler Hoang <tyler@tylerhoang.xyz> | 2026-05-26 19:28:43 -0700 |
| commit | 66802e23d77a23b72ac786d049a6ce653c5150eb (patch) | |
| tree | e6c1db8a398730a4be8141dba3aaa2f2cadad01e /aero.js | |
| parent | f41c502a0aaa1c835cebc5b723bf37facc00acca (diff) | |
redesign: add Y2K chrome theme + theme switcher
- Add Y2K Chrome / Frutiger Aero two-theme switcher (floating pill, top-right)
- Theme persists via localStorage under 'tyler.theme', no flash on load
- Chrome theme: brushed-metal panels, iridescent titlebar seam, holographic
cursor, blueprint wallpaper, Audiowide/Michroma/Space Grotesk fonts
- Aero theme: upgraded to Plus Jakarta Sans + IBM Plex Mono
- Z-index hygiene: .icons → 10, .win → 50, .bubble-field → 0
- Sparkle cursor is theme-aware (cyan→pink for chrome, warm rainbow for aero)
- Music toggle is theme-aware: bazaar theme (aero) / coolman (chrome),
swaps live if you change theme while music is playing
- Add img/wallpaper-chrome.png (blueprint wallpaper for chrome theme)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'aero.js')
| -rw-r--r-- | aero.js | 60 |
1 files changed, 56 insertions, 4 deletions
@@ -1,4 +1,4 @@ -// Shared Aero JS: bubbles, sparkle cursor, music toggle, drag windows, helpers. +// Shared Aero JS: bubbles, sparkle cursor, music toggle, drag windows, theme switcher, helpers. function spawnBubbles(host, count = 22) { const f = document.createElement('div'); @@ -50,8 +50,14 @@ function sparkleCursor() { s.className = 'sparkle'; s.style.left = e.clientX + 'px'; s.style.top = e.clientY + 'px'; - const hue = 30 + Math.random() * 200; - s.style.background = `radial-gradient(circle, oklch(95% 0.12 ${hue}) 0%, oklch(85% 0.18 ${hue} / 0.6) 40%, transparent 70%)`; + const theme = document.body.dataset.theme; + // chrome: iridescent / holographic palette (cyan→magenta→pink) + // aero: warm-cool rainbow as before + const hue = theme === 'chrome' + ? 200 + Math.random() * 160 + : 30 + Math.random() * 200; + const chroma = theme === 'chrome' ? 0.22 : 0.18; + s.style.background = `radial-gradient(circle, oklch(96% 0.10 ${hue}) 0%, oklch(82% ${chroma} ${hue} / 0.6) 40%, transparent 70%)`; document.body.appendChild(s); setTimeout(() => s.remove(), 900); }); @@ -147,6 +153,45 @@ function bindMusicToggle(root) { }); } +// THEME SWITCHER — Aero (Frutiger) ↔ Chrome (Y2K) +const THEME_KEY = 'tyler.theme'; +const THEMES = ['aero', 'chrome']; + +function getTheme() { + const t = localStorage.getItem(THEME_KEY); + return THEMES.includes(t) ? t : 'aero'; +} +function setTheme(t) { + if (!THEMES.includes(t)) t = 'aero'; + document.body.setAttribute('data-theme', t); + localStorage.setItem(THEME_KEY, t); + document.querySelectorAll('.theme-switcher button').forEach(b => { + b.classList.toggle('active', b.dataset.theme === t); + }); + try { window.dispatchEvent(new CustomEvent('themechange', { detail: t })); } catch(_){} +} +function mountThemeSwitcher(host) { + host = host || document.body; + const wrap = document.createElement('div'); + wrap.className = 'theme-switcher no-drag'; + wrap.innerHTML = THEMES.map(t => ` + <button data-theme="${t}" title="${t}" class="no-drag"> + <span class="ts-dot ${t}"></span>${t} + </button> + `).join(''); + host.appendChild(wrap); + wrap.querySelectorAll('button').forEach(b => { + b.addEventListener('click', () => setTheme(b.dataset.theme)); + }); + setTheme(getTheme()); + return wrap; +} +function initTheme() { + document.body.setAttribute('data-theme', getTheme()); +} + +// REAL API INTEGRATIONS + async function fetchLastFm(user = 'trollshotlol', key = 'e4d5c973811037717f7603f616259cdf', limit = 4) { const url = `https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=${user}&api_key=${key}&format=json&limit=${limit}`; const r = await fetch(url); @@ -182,4 +227,11 @@ async function fetchReelMouthFeed(limit = 6) { return await r.json(); } -window.Aero = { spawnBubbles, makeClouds, sparkleCursor, makeDraggable, counterHTML, nowPlayingHTML, animateEq, musicToggleHTML, bindMusicToggle, fetchLastFm, fetchFilms, fetchVisitorCount, fetchReelMouthFeed }; +window.Aero = { + spawnBubbles, makeClouds, sparkleCursor, makeDraggable, + counterHTML, nowPlayingHTML, animateEq, musicToggleHTML, bindMusicToggle, + // theme api + getTheme, setTheme, mountThemeSwitcher, initTheme, THEMES, + // real api integrations + fetchLastFm, fetchFilms, fetchVisitorCount, fetchReelMouthFeed, +}; |
