1 ---
2 name: mockup-extract
3 description: "Use when the user wants to pull an existing component from their main app onto the canvas — whether to redesign it, create variants, or simply display it as a visual reference. Also activate when the user asks to redesign, improve, or create variants of any UI that already exists as code in the main app, even if they don't explicitly say 'extract' — the real source code must be used as the starting point, never hand-coded approximations. Copies the component and its dependencies into the mockup sandbox, rewrites imports, stubs external dependencies, and embeds the result as an iframe on the canvas. Activate when the user says 'put my X on the canvas', 'show my current Y on the board', 'redesign my existing Z', 'create variants of my current W', 'improve my Y', or wants to see or iterate on something already in the app."
4 ---
5
6 # Mockup Extract Skill
7
8 Pull an existing component from the main app into the `mockup/` sandbox so it can be previewed on the canvas and used as a starting point for design iteration.
9
10 ## When to Use
11
12 Activate this skill when the user:
13
14 - Wants to see an existing component on the canvas as a visual reference ("show my homepage on the board", "put my current settings page on the canvas")
15 - Wants to redesign an existing component ("redesign my navbar", "redo my pricing page", "improve the onboarding flow")
16 - Wants to create variants starting from an existing component
17 - Needs to compare their current design against new alternatives
18
19 **Important:** This skill must also be activated implicitly when the user asks to redesign, improve, or create variants of something that already exists as code in the main app — even if they don't say "extract". If the component exists in the codebase, extract it first. Never rebuild an existing component from scratch by hand-coding approximations; you will get exact dimensions, colors, spacing, opacity values, and other details wrong. The real source code has the correct values.
20
21 ## Subagent Guidance
22
23 If you need to parallelize extraction (e.g., extract multiple components at once), use a **GENERAL** subagent — never a DESIGN subagent. Extraction is an engineering task (import graph tracing, dependency stubbing, path rewriting) that requires codebase navigation, not creative visual output.
24
25 ## Prerequisites
26
27 The mockup sandbox must be set up first. If `mockup/` doesn't exist, activate the {{skill("mockup-sandbox")}} skill to set it up before proceeding.
28
29 ## Do Not Iframe the Main App Directly
30
31 When the user asks to "show my component on the canvas" or "redesign my navbar," do **not** create an iframe pointing at the main app's dev server URL. This is the wrong approach because:
32
33 - It shows the entire app (navbar, sidebar, footer, routing), not the target component in isolation
34 - You cannot create independent design variants from it
35 - Clicking links or buttons inside the iframe navigates away from the component
36 - Editing the main app code changes the iframe live, making it impossible to compare before/after
37
38 Instead, always extract the component into the `mockup/` sandbox and embed the sandbox's `/preview/` URL.
39
40 ## Process
41
42 ### Step 1: Locate and read the target component
43
44 Ask the user which component to extract if it isn't clear. Read the component file and understand its structure and imports.
45
46 ### Step 2: Analyze the dependency tree
47
48 Read the target component and trace every import. Classify each dependency:
49
50 | Category | When | Action |
51 |---|---|---|
52 | **Inline** | Small sub-components, simple hooks, utility functions (<50 lines) | Copy the code directly into the mockup file |
53 | **Copy** | Larger shared components, complex hooks, asset files | Copy into `mockup/src/` with updated import paths |
54 | **Stub** | Context providers, API calls, routing, auth, global state | Replace with static mock data or no-op wrappers |
55
56 Walk the full import chain -- a component may import a hook that imports a context that imports an API client. Trace until you reach leaf dependencies or hit a stub boundary.
57
58 ### Step 3: Handle external dependencies
59
60 For dependencies that can't transfer cleanly:
61
62 - **API calls / data fetching:** Replace with hardcoded mock data matching the response shape. Use realistic values.
63 - **Context providers (auth, theme):** Inline the values as constants.
64 - **Routing (`useNavigate`, `Link`, `useParams`):** Replace with no-ops or static values.
65 - **Global state (Redux, Zustand):** Extract the relevant slice as a local `useState` or constant.
66
67 ### Step 4: Rewrite import paths
68
69 `@/` resolves to different roots in the main app vs the sandbox:
70
71 - Main app: `@/` → `client/src/`
72 - Sandbox: `@/` → `mockup/src/`
73
74 Every `@/` import must point to a file that exists under `mockup/src/`. If the imported file doesn't exist in the sandbox, either copy it there or inline it. `@/components/ui/*` imports work without changes (shadcn/ui is pre-installed).
75
76 ### Step 5: Create `_group.css` and the mockup component
77
78 The main app's global styles are invisible to Step 2's import trace — they live in `index.html` `<link>` tags and global CSS, not in any `import` statement. Collect them into a group-level stylesheet that every component in this group will explicitly import.
79
80 Create `mockup/src/components/mockups/{group}/_group.css` with everything the app applies globally:
81
82 - **CSS variables** — copy the `:root` and `.dark` blocks from the main app's `client/src/index.css` so semantic classes like `bg-background` and `text-foreground` resolve to the app's values, not the sandbox defaults.
83 - **External font links** — read the main app's `client/index.html` for `<link href="https://fonts.googleapis.com/...">` (or Adobe Fonts, etc.) and convert each to `@import url("...");` at the top of `_group.css`.
84 - **`@font-face` declarations** — if the main app self-hosts fonts, copy the `@font-face` blocks and the font files they reference.
85
86 Do **not** edit the sandbox's global `index.css` — that leaks this app's tokens into every unrelated mockup group. Do **not** add font `<link>` tags to `mockup/index.html` — that file is shared across all mockup groups, so app-specific fonts would load for every unrelated preview. The sandbox already pre-loads a large common font bundle there; put any additional app-specific fonts in `_group.css` via `@import` to keep them scoped to this extraction.
87
88 Then create `mockup/src/components/mockups/{group}/Current.tsx`:
89
90 ```tsx
91 import './_group.css';
92
93 export function Current() {
94 // ... extracted component
95 }
96 ```
97
98 The `_group.css` import loads after the plugin's base `index.css` import, so its rules win by normal cascade order. Every variant you create later (`VariantA.tsx`, `VariantB.tsx`) also imports `./_group.css` to inherit the same baseline. A variant that needs to diverge adds a second import for its own sibling CSS file.
99
100 Use a descriptive group name (e.g., `navbar-redesign/`). Export a single component per file; named or default exports both work. Use `min-h-screen` on the root element.
101
102 ### Step 6: Type-check, embed, and create variants
103
104 Type-check with `cd mockup && npm run check`. Embed on the canvas using the sandbox `/preview/` URL (see {{skill("mockup-sandbox")}} for iframe creation). Label it "Current", then create new variant files alongside it.
105
106 ## Guidelines
107
108 - **Prefer inlining over copying.** Fewer files = easier iteration. Inline anything under ~50 lines.
109 - **Keep mock data realistic.** Visual fidelity depends on it.
110 - **Don't import from the main app.** Every import must resolve within `mockup/src/`.
111 - **Preserve the visual output exactly.** The extracted component should look identical to the original.
112 - **Copy assets first.** Images and icons must exist in `mockup/` before the component references them.
113
114 ## Common Mistakes
115
116 - **Leaving `@/` imports pointing to main app files.** Every `@/` path must resolve under `mockup/src/`.
117 - **Forgetting nested dependencies.** Trace the full import chain — component → hook → context → API client.
118 - **Not stubbing side effects.** API calls, analytics, and router navigations will crash in the sandbox.
119 - **Copying too much.** Extract only what the target component needs.
120 - **Editing the global `index.css` instead of creating `_group.css`.** The extraction's tokens leak into every other mockup group in the sandbox.
121 - **Forgetting `import './_group.css'` in the component file.** Without it the component renders with sandbox defaults, not the app's tokens. No error — it just looks wrong.
122 - **Adding font `<link>` tags to `mockup/index.html`.** That file is shared across all mockup groups — app-specific fonts leak into every unrelated preview. Put fonts in `_group.css` via `@import` instead to keep them scoped to this group.
123 - **Assuming fonts loaded because nothing errored.** Missing fonts fall back silently — no console error, no build failure. The component still renders, just with the wrong stroke weight, character width, and spacing. Verify typography visually against the original; "it didn't crash" is not "it looks right."