$npx -y skills add bluzir/claude-code-design --skill interactive-prototypeBuild a hi-fi clickable React prototype with realistic device chrome. Triggered by "prototype", "clickable", "app mockup", "interactive demo".
| 1 | # Interactive Prototype |
| 2 | |
| 3 | Build a working clickable prototype — not a static mockup. Uses React + Babel inline with pinned versions, wrapped in a DeviceFrame. |
| 4 | |
| 5 | ## Phase 0 — Context pre-flight (auto-detect, ONE question max) |
| 6 | |
| 7 | Before design questions, silently check for context: |
| 8 | 1. `Read .claude/design-tokens.json` if exists |
| 9 | 2. `Bash(ls ~/.claude/design-systems/ 2>/dev/null)` — if brief mentions a brand matching a folder name → auto-apply |
| 10 | 3. `Glob` for codebase tokens: `**/tailwind.config.*`, `**/theme.{ts,js,json}`, `**/tokens.{css,scss}`, `**/_variables.*` |
| 11 | 4. Scan brief for: github URL → `Skill: ingest-github`; Figma URL → `Skill: ingest-figma`; image attachment → `Skill: ingest-screenshot`; `.md`/`.pdf` → `Read` |
| 12 | |
| 13 | If nothing found, ask ONE `AskUserQuestion`: design system from registry / codebase / screenshot / Figma / none (use frontend-design) / Claude decides. Report "Using <context>. Proceeding." |
| 14 | |
| 15 | ## Phase 1 — Ambiguity gate |
| 16 | |
| 17 | Check brief for: platform (iOS/Android/desktop/web), app category (food delivery, social, productivity, etc.), feature count, design context (brand/codebase). |
| 18 | |
| 19 | If platform + category present → max 2 clarifying questions. Otherwise `AskUserQuestion`: |
| 20 | - Platform |
| 21 | - Screens needed (list) |
| 22 | - Transitions between screens (instant / slide / fade / custom) |
| 23 | - Does it need "live data" mocking (fake API returns) |
| 24 | - How interactive — taps only, or scroll/swipe/drag |
| 25 | - Variations wanted |
| 26 | |
| 27 | **Do not** ask about brand context — Phase 0 already handled it. |
| 28 | |
| 29 | ## Phase 2 — Visual system |
| 30 | |
| 31 | Using context from Phase 0, commit to a mobile-aware system: |
| 32 | - Min 44px hit targets on mobile |
| 33 | - Consistent spacing / type scale from loaded tokens |
| 34 | - If no tokens → invoke `Skill: frontend-design` |
| 35 | |
| 36 | ## Phase 3 — Build |
| 37 | |
| 38 | 1. `artifacts/<slug>.html` with shell: |
| 39 | ```html |
| 40 | <!doctype html> |
| 41 | <html> |
| 42 | <head> |
| 43 | <meta charset="utf-8"/> |
| 44 | <title>{{name}}</title> |
| 45 | <script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script> |
| 46 | <script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script> |
| 47 | <script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script> |
| 48 | <script src="./device_frame.jsx" type="text/babel"></script> |
| 49 | <script src="./animations.jsx" type="text/babel"></script> |
| 50 | <style>body { margin: 0; display: flex; align-items: center; justify-content: center; min-height: 100vh; background: #f4f4f6; }</style> |
| 51 | </head> |
| 52 | <body> |
| 53 | <div id="root"></div> |
| 54 | <script type="text/babel"> |
| 55 | const { useState } = React; |
| 56 | // your components here |
| 57 | function App() { |
| 58 | const [screen, setScreen] = useState('home'); |
| 59 | return <DeviceFrame kind="ios"> |
| 60 | {screen === 'home' && <HomeScreen onNav={setScreen}/>} |
| 61 | {screen === 'detail' && <DetailScreen onBack={() => setScreen('home')}/>} |
| 62 | </DeviceFrame>; |
| 63 | } |
| 64 | ReactDOM.createRoot(document.getElementById('root')).render(<App/>); |
| 65 | </script> |
| 66 | </body> |
| 67 | </html> |
| 68 | ``` |
| 69 | 2. `Bash(cp starters/device_frame.jsx "$(dirname <html>)/")` + `Bash(cp starters/animations.jsx "$(dirname <html>)/")` — copy into the same dir as the HTML |
| 70 | 3. Navigation pattern: `useState` for current screen. For transitions use `<Transition>` from animations.jsx. |
| 71 | 4. **Critical React rule:** never `const styles = {...}`. Use component-prefixed names: `const headerStyles`, `const cardStyles`. Inline styles also OK. |
| 72 | 5. Mock data inline; no external fetch. |
| 73 | |
| 74 | ## Phase 4 — Verify |
| 75 | |
| 76 | **Important:** because this artifact loads external `.jsx` starters, `file://` will hit CORS errors. Run `/serve` first (one-time), then preview via http: |
| 77 | |
| 78 | ``` |
| 79 | /serve |
| 80 | /done http://127.0.0.1:4567/artifacts/<slug>.html |
| 81 | ``` |
| 82 | |
| 83 | Fix errors → `Skill: verify-artifact` in background. |
| 84 | |
| 85 | ## Phase 5 — Next steps |
| 86 | |
| 87 | - `/make-tweakable` to expose knobs (primaryColor, fontSize, density variants) |
| 88 | - `/export-standalone` for offline deliverable |
| 89 | - `/handoff` to produce component files for the dev team |
| 90 | - `/register-asset` to add to overview |