Skip to content
Back to all cases

AI CASE

This portfolio

The site you are reading is the case itself. It started as a Lovable template, design and code now come out of Claude Code, the logo was generated, and work only reaches production after review. The admin I use to update it is part of the case too.

Published on Updated on

PERIOD
2026 - heden
USED
ClaudeVS CodeCanva

The problem

A portfolio that says I build with AI proves nothing. Anyone can write that. The only thing separating someone who does it from someone who talks about it is whether the thing you are looking at was made that way, and whether you can recount where it went wrong.

The approach

The site started from a Lovable template, and since the rebrand design and code come out of Claude Code. The logo was generated. Every proportion, from the slant of the letters to the width of the stem, is a parameter in a script. Change a parameter, run it again, and the favicon and the social preview follow automatically.

The site makes zero requests to external hosts. Fonts, icons and logos are local, and the visitor statistics are cookieless and load from the site's own domain. As a result no cookie banner is needed.

All work on the site happens in a staging environment and only reaches production after review. Since 26 August changes to the admin go live after Claude Code's own tests and a code review.

How it went

  1. Step 01 ·

    Starting from a Lovable template

    The site started on 27 July as a Lovable template. Two days later Lovable's bot added around 23 commits on top of it in a single day.

  2. Step 02 ·

    Own brand, written by hand in code

    Every Lovable prompt reopened the discussion about colour and layout, and every prompt cost credits. So I fixed my own brand identity and wrote the rebrand by hand in code, using zero Lovable credits. Since then the logo comes out of a script that I rerun whenever I want to change something.

  3. Step 03 ·

    To Vercel, live on its own domain

    On 30 July I left Lovable's hosting and moved the site to Vercel. The same day it went live on its own domain. In the same round I worked through feedback on the portfolio and added the timeline, photos, mobile sliders, SEO and visitor statistics.

  1. Step 04 ·

    Case pages in two languages

    On 5 and 6 August I separated the content from the code, into files that are checked during the build, so that an admin could write the text later. On 7 August the cases got their own pages in two languages and a fourth case was added. Claude Code rewrote the site copy in my voice, and in a blind round I picked four of the five rewritten fragments.

  2. Step 05 ·

    A mobile round and a security review

    Below 768 pixels the site got a fold-out menu, sections became accordions and buttons got larger touch targets. In the same round the site went through a security review.

  1. Step 06 ·

    My own admin goes live

    This site says work only goes live after review, so the same had to hold for my own admin. An off-the-shelf CMS was ruled out, because as portfolio work it proves nothing. Since 13 August my own admin runs at /admin, and nothing from it goes live without review.

  2. Step 07 ·

    An illustration for every case

    Until mid-August no case had an image, only small tool icons. On 16 August every case got an illustration in a hand-drawn style, on the overview and in the homepage teaser.

  3. Step 08 ·

    From admin to editor and page builder

    Between 16 and 26 August the admin grew into an editor with live preview, a block library and a page builder. Since 26 August changes to the admin go to production after Claude Code's own tests and a code review.

  1. Step 09 ·

    Redesign, rolled back and live again

    On 30 August a full redesign of the site and the admin went live before I had seen it. The same day it came off production on my instruction, and the design rounds happened on staging after all. I wanted the classic header back, then gave the go on version 6, and on 1 September that version went to production.

The result

Two languages, no external requests, and the content is separated from the code. All text sits in a separate file that is checked against a model during the build. If the content is wrong there is no build, and therefore no deploy. Since 13 August I have been updating the site through an admin of my own, without it being a code change, and by now that admin is an editor with live preview, a block library and a page builder. Since 1 September the site and the admin run on a completely new design.

What went wrong

Three mistakes are worth recounting, and they are exactly the point of this case.

While separating the content I put the validation in the place where the page reads its text. Neatly reasoned, and wrong, because that code also runs in the browser. So the entire validation library travelled along to every visitor. 58 kilobytes to check data that had long since been approved, on a site whose whole premise is that it loads not one byte too many.

It surfaced because I looked at what was actually in the output after the build.

Which is exactly why I found the same mistake again a day later, in a different shape. The case pages were new, and to fill the list on the front page I loaded every case. So the full text of every case, in both languages, sat in the file you download when you only open the front page. That was 68 kilobytes, of which 89 percent never reached the screen there. With every case still to come, that would only have grown. The front page now fetches only the titles and the summaries, and a case's text arrives when you open it.

The first time was a slip. The second time, within a week, was a pattern. My default is to send too much along because it looks tidier in the code.

The third mistake dates from 30 August. A full redesign of the site and the admin went live before I had seen it, while the agreement is that something like that first sits on staging and gets shown to me. The same day it came off production on my instruction. After a few design rounds, in which among other things I wanted the classic header back, I gave the go on version 6, and it has been live since 1 September.

Other cases