Skip to main content

Changelog

This site is a living thing. It grows, breaks, gets rebuilt, and occasionally surprises me.

50+ commits since 2013186 posts20 releases

2018

v0.12018website v1

Original Site Launch

First version with Tachyons CSS, audio player for DJ mixes, Pinboard bookmarks integration, Are.na vibes section, and a shop. The whole thing was held together with good intentions and functional CSS. It worked, somehow.

50 commits · 30 files launch
Tachyons CSS, Vue.js, Pinboard API, Are.na API

2019

v0.32019website v1

Markdown Pipeline

Rebuilt the content system with markdown-it parser, table of contents generation, and JSON resume integration. This was the first time the site felt like a real publishing system instead of a bunch of HTML files.

15 commits · 20 files content, infrastructure
markdown-it, JSON Resume

2020

v0.42020website v1

Dark Mode & Photoblog

Implemented dark mode toggle and automated photoblog system. 2020 was the year everyone added dark mode. I also automated photo uploads because life's too short to manually resize images.

12 commits · 15 files design, automation
CSS custom properties, Node.js

2021

v0.52021website v1

Art Section

Added dedicated art pages and updated projects with NBC News and CCRB journalism pieces. The site started pulling double duty as portfolio and blog around this point.

10 commits · 8 files content, portfolio
Vue.js

2023

v0.7Q4 2023website v1

Tailwind Redesign

Ripped out Tachyons and replaced it with Tailwind CSS + Nuxt UI. Added 3D canvas experiments and GitHub data integration. The Tachyons-to-Tailwind migration was one of those things that took a weekend but paid off for years.

25 commits · 40 files design, infrastructure
Tailwind CSS, Nuxt UI, Three.js

2024

v2.0Oct 2024

Stats Dashboard

Personal metrics aggregating GitHub, YouTube, LastFM, Chess.com, and a bunch of other APIs into one dense dashboard. Two versions: full stats for the web (~2.4KB) and a lite version optimized for iOS Shortcuts (~345 bytes). Because sometimes you want to know your chess rating from your watch.

18 commits · 12 files api, data-viz
GitHub API, YouTube API, LastFM API, Chess.com API
v1.0Sep 2024

website2 Launch

Complete rebuild from scratch. Nuxt 3, Docker deployment, new markdown processing pipeline. Fresh start after 6 years on the old stack. The content pipeline goes Obsidian -> processMarkdown.mjs -> structured JSON -> Vue components. Write in your editor, publish with a git push. The way it should be.

150 commits · 200 files launch, infrastructure
Nuxt 3, Docker, TypeScript, Tailwind CSS
v0.9Q2 2024website v1

Pottery Shop & RSS

Added a pottery page with Stripe checkout because apparently I make ceramics now. Also RSS feed and a public tags.json endpoint. The pottery page was mostly an excuse to learn Stripe's API, but people actually bought things.

8 commits · 10 files commerce, rss
Stripe, RSS
v0.8Q2 2024website v1

Scrap Graph View

Interactive graph visualization of scraps with Supabase backend integration. The precursor to the threads visualization -- same impulse to see how ideas connect, just rougher around the edges.

5 commits · 6 files visualization, data
D3.js, Supabase

2025

v3.0Dec 2025

Flashcard System

Built a full spaced repetition flashcard system because I kept forgetting things I'd already written about. 3D card flip animations, multi-deck support, the whole deal. There's something deeply satisfying about turning your own blog posts into study material. API endpoints for learning data so I can track what sticks.

8 commits · 12 files learning, interactive
Vue 3, CSS 3D transforms
v2.9Dec 2025

Threads Visualization

D3 force-directed graph showing how posts, scraps, and tags actually connect to each other. You scroll through 350vh of interconnected content and watch the relationships emerge. Top 25 tags pinned as maypoles down the page in a sine wave. It's the kind of thing that makes you realize how much you've written about the same three topics.

15 commits · 8 files visualization, d3
D3.js, Canvas API, anime.js
v2.8Dec 2025

Scraps Browser

New page for browsing the Supabase scraps collection. Tag filtering, metadata display, the whole archival experience. Scraps are the stuff that doesn't quite make it into a blog post but is too good to lose -- bookmarks, notes, fragments of ideas. Now they have a proper home.

6 commits · 5 files content, archive
Supabase, Vue 3
v2.7Nov 2025

Kalshi Predictions Integration

Live prediction market portfolio tracking with real-time P&L, calibration analysis, and position commentary. I wanted to put my money where my forecasts are, literally. Tracks how well-calibrated my bets are against my stated confidence levels. The calibration curve is humbling.

