<feed xmlns='http://www.w3.org/2005/Atom'>
<title>fun.git/aero.js, branch master</title>
<subtitle>Source code of personal website</subtitle>
<id>https://git.tylerhoang.xyz/fun.git/atom?h=master</id>
<link rel='self' href='https://git.tylerhoang.xyz/fun.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.tylerhoang.xyz/fun.git/'/>
<updated>2026-05-29T08:50:33Z</updated>
<entry>
<title>chrome: add moving shard background + CLAUDE.md</title>
<updated>2026-05-29T08:50:33Z</updated>
<author>
<name>Tyler Hoang</name>
<email>tyler@tylerhoang.xyz</email>
</author>
<published>2026-05-29T08:50:33Z</published>
<link rel='alternate' type='text/html' href='https://git.tylerhoang.xyz/fun.git/commit/?id=2ead51ef77c4872a188217cca8b82f5b02053ecd'/>
<id>urn:sha1:2ead51ef77c4872a188217cca8b82f5b02053ecd</id>
<content type='text'>
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 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>theme: make chrome the default and move it left in the selector</title>
<updated>2026-05-29T04:13:35Z</updated>
<author>
<name>Tyler Hoang</name>
<email>tyler@tylerhoang.xyz</email>
</author>
<published>2026-05-29T04:13:35Z</published>
<link rel='alternate' type='text/html' href='https://git.tylerhoang.xyz/fun.git/commit/?id=41c352e939a3389b9c7a18065c1c25c005e98bfe'/>
<id>urn:sha1:41c352e939a3389b9c7a18065c1c25c005e98bfe</id>
<content type='text'>
Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>refactor: extract inline css/js from index.html</title>
<updated>2026-05-29T01:25:41Z</updated>
<author>
<name>Tyler Hoang</name>
<email>tyler@tylerhoang.xyz</email>
</author>
<published>2026-05-29T01:25:41Z</published>
<link rel='alternate' type='text/html' href='https://git.tylerhoang.xyz/fun.git/commit/?id=34f0486f091ded7112442a00f8c5c5ecae342265'/>
<id>urn:sha1:34f0486f091ded7112442a00f8c5c5ecae342265</id>
<content type='text'>
index.html shrank from 1650 to 349 lines. Inline &lt;style&gt;
moved to index.css, ARTICLES data to articles.js, the rest of
the inline script to index.js. Also:

- drop unused bindMusicToggle from aero.js
- collapse duplicate click+dblclick icon handlers
- dedup music-toggle gradient via .mt-btn.on class
- replace inline styles in films/podcast/now-playing renderers
  with semantic classes (.film-when, .pod-ep, .np-row, etc.)
- precompute article readMin and plainTitle once instead of on
  every render

Co-Authored-By: Claude Opus 4.7 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>aero: align sparkle cursor with pointer at non-1.0 zoom</title>
<updated>2026-05-29T01:14:54Z</updated>
<author>
<name>Tyler Hoang</name>
<email>tyler@tylerhoang.xyz</email>
</author>
<published>2026-05-29T01:14:54Z</published>
<link rel='alternate' type='text/html' href='https://git.tylerhoang.xyz/fun.git/commit/?id=7b67d90f4f25eca2480d0d769ec5ab6305c4b4c6'/>
<id>urn:sha1:7b67d90f4f25eca2480d0d769ec5ab6305c4b4c6</id>
<content type='text'>
The sparkle div is appended inside the zoomed &lt;html&gt;, so writing raw
clientX/Y into style.left/top placed each sparkle at clientX*zoom on
screen — drifting toward the origin. Divide by window.__uiScale.
</content>
</entry>
<entry>
<title>aero: fix 1:1 drag at non-1.0 zoom, scale window text on resize</title>
<updated>2026-05-29T01:13:06Z</updated>
<author>
<name>Tyler Hoang</name>
<email>tyler@tylerhoang.xyz</email>
</author>
<published>2026-05-29T01:13:06Z</published>
<link rel='alternate' type='text/html' href='https://git.tylerhoang.xyz/fun.git/commit/?id=343b9992e296c2b6ce14a0dabafac31b45620e30'/>
<id>urn:sha1:343b9992e296c2b6ce14a0dabafac31b45620e30</id>
<content type='text'>
Drag and resize handlers were reading pointer deltas in visual pixels
but writing to style.left/width which live in the (zoomed) layout
coord space — so dragging at zoom 0.7 lagged 30% behind the cursor.
Now divide deltas by window.__uiScale (set by the desktop-fit script).

