Skip to content
All posts
DevelopmentAI

September 30, 2026

5 min read

How I built this site: vibe coding and the "it works" trap

I built this site by describing it to an AI, not by typing code. The first version worked, but it wasn't right. The second started from a five-color palette and went through a review that raised forty findings.

#Vibe Coding#AI#Next.js#Design

I didn't write this site; I described it. I tell an AI model what I want and it writes the code; I steer, review and decide. That's called vibe coding: describing what you want instead of typing the code line by line, and managing what comes out. It sounds like a shortcut, and up to a point it is. This post is a record of where that shortcut paid off on this site, and where it fooled me.

01Version one worked

I built the first version with an older model. The foundation is the same today: Next.js, React and Tailwind, deployed on Vercel. There's no database; everything compiles to static HTML at build time, and each language has its own URLs. The site was live, it worked, and nothing looked off to me. When I went back over it months later, this is what turned up:

  • The design leaned on 2021-era trends: frosted glass cards and big, blurry yellow blobs drifting around the background.
  • Only three of the five colors in my palette were actually used.
  • A silent Tailwind bug meant opacity classes like text-foreground/60 were never generated. All the text that was meant to be secondary came out as prominent as the main text, and the submit button on the contact form had no visible background at all.
  • My profile photo was a small portrait sitting in the middle of a 1080×1080 grey canvas. So the round avatar and the favicon both showed a stamp-sized picture instead of a face.

Nobody noticed some of these for months, me included. The page looked fine. Nothing crashed; the mistakes just sat there quietly. The glass I did know about; I had even written in another post that it was a trend. Knowing, it turns out, wasn't enough to change it.

02Five colors, one file

In September 2026 I rebuilt the site, this time with a newer model: Claude. I gave it a Photoshop swatch file (.aco) with five colors in it and asked for a more modern site. That was the whole brief.

The colors: #F2F2F2 for the background, #D9D9D9 for light surfaces, #121212 for the dark background, #282828 for dark surfaces, and #FFEA67, a yellow, as the accent. The model parsed the binary file on its own and pulled the colors out. Then it noticed something: the yellow behind my portrait was #FEEA67, one step away from the accent. So the photo became part of the palette too.

03A constraint became a rule

Working with five colors came with a prohibition. Yellow text on the light grey has a contrast ratio of about 1.1:1; in practice, nobody can read it. So in light mode, yellow is never a text color. It's only ever a fill, and the text on top of it is always near-black. I didn't invent that rule; the colors imposed it. My part was not bending it.

The rest took shape inside that frame. Flat tiles replaced the glass cards; the typefaces became Geist and Geist Mono. The landing page moved to a bento-style layout, a faint dot grid went into the background, and the "AI" link column came back.

The word "modern" was in my request too, but it isn't what shaped the result. "Make it modern" is an open prompt; the gap gets filled with whatever patterns the model is most used to. Five colors gave it solid ground to stand on. A tight constraint did better than a wide request.

04Forty findings, thirty survived

Once the new design settled, I didn't call it done, because the first version had taught me something: "it works" and "it's right" are different things. I had several AI agents review the site at the same time, each from a different angle. Some went through both themes visually at widths from 320 to 1440 pixels, some measured accessibility with actual contrast math, and some checked the build and whether the code was correct. Then I asked separate agents to try to refute each finding.

Of forty findings, thirty survived that round. The other ten were knocked down, so the reviewers weren't always right either. Among the ones left standing were some plain bugs:

  • Blog dates caused a hydration error and showed the wrong day to visitors west of UTC.
  • The navbar broke at exactly 768 pixels; the Turkish menu labels are longer than the English ones.
  • The mobile menu didn't close when you tapped outside it.
  • Because of CSS class order, the form's error borders never showed up in light mode.

None of these jump out when you glance at the page, but every one of them reaches a visitor sooner or later. Asking an agent to prove something wrong is a lot cheaper than hearing about it from a visitor.

05Where my job went

With vibe coding, I'm not the one typing the code; that part really is gone. But the work didn't disappear; it moved. My time now goes into deciding what's good, putting the right boundaries in front of the model, and verifying what comes out.

The model is fast. When it's wrong, it's wrong just as fast and just as confidently, and its mistakes look perfectly fine. An invisible button background or an error border that never shows up in light mode doesn't give itself away. Everything on the screen is in place. It just isn't right.

Vibe coding doesn't remove the need to understand what you ship. I may not type the code, but the domain has my name on it. A line I don't understand is a decision made in my name that I never made.

The site is better now; it isn't finished. If you spot a bug, write to me. The submit button on the contact form is visible these days.

Share

Written by

Ömer Öztürk

On my personal channel I share my inner monologue; on my AI channel, generative AI, vibe coding and the ventures I build with AI.

Related posts