Aaron ButlerCreative Design

aaronbutler.com

The site you're on right now. A personal portfolio and living design system built with Next.js and Claude Code, spanning an interactive constellation landing, grouped case studies, a photography gallery, and a custom in-browser content editor.

RoleSr. Creative Technologist
Year2026
Skills
PRODUCTUI/UXLLMWEB
01
Overview

From Squarespace to my own stack

My portfolio site has bounced around a few different locations. I built my first coding it up in HTML and uploading through an FTP server and then finally moving over to Squarespace when it was time for a refresh. While I had more options on Squarespace it was still limited in regards to what I could do as a non-programmer.
Most recently I tried out Figma Sites. I liked it. I work in Figma extensively so being able to create wireframes and then publish them straight from Figma in one click made for a tidy ecosystem, and it was a step up from the Squarespace site. But Figma Sites was still young when I started working with Claude Code, and like any hosted builder it could only give me what it currently supported. Even while making progress with Figma Sites deep down I knew I wouldn't be able to get the site I wanted.
Once I got comfortable with Claude Code one of the first major projects I wanted to undertake was moving to a completely selfhosted, built and maintained personal website. I wanted to build the portfolio I'd always wanted instead of the one a builder would allow. I wanted total control: a place to exercise the creatively technical way I think and try any idea I wanted, with the only real limit being external cost. Hiring a front and back end engineer was always an option, but that would have meant scoping and freezing decisions up front to make good use of their time not to mention out of pocket expenses. Claude Code gave me a different arrangement. I could work at my own pace, for a fixed monthly fee, on the portfolio and every other project I had going at the same time.
The site, which you're on now, is live and has been evolving since March 2026. I'm not a programmer, but I've been a technically minded designer and problem solver my entire career. This has helped tremendously in working with Claude Code and AI in figuring out the right chain of questions to ask in order to get what I want built from this collaboration.
02
Challenge

A deliberate budget ceiling

I didn't want to spend much, if anything, on the website since it's main purpose was just a landing page for my portfolio and personal projects. So the whole thing needed to run on a tight, deliberate budget, with decisions weighed against cost from the start. What I pay for is the GitHub minimum and a Claude Max 5x subscription. Every other service the site touches is on a free account. Inside that ceiling I wanted maximum capability, which meant the budget wasn't a footnote to the design; it shaped the technical choices directly. static export, self-hosting where it was affordable, a token system that lets one change ripple across the whole site instead of being hand-applied. A lot of what the site is came out of getting the most I could without paying for more than I needed. I learned to appreciate constraints as a designer very early into my design career.
03
Process

Building the site

A token-driven design system

I wanted a real place to practice building and maintaining a token-driven design system, close to the industry-standard experience, but on my own terms. The site runs on a central token layer: ~170 variables in a single root block, used ~900 times across the stylesheet, the components, and the pages. Color and type are genuinely token-driven, so recoloring the whole site or retuning the type scale is a one-line edit that propagates everywhere. Spacing works differently. The tokens for it exist, but I barely used them: spacing is written directly, on a 4px grid with a reserved 2px half-step for smaller elements like chips. Typography runs on its own scale rather than being bound to the grid. It's token-based, not tokenized down to the last pixel, which is the honest version of what a design system looks like when one person maintains the whole thing. The tokens are the clear win: they're what let me change components site-wide with almost no effort and keep a consistent look and feel throughout.

Adding a light mode

The site started dark and stayed that way for months. Adding a light palette was the real test of whether the token layer had been worth the discipline.
It was. Light mode is ~50 overrides, not a second design system. The dark values are the default, and the light block only redefines what actually differs: surfaces, text tones, scrims, borders, and the accent colors. The other ~120 tokens inherit. That ordering matters more than it sounds. A token added later gets the dark value until someone deliberately gives it a light one, so the failure mode is "looks like dark mode," never "undefined."
Deciding what shouldn't change took about as long as deciding what should. Shadows stay dark in both palettes. So do the type scale, the spacing steps, the radii, the motion timings, and the expertise-pill colors, because those are brand values rather than surface-dependent ones.
Two things needed a real solution rather than a token. Logos with baked-in ink can't be recolored by CSS at all, so both variants ship and the palette picks one with a display swap: no JavaScript, no hydration risk. And the radial gradient sitting behind transparent logo marks had to go flat on light. On dark it does real work, lifting a white mark clear of a near-black field. On light there isn't enough range between the gradient and the surface for it to read as depth — it just reads as a rendering artifact.
The site is a static export, so there's no server to ask which theme a visitor prefers. An inline script sets it before first paint. Without that, every load flashes dark and then corrects itself.
The same work index rendered in both themes
Drag to wipe between themes. No per-component overrides — one set of token values swaps, and every surface follows.

