Engineer

I Have Zero UX Sense. So I Let Claude Code Design the Site.

Let me be honest with you: I have no UI/UX sense. None. Left to my own devices, I would ship a white page with black text, three broken margins, and call it “clean.” I’ve made peace with this.

What I do have is Claude Code, a clear opinion about Bauhaus aesthetics, and a willingness to iterate until something looks good. This is the story of how this site got built.


The Brief

The brief I gave was basically: “Bauhaus. Bold. Looks like an engineer built it on purpose, not by accident.”

The design system that came back has a name now. Five tokens:

--blue:   #1D3557   /* structural */
--red:    #E63946   /* accent, errors, heat */
--yellow: #F4A261   /* warning, decoration */
--black:  #111111   /* base */
--white:  #F1FAEE   /* off-white, easier on the eyes */

Three fonts: League Spartan for headings (geometric, authoritative), DM Sans for body (humanist, readable), Space Mono for labels and code (monospace, data-native). --unit: 8px as the spacing primitive — everything derived from it.

A background grid overlay at 2.8% opacity. A grain texture on top of everything at 3.8% opacity. The kind of details that make something feel considered rather than generated.

I didn’t pick any of those values. I described what I wanted. Claude Code made the decisions and I approved them. That’s the workflow.


The Features I Asked For

Bauhaus flanks — I wanted something in the margins on wide screens. “Cloud engineering inspired.” What I got: a VPC topology diagram on the left (circle gateway, subnet rectangles, EC2 instances, data bars) and an IAM identity pipeline on the right (IdP → IdC → role → session tags → resource). Both as inline SVGs, proportionally scaling with the viewport, gone entirely below 1700px.

I described the concept. I did not design the SVGs. I could not have designed those SVGs.

Audience selector — The posts are written for four different readers: engineers who want every detail, engineering leaders thinking about process, C-suite thinking about risk and ROI, and skeptics who don’t trust AI at all. The selector filters the post grid by audience. Non-matching cards reorder to the bottom — they don’t disappear, they just move. The preference is saved to localStorage.

I asked for this to feel like a toggle, not a search filter. The CSS order approach (not opacity, not display: none) was Claude’s call. It was the right call.

Scrolling ticker — The old meta strip said “AWS · Entra ID · Claude Code · Real builds. No fluff.” Static. Boring. I asked for something that scrolls, grows as the blog grows, and has actual personality.

What came back was 18 phrases generated from blog post tags:

YAML therapy for engineers · The AI intern that never sleeps · Who even are you, IAM? · Tag everything. Own the audit. · SSH keys are so 2015 · SCIM: not a typo · We broke AWS so you don’t have to · Red. Green. Refactor. Repeat.

I approved those with one edit. The ticker auto-grows — it pulls tags from all posts at build time, so new topics surface automatically.

Callout blocks — Inspired by an old HTML prototype I had. Error blocks for gotchas, principle blocks for conclusions, plain blocks for notable asides. The kind of visual punctuation that makes a long technical post readable.

Entra's federation metadata URL returns 12 signing certificates. IAM Identity Center silently fails with "Retry Failed Steps" when you upload it. That's what an error callout looks like. You notice it.

Pinned posts — One post should always be first regardless of date. Added a pinned: true frontmatter field to the content schema. Three lines of sort logic. Done.


The Part Where I Broke Mobile

Every single time.

I’d ask for something — flanks, callouts, wider content columns — and it would look great on desktop and then I’d check mobile and something would be overflowing or too tall or taking up too much space.

The audience selector buttons were a full-width stacked column. Fixed to a 2×2 grid. The meta strip was wrapping to three lines. Fixed with flex-wrap: nowrap; overflow: hidden. Callout blocks were blowing out the viewport width on mobile because grid children don’t shrink below their content width unless you explicitly set min-width: 0.

CSS grid children have min-width: auto by default. Set article { min-width: 0; overflow-x: hidden; } or your content will overflow on mobile whenever it's wider than expected. Every time.

The fix was always fast once the cause was known. The pattern was: check mobile, find the break, fix the CSS, confirm. The part I kept getting wrong was skipping the mobile check.


The Playwright Suite

After breaking mobile three times in one session, I asked for a full test suite so it would never happen silently again.

192 tests across desktop (1440px), tablet (768px), and mobile (390px). Every route. Every callout. The suite catches:

When a callout broke mobile, the test output told me exactly which one:

Callouts overflowing: The problem, Gotcha — Entra metadata has 12 certs, Conductor and Orchestra

That’s the right level of information. Fix it and rerun.

The suite runs in about 18 seconds locally. It lives in tests/layout.spec.ts. Run it before every deploy.


What I’d Tell Another Engineer

You don’t need design instincts. You need:

  1. A clear opinion about what you want it to feel like
  2. The ability to say “that’s not it” and “yes, that’s it”
  3. Enough CSS knowledge to understand why something broke
  4. A test suite that catches what your eye misses

Claude Code handled every design decision I couldn’t make — colour values, SVG geometry, animation timing, typography sizing, spacing ratios. I approved the direction and reviewed the output. The same model as everything else I build with it.

The site you’re reading was built this way. Every component, every layout rule, every pixel of those flank SVGs.

I have zero UX sense. The design system, the flanks, the ticker, the callout blocks — none of that came from me. What came from me was the brief, the feedback, and the judgment about when it was done.


The Playwright suite is in the repo. Run npx playwright test before you ship anything. It will tell you exactly what broke and where.