Interactive Prototype
Build a working clickable prototype — not a static mockup. Uses React + Babel inline with pinned versions, wrapped in a DeviceFrame.
Phase 0 — Context pre-flight (auto-detect, ONE question max)
Before design questions, silently check for context:
Read .claude/design-tokens.jsonif existsBash(ls ~/.claude/design-systems/ 2>/dev/null)— if brief mentions a brand matching a folder name → auto-applyGlobfor codebase tokens:**/tailwind.config.*,**/theme.{ts,js,json},**/tokens.{css,scss},**/_variables.*- Scan brief for: github URL →
Skill: ingest-github; Figma URL →Skill: ingest-figma; image attachment →Skill: ingest-screenshot;.md/.pdf→Read
If nothing found, ask ONE AskUserQuestion: design system from registry / codebase / screenshot / Figma / none (use frontend-design) / Claude decides. Report "Using . Proceeding."
Phase 1 — Ambiguity gate
Check brief for: platform (iOS/Android/desktop/web), app category (food delivery, social, productivity, etc.), feature count, design context (brand/codebase).
If platform + category present → max 2 clarifying questions. Otherwise AskUserQuestion:
- Platform
- Screens needed (list)
- Transitions between screens (instant / slide / fade / custom)
- Does it need "live data" mocking (fake API returns)
- How interactive — taps only, or scroll/swipe/drag
- Variations wanted
Do not ask about brand context — Phase 0 already handled it.
Phase 2 — Visual system
Using context from Phase 0, commit to a mobile-aware system:
- Min 44px hit targets on mobile
- Consistent spacing / type scale from loaded tokens
- If no tokens → invoke
Skill: frontend-design
Phase 3 — Build
artifacts/<slug>.htmlwith shell:<!doctype html> <html> <head> <meta charset="utf-8"/> <title>{{name}}</title> <script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script> <script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script> <script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script> <script src="./device_frame.jsx" type="text/babel"></script> <script src="./animations.jsx" type="text/babel"></script> <style>body { margin: 0; display: flex; align-items: center; justify-content: center; min-height: 100vh; background: #f4f4f6; }</style> </head> <body> <div id="root"></div> <script type="text/babel"> const { useState } = React; // your components here function App() { const [screen, setScreen] = useState('home'); return <DeviceFrame kind="ios"> {screen === 'home' && <HomeScreen {screen === 'detail' && <DetailScreen => setScreen('home')}/>} </DeviceFrame>; } ReactDOM.createRoot(document.getElementById('root')).render(<App/>); </script> </body> </html>Bash(cp starters/device_frame.jsx "$(dirname <html>)/")+Bash(cp starters/animations.jsx "$(dirname <html>)/")— copy into the same dir as the HTML- Navigation pattern:
useStatefor current screen. For transitions use<Transition>from animations.jsx. - Critical React rule: never
const styles = {...}. Use component-prefixed names:const headerStyles,const cardStyles. Inline styles also OK. - Mock data inline; no external fetch.
Phase 4 — Verify
Important: because this artifact loads external .jsx starters, file:// will hit CORS errors. Run /serve first (one-time), then preview via http:
/serve
/done http://127.0.0.1:4567/artifacts/<slug>.html
Fix errors → Skill: verify-artifact in background.
Phase 5 — Next steps
/make-tweakableto expose knobs (primaryColor, fontSize, density variants)/export-standalonefor offline deliverable/handoffto produce component files for the dev team/register-assetto add to overview