Finding the look

Part of this adventure was trying out Claude Design, which was fairly new at the time, to see how well it handled rapid iteration. I started broad. I took a vertical screenshot of my entire LinkedIn resume and asked it to build a portfolio site for a Sr. Creative Technologist with product, UX, and game design experience. The results proved the approach worked, but the designs didn't click with me enough to run with. Deep down I knew I would never just go with what Claude put forth but use it as a jumping off point depending on how well it worked or not. After further back and forth Claude was able to sharpen what I actually wanted, and I moved on to the real work: the palette and the system. The palette I landed on I had built myself, using a Figma plugin to rapidly generate options by color theory (complementary, split, square, analogous, monochromatic, triadic) until I had a set I was happy with. From there I had Claude generate a bunch of design systems and wireframes using the system so I could see how the combinations worked together. I refined colors, fonts, styles, and components until it felt right. Once the palette and template were settled, Claude packaged up the system and I handed it to a fresh Claude Code session that would be responsible for building the site moving forward.
Figma stays the source of truth. I use Figma's MCP server to have Claude read my wireframes directly, and I run it in reverse too, exporting a near one-to-one version of a page or component back into Figma to keep iterating on it there.

Owning the pieces

This site has allowed me to stop relying on other people's platforms. I pulled my photography off Flickr and host it myself now. Every video on the site today is hosted on my own storage. Vimeo is where 4K files go, or anything that would benefit from giving the viewer resolution options, since bandwidth is where self-hosting gets expensive. That split is planned rather than in use, which keeps the running cost of the site where I want it. In-browser 3D model viewing was something I'd wanted to do for a while; when I got back into Blender the idea came back, so I had Claude research the options rather than assume it was possible, and the 3D solution it found is live on the site now. The collapsing page behavior was me wanting the kind of feature-rich front and back end I'd only ever gotten to build inside a company. I know what I want to achieve, and Claude was the piece that let me build and maintain these systems on my own.
3D models, viewable in the browser without leaving the site. To try out this feature check out the [Studio Alpha](/work/product-ux/ms-studio-alpha/) case study.
3D models, viewable in the browser without leaving the site. To try out this feature check out the Studio Alpha case study.

A constellation on the landing page

The landing page doesn't scroll. It's a field of stars that drift on their own, and connecting four particular ones lights them up as A, B, C, and D, my practice's initials, with the lines drawing themselves in. It works by tapping on a phone as well as by clicking. The design problem worth solving there was discoverability, since nothing on the page tells you to try it. The answer was to let the field occasionally connect a couple of points on its own, so a curious visitor sees something happen and works out the rest, and I can always raise the number of points if that turns out to be too subtle. The star field carries through the rest of the site as a background, but the game only exists on the landing page.
Early landing page prototypes: a drifting star field, no scroll.
Early landing page prototypes: a drifting star field, no scroll.
Connect four stars and they surface as A, B, C, D.
Connect four stars and they surface as A, B, C, D.
04
Outcome

A living sandbox

The site is live, and it keeps changing, which is the point. It does what I set out to do: a design system I own and maintain, my own media hosted on my own terms, and interactions I could never have built on a hosted builder, all running inside a budget I can name to the dollar. It's a sandbox, so nothing is final, and that suits me. When I want to try something, I try it.
This case study you're reading is rendered by the data-driven system a Claude Code session built, and an initial draft was written by a Claude AI case study session I created, handed off to the Claude Code site dev session and then further iterated on and rewritten as needed by me. That's a small recursion I'll admit to. I'm in the process of writing up my experiences working with Claude Code and AI so I can share the details of how this whole collaboration experience has been.