Chapter 6 of 14

Giving Freddy a Face

The Capture and Browse screens get real styling — and the chapter's big idea: an agent that can see the UI it builds stops needing you as its eyes.

The problem

UI work with a blind agent is dictation: "the tag pills overlap the textarea on narrow screens" … "no, now there's too much padding" … "the button is vertically misaligned with the input." You are a human OCR layer between the browser and the model. It works, but it's slow, lossy, and exhausting — visual problems described in prose lose most of their information.

The hard way

Beyond the dictation loop, blind UI work has a second failure mode: the agent styles by statistics. It writes Tailwind that is plausible — and the page renders as generic AI-slop: three shades of gray that almost match, spacing that jumps between scales, focus states forgotten. Nothing is wrong enough to name, everything is slightly off.

The Elyra way: install design-tools

/ext

Select design-tools, /reload. Four tools arrive; three carry this chapter:

  • screenshot_url — screenshots any URL (localhost and .test domains included), returns the image into the conversation for the model to analyze, and reports browser console errors alongside.
  • design_diff — before/after comparison of two screenshots; flags unintended visual regressions.
  • design_system_check — static Tailwind consistency analysis: mixed spacing scales, off-palette colors, missing focus states.
Freddy lives in a Grove-parked folder, so he's already served at https://freddy.test — a real URL the screenshot tool can hit. Any dev server URL works the same way.

The Capture screen

Brief the look once, in plain language, with constraints:

> Style the Capture page: calm, minimal, ink-on-paper feel.
  One centered column (max-w-2xl), the capture box is the
  hero - large, autofocused, borderless until focus. Tag
  input below as small pills. Svelte 5 runes only. Stick to
  Tailwind's spacing scale and one gray palette. When done,
  screenshot https://freddy.test and evaluate your own work
  before showing me anything.

That last sentence is the whole chapter. The agent writes the Svelte, then — without you running anything:

The agent sees its own work

  screenshot_url https://freddy.test
  [screenshot captured - 1440x900]
  Console: 0 errors, 0 warnings

  Evaluating: the capture box reads as the hero and autofocus
  works. Two issues I'll fix:
  1. The tag pills sit flush against the textarea (gap-1);
     the composition needs gap-3 to breathe.
  2. Placeholder contrast is ~3.2:1 (text-gray-300) - below
     WCAG AA. Moving to text-gray-400.

  edit resources/js/pages/Capture.svelte
  Successfully replaced 2 block(s).

Read that again: the agent screenshotted its own page, found the spacing problem and an accessibility problem you'd have missed, and fixed both — in one turn, before presenting anything. The console line matters too: a Svelte hydration warning would have surfaced right there, not three chapters later.

Visual diffs when you change things

Next session you restyle the tag pills. How do you know nothing else moved?

> Screenshot the Capture page, then restyle the tag pills as
  outlined chips. Screenshot again and run a design diff -
  I want to know about anything that changed besides the
  pills.

  design_diff (before/after)
  Intended: tag pills are now outlined chips.
  Unintended: the form's vertical rhythm shifted 4px because
  the chip border added height - the capture box moved down.
  Fixing with h-7 on the chips to restore the baseline.

That 4px shift is exactly the class of regression that ships unnoticed and makes UIs feel worn over time. Caught mechanically, every time.

Design-system consistency

After the Browse screen lands (same workflow: brief, build, self-screenshot, fix), close the chapter with an audit across both pages:

> Run a design system check on both Svelte pages.

  design_system_check resources/js/pages/Capture.svelte
  design_system_check resources/js/pages/Browse.svelte

  - Browse.svelte:41 uses gray-500 for secondary text;
    Capture uses gray-400 for the same role. Unify on 400.
  - Browse.svelte:18 mixes p-4 and p-5 in sibling cards.
  - Both pages: focus-visible rings present. Good.

Two files in, and Freddy already has a de facto design system — enforced by a tool, not by memory. Add the verdicts to AGENTS.md ("secondary text is gray-400; spacing scale steps: 3, 5, 8") and every future page inherits them.

> Commit as "feat: capture + browse UI"

What you learned

  • "Screenshot and evaluate your own work before showing me" — add it to every UI prompt. The agent becomes its own first reviewer.
  • Console output rides along with every screenshot — hydration warnings and JS errors surface at the moment they exist.
  • design_diff after restyling catches the unintended 4px regressions that prose never mentions.
  • design_system_check turns taste into rules — then AGENTS.md makes the rules permanent.
  • Brief aesthetics with constraints (one palette, one spacing scale, one hero) — constraints are what keep generated UI from looking generated.
Next: in Chapter 7, tests that keep Freddy honest: Pest, test-gen, and /goal loops where the agent works until the suite is green.