Landing an AI-generated design as Vue SFCs
When a design arrives as a Claude Design "Send to Claude Code" bundle, a claude.ai artifact, or any HTML/React mockup, the goal is working Vue SFCs against PrimeVue + the active preset — not a literal port of the bundle. The bundle is reference material; the brand already lives in the preset.
This document is the canonical repo-side procedure. The design-handoff-build skill at .agents/skills/design-handoff-build/ carries the pre-flight checklists and forbidden-patterns lists that enforce the moves below.
Principle: the bundle is a requirements doc, not a visual spec
The Claude Design bundle (or any AI mockup) tells you what data is shown, what actions exist, what decisions the screen enables — the business intent. It does NOT tell you how to render it in OnRamp. The bundle's inline hex colors, custom shells, ad-hoc layouts, and density choices are a sketch, not load-bearing.
It is expected — and desirable — that the generated UI looks materially different from the bundle. The bundle's intent is what you preserve. The rendering follows the OnRamp design system + PrimeVue Aura conventions.
If you find yourself trying to match the bundle's layout structure exactly, stop. You're translating a wireframe instead of designing a product page.
The design decision hierarchy
Every non-trivial rendering decision walks a numbered ladder, stopping at the first step that gives a concrete answer. The canonical ladder — all six steps, in order — lives in .agents/skills/design-handoff-build/references/decision-hierarchy.md; walk it there rather than a copy here.
Two notes specific to this repo's current state:
- Golden references exist (see
conventions.md"Golden references") — read the one matching your screen's shape before generating. The canonical recipes inconventions.md(e.g. §4 for the tinted-icon-badge pattern,<Button :severity rounded text>) are the prose behind them; for shapes with no registry row yet (detail/edit, modal/drawer), the recipes do that step's work. - Sakai is inspiration, not law. It uses raw ramp utilities (
bg-blue-100 text-blue-500),!important(text-xl!), and<div class="card">— all forbidden in OnRamp. Translate Sakai's intent through OnRamp composites and severity primitives; never copy its markup.
Required moves (in order)
Pick the app and alias. This procedure targets org-admin →
app/ui-organization/(@/); it sets the active preset,cssLayer, and dark selector — see thecssLayerguardrail in.claude/rules/ui-design-system.md. A customer-portal screen is a Mode-2 migration — defer to/primevue+ui-customer-primevue, build underpages/v2/**, never the frozenpages/private/**; the org conventions here do not apply unmodified.Map every primitive to PrimeVue v4 BEFORE writing. Open the cheatsheet in the
design-handoff-buildskill (.agents/skills/design-handoff-build/references/component-cheatsheet.md) and walk the design — for every card, chart, filter, status indicator, tab, button, etc., pick the PrimeVue answer.If a primitive isn't in the cheatsheet, look it up via
@primevue/mcpfirst. Falling back:https://primevue.org/<component>.md. The pinned version is in.claude/rules/ui-design-system.md("Stack & PrimeVue v4 names").Hand-rolling is a failure mode. If you find yourself writing
<div class="card">or<svg>...<path d="M...">, stop — there's a PrimeVue component for that.Anything with truly no PrimeVue equivalent (e.g. some heatmaps) stays a custom composite under
app/ui-organization/components/composites/— never inline in the page file.Severity, never color names. Map every status/state to a meaning per the canonical severity vocabulary in
.claude/rules/ui-design-system.md("Severity is meaning, not intensity") —danger/warn/success/info/secondary/primary. Apply via:severity="…"on PrimeVue components, never a color name (severity="amber") and never a raw ramp utility (text-red-500,bg-amber-100— both forbidden). The severity → color resolution is owned by the preset; don't encode it here.Mock data rule — severity codes, never colors. Color values in mock data are severity codes only (
'danger','warn', etc.) — never token strings, never hex. The canonical prohibition (with the why and the grep pattern) isdocs/design-system/forbidden-patterns.md#3; charts resolve severity → color through thecomposites/chart/layer (conventions.md§5).Write the SFC in
<script setup>. Import PrimeVue components and use them directly — the active preset themes them. No:pt/:dtdefaults (only as named, commented escape hatches for specific gaps), no.p-*scoped color overrides, no.cp-prime-*classes, nouseOnRampTheme.Use tokens, never hex. Reference
--color-*for brand/neutral values andvar(--vendor-color)where vendor branding applies. For brand color in non-PrimeVue surfaces (SVG, JS color math), useuseOnRampBrandfrom@onramp/theme/onramp-brand.If a needed semantic is missing, fix it at the right layer. A brand value →
design-system/DESIGN.md+bun run tokens. An app-level semantic (page ground, severity palette) or deliberate deviation → the app preset (app/ui-organization/theme/preset.js). Never patch at the call site.Self-check against the forbidden-patterns list. Before declaring done, grep your output for the entries in
.agents/skills/design-handoff-build/references/forbidden-patterns.md. Raw ramp utilities, hex,!important, v3 component names, color stored as data — these must all be zero matches.Run
/design-handoff-evalon the output. Mandatory final step. The eval produces a structured drift report; surface findings and fix the high-priority ones (or explicitly flag and accept them) before declaring the task done.Browser-verify — run the light/dark/vendor-color checklist in
.claude/rules/ui-design-system.md. If you can't run the dev server this session, say so explicitly rather than claiming the UI works.
Prompt templates
Implement a design as org-admin UI:
Build
<feature>as a Vue 3.5<script setup>SFC underapp/ui-organization/. Compose on PrimeVue v4 components (auto-themed by the active org preset — no:pt/:dt, no.p-*scoped color CSS, no!importantutilities). Map every primitive via the cheatsheet at.agents/skills/design-handoff-build/references/component-cheatsheet.md. Color through:severityor semantic primeui utilities only — never raw ramp (text-red-500), never hex. Mock data carries severity codes, never token strings or hex. Run/design-handoff-evalbefore declaring done.
Land a Claude Design artifact:
Here's a Claude Design bundle for
<screen>. Treat the HTML as reference only. Emit Vue SFCs against PrimeVue + the active preset; map its primitives to v4 PrimeVue components via the cheatsheet; drop its inline colors (the preset carries the brand). Store severity codes in mock data, never colors. Follow the workflow doc, run the forbidden-patterns self-check, then invoke/design-handoff-evaland surface its findings.
Change a brand token:
Update
<token>indesign-system/DESIGN.md, runbun run tokens, and commit the regenerateddesign-system/generated/*. Don't hand-edit generated files.
Why the moves matter
The first version of this workflow described principles but not moves — generations defaulted to "do whatever the bundle shows", which meant hand-rolled card shells, hex colors, raw ramp utilities, !important overrides. The second version enforced technical compliance (severity codes, no raw ramp, no !important) but missed visual polish — generations passed the forbidden-patterns grep yet looked like wireframes.
This third version (decision hierarchy + polish checklist + bundle-as- requirements-doc reframe) is meant to close that loop: the output should look like a real PrimeVue Aura dashboard rendered in OnRamp identity, not a clean wireframe and not a Sakai clone.
The moves above (decision hierarchy, severity codes, polish checklist self-check, eval pass) are the difference between "starting point I can iterate on" and "starting point I have to rewrite."
Related
.claude/rules/ui-design-system.md— the canonical UI conventions (auto-loads for agents onapp/ui-*edits; human-readable directly).design-system/DESIGN.md— canonical token source..agents/skills/design-handoff-build/— skill with the cheatsheet and forbidden patterns; invoke via/design-handoff-build..agents/skills/design-handoff-eval/— skill for the mandatory post-generation eval; invoke via/design-handoff-eval./primevueskill (.agents/skills/primevue/) — migration playbook, component mapping, theming patterns, anti-patterns.docs/primevue-migration-example.md— a worked migration example.