← home

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.

A few of the monochrome design mockups ChatGPT generated from the brief.
a few of the options — I picked the simplest one

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:

layerchoice
frameworkSvelteKit
stylingTailwind CSS
highlightShiki (build-time)
hostingCloudflare

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:

  1. Svelte — the framework
  2. ChatGPT — the first sketches
  3. Claude Code — the build

Video embeds work too — loaded lazily and framed like the images:

an embedded video

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.

© 2026 ekkx