10 commits · 14 files predictions, finance
Kalshi API, D3.js
v2.6Nov 2025

Gear Inventory Overhaul

Rebuilt the gear page with smart unit conversion, favorites, weight-per-category stats, and Tuftian data visualizations. Every piece of gear I own, weighed and categorized. The histogram of weight distribution by category is chef's kiss. 8px baseline grid, ultra-dense tables, sparklines inline. Edward Tufte would approve (I hope).

20 commits · 9 files data-viz, design
CSV, D3.js, Tailwind CSS
v2.5Oct 2025

Tufte-Style Sidenotes

Major typography overhaul. Footnotes now appear as margin notes on desktop, the way Tufte intended. Replaced an 800-line complex sidenotes system with a 113-line client-side plugin that just works. Delete-driven development at its finest. Georgia serif, proper vertical rhythm, the whole editorial treatment.

14 commits · 22 files typography, design
CSS, TypeScript plugin
v2.4Aug 2025

Dynamic Tags System

Tags endpoint with journalist pyramid ordering -- most important and frequently used tags surface first, like a newsroom would prioritize stories. Also added llms.txt for AI crawlers because the robots should know what they're reading too.

7 commits · 6 files api, content
TypeScript, Nuxt server routes
v2.3Jul 2025

Cryptographic Predictions

10 predictions for 2025-2029, SHA-256 hashed and committed to git. The idea is simple: write down what you think will happen, commit to it in public, then come back later and see how wrong you were. Accountability through math.

9 commits · 15 files predictions, crypto
SHA-256, Git
v2.2Jun 2025

Scrapbook View

Data-dense scrapbook view with tag filtering and an enhanced Pinboard bookmarklet with smart tag suggestions. The bookmarklet auto-suggests tags based on the page content, which is the kind of small automation that saves you 3 seconds a hundred times a day.

5 commits · 8 files bookmarks, tools
Pinboard API, JavaScript bookmarklet
v2.1May 2025

Predictions API

Built the foundation for the forecasting section. Predictions system with cryptographic verification -- SHA-256 hashes locked into git commits so you can't retroactively claim you predicted something you didn't. Honest futures.

6 commits · 10 files predictions, api
Node.js, SHA-256

2026

v3.1Apr 2026

The Great Alt Text Campaign

Added AI-generated descriptions to 881 images because every reader deserves to know what they're looking at. Used Claude's vision API with a content-first prompt, confidence scoring, and a manual review queue for the tricky ones. Also restored 87 dead Cloudinary images from backups and replaced 10 dead links with Internet Archive URLs. Accessibility isn't a feature, it's the floor.

12 commits · 168 files accessibility, ai
Claude Haiku, Cloudinary API, Node.js
Raw git commits (50)
3
ci
1
style
1
deploy
14
fix
2
visibility
1
processed
1
plugins
2
scraps
4
other
3
content
12
docs
2
chore
1
refactor
1
feat
1
test
1
a11y

NOV 01, 2026

8d6b08eci

ci(webmentions): hourly run so scheduled posts get announced

EJ Fox · 1:29 AM

83bedeastyle

style: prettier on files flagged by lint

EJ Fox · 1:10 AM

2e162cddeploy

deploy: snapshot live content before checkout; every failure path alerts

EJ Fox · 1:07 AM

754970ffix

fix: sealed keys can't be silently replaced; unshared scraps expire; catalog

EJ Fox · 1:06 AM

eb0d741fix

fix: renderer-hashed cache key, named stats caches, pg pool error handlers

EJ Fox · 12:08 AM

OCT 31, 2026

14d9624visibility

visibility: lint dispatch pieces for a removed hidden: key; soften gone-urls wording

EJ Fox · 11:01 PM

58960ecvisibility

visibility: one function, five states (sealed > draft > scheduled > unlisted > public)

EJ Fox · 10:57 PM

516e210processed

processed: refresh cache that was stale on main (no code change)

EJ Fox · 10:41 PM

8221e27plugins

plugins: run DOM enhancers on page:finish, not router.afterEach

EJ Fox · 9:26 PM

OCT 29, 2026

a11f579scraps

scraps: chromeless /scraps/embed/<id> for Scrapworld's live card backs

EJ Fox · 3:04 PM

3b9d183other

scraps permalink: site typography (Vault Alarm heading, Georgia reading text, mono data)

EJ Fox · 2:03 PM

c1dcad6scraps

scraps: per-scrap permalink page /scraps/<id> (shared only)

EJ Fox · 2:02 PM

9ce08f6content

content(projects): remove made-up and broken project images

EJ Fox · 12:32 AM

OCT 27, 2026

ba062fcfix

