Chapter three · Days 9–15 · Mar 3–9, 2026
An AI will happily generate a screen that looks like every other screen it has ever seen. Getting something with a soul requires the one thing the model doesn’t have: your taste, applied relentlessly.
The traditional loop is: design in Figma, then implement. I tried it for exactly two days and abandoned it, because a strange thing had become true: SwiftUI, with live previews, is now faster than Figma for a solo builder. The AI turns a design idea into running UI in about ninety seconds; the preview renders it instantly; on-device it takes one build. When the medium is that cheap, you don’t sketch - you iterate in the real material.
The risk is obvious: iterate without a destination and you get a screensaver, not a design. So before generating a single screen I spent one evening writing a design brief the AI could be held to - the aesthetic constitution of the app. This is the part people skip, and it’s the part that shows.
❯ Before we design any screens, write the design brief for Kilnfolk with me. References to hold in mind: the Weight Watchers app's clarity (not its palette), Things 3's restraint, and the physical world of the user: stoneware, index cards, kiln shelves, pencil. Editorial, warm, paper-like. Not playful. Not corporate. Define: (1) three adjectives the UI must never betray, (2) colour: max 5 tokens, derived from clay/ash/glaze, (3) type: Apple system serif for display, SF Pro for body - sizes and weights only, no custom fonts in v1, (4) spacing: an 8-point scale, generous, (5) one signature detail that makes it unmistakably Kilnfolk. ⏺ …proposed a subtle "sgraffito line" - a hairline scored through headers, like a needle tool through slip - as the signature detail. It ships in the app today. Judges on r/Pottery noticed it in the first screenshot thread without being told it was intentional.
The brief became code before any screen did: a single Theme.swift file with 18 tokens. This one file paid for itself a hundred times - every later prompt could say “use .kilnSurface” instead of re-describing a colour, and the AI stopped inventing new shades of beige behind my back. Constraining the AI’s palette is how you stop vibe-coded apps from looking procedurally generated.
enum Kiln { // surfaces static let paper = Color(#F7F3EC) static let card = Color(#FFFDF8) static let ink = Color(#221E1A) // accents - from the studio static let clay = Color(#B4502E) // terracotta static let ash = Color(#8A857C) // wood ash static let celadon = Color(#7D8B6F) // success static let shino = Color(#C08A3E) // warning // the signature detail static func sgraffito() -> some View { Rectangle().fill(ash.opacity(0.5)) .frame(height: 1) .padding(.top, 2) } }
The firing detail screen - the screen a potter sees at 11pm when the kiln lid opens - took twenty-three iterations across four evenings. Not because the AI is bad at UI, but because I was calibrating my own taste against its output. The arc:
The lesson: iteration count is not failure. It is the design process. Vibe coding just compresses the cost of each round to minutes.
Four moves, in ascending order of power:
Taste is the one part of vibe coding that doesn’t get automated. It’s the whole job description now.
The taste pipeline: aesthetic constitution (one page) → tokens in code (one file) → generate screens against references, not adjectives → critique by hierarchy (“what’s the hero?”) → thumb-test on device. And log your iteration count. If it’s under five per important screen, you’re accepting first drafts.