Also: when a window is resized, scale its title bar and body via
`zoom` so the text inside grows/shrinks with the window. Baseline is
captured on first resize.
</content>
</entry>
<entry>
<title>browser+resize: implement proper faux browser + resizable windows per design handoff</title>
<updated>2026-05-27T03:11:26Z</updated>
<author>
<name>Tyler Hoang</name>
<email>tyler@tylerhoang.xyz</email>
</author>
<published>2026-05-27T03:11:26Z</published>
<link rel='alternate' type='text/html' href='https://git.tylerhoang.xyz/fun.git/commit/?id=a7ef2c9d7f459145fac5b8a78679aa71b292397c'/>
<id>urn:sha1:a7ef2c9d7f459145fac5b8a78679aa71b292397c</id>
<content type='text'>
Browser window (w-browser, Internet icon):
- Full aqua browser chrome: toolbar with back/fwd/reload/home SVG nav buttons,
  URL bar (lock + scheme + host + path + blinking caret), bookmark chips
  with colored 12x12 favicon squares, scrollable page surface, status bar
  with animated progress bar
- History stack (back/forward state, disable at ends)
- Delegated click handler via data-go attributes for in-page navigation
- Refresh button spins 700ms via CSS animation
- Address bar + title bar update on every navigation
- ARTICLES array with 4 entries (self-hosting, jazz, cooking, film) with
  drop-cap, Georgia body, IBM Plex Mono metadata, blockquotes, inline ilinks
- Chrome theme: brushed mercury toolbar, dark navy article surface with
  iridescent radial hotspots, Audiowide titles with chromeShimmer drop-cap,
  Michroma UI labels, iridescent progress bar, custom scrollbar

Resizable windows:
- makeResizable() in aero.js: appends .rs-e (right edge), .rs-s (bottom edge),
  .rs-se (SE grip) handles; tracks mousedown/move/up; enforces minW/minH
- .win.resized flex-column flip: body fills remaining height and scrolls
- Aero grip (3-stripe diagonal, blue); Chrome grip (iridescent purple/cyan/pink)
- Body cursor forced via body.rs-cursor-* classes during drag

CSS in aero.css: chrome overrides for resize handle + full browser window theme
CSS in index.html: resize handle rules, full browser/article reading styles

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>redesign: add Y2K chrome theme + theme switcher</title>
<updated>2026-05-27T02:28:43Z</updated>
<author>
<name>Tyler Hoang</name>
<email>tyler@tylerhoang.xyz</email>
</author>
<published>2026-05-27T02:28:43Z</published>
<link rel='alternate' type='text/html' href='https://git.tylerhoang.xyz/fun.git/commit/?id=66802e23d77a23b72ac786d049a6ce653c5150eb'/>
<id>urn:sha1:66802e23d77a23b72ac786d049a6ce653c5150eb</id>
<content type='text'>
- 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 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>podcast: switch to server-side php proxy for rss feed</title>
<updated>2026-05-27T01:23:46Z</updated>
<author>
<name>Tyler Hoang</name>
<email>tyler@tylerhoang.xyz</email>
</author>
<published>2026-05-27T01:23:46Z</published>
<link rel='alternate' type='text/html' href='https://git.tylerhoang.xyz/fun.git/commit/?id=c8a588062f31b00b8c302a3e9f5fff6b43110dc2'/>
<id>urn:sha1:c8a588062f31b00b8c302a3e9f5fff6b43110dc2</id>
<content type='text'>
itunes api unreachable from browser on vps. podcast.php fetches
anchor.fm rss server-to-server, parses xml, returns json.
1h cache header to avoid hammering the feed.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>podcast: wire reel mouth rss via itunes lookup api</title>
<updated>2026-05-27T01:22:12Z</updated>
<author>
<name>Tyler Hoang</name>
<email>tyler@tylerhoang.xyz</email>
</author>
<published>2026-05-27T01:22:12Z</published>
<link rel='alternate' type='text/html' href='https://git.tylerhoang.xyz/fun.git/commit/?id=ee3b563ecec4a6e9e7755d3ed6bc08faa3916545'/>
<id>urn:sha1:ee3b563ecec4a6e9e7755d3ed6bc08faa3916545</id>
<content type='text'>
- add fetchReelMouthFeed() to aero.js using itunes api (id 1709836497)
- replace hardcoded episodes with dynamic #pod-episodes container
- swap in real artwork on load, fallback placeholder until then
- fix links: apple podcasts, anchor.fm rss feed
- lazy-loads on first window open, cached after that

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>redesign: frutiger aero faux-OS desktop</title>
<updated>2026-05-26T07:33:22Z</updated>
<author>
<name>Tyler Hoang</name>
<email>tyler@tylerhoang.xyz</email>
</author>
<published>2026-05-26T07:33:22Z</published>
<link rel='alternate' type='text/html' href='https://git.tylerhoang.xyz/fun.git/commit/?id=b2827329a32d3fe627a62bd4ff4191b2a3e4407f'/>
<id>urn:sha1:b2827329a32d3fe627a62bd4ff4191b2a3e4407f</id>
<content type='text'>
replaces the old enter/index pages with a draggable-windows desktop
metaphor. wires last.fm now-playing, films.tylerhoang.xyz diary, and
a php visitor counter; keeps background music via /mus/mmt.mp3.

Co-Authored-By: Claude Opus 4.7 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
