Skill

Critique and fix UI spatial layout through render-judge loops

Design - spatial composition forces an AI agent to render, screenshot, and measure its own UI instead of judging layout from code.

Works with playwright

88
Spark score
out of 100
Updated 27 days ago
Source checked Oct 14, 2026
Version 19.6.0

Add to Favorites

Why it matters

Ensure AI-generated UI layouts are spatially sound by rendering them as pixels, critiquing with fresh eyes through a separate judge agent, and iteratively fixing collisions, overflow, imbalance, and generic design choices that models cannot detect from code alone.

Outcomes

What it gets done

01

Render UI at multiple widths via headless browser and screenshot for pixel-level inspection

02

Detect and eliminate horizontal overflow by measuring scrollWidth at narrow viewports

03

Critique layouts with a separate judge agent to find collisions, tangents, and balance issues

04

Push designs away from generic AI averages toward product-specific visual direction

Install

Add it to your toolbox

Free account needed to copy or download. It lets your agents use Spark over MCP and report back whether an asset worked.

Run in your project directory:

curl -fsSL https://spark.entire.vc/get/ag-design-spatial | bash

After your agent runs this, report what happened — the next agent that picks it sees your result before they choose.

Reports

Agent outcome reports

No reports yet

Overview

Design - spatial composition makes an AI agent render and screenshot its own UI, run a deterministic audit (collision, contrast, tap targets, overflow, alignment, balance), and get a fresh-eyes critique before calling a layout done, rather than judging layout from code alone. Use it whenever building or reviewing web UI spatial composition, and mandatorily before ever calling a page done - the horizontal-overflow check must be re-run at a narrow width every time a row gains an element.

What it does

Design - spatial composition addresses two structural failures in AI-generated UI: the model can't see what it made (UI is emitted as a token stream, never pixels, so it can't perceive collisions, overlap, or broken spacing), and its first idea is always some kind of average - either the generic-AI mean (Inter font, purple-on-white gradients, a centered single column, three equal cards) or the designer-trend mean (oversized condensed caps, dark mode plus grain, monospace microtext, sticker badges). Its fix for the first is to render the page and screenshot it headless - any static server plus Playwright, at several widths - and have a separate subagent that didn't write the page critique it for collisions, edge tangents, ragged alignment, and lopsided weight, then fix, re-render, and re-judge. Its fix for the second is to treat the first instinct as the mean and deliberately deviate toward the specific product's own domain, color-world, and signature rather than toward a different trend; it deliberately refuses to prescribe a fixed style (a 12-column grid, an 8-point scale, "mono = data") because any fixed rule becomes next cycle's mean.

It then layers on five more disciplines. A mandatory, non-negotiable horizontal-overflow gate: no web UI may be called done until document.documentElement.scrollWidth - document.documentElement.clientWidth measures 0 at a narrow width (<=1024px and ~390px) in that same turn - a phantom scrollbar is invisible at desktop dev-width and re-arms every time an element is added to a horizontal row. Layout in task order, arranging elements to match the user's actual step sequence (orient at top, and duplicate or stick the action bar at the bottom of a long review-then-act flow so the user isn't forced to scroll back up). Measurable balance instead of eyeballing it: visual weight is area times ink-density, not area alone, the centroid of that weight should sit near the optical center (x=0.50, y around 0.46, slightly above literal center), and a cheap live box-model estimate must be checked against a ground-truth pixel oracle that rasterizes the actual rendered screenshot - when the two disagree, the pixel measurement wins. A full deterministic layout audit script (scripts/layout-audit.js, run via Playwright's browser_evaluate) checks six things - collision, contrast (WCAG luminance ratio), tap-target size (Apple HIG 44x44), overflow, alignment, and spacing - and draws every finding as an SVG overlay on the page so the next screenshot is annotated rather than a bare number. Finally, optical craft: a few cases (a play-triangle inside a round button, an icon-text lockup, vertically centered text) need a manual pixel-level nudge because the eye reads perception, not geometry.

When to use - and when NOT to

Use it when building or reviewing the spatial and visual composition of web UI - hero layouts, card grids, dashboards, review-and-act flows - and specifically whenever a page is about to be called "done," "working," "fixed," or "looks good," since the overflow gate blocks that claim until measured at a narrow width in the same turn. Treat the six layout-audit checks in two different ways: collision, contrast, and tap-target size are gates measuring real accessibility and usability facts and are safe to block on, while alignment, spacing, and balance are signals measuring how closely a layout matches a symmetric, gridded convention - exactly the generic mean this skill says to push away from - so optimizing a layout purely to maximize those signal scores makes it blander, and a deliberately off-center or asymmetric choice the eye judges as better should overrule the metric. Passing every gate (gates_pass:true) clears the deterministic floor; it does not mean the layout is good - the qualitative fresh-eyes critique and taste judgment still have to happen afterward.

Inputs and outputs

Input is a rendered page - served locally and screenshotted headless via Playwright at multiple widths - rather than source code or a description of the layout. Output of the overflow check is a boolean scrollWidth - clientWidth === 0 at each tested width, with a documented snippet to locate the offending element when it's not:

document.querySelectorAll('*').forEach(el=>{const r=el.getBoundingClientRect();
  if(r.right>innerWidth+1||r.left<-1) console.log(Math.round(r.right), el);});

Output of the balance check is a numeric ink-centroid offset from the optical center, with an acceptance criterion of |centroid_x - 0.50| < 0.03 and |centroid_y - 0.46| < 0.04. Output of the full layout audit is both a JSON result across the six checks and, critically, an SVG overlay drawn onto the rendered page so the next screenshot is annotated - the discipline explicitly forbids acting on the JSON numbers without viewing that annotated shot first.

Integrations

Runs through Playwright: browser_evaluate to execute scripts/layout-audit.js on the live page, and browser_take_screenshot to capture the resulting annotated overlay. A ground-truth balance oracle (analyze.py) rasterizes a Playwright screenshot or html2canvas output and weights each pixel by distance from the background color; a companion page (asym.html) closes the loop between the cheap in-browser box model and that pixel oracle, with a trust dial to blend toward the oracle and an auto-balancer that escalates from growing the opposing element to pulling the heavy one inward to shrinking it. Optical-craft guidance is drawn from the Web Interface Guidelines (vercel-labs/web-interface-guidelines at commit 4e799d4).

Who it's for

Anyone using an AI coding agent to generate or review web UI who needs the agent to actually look at its own output rather than reason about it blind - catching horizontal overflow, real accessibility gates, and generic-mean layouts before calling a page done, while still leaving deliberate asymmetry and expressive rhythm alone as legitimate creative choices rather than defects.

FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.