Design Generation
SkillMediaGives your agent a design Claude skill for turning prompts or screenshots into working interactive HTML page prototypes.
Available today. Use it from your connected AI after setup.
No other account needed.
Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
Then ask your AI: use the Design Generation skill
About this skill
Generate or refine complete interactive HTML prototypes in Design. Use when creating screens, variants, Alpine/Tailwind prototypes, tweaks, or visual refinements from a prompt or selected design.
What this skill tells your AI
The instructions your AI receives, as published by builderio/agent-native in templates/design/.agents/skills/design-generation/SKILL.md and read by ahel’s review.
How to generate complete, interactive HTML prototypes using Alpine.js + Tailwind CSS (via CDN). This is the core skill for the design agent.
Technology Stack
Every generated design uses:
- Tailwind CSS v4 — via
@tailwindcss/browser@4CDN (NOT the old v3 CDN) - Alpine.js 3.x — via
alpinejs@3.15.11CDN withdeferattribute - Google Fonts — for distinctive typography (never Inter/Roboto/Arial)
- CSS Custom Properties — for theming and tweaks panel integration
Why the workflow exists — it is the anti-slop engine
Generic output ("AI slop") is a workflow failure, not a lack of talent. When one prompt has to set the taste, explore the options, and emit final code all at once, the safest answer is the statistical average of the training data: Inter, an indigo→violet gradient, a centered hero, three rounded icon cards. Design beats this by splitting those jobs across the tools — use them in order, don't collapse them:
- Direction —
show-design-questions(or a stated thesis) sets taste on purpose. - Exploration —
present-design-variantscompares genuinely different directions before committing to one. This step kills sameness; never skip it for open-ended work. - Spec — a linked design system and the
:roottoken block capture the chosen look as reusable rules. - Code —
generate-design/edit-designexecute a decision already made instead of guessing.
Jumping straight to code is how you get slop. Let the phases (below) do the work.
First decide the mode: reproduce or explore
The workflow above assumes an under-specified prompt. When the user has already specified the design, that same workflow is the failure — exploration reads to them as "the agent ignored everything I gave it".
Before Phase 1, check for specification signals:
- an attached screenshot, mockup, or photo of a UI,
- a linked design system / Brand Kit,
- a written outline naming concrete screens, sections, components, or copy,
- a named existing product/page to match, or pasted markup or tokens.
Any one of these puts you in reproduce mode. In reproduce mode:
- Do not call
present-design-variants. Three divergent directions when the user handed you one is not exploration, it is discarding their work. Produce the one thing they specified. - Do not call
show-design-questionsabout anything the supplied material already answers. Ask only about a genuine gap, and prefer stating an assumption over asking. - Every "Do" in the aesthetic quality bar below is off wherever it would contradict the supplied material. Those rules break ties in the absence of a spec; they never outvote one.
- Reproduce first, improve second. Match the structure, then raise quality within it, and say what you changed and why.
Mixed input is normal: reproduce what was given, use the quality bar only for the parts genuinely left open. When a supplied reference and the linked design system disagree, follow the design system for tokens (color, type, spacing, radius) and the reference for layout and composition, then say you did.
A reference screenshot is a specification, not a mood board
When the user attaches an image of a UI, read it as a layout spec and reproduce it: the same regions in the same positions, the same navigation pattern, the same information hierarchy and density, the same component grammar (tabs vs. pills, cards vs. rows, sidebar vs. topbar), the same approximate proportions. Name what you see before you build, so the user can correct a misread early. Deviate only where the image is genuinely unreadable or an explicit instruction overrides it — and say which, rather than silently substituting your own composition.
An attached image is only guaranteed to be visible on the turn it arrived. If a screenshot was described earlier in the thread but you cannot see one now, say so and ask for a re-attach — never quietly design from the text alone.
Authority and direction record
Before generating, make a compact direction record: the job this surface must do, its audience, one-sentence visual thesis, the active design-system id or token source, approved references, and any unresolved choice that could change the result. This keeps a strong point of view without asking the model to fill in the user's intent silently.
Resolve visual authority in this order:
- The current-turn product, audience, content, accessibility, and explicit brand constraints.
- The active Agent-Native design system and its registered tokens, components, type, imagery rules, and custom instructions.
- Approved Creative Context assets, components, and examples.
- Impeccable-inspired quality heuristics for hierarchy, subtraction, composition, contrast, motion, and bounded review.
- Generic defaults only when the sources above are absent.
The active design system is a contract, not a mood board. Do not swap its palette, fonts, component grammar, or imagery policy because a generic anti-pattern list prefers something else. A user can explicitly request a replacement or detachment; do not infer that request from a vague adjective. References can guide composition and narrative, but they do not silently transfer their tokens or brand identity.
When the source is a transcript, meeting note, or pasted brief, treat it as evidence rather than a finished story. Preserve the user's terminology and exact claims, separate facts from interpretation and visual references, and ask one targeted question or mark an assumption when a missing choice would change the design. Never smooth an evidence gap into confident copy.
Aesthetic quality bar — beat distributional convergence
The rules in this section are fallback quality heuristics for prompts that leave the look open. They do not override an active Agent-Native design system, a supplied reference, or an explicit brand constraint. A banned item stops being banned the moment the user's own material specifies it — if their Brand Kit's body font is Inter, the design ships Inter; if their screenshot is a centered hero with three icon cards, the design ships that. Substituting a "better" choice for a specified one is the single most-reported failure of this app. When you follow a specified value that appears on a "don't" list below, just follow it — no apology, no note, no compensating flourish elsewhere.
You sample toward the "on-distribution" center by default; refuse it. Every "don't" here carries a "do" — a banned default plus where to go instead — because banning Inter alone just makes you reach for Roboto next. Use a banned item only if the user explicitly asks, or their design system or reference already uses it.
- Fonts. Don't: Inter, Roboto, Arial, Open Sans, system-ui. Do: a distinctive Google Font pairing matched to the chosen aesthetic (see the table) — editorial serif, grotesk display + mono, or one variable font pushed across weight extremes.
- Color. Don't: the indigo/violet slop palette (
#6366F1,#8B5CF6,#A855F7), a purple gradient on white, or everything in default grays. Do: anchor on one non-default family — clay/ochre/terracotta, ink/bone/mustard, charcoal/lime, oxblood/cream, navy/copper, warm paper (#FBF7F0) over pure white — with one decisive accent used sparingly for hierarchy, not decoration. - Layout. Don't: centered hero + one CTA + a row of three icon cards,
rounded-everything,
0.1-opacity drop shadows, blanket glassmorphism, or the badge-above-headline cliché. Do: asymmetric 60/40 or 70/30 splits, uneven visual weight, one clear focal point, and flat confident surfaces. - Background. Don't: a single flat fill. Do: layered gradients, a geometric pattern, grain, or a contextual texture that matches the theme.
- Copy & voice. Don't: lorem ipsum or buzzword filler ("empower", "seamless", "leverage", "revolutionize", "in today's fast-paced world"). Do: realistic domain content in a specific voice — copy is design material.
Second-order convergence is real. Even your "creative" picks converge (Space Grotesk everywhere; teal accent + blinking dot + left accent bars). Vary deliberately across generations so two designs never share a fingerprint — but only across designs you had to invent. A token the user's own system specifies is theirs, not your fingerprint: consistency with their brand is the goal, and varying away from it to avoid repeating yourself is a bug.
Principles to quote back while building: color creates hierarchy, not decoration · density over decoration · earn every animation · commit to one point of view. Match code to the vision — maximalist themes want elaborate motion and effects; minimal themes want restraint and precise spacing. Elegance is executing one vision fully.
References beat adjectives, but only with a reason. "Linear: the quiet confidence of its spacing" or "Stripe: dense but never crowded" points somewhere specific; "Linear" alone collapses back to the average, and replying to your own output with "make it cleaner / more premium" means you're negotiating with vibes.
Prompt the design in four layers
Decide each layer explicitly before writing HTML. This is what makes variations genuinely distinct instead of three near-identical layouts:
- Context — audience, domain, and the one job this screen must do.
- Structure — a named layout topology: bento grid, sidebar app shell, editorial column, split-screen, masonry, dashboard tiles.
- Aesthetic — a named visual movement: editorial serif, neo-brutalist, glassmorphic, Swiss/International, warm organic, technical/mono, etc. Each variant gets a different aesthetic + font pairing.
- Tech stack — Tailwind v4 + Alpine, mobile-first, light/dark via tokens.
Push each dimension to extremes rather than safe middles: weight extremes
(100–200 vs 800–900), 3×+ type-scale jumps, one dominant color + a single sharp
accent, layered gradient/pattern backgrounds (not flat fills), and one
orchestrated staggered page-load reveal (via animation-delay).
Pick a preset by projectType:
- Brand / marketing (landing pages, decks): expressive, atmospheric, animated, full-bleed.
- Product / app (dashboards, tools): dense, restrained, token-driven, fast.
Measurable rules (bake these in)
- 8px spacing grid — all padding/margins/gaps are multiples of 4/8.
- Absolute
left/topare whole pixels, and multiples of the screen'slayoutGrid.sizewhendesign-selectionreports one. A fractional or off-grid position reads as a mistake to a designer and does not match what dragging the same element produces. Set a screen's grid withset-layout-grid. - Body text ≥ 16px, labels ≥ 12px.
- Big type-scale jumps for hierarchy (don't rely on tiny size deltas).
- WCAG contrast: 4.5:1 normal text, 3:1 large text. Verify accent-on-background.
- Mobile-first breakpoints; never ship a layout that breaks under 640px.
- No arbitrary one-off Tailwind values where a scale step exists.
- Token grounding is non-negotiable: every color/font/radius references a
:rootCSS variable. Never hardcodetext-white/bg-black/ hex literals in the markup — that's what keeps brand + multi-screen consistency automatic.
Type-scale recipe
Use this as a starting scale, then adjust to the chosen Aesthetic:
- Display: 56-96px · H1: 40-64px · H2: 28-36px · Body: 16-18px · Caption: 12-13px.
- Each adjacent step should be at least 1.25× the one below it — smaller jumps read as "almost the same size" rather than a deliberate hierarchy.
- A hero/display line should be at least 3× the body size.
- Line-heights: display/H1 tight at 1.05-1.15, H2/H3 at 1.2-1.3, body relaxed at 1.5-1.7.
- Measure (line length) for body copy: 60-75 characters; constrain with
max-widthinchunits, not a raw pixel guess.
Section rhythm
Pick one section padding value and repeat it for every top-level section on the page/screen: 96-128px on desktop, 48-64px on mobile. Don't let each section invent its own padding — that's what makes a page feel unplanned. Use spacing to encode grouping: gaps inside a card or cluster should be visibly smaller than the gap between cards/sections — if inside-group and between-group spacing match, the eye can't tell where one group ends and the next begins.
Verifiable contrast pairs
Don't just assert "WCAG AA" — check the actual token pairs the design ships.
The most common real failure is muted text (--color-text-muted) directly on
a card/surface background rather than the page background; verify that pair
specifically, not just text-on-page. If an accent color doubles as text (a
link, an active nav item, a price), it usually fails 4.5:1 against typical
surfaces — add a separate --color-accent-text variant tuned for text-on-
background contrast rather than reusing the decorative accent for copy.
Richer tokens
Go beyond the minimal :root block in the HTML Structure Requirements below
when the design needs it — add --space-section (see Section rhythm),
--color-border, --color-accent-text (see contrast pairs above),
--shadow-card, and a success/warning/danger trio
(--color-success / --color-warning / --color-danger) once the design has
status states, alerts, or form validation to express. Keep font tokens as
placeholders you fill per design (see HTML Structure Requirements) rather than
hardcoding a concrete family in a shared template.
Building on existing code, screens, or a design system
When a design system, tokens, current screens, or a connected codebase already exist, the slop risk flips: the failure is ignoring the brand and reverting to defaults. The banned-defaults list above still applies, plus:
- Inspect before inventing. Read the linked design system, the current
:roottokens, and existing screens (or the connected localhost/repo) first. Derive the type scale, palette, radius, density, and component language from what is actually there — don't restate a generic direction. - Treat every reversion as a missing spec entry. If output drifts to a
default (Inter, pill buttons, a stock radius) despite the brand, don't just
re-prompt — pin the explicit value into
:rootso it can't drift again. - Consistency is not sameness. Tokens alone make every screen "the same in your colors". Keep structure and layout genuinely varied per screen while the palette, type, and components stay on-brand.
Generation Application State
design-generation-session:<designId>— multi-screen generation planning state fromgenerate-screens(canvas region assignments, per-frame instructions consumed bygenerate-design).show-design-questionsopens pre-generation questions in the main canvas (show-questionsstate).guided-questionsmay hold a one-click chat choice for the current variant set.
Generation Workflow — the canonical 5-phase flow
This flow mirrors Claude Design's UX: clarify only what's unclear → show variants → user picks → refine. Don't collapse phases into one shot for new, open-ended designs.
Creative-context gate
Before Phase 1, read the creative-context skill and retrieve components,
interaction examples, visual style, and factual evidence as separate roles.
Respect contextMode: "off" and pinned packs. Apply its reuse ladder exactly:
use an approved native component/template/asset unchanged, compose approved
pieces, lightly adapt a real example, generate from narrowly retrieved
references, then generate net-new only when the relevant corpus is empty.
Retrieval is a separate operation from generate-screens, generate-design,
or present-design-variants.
Keep the selected immutable contextPackId and reuse labels on the generation
session and every resulting screen/variant. Rendered HTML and screenshots are
not provenance. App-local design systems and components remain the fallback
when shared retrieval finds no relevant evidence.
Phase 1 — Create the project + ask before generating
pnpm action create-design --title "Project Name" --projectType prototype
pnpm action navigate --view editor --designId <returned-id>
The navigate step is only for first-party/local app agents that can write
application state. External MCP hosts should surface the create-design
returned "Open design" link, then use present-design-variants to open the
visual picker.
Then, for a brief or ambiguous first prompt to a new design, call
show-design-questions BEFORE generating. The editor renders a full-canvas
overlay; answers come back as a chat message. Size the question count to how
much is actually unresolved — most prompts warrant 2-4 questions, not the full
1-8 range — and never ask about something the prompt already specified (a
stated color, audience, or layout is settled; don't re-ask it as a choice).
Skip the questions entirely when:
- the prompt is already specific enough to generate from (names the audience, purpose, and a visual direction, e.g. "a dark, data-dense analytics dashboard for ops engineers" or "re-skin this with my brand colors");
- it's a tweak/edit/refinement to an existing design rather than a new one —
go straight to
edit-design(see Phase 3 and "Making edits" below); - the user already answered a question set for this design and is now iterating — don't re-ask settled ground on follow-up prompts for the same design; or
- the user says "decide for me," "surprise me," "just build it," or similar.
The turn that opens show-design-questions already checked Creative Context
and any published Brand DNA before this skill loads, and the directives it
built name exactly which topics (form factor, aesthetic direction,
features/content, interactions/polish, exploring variations) are already
answered. Never re-ask a topic those directives list as covered, and never
skip a topic they don't — a single unrelated context member (a doc, a spec)
must not suppress a question it has no bearing on.
Asking on every prompt is as much a failure mode as never asking: a detailed prompt that already answers the obvious questions should generate immediately, and a design already in flight should not be interrupted with a second questionnaire.
pnpm action show-design-questions \
--designId "<id>" \
--title "Quick questions about your todo app" \
--questions '[{"id":"form_factor","type":"text-options","question":"What form factor?","options":[{"label":"Desktop web app","value":"desktop"},{"label":"Mobile app","value":"mobile"},{"label":"Both / responsive","value":"responsive"},{"label":"Decide for me","value":"decide"}],"allowOther":true}]'
Favor choice-first questions (2-5 concrete options, allowOther: true, and a
"Decide for me" option when any answer is acceptable) over open-ended
freeform text, and avoid multiSelect unless the question genuinely allows
combining multiple answers — stacking multi-select questions multiplies
follow-up ambiguity instead of resolving it.
Carry the form-factor answer through to generation — do not just ask and discard it. Map the answer to the design's device SET, not to separate per-device screen files. Device widths of the SAME page are breakpoint frames of one document (see the responsive-breakpoints skill), never a mobile.html + desktop.html pair. Pass the answer through generate-design's devices param — ("mobile"|"tablet"|"desktop")[], default ["desktop","mobile"]:
- If the prompt/answer names specific devices, generate EXACTLY those, deduped ("mobile" only → one mobile frame; "mobile, tablet, desktop" → all three).
- If nothing about form factor is specified — or the answer is "Both / responsive" or "Decide for me" — default to
["desktop","mobile"]: a Desktop base + a Mobile frame only. Never auto-add a tablet, a redundant desktop, or a stray duplicate frame.
The WIDEST requested device is the base/primary frame; narrower devices become breakpoint frames (never at the primary width). Device frame sizes: mobile 390×844, tablet 768×1024, desktop 1440×900. present-design-variants still takes explicit width/height per variant to size its exploration screens (see Phase 2).
Phase 2 — Generate side-by-side variations (2-5, three by default)
Skip this phase entirely in reproduce mode (see "First decide the mode" above) — a screenshot, a written outline, or a linked design system means the direction is already chosen, and offering three alternatives to it is the behavior users report as "the agent ignored my design".
For new designs whose direction is genuinely open, default to three
variations (present-design-variants accepts 2-5; three is the sweet spot).
Call present-design-variants for both first-party and external MCP-host
flows. It saves each candidate as a normal
overview-board screen, then renders an inline chat choice with one button per
screen name.
{
"designId": "<the design id>",
"prompt": "Pick a direction",
"variants": [
{ "id": "a", "label": "Editorial Serif", "width": 1440, "height": 900, "content": "<!DOCTYPE html>...full self-contained HTML..." },
{ "id": "b", "label": "Bold Brutalist", "width": 1440, "height": 900, "content": "<!DOCTYPE html>..." },
{ "id": "c", "label": "Soft & Spacious", "width": 1440, "height": 900, "content": "<!DOCTYPE html>..." }
]
}
Each content is a complete, self-contained document (Alpine.js + Tailwind via CDN, full <head>, CSS variables in :root). Variations should be structurally and compositionally distinct — different layout grammars, hierarchy, density, and focal points — never just color swaps. When a design system is linked, keep its tokens, typography, components, and imagery rules fixed across variants; vary those only when the user explicitly asks to explore a replacement system. Label the directions with concrete names ("Editorial split", not "Variant A").
Pass width/height on every variant to match the form-factor answer (mobile ≈ 390×844, tablet ≈ 768×1024, desktop ≈ 1440×900) — the example above is desktop-sized. When content is omitted, present-design-variants infers a size from the prompt/label/description text and the width/height you pass still wins when given.
Wait for the user's pick before refining. Once they choose, keep the selected
screen, delete the unchosen variant screens with delete-file, and continue
from the kept screen by calling get-design-snapshot with the selected
screen's fileId, then calling edit-design on that same fileId. Use
mode: "replace-file" when expanding the representative placeholder into the
full chosen direction. Do not call generate-design after a variant pick. If
inline chat choice buttons are unavailable in the host, ask the user to tell you
the preferred screen name. Do not ask them to paste HTML or a generated handoff
summary; the variants are already real screens on the board.
Phase 3 — Save with generate-design (when not using variants)
Skip variants and call generate-design directly for: a brand-new first
renderable file, multi-screen additions to an existing design, or one-shot
prompts where the direction is unambiguous. For refinements to an already-picked
design or selected screen, use get-design-snapshot followed by edit-design
instead.
pnpm action generate-design \
--designId "<id>" \
--prompt "Description of the design" \
--files '[{"filename":"index.html","content":"<full HTML>","fileType":"html"}]' \
--tweaks '[{"id":"accent","label":"Accent","type":"color-swatch","options":[...],"defaultValue":"#0EA5E9","cssVar":"--color-accent"}]' \
--devices '["desktop","mobile"]' \
--canvasFrames '[{"filename":"index.html","x":0,"y":0,"width":1440,"height":900}]'
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 7k
- Forks
- 613
- Last commit
- Sep 2026
Advanced
- Item type
- skill
- Key
design-generation- Source
- github.com/builderio/agent-native