fix(scripts): orphan sweep runs, failed posts fail the build, safer author tools

EJ Fox · 6:43 PM

f3a367efix

fix(pages,components): reading highlights, gear data, stats tiles, atlas load race, tz

EJ Fox · 6:40 PM

36f662dfix

fix(server): harden API input handling, filters and error bodies

EJ Fox · 6:38 PM

1286704fix

fix(api): delete /api/umami/auth

EJ Fox · 5:08 PM

1536158docs

docs(code-guide): allow path-form @file for repeated filenames

EJ Fox · 4:49 AM

889ccf6docs

docs: fix three comment paths that gf couldn't follow

EJ Fox · 4:49 AM

c9b1563docs

docs: audit findings from the comment pass; correct two CLAUDE.md claims

EJ Fox · 4:45 AM

a29e6acdocs

docs(server/api): headers for all 94 routes; server/README matches the routes on disk

EJ Fox · 4:44 AM

df1a8a3docs

docs(server utils/middleware/routes): headers, run order, why-comments; server/utils/README

EJ Fox · 4:38 AM

d971357docs

docs(utils,composables,plugins,layouts,types,config): headers, sections, READMEs

EJ Fox · 4:37 AM

c60dc0edocs

docs(pages/*/): headers, sections and why-comments for nested pages

EJ Fox · 4:36 AM

72c4d66docs

docs(scripts/build,plugins,utils): pipeline map in processMarkdown, headers and why-comments

EJ Fox · 4:35 AM

54a5f48docs

docs(components): headers, sections and why-comments for all 72 components; components/README

EJ Fox · 4:32 AM

83db8a7docs

docs(pages): headers, sections and why-comments for top-level pages; pages/README route map

EJ Fox · 4:30 AM

5cbb4cfdocs

docs(scripts): headers + why-comments for meta/author/blog/qa/og-image; fix stale README

EJ Fox · 4:28 AM

15b3257docs

docs: repo map, code guide, docs index; fix stale README claims

EJ Fox · 4:23 AM

OCT 26, 2026

75f1440fix

fix(light mode): readable secondary text and status colors

EJ Fox · 8:10 PM

b009304fix

fix(layout): stop posts reflowing and overflowing on phones

EJ Fox · 7:36 PM

69fc298chore

chore: delete ~1,000 dead lines; tag 3 code fences; add .ignore

EJ Fox · 7:07 PM

a1d1ff3refactor

refactor(crown): a big post is a .vue body next to its .md

EJ Fox · 5:38 PM

4c1c187chore

chore: remove rotated images everywhere

EJ Fox · 5:33 PM

2059171fix

fix(crown): images fade in at their tilt; no rotation on scroll

EJ Fox · 5:14 PM

e3d84dbfix

fix(crown): images ease into their tilt instead of snapping

EJ Fox · 4:57 PM

568359ffix

fix(crown): useCrownedPost 500'd on SSR; light-mode meta bar

EJ Fox · 4:49 PM

6f70a6bfix

fix(crown): format with prettier's API, not npx

EJ Fox · 4:38 PM

e81f694fix

fix(crown): clean feed HTML; sealed check first

EJ Fox · 4:37 PM

3e656a3fix

fix(crown): bind srcset so Nuxt doesn't import Cloudinary URL pieces

EJ Fox · 4:34 PM

4869f69feat

feat(crown): a crowned post's prose lives in its Vue page

EJ Fox · 4:25 PM

OCT 23, 2026

6347683ci

ci: smoke-test ejfox.com after every deploy, alert Discord on failure

EJ Fox · 4:11 PM

3fd53d4test

test: yarn smoke, a read-only production smoke test

EJ Fox · 3:55 PM

OCT 22, 2026

878af45content

content: delete 2022-prototyping-toolkit; hook skips without deps

EJ Fox · 6:14 PM

f04bb6eci

ci: fail when a public URL stops resolving (check-urls)

EJ Fox · 2:52 PM

7933abdcontent

content: re-publish how-i-built-coach-artie

EJ Fox · 2:33 PM

OCT 21, 2026

e9628b2a11y

a11y: dark-mode zinc-500 one notch lighter (contrast 4.35 → 4.6:1)

EJ Fox · 5:42 PM

beca81fother

/stats goes live: background refresh with a visible "updated" flash

EJ Fox · 2:41 AM

294f112other

/stats: hydrate sections on scroll, skip offscreen layout, defer 700KB fetch

EJ Fox · 2:03 AM

OCT 20, 2026

9b8416aother

/calendar quick slots: full-width rows on phones instead of a cramped 3-up

EJ Fox · 5:02 PM