design-clone 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,6 +10,7 @@ Clone website designs with multi-viewport screenshots, HTML/CSS extraction, and
10
10
 
11
11
  - **Multi-viewport screenshots**: Desktop (1920px), Tablet (768px), Mobile (375px)
12
12
  - **HTML/CSS extraction**: Clean source files with unused CSS removal
13
+ - **Hover state capture**: Screenshots and CSS for interactive element states (phase 2)
13
14
  - **AI structure analysis**: Gemini Vision analyzes page layout (optional)
14
15
  - **Asset extraction**: Downloads images, fonts, icons
15
16
  - **Menu verification**: Tests responsive navigation functionality
@@ -75,14 +76,21 @@ Full pixel-perfect clone:
75
76
 
76
77
  ```
77
78
  cloned-design/
78
- ├── desktop.png # 1920x1080 screenshot
79
- ├── tablet.png # 768x1024 screenshot
80
- ├── mobile.png # 375x812 screenshot
81
- ├── source.html # Cleaned HTML
82
- ├── source.css # Filtered CSS
83
- ├── source-raw.css # Original CSS (unfiltered)
84
- ├── structure.md # AI analysis (if GEMINI_API_KEY set)
85
- ├── tokens.json # Extracted design tokens
79
+ ├── desktop.png # 1920x1080 screenshot
80
+ ├── tablet.png # 768x1024 screenshot
81
+ ├── mobile.png # 375x812 screenshot
82
+ ├── source.html # Cleaned HTML
83
+ ├── source.css # Filtered CSS
84
+ ├── source-raw.css # Original CSS (unfiltered)
85
+ ├── animations.css # Extracted @keyframes definitions
86
+ ├── animation-tokens.json # Animation metadata (keyframes, transitions, timings)
87
+ ├── hover.css # Generated :hover CSS rules (with --capture-hover)
88
+ ├── structure.md # AI analysis (if GEMINI_API_KEY set)
89
+ ├── tokens.json # Extracted design tokens
90
+ ├── hover-states/ # Hover state captures (with --capture-hover)
91
+ │ ├── hover-N-normal.png # Element before hover
92
+ │ ├── hover-N-hover.png # Element during hover
93
+ │ └── hover-diff.json # Captured element summary
86
94
  └── assets/
87
95
  ├── images/
88
96
  ├── fonts/
package/SKILL.md CHANGED
@@ -13,6 +13,7 @@ Clone website designs with multi-viewport screenshots, HTML/CSS extraction, CSS
13
13
  - **Direct Unsplash Images** - Real images without API key needed
14
14
  - **Japanese Design Principles** - Ma, Kanso, Shibui, Seijaku for elegant designs
15
15
  - **Multi-viewport Screenshots** - Desktop, tablet, mobile captures
16
+ - **Hover State Capture** - Interactive element screenshots and :hover CSS generation
16
17
  - **Gemini Vision Analysis** - AI-powered design token extraction
17
18
  - **ui-ux-pro-max Quality Check** - Accessibility, hover states, contrast validation
18
19
 
@@ -164,6 +165,7 @@ node src/core/screenshot.js \
164
165
  --url "URL" \
165
166
  --output ./output \
166
167
  --extract-html --extract-css \
168
+ --capture-hover true \
167
169
  --full-page
168
170
 
169
171
  # Step 2: Filter CSS
@@ -199,6 +201,8 @@ python3 $HOME/.claude/skills/ui-ux-pro-max/scripts/search.py "animation hover" -
199
201
  python3 $HOME/.claude/skills/ui-ux-pro-max/scripts/search.py "z-index" --domain ux
200
202
  ```
201
203
 
204
+ **Note:** Step 1 includes `--capture-hover true` to capture interactive element states and generate `:hover` CSS rules. Outputs include `hover-states/` directory and `hover.css`.
205
+
202
206
  ## Quality Checklist (ui-ux-pro-max)
203
207
 
204
208
  After generating HTML/CSS, verify these items using `ui-ux-pro-max` skill:
@@ -256,6 +260,73 @@ After generating HTML/CSS, verify these items using `ui-ux-pro-max` skill:
256
260
  | Shibui (渋い) | Subtle elegance | Soft shadows, gentle transitions |
