# Interactive Prototype

> Build a hi-fi clickable React prototype with realistic device chrome. Triggered by "prototype", "clickable", "app mockup", "interactive demo".

- Skill: `bluzir/interactive-prototype` (Agent Skill)
- Install (CLI): `npx skillmds@latest add bluzir/interactive-prototype`
- Raw SKILL.md: https://api.skillmd.com/api/skills/bluzir/interactive-prototype/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: bluzir (https://skillmd.com/u/bluzir)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/bluzir/interactive-prototype

---


# 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:
1. `Read .claude/design-tokens.json` if exists
2. `Bash(ls ~/.claude/design-systems/ 2>/dev/null)` — if brief mentions a brand matching a folder name → auto-apply
3. `Glob` for codebase tokens: `**/tailwind.config.*`, `**/theme.{ts,js,json}`, `**/tokens.{css,scss}`, `**/_variables.*`
4. 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 <context>. 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

1. `artifacts/<slug>.html` with shell:
   ```html
   <!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 onNav={setScreen}/>}
           {screen === 'detail' && <DetailScreen onBack={() => setScreen('home')}/>}
         </DeviceFrame>;
       }
       ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
     </script>
   </body>
   </html>
   ```
2. `Bash(cp starters/device_frame.jsx "$(dirname <html>)/")` + `Bash(cp starters/animations.jsx "$(dirname <html>)/")` — copy into the same dir as the HTML
3. Navigation pattern: `useState` for current screen. For transitions use `<Transition>` from animations.jsx.
4. **Critical React rule:** never `const styles = {...}`. Use component-prefixed names: `const headerStyles`, `const cardStyles`. Inline styles also OK.
5. 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-tweakable` to expose knobs (primaryColor, fontSize, density variants)
- `/export-standalone` for offline deliverable
- `/handoff` to produce component files for the dev team
- `/register-asset` to add to overview

