I spent a couple of busy days in New York for work last week. On the flight home to Seattle I pulled out my tablet, opened Claude, and decided to take a pass at cleaning up this site from seat 14A. By the time we were descending over the Cascades, a fourteen-commit refactor was built, tested, and pushed. When I got home all I had to do was pull and look it over.

Why the Connection Didn't Matter

In-flight wifi is famously bad, and mine was no exception. It didn't really matter. The agent wasn't running on my tablet — it was running in the cloud. My job was to type intent and read diffs, which is kilobytes over the wire, not gigabytes. Builds, tests, and commits all happened on a remote machine with a real connection to npm and GitHub. The latency that would have killed a local dev loop was mostly invisible, because the local dev loop wasn't local.

That's the part I keep thinking about. The place where your code runs matters more than the place where you type.

What Changed

Nothing in this pass was glamorous. It was the kind of cleanup you keep meaning to do and never quite get to.

Slimmer base layout. The base.njk template had grown into a wall of inline CSS and JavaScript. I pulled the styles out into assets/css/main.css and the lightbox and theme toggles into assets/js/lightbox.js and assets/js/theme.js. The template dropped from roughly 640 lines to 230, and the extracted files are now cacheable across every page on the site.

Feeds and metadata. Added an Atom feed at /feed.xml, a proper sitemap at /sitemap.xml, and Open Graph and Twitter card tags on every page. None of it is visible to a reader browsing the site, but it's the difference between a link looking like a raw URL when someone shares it and looking like an actual post with a title and image.

Modernized image pipeline. Migrated the blog image transform to Eleventy's eleventyImageTransformPlugin instead of the hand-rolled version it had before. Tightened the gallery pipeline too: deduped images that were getting optimized more than once, started reading real dimensions out of the source files, and got the build stats to report numbers that actually match reality.

The gallery page after the pipeline cleanup — same grid, cleaner machinery underneath.

Repo tidying. Moved the one-time migration scripts (Squarespace, Ghost, Eventide Academy imports) into scripts/migrations/ so the scripts/ root only contains things I still run. Dropped a custom slugify filter in favor of Eleventy's built-in one. Replaced blog.json and pages.json with .11tydata.js so the default frontmatter can use actual JavaScript.

The thing I kept noticing as the changes went in was how little of it was visible from the outside. The gallery still looks like the gallery. Posts still render with the same auto-grouped image grids and the same lightbox.

A blog post with an auto-grouped image grid — the pipeline was rebuilt underneath, the layout is unchanged.

The Loop

The rhythm of working this way on a plane was simpler than I expected. Describe the change. Let it run. Read the diff. Ask for an adjustment, or ask it to commit and move on. When the wifi dropped for a few minutes over somewhere in Montana, the agent just kept working — I came back to a finished task waiting for review.

By the time the flight landed, every change was built, tested, committed, and pushed. No half-finished branch. No "I'll pick this up tomorrow." When I got home I pulled main, spun up the dev server, clicked around the site, and confirmed everything still worked.

What I Learned

Cloud-backed agents decouple the dev loop from your connection. A flaky connection is fine if the only thing crossing it is text. I've been burned enough times by local builds failing on airplane wifi to install the wrong dep; running the whole loop on a remote machine sidesteps the problem entirely.

Cacheability is almost free if you pay attention. Moving inline CSS and JS into /assets was a small change with outsized caching wins — every page after the first one now skips a few hundred lines of duplicated bytes.

Small refactor passes compound. Nothing in this change was load-bearing on its own. Shorter templates, real plugins instead of hand-rolled transforms, cleaner script folders, deleted dead code. Put them all together and the codebase is meaningfully easier to work in the next time.

The commits are on GitHub if you want to see the diff.