257
261
  | Seijaku (静寂) | Tranquility | Calm colors, visual harmony |
258
262
 
263
+ ## Animation & Interaction Capture (v1.2+)
264
+
265
+ ### CSS Animations
266
+
267
+ Automatically extracts @keyframes and transition properties when using `--extract-css`:
268
+
269
+ ```bash
270
+ node src/core/screenshot.js --url https://example.com --output ./out --extract-css true
271
+ ```
272
+
273
+ **Output:**
274
+ - `animations.css` - All @keyframes definitions with frame data
275
+ - `animation-tokens.json` - Detailed animation metadata (durations, timing functions)
276
+
277
+ ### Hover State Capture
278
+
279
+ Capture interactive element hover states:
280
+
281
+ ```bash
282
+ node src/core/screenshot.js --url https://example.com --output ./out --capture-hover
283
+ ```
284
+
285
+ **Output:**
286
+ - `hover-states/` - Before/after screenshots for each interactive element
287
+ - `hover.css` - Generated :hover rules from computed style differences
288
+ - `hover-diff.json` - Style diff data
289
+
290
+ **Detection Methods:**
291
+ 1. CSS-based: Parses :hover selectors from extracted CSS
292
+ 2. DOM-based: Queries buttons, links, and interactive elements
293
+
294
+ ### Video Recording
295
+
296
+ Record scroll preview video (opt-in due to 3-5x capture time increase):
297
+
298
+ ```bash
299
+ # WebM (native, no extra deps)
300
+ node src/core/screenshot.js --url https://example.com --output ./out --video
301
+
302
+ # MP4 (requires ffmpeg)
303
+ node src/core/screenshot.js --url https://example.com --output ./out --video --video-format mp4
304
+
305
+ # GIF (requires ffmpeg)
306
+ node src/core/screenshot.js --url https://example.com --output ./out --video --video-format gif
307
+
308
+ # Custom duration (default: 12000ms)
309
+ node src/core/screenshot.js --url https://example.com --output ./out --video --video-duration 8000
310
+ ```
311
+
312
+ **Output:**
313
+ - `preview.webm` (default) or `preview.mp4` / `preview.gif`
314
+
315
+ **ffmpeg Setup (for MP4/GIF):**
316
+ ```bash
317
+ npm install fluent-ffmpeg @ffmpeg-installer/ffmpeg
318
+ ```
319
+
320
+ ### Feature Flags Reference
321
+
322
+ | Flag | Default | Description |
323
+ |------|---------|-------------|
324
+ | `--extract-animations` | true (with --extract-css) | Extract @keyframes and transitions |
325
+ | `--capture-hover` | false | Capture hover state screenshots |
326
+ | `--video` | false | Record scroll preview video |
327
+ | `--video-format` | webm | Video format: webm, mp4, gif |
328
+ | `--video-duration` | 12000 | Video duration in ms |
329
+
259
330
  ## Environment Variables
260
331
 
261
332
  Create `.env` file (see `.env.example`):
@@ -270,6 +341,9 @@ GEMINI_API_KEY=your-key # Optional: enables AI structure analysis
270
341
  |--------|----------|---------|
271
342
  | screenshot.js | src/core/ | Capture screenshots + extract HTML/CSS |
272
343
  | filter-css.js | src/core/ | Filter unused CSS rules |
344
+ | animation-extractor.js | src/core/ | Extract @keyframes and transitions from CSS |
345
+ | state-capture.js | src/core/ | Capture hover states for interactive elements |
346
+ | video-capture.js | src/core/ | Record scroll preview video with optional ffmpeg conversion |
273
347
  | extract-assets.js | src/core/ | Download images, fonts, icons |
274
348
  | discover-pages.js | src/core/ | Discover navigation links |
275
349
  | multi-page-screenshot.js | src/core/ | Capture multiple pages |
@@ -17,6 +17,8 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
17
17
  const SKILL_SOURCE = path.resolve(__dirname, '../..');
18
18
  // Destination: ~/.claude/skills/design-clone
19
19
  const getSkillDest = () => path.join(process.env.HOME || process.env.USERPROFILE || '', '.claude/skills/design-clone');
20
+ // Commands destination: ~/.claude/commands/design/
21
+ const getCommandsDest = () => path.join(process.env.HOME || process.env.USERPROFILE || '', '.claude/commands/design');
20
22
 
21
23
  /**
22
24
  * Install skill to Claude Code skills directory
@@ -93,6 +95,29 @@ export async function init(args) {
93
95
  process.exit(1);
94
96
  }
95
97
 
98
+ // Copy slash commands to ~/.claude/commands/design/
99
+ console.log('Installing slash commands...');
100
+ try {
101
+ const COMMANDS_DEST = getCommandsDest();
102
+ const COMMANDS_SOURCE = path.join(SKILL_SOURCE, 'commands/design');
103
+
104
+ // Ensure commands directory exists
105
+ await fs.mkdir(COMMANDS_DEST, { recursive: true });
106
+
107
+ // Copy command files
108
+ const commandFiles = await fs.readdir(COMMANDS_SOURCE).catch(() => []);
109
+ for (const file of commandFiles) {
110
+ if (file.endsWith('.md')) {
111
+ const src = path.join(COMMANDS_SOURCE, file);
112
+ const dest = path.join(COMMANDS_DEST, file);
113
+ await fs.copyFile(src, dest);
114
+ console.log(` Installed: /design:${file.replace('.md', '')}`);
115
+ }
116
+ }
117
+ } catch (error) {
118
+ console.warn(` Warning: Could not install slash commands: ${error.message}`);
119
+ }
120
+
96
121
  // Install dependencies
97
122
  if (!skipDeps) {
98
123
  // Node.js dependencies
@@ -156,6 +181,9 @@ export async function init(args) {
156
181
  console.log('\n✓ design-clone skill installed successfully!\n');
157
182
  console.log('Next steps:');
158
183
  console.log(' 1. (Optional) Set GEMINI_API_KEY in ~/.claude/.env for AI analysis');
159
- console.log(' 2. Use /design:clone or /design:clone-px in Claude Code');
184
+ console.log(' 2. Use slash commands in Claude Code:');
185
+ console.log(' /design:clone - Clone single page');
186
+ console.log(' /design:clone-site - Clone multiple pages');
187
+ console.log(' /design:clone-px - Pixel-perfect clone');
160
188
  console.log('\nRun "design-clone verify" to check installation status.');
161
189
  }
@@ -0,0 +1,135 @@
1
+ ---
2
+ description: Clone multiple pages from a website with shared CSS and navigation
3
+ argument-hint: [url] [--max-pages N] [--ai]
4
+ ---
5
+
6
+ Clone multiple pages from this website with shared CSS and working navigation:
7
+ <url>$ARGUMENTS</url>
8
+
9
+ ## Required Skills (Priority Order)
10
+ 1. **`chrome-devtools`** - Multi-viewport screenshot capture
11
+ 2. **`ai-multimodal`** - Gemini Vision for design token extraction (with --ai flag)
12
+
13
+ ## Pipeline Overview
14
+
15
+ ```
16
+ URL -> Page Discovery -> Multi-page Capture -> CSS Filtering & Merge -> Link Rewriting -> [AI Tokens] -> Output
17
+ ```
18
+
19
+ ## Workflow
20
+
21
+ ### STEP 1: Run Clone-Site Command
22
+
23
+ Use the design-clone CLI to clone multiple pages:
24
+
25
+ ```bash
26
+ # Basic usage - auto-discovers pages from navigation
27
+ design-clone clone-site "$ARGUMENTS"
28
+
29
+ # With options
30
+ design-clone clone-site "$ARGUMENTS" --max-pages 5
31
+
32
+ # Specific pages
33
+ design-clone clone-site "$ARGUMENTS" --pages /,/about,/contact
34
+
35
+ # With AI design token extraction (requires GEMINI_API_KEY)
36
+ design-clone clone-site "$ARGUMENTS" --ai
37
+ ```
38
+
39
+ ### CLI Options
40
+
41
+ | Option | Default | Description |
42
+ |--------|---------|-------------|
43
+ | `--pages <paths>` | auto | Comma-separated paths (e.g., /,/about,/contact) |
44
+ | `--max-pages <n>` | 10 | Maximum pages to auto-discover |
45
+ | `--viewports <list>` | desktop,tablet,mobile | Viewport list |
46
+ | `--yes` | false | Skip confirmation prompt |
47
+ | `--output <dir>` | ./cloned-designs/{timestamp}-{domain} | Custom output directory |
48
+ | `--ai` | false | Extract design tokens using Gemini AI |
49
+
50
+ ### STEP 2: Process Flow (Automatic)
51
+
52
+ The command executes these steps automatically:
53
+
54
+ 1. **Page Discovery** - Crawls navigation links, respects same-domain
55
+ 2. **Multi-page Capture** - Screenshots + HTML/CSS for each page
56
+ 3. **CSS Merge** - Combines filtered CSS with deduplication (15-30% reduction)
57
+ 4. **Link Rewriting** - Updates internal links to local .html files
58
+ 5. **Token Extraction** (if --ai) - Gemini Vision extracts design tokens
59
+ 6. **Manifest Generation** - Creates manifest.json with page metadata
60
+
61
+ ### Output Structure
62
+
63
+ ```
64
+ cloned-designs/{timestamp}-{domain}/
65
+ ├── analysis/ # Screenshots by viewport
66
+ │ ├── desktop/
67
+ │ │ ├── index.png
68
+ │ │ ├── about.png
69
+ │ │ └── contact.png
70
+ │ ├── tablet/
71
+ │ └── mobile/
72
+ ├── html/ # Raw extracted HTML (source)
73
+ ├── css/ # Per-page CSS (raw + filtered)
74
+ ├── pages/ # HTML with rewritten links
75
+ │ ├── index.html # Links to ../styles.css
76
+ │ ├── about.html
77
+ │ └── contact.html
78
+ ├── styles.css # Merged + deduplicated CSS
79
+ ├── tokens.css # Design tokens (if --ai)
80
+ ├── design-tokens.json # Token data (if --ai)
81
+ ├── manifest.json # Page metadata + mapping
82
+ └── capture-results.json
83
+ ```
84
+
85
+ ### STEP 3: Review & Edit
86
+
87
+ After cloning:
88
+
89
+ 1. **Test navigation** - Open `pages/index.html` in browser
90
+ 2. **Verify CSS** - Check that styles.css covers all pages
91
+ 3. **Check screenshots** - Review analysis/ for visual reference
92
+ 4. **Edit tokens** (if --ai) - Modify tokens.css to customize design
93
+
94
+ ## Features
95
+
96
+ - **Auto-discovers pages** from navigation (SPA-aware)
97
+ - **Shared CSS** with deduplication (15-30% reduction)
98
+ - **Filtered CSS** - Uses per-page filtered CSS, not raw
99
+ - **Working internal links** - Rewrites to local .html files
100
+ - **Progress reporting** - Shows capture progress
101
+ - **Graceful errors** - Continues on individual page failures
102
+ - **AI tokens** (optional) - Gemini Vision design token extraction
103
+
104
+ ## Environment Variables
105
+
106
+ ```bash
107
+ # Optional: For AI token extraction with --ai flag
108
+ GEMINI_API_KEY=your-key
109
+ ```
110
+
111
+ ## Examples
112
+
113
+ ```bash
114
+ # Clone with auto-discovery (up to 10 pages)
115
+ /design:clone-site https://example.com
116
+
117
+ # Clone specific pages only
118
+ /design:clone-site https://example.com --pages /,/about,/pricing
119
+
120
+ # Clone with AI token extraction
121
+ /design:clone-site https://example.com --ai --max-pages 5
122
+
123
+ # Clone to custom directory
124
+ /design:clone-site https://example.com --output ./my-clone
125
+ ```
126
+
127
+ ## Error Handling
128
+
129
+ | Scenario | Behavior |
130
+ |----------|----------|
131
+ | Page fails to load | Continues with other pages, logs warning |
132
+ | No navigation found | Falls back to homepage only |
133
+ | CSS extraction fails | Uses raw CSS fallback |
134
+ | No GEMINI_API_KEY | Skips token extraction, logs hint |
135
+ | Python not found | Skips AI features, continues |
@@ -22,10 +22,14 @@ node src/core/screenshot.js [options]
22
22
  | --close | bool | false | Close browser after capture (false keeps session) |
23
23
  | --extract-html | bool | false | Extract cleaned HTML |
24
24
  | --extract-css | bool | false | Extract all CSS from page |
25
+ | --extract-animations | bool | true* | Extract @keyframes and transitions (enabled with --extract-css) |
25
26
  | --filter-unused | bool | true | Filter CSS to remove unused selectors |
27
+ | --capture-hover | bool | false | Capture hover state screenshots and generate :hover CSS |
26
28
  | --verbose | bool | false | Verbose logging |
27
29
 
28
- **Output**: JSON with screenshot paths and metadata. Includes `browserRestarts` count tracking for stability monitoring.
30
+ *Default true when --extract-css is enabled, can be disabled with `--extract-animations false`
31
+
32
+ **Output**: JSON with screenshot paths and metadata. Includes `browserRestarts` count tracking for stability monitoring. When `--capture-hover` is enabled, also includes hover state results in output.
29
33
 
30
34
  ## filter-css.js
31
35
 
@@ -92,3 +96,23 @@ Verify layout consistency.
92
96
  ```bash
93
97
  node src/verification/verify-layout.js --html FILE
94
98
  ```
99
+
100
+ ## state-capture.js
101
+
102
+ Capture hover states for interactive elements.
103
+
104
+ Used internally by screenshot.js with `--capture-hover` flag.
105
+
106
+ | Export | Description |
107
+ |--------|-------------|
108
+ | `captureAllHoverStates(page, cssString, outputDir)` | Detect interactive elements and capture normal/hover screenshots |
109
+ | `captureHoverState(page, selector, outputDir, index)` | Capture hover state for a single element |
110
+ | `generateHoverCss(results)` | Generate `:hover` CSS rules from captured style diffs |
111
+ | `detectInteractiveElements(page, cssString)` | Detect interactive elements via CSS analysis and DOM query |
112
+
113
+ **Key Features:**
114
+ - Dual detection: CSS-based (`:hover` selectors) and DOM-based (interactive elements, transitions)
115
+ - Per-element style diff capture (backgroundColor, color, transform, boxShadow, etc.)
116
+ - Automatic screenshot pair generation (normal + hover states)
117
+ - CSS rule generation from detected style changes
118
+ - Validates selectors and skips hidden/invisible elements
@@ -131,6 +131,8 @@ Both Node.js and Python share same resolution order:
131
131
  | Script | Location | Language | Purpose |
132
132
  |--------|----------|----------|---------|
133
133
  | screenshot.js | src/core/ | Node.js | Screenshot capture, HTML/CSS extraction |
134
+ | animation-extractor.js | src/core/ | Node.js | Extract @keyframes, transitions, animation properties |
135
+ | state-capture.js | src/core/ | Node.js | Capture hover states for interactive elements |
134
136
  | filter-css.js | src/core/ | Node.js | Remove unused CSS selectors |
135
137
  | extract-assets.js | src/core/ | Node.js | Download images, fonts, icons |
136
138
  | analyze-structure.py | src/ai/ | Python | Gemini AI structure analysis |
@@ -179,42 +181,68 @@ bin/
179
181
  ### design:clone
180
182
 
181
183
  ```
182
- URL → src/core/screenshot.js → Screenshots (3 viewports)
183
- → source.html (cleaned)
184
- → source-raw.css
185
- → src/core/filter-css.js → source.css (filtered)
184
+ URL → src/core/screenshot.js → Screenshots (3 viewports)
185
+ → source.html (cleaned)
186
+ → source-raw.css
187
+ → src/core/filter-css.js → source.css (filtered)
188
+ → src/core/animation-extractor → animations.css
189
+ → animation-tokens.json
190
+ → src/core/state-capture.js* → hover-states/ (hover screenshots)
191
+ → hover.css (generated :hover rules)
186
192
  ```
187
193
 
194
+ *Enabled with `--capture-hover true` flag
195
+
188
196
  ### design:clone-px
189
197
 
190
198
  ```
191
- URL → src/core/screenshot.js → Screenshots + HTML/CSS
192
- → src/core/filter-css.js → Filtered CSS
193
- → src/core/extract-assets.js assets/ (images, fonts, icons)
194
- → src/ai/analyze-structure.py structure.md (AI analysis)
195
- → src/ai/extract-design-tokens.py tokens.json, tokens.css
196
- → src/verification/verify-menu.js Menu validation report
199
+ URL → src/core/screenshot.js → Screenshots + HTML/CSS
200
+ → src/core/filter-css.js → Filtered CSS
201
+ → src/core/animation-extractor animations.css, animation-tokens.json
202
+ → src/core/state-capture.js* hover-states/, hover.css
203
+ → src/core/extract-assets.js assets/ (images, fonts, icons)
204
+ → src/ai/analyze-structure.py structure.md (AI analysis)
205
+ → src/ai/extract-design-tokens.py → tokens.json, tokens.css
206
+ → src/verification/verify-menu.js → Menu validation report
197
207
  ```
198
208
 
209
+ *Hover state capture enabled by default in design:clone-px workflow
210
+
199
211
  ## Output Structure
200
212
 
201
213
  ```
202
214
  cloned-design/
203
- ├── desktop.png # 1920x1080
204
- ├── tablet.png # 768x1024
205
- ├── mobile.png # 375x812
206
- ├── source.html # Cleaned HTML
207
- ├── source.css # Filtered CSS
208
- ├── source-raw.css # Original CSS
209
- ├── structure.md # AI analysis (optional)
210
- ├── tokens.json # Design tokens
211
- ├── tokens.css # CSS variables
215
+ ├── desktop.png # 1920x1080
216
+ ├── tablet.png # 768x1024
217
+ ├── mobile.png # 375x812
218
+ ├── source.html # Cleaned HTML
219
+ ├── source.css # Filtered CSS
220
+ ├── source-raw.css # Original CSS
221
+ ├── animations.css # Extracted @keyframes definitions
222
+ ├── animation-tokens.json # Animation metadata (keyframes, transitions, timings)
223
+ ├── hover.css # Generated :hover CSS rules (when --capture-hover)
224
+ ├── structure.md # AI analysis (optional)
225
+ ├── tokens.json # Design tokens
226
+ ├── tokens.css # CSS variables
227
+ ├── hover-states/ # Hover state captures (when --capture-hover)
228
+ │ ├── hover-0-normal.png # Element before hover
229
+ │ ├── hover-0-hover.png # Element during hover
230
+ │ ├── hover-1-normal.png # ...
231
+ │ ├── hover-1-hover.png
232
+ │ └── hover-diff.json # Summary of detected and captured elements
212
233
  └── assets/
213
234
  ├── images/
214
235
  ├── fonts/
215
236
  └── icons/
216
237
  ```
217
238
 
239
+ **Hover State Output** (when `--capture-hover true`):
240
+ - `hover-states/`: Directory containing hover state captures
241
+ - `hover-N-normal.png`: Screenshot of element in normal state
242
+ - `hover-N-hover.png`: Screenshot of element with hover state applied
243
+ - `hover-diff.json`: Summary with detected count, captured count, and style differences for each element
244
+ - `hover.css`: Generated CSS rules with `:hover` selectors extracted from style diffs
245
+
218
246
  ## Dependencies
219
247
 
220
248
  ### Node.js (package.json)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "design-clone",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "type": "module",
5
5
  "description": "Claude Code skill for cloning website designs via multi-viewport screenshots, HTML/CSS extraction, and Gemini AI analysis",
6
6
  "bin": {
@@ -9,6 +9,7 @@
9
9
  "files": [
10
10
  "bin/",
11
11
  "src/",
12
+ "commands/",
12
13
  "templates/",
13
14
  "docs/",
14
15
  "SKILL.md",
@@ -53,5 +54,9 @@
53
54
  "puppeteer": {
54
55
  "optional": true
55
56
  }
57
+ },
58
+ "optionalDependencies": {
59
+ "fluent-ffmpeg": "^2.1.2",
60
+ "@ffmpeg-installer/ffmpeg": "^1.1.0"
56
61
  }
57
62
  }