project
building this site
2026.05.24
This is the first note on the site, so I want it to be about the site itself: why I made it, the decisions along the way, and how it was built.
the brief
I didn’t want much — one place for the things I make and the things I think about, kept simple. I wrote down what I wanted before writing any code:
- minimal and monochrome: black, white, and grey
- a portfolio and a blog in one, shown as a plain list
- thoughts, creative work, and finished projects in the same place
- no left/right panels — the list of posts is the first thing you see
- a simple header, with a bar that reacts to the music that’s playing
- each post showing a title, a genre, a date, and a small generated thumbnail
I like things that are simple, essential, and effective. That’s the whole idea behind the design.
drawing it first
I’m not a designer. I’m a full-stack engineer who mostly works on the backend, and I’m not sure I have a good eye for visual design. So before writing code, I gave the brief — almost word for word — to ChatGPT (with Images 2.0) and asked it to suggest a design. It gave me a few options, and choosing between options was much easier than starting from nothing.
why svelte
Two reasons: it’s simple, and it’s fast. I’d had enough of how much hidden behaviour React expects you to keep track of, so I tried Svelte, and I stayed with it. (An earlier site of mine, which I later dropped, was also Svelte, so some of it was familiarity.) It also prerenders to static HTML easily, which fits a site that’s mostly text with a bit of artwork.
The stack stayed small on purpose:
| layer | choice |
|---|---|
| framework | SvelteKit |
| styling | Tailwind CSS |
| highlight | Shiki (build-time) |
| hosting | Cloudflare |
built by claude code
I didn’t write the implementation myself. I gave the whole build to Claude Code (Opus 4.7) and made the decisions: the brief, the design choices, and a lot of small adjustments — smaller here, lighter there, match this animation to that one. I care about UI and UX, probably more than most people do for a personal project, so I spent most of my attention on the details.
a weekend
The whole site was built over one weekend — two days, about eight hours in total. The agent works so fast that my time went mostly to two things: deciding what I wanted, and checking that the result worked. Sometimes I wonder whether reviewing every line of code by hand is on its way out.
There’s also an upside I didn’t expect. When you can build something this quickly, it’s much easier to stay motivated and actually ship it — the distance between an idea and a working site gets very short. Agents becoming common will bring good and bad, but that’s for another post.
the sound
The bar under the wordmark isn’t just decoration — it reacts to whatever is playing in the small player, so feel free to press play. The first track is me playing one of Rachmaninoff’s Études-Tableaux (Op. 33): I played it in as MIDI, rendered it with the Hammersmith Free piano (a VST), and mixed it myself, so it’s close to a studio recording rather than a rough one.
Later I’d like the player to hold more than my own playing, including unreleased electronic tracks I make in a DAW. I want it to be a proper place for sound, not just a gimmick.
The interface makes sounds too, and none of them are recordings — they’re generated in the browser with the Web Audio API. Tapping something gives a short, soft click; dragging the player’s seek or volume bar makes a fine jijiji as the value changes. Both are short bursts of filtered noise, kept quiet so they feel incidental rather than like notifications.
what this thing can do
While I was here, I wanted to see what the blog can render. A quick tour.
Inline code works, and full code blocks get syntax highlighting and a copy
button:
<script>
let { level = 0 } = $props(); // audio amplitude, 0–1
</script>
<!-- the reactive underline beneath the wordmark -->
<span class="underline" style="transform: scaleX({Math.min(level * 2.6, 1)})"></span> Configuration is just a small object — adding a track to the player takes a few lines:
tracks: [
{
title: 'Rachmaninoff, Op. 33: No. 8 in G Minor. Moderato',
artist: 'ekkx',
src: '/music/rachmaninoff-op-33-no-8-g-minor-moderato.mp3'
}
] Lists, quotes, links, and tables all render in the same plain style. The tools I used:
- Svelte — the framework
- ChatGPT — the first sketches
- Claude Code — the build
Video embeds work too — loaded lazily and framed like the images:
That’s the site. I want it to stay small and change slowly. More notes — on software, on sound, and on whatever I’m working on — soon. If you’d like to follow along, there’s an RSS feed.