@kood/claude-code 0.3.15 → 0.3.17
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/dist/index.js +6 -3
- package/package.json +1 -1
- package/templates/.claude/skills/figma-to-code/SKILL.md +482 -0
- package/templates/.claude/skills/figma-to-code/references/design-tokens.md +400 -0
- package/templates/.claude/skills/figma-to-code/references/figma-mcp-tools.md +285 -0
- package/templates/.claude/skills/figma-to-code/references/layout-mapping.md +557 -0
- package/templates/.claude/skills/figma-to-code/references/responsive-design.md +364 -0
- package/templates/.claude/skills/figma-to-code/references/verification.md +219 -0
- package/templates/nextjs/docs/skills/figma-to-code/SKILL.md +482 -0
- package/templates/nextjs/docs/skills/figma-to-code/references/design-tokens.md +400 -0
- package/templates/nextjs/docs/skills/figma-to-code/references/figma-mcp-tools.md +285 -0
- package/templates/nextjs/docs/skills/figma-to-code/references/layout-mapping.md +557 -0
- package/templates/nextjs/docs/skills/figma-to-code/references/responsive-design.md +364 -0
- package/templates/nextjs/docs/skills/figma-to-code/references/verification.md +219 -0
- package/templates/tanstack-start/docs/skills/figma-to-code/SKILL.md +482 -0
- package/templates/tanstack-start/docs/skills/figma-to-code/references/design-tokens.md +400 -0
- package/templates/tanstack-start/docs/skills/figma-to-code/references/figma-mcp-tools.md +285 -0
- package/templates/tanstack-start/docs/skills/figma-to-code/references/layout-mapping.md +557 -0
- package/templates/tanstack-start/docs/skills/figma-to-code/references/responsive-design.md +364 -0
- package/templates/tanstack-start/docs/skills/figma-to-code/references/verification.md +219 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
# Responsive Design Implementation Guide
|
|
2
|
+
|
|
3
|
+
Guide for implementing Figma designs 100% accurately across all devices.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Breakpoints
|
|
8
|
+
|
|
9
|
+
### Standard Breakpoints
|
|
10
|
+
|
|
11
|
+
| Device | Range | Tailwind Prefix |
|
|
12
|
+
|--------|-------|-----------------|
|
|
13
|
+
| **Mobile** | 320px ~ 767px | (default) |
|
|
14
|
+
| **Tablet** | 768px ~ 1023px | `md:` |
|
|
15
|
+
| **Desktop** | 1024px+ | `lg:` |
|
|
16
|
+
|
|
17
|
+
### Tailwind v4 Media Queries
|
|
18
|
+
|
|
19
|
+
```css
|
|
20
|
+
/* globals.css */
|
|
21
|
+
@import "tailwindcss";
|
|
22
|
+
|
|
23
|
+
@theme {
|
|
24
|
+
/* Custom breakpoints (if needed) */
|
|
25
|
+
--breakpoint-mobile: 320px;
|
|
26
|
+
--breakpoint-tablet: 768px;
|
|
27
|
+
--breakpoint-desktop: 1024px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Or use CSS media queries */
|
|
31
|
+
@media (min-width: 768px) {
|
|
32
|
+
/* Tablet */
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@media (min-width: 1024px) {
|
|
36
|
+
/* Desktop */
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Figma Constraints → CSS Mapping
|
|
43
|
+
|
|
44
|
+
### Horizontal Constraints
|
|
45
|
+
|
|
46
|
+
| Figma | CSS | Description |
|
|
47
|
+
|-------|-----|-------------|
|
|
48
|
+
| **Left** | `justify-self: start` | Fixed left |
|
|
49
|
+
| **Right** | `justify-self: end` | Fixed right |
|
|
50
|
+
| **Left + Right** | `width: 100%` | Fill parent width |
|
|
51
|
+
| **Center** | `margin: 0 auto` | Center alignment |
|
|
52
|
+
| **Scale** | `width: 50%` | Maintain ratio |
|
|
53
|
+
|
|
54
|
+
### Vertical Constraints
|
|
55
|
+
|
|
56
|
+
| Figma | CSS | Description |
|
|
57
|
+
|-------|-----|-------------|
|
|
58
|
+
| **Top** | `align-self: start` | Fixed top |
|
|
59
|
+
| **Bottom** | `align-self: end` | Fixed bottom |
|
|
60
|
+
| **Top + Bottom** | `height: 100%` | Fill parent height |
|
|
61
|
+
| **Center** | `margin: auto 0` | Vertical center |
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Layout Change Patterns
|
|
66
|
+
|
|
67
|
+
### Grid → List (Desktop → Mobile)
|
|
68
|
+
|
|
69
|
+
**Desktop (1024px+):**
|
|
70
|
+
```tsx
|
|
71
|
+
<div className="grid grid-cols-4 gap-6">
|
|
72
|
+
<Card />
|
|
73
|
+
<Card />
|
|
74
|
+
<Card />
|
|
75
|
+
<Card />
|
|
76
|
+
</div>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Mobile (320-767px):**
|
|
80
|
+
```tsx
|
|
81
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 md:gap-6">
|
|
82
|
+
<Card />
|
|
83
|
+
<Card />
|
|
84
|
+
<Card />
|
|
85
|
+
<Card />
|
|
86
|
+
</div>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Horizontal → Vertical (Desktop → Mobile)
|
|
90
|
+
|
|
91
|
+
**Desktop: Horizontal alignment**
|
|
92
|
+
```tsx
|
|
93
|
+
<div className="flex flex-col lg:flex-row gap-4 lg:gap-8">
|
|
94
|
+
<div className="flex-1">Left Content</div>
|
|
95
|
+
<div className="flex-1">Right Content</div>
|
|
96
|
+
</div>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Mobile: Vertical alignment**
|
|
100
|
+
- `flex-col` (default)
|
|
101
|
+
- `lg:flex-row` (Desktop)
|
|
102
|
+
|
|
103
|
+
### Hide/Show
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
{/* Show on mobile only */}
|
|
107
|
+
<nav className="lg:hidden">
|
|
108
|
+
Mobile Menu
|
|
109
|
+
</nav>
|
|
110
|
+
|
|
111
|
+
{/* Show on desktop only */}
|
|
112
|
+
<nav className="hidden lg:block">
|
|
113
|
+
Desktop Menu
|
|
114
|
+
</nav>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Responsive Font Sizes
|
|
120
|
+
|
|
121
|
+
### Method 1: Tailwind Responsive Classes
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
<h1 className="text-[24px] md:text-[32px] lg:text-[40px]">
|
|
125
|
+
Heading
|
|
126
|
+
</h1>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Method 2: clamp() (Recommended)
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
<h1 className="text-[clamp(24px,5vw,40px)]">
|
|
133
|
+
Heading
|
|
134
|
+
</h1>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**clamp(minimum, preferred, maximum):**
|
|
138
|
+
- Minimum: Size at 320px
|
|
139
|
+
- Preferred: Viewport-based size
|
|
140
|
+
- Maximum: Size at 1920px
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Responsive Spacing
|
|
145
|
+
|
|
146
|
+
### Padding
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
<div className="p-[16px] md:p-[24px] lg:p-[32px]">
|
|
150
|
+
Content
|
|
151
|
+
</div>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Gap
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
<div className="flex gap-[12px] md:gap-[16px] lg:gap-[24px]">
|
|
158
|
+
<Item />
|
|
159
|
+
<Item />
|
|
160
|
+
</div>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Responsive Images
|
|
166
|
+
|
|
167
|
+
### Method 1: <picture> Tag
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
<picture>
|
|
171
|
+
{/* Desktop */}
|
|
172
|
+
<source
|
|
173
|
+
media="(min-width: 1024px)"
|
|
174
|
+
srcSet="/images/hero/banner-desktop.webp"
|
|
175
|
+
/>
|
|
176
|
+
{/* Tablet */}
|
|
177
|
+
<source
|
|
178
|
+
media="(min-width: 768px)"
|
|
179
|
+
srcSet="/images/hero/banner-tablet.webp"
|
|
180
|
+
/>
|
|
181
|
+
{/* Mobile (fallback) */}
|
|
182
|
+
<img
|
|
183
|
+
src="/images/hero/banner-mobile.webp"
|
|
184
|
+
alt="Hero Banner"
|
|
185
|
+
className="w-full h-auto"
|
|
186
|
+
/>
|
|
187
|
+
</picture>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Method 2: srcSet
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
<img
|
|
194
|
+
src="/images/hero/banner-mobile.webp"
|
|
195
|
+
srcSet="
|
|
196
|
+
/images/hero/banner-mobile.webp 768w,
|
|
197
|
+
/images/hero/banner-tablet.webp 1024w,
|
|
198
|
+
/images/hero/banner-desktop.webp 1920w
|
|
199
|
+
"
|
|
200
|
+
sizes="(max-width: 767px) 100vw, (max-width: 1023px) 100vw, 1920px"
|
|
201
|
+
alt="Hero Banner"
|
|
202
|
+
/>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Method 3: Tailwind Responsive Classes
|
|
206
|
+
|
|
207
|
+
```tsx
|
|
208
|
+
{/* Mobile: vertical, Desktop: horizontal */}
|
|
209
|
+
<img
|
|
210
|
+
src="/images/hero/banner.webp"
|
|
211
|
+
alt="Hero"
|
|
212
|
+
className="w-full h-auto lg:w-1/2"
|
|
213
|
+
/>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Container Responsive
|
|
219
|
+
|
|
220
|
+
### Max Width
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
<div className="max-w-[375px] md:max-w-[768px] lg:max-w-[1200px] mx-auto px-4 md:px-6 lg:px-8">
|
|
224
|
+
Content
|
|
225
|
+
</div>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Full Width
|
|
229
|
+
|
|
230
|
+
```tsx
|
|
231
|
+
{/* Mobile: full, Desktop: limited */}
|
|
232
|
+
<div className="w-full lg:max-w-[1200px] lg:mx-auto">
|
|
233
|
+
Content
|
|
234
|
+
</div>
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Responsive Navigation
|
|
240
|
+
|
|
241
|
+
### Hamburger Menu (Mobile)
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
const [isOpen, setIsOpen] = useState(false)
|
|
245
|
+
|
|
246
|
+
return (
|
|
247
|
+
<header>
|
|
248
|
+
{/* Mobile Hamburger */}
|
|
249
|
+
<button
|
|
250
|
+
className="lg:hidden"
|
|
251
|
+
onClick={() => setIsOpen(!isOpen)}
|
|
252
|
+
>
|
|
253
|
+
<svg className="w-6 h-6" />
|
|
254
|
+
</button>
|
|
255
|
+
|
|
256
|
+
{/* Mobile Menu */}
|
|
257
|
+
{isOpen && (
|
|
258
|
+
<nav className="lg:hidden fixed inset-0 bg-white z-50">
|
|
259
|
+
<ul>
|
|
260
|
+
<li>Menu 1</li>
|
|
261
|
+
<li>Menu 2</li>
|
|
262
|
+
</ul>
|
|
263
|
+
</nav>
|
|
264
|
+
)}
|
|
265
|
+
|
|
266
|
+
{/* Desktop Menu */}
|
|
267
|
+
<nav className="hidden lg:flex gap-8">
|
|
268
|
+
<a href="/">Menu 1</a>
|
|
269
|
+
<a href="/">Menu 2</a>
|
|
270
|
+
</nav>
|
|
271
|
+
</header>
|
|
272
|
+
)
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Validation Checklist
|
|
278
|
+
|
|
279
|
+
### Mobile (320-767px)
|
|
280
|
+
|
|
281
|
+
```
|
|
282
|
+
□ Layout: Grid → List conversion verified
|
|
283
|
+
□ Font: Small size applied
|
|
284
|
+
□ Spacing: Reduced padding/gap verified
|
|
285
|
+
□ Images: Mobile images load verified
|
|
286
|
+
□ Navigation: Hamburger menu verified
|
|
287
|
+
□ Touch targets: Minimum 44x44px verified
|
|
288
|
+
□ Design matches Figma mobile design 100%
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Tablet (768-1023px)
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
□ Layout: 2-column grid verified
|
|
295
|
+
□ Font: Medium size applied
|
|
296
|
+
□ Spacing: Medium padding/gap verified
|
|
297
|
+
□ Images: Tablet images load verified
|
|
298
|
+
□ Design matches Figma tablet design 100%
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Desktop (1024px+)
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
□ Layout: 4-column grid verified
|
|
305
|
+
□ Font: Large size applied
|
|
306
|
+
□ Spacing: Wide padding/gap verified
|
|
307
|
+
□ Images: Desktop images load verified
|
|
308
|
+
□ Navigation: Full menu displayed
|
|
309
|
+
□ Design matches Figma desktop design 100%
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## Debugging
|
|
315
|
+
|
|
316
|
+
### Chrome DevTools
|
|
317
|
+
|
|
318
|
+
```
|
|
319
|
+
1. Open DevTools (F12)
|
|
320
|
+
2. Toggle Device Toolbar (Ctrl+Shift+M)
|
|
321
|
+
3. Select device or enter custom size
|
|
322
|
+
4. Verify at each breakpoint:
|
|
323
|
+
- Layout changes
|
|
324
|
+
- Font sizes
|
|
325
|
+
- Spacing
|
|
326
|
+
- Image loading
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Media Query Verification
|
|
330
|
+
|
|
331
|
+
```js
|
|
332
|
+
// Check current media query in Console
|
|
333
|
+
window.matchMedia('(min-width: 768px)').matches // true/false
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## Best Practices
|
|
339
|
+
|
|
340
|
+
### DO
|
|
341
|
+
|
|
342
|
+
| Principle | Description |
|
|
343
|
+
|-----------|-------------|
|
|
344
|
+
| **Mobile First** | Base styles → md: → lg: order |
|
|
345
|
+
| **Exact Breakpoints** | Match Figma breakpoints exactly |
|
|
346
|
+
| **Test All Devices** | Verify mobile/tablet/desktop |
|
|
347
|
+
| **Responsive Images** | Provide device-specific images |
|
|
348
|
+
|
|
349
|
+
### DON'T
|
|
350
|
+
|
|
351
|
+
| Forbidden | Reason |
|
|
352
|
+
|-----------|--------|
|
|
353
|
+
| **Desktop Only** | Ignoring mobile causes mismatch |
|
|
354
|
+
| **Fixed Sizes** | `width: 375px` breaks responsiveness |
|
|
355
|
+
| **Arbitrary Breakpoints** | Must match Figma |
|
|
356
|
+
| **Single Image** | Inefficient for all devices |
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## References
|
|
361
|
+
|
|
362
|
+
- [Figma Constraints](https://help.figma.com/hc/en-us/articles/360039957734)
|
|
363
|
+
- [Tailwind Responsive Design](https://tailwindcss.com/docs/responsive-design)
|
|
364
|
+
- [MDN Responsive Images](https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images)
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# Design-Code Verification Guide
|
|
2
|
+
|
|
3
|
+
Checklist for verifying accuracy between Figma design and code.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Verification Checklist
|
|
8
|
+
|
|
9
|
+
### Colors
|
|
10
|
+
|
|
11
|
+
| Check Item | Method |
|
|
12
|
+
|----------|--------|
|
|
13
|
+
| Figma value | Color Picker → #3182F6 |
|
|
14
|
+
| Browser value | DevTools → Computed → `background-color` |
|
|
15
|
+
| Match verification | `getComputedStyle(el).backgroundColor` |
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
□ Primary/Secondary colors
|
|
19
|
+
□ Semantic colors (success/error/warning)
|
|
20
|
+
□ Text/background/border colors
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Spacing
|
|
24
|
+
|
|
25
|
+
| Check Item | Method |
|
|
26
|
+
|----------|--------|
|
|
27
|
+
| Figma value | Auto Layout → Gap 18px, Padding 24px |
|
|
28
|
+
| Browser value | DevTools → Layout → Box Model |
|
|
29
|
+
| Match verification | `getComputedStyle(el).gap` |
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
□ gap value
|
|
33
|
+
□ padding (top/right/bottom/left)
|
|
34
|
+
□ margin (if applicable)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Typography
|
|
38
|
+
|
|
39
|
+
| Check Item | Method |
|
|
40
|
+
|----------|--------|
|
|
41
|
+
| Figma value | Text Style → 28px/600/36px/-0.02em |
|
|
42
|
+
| Browser value | DevTools → Computed |
|
|
43
|
+
| Match verification | `getComputedStyle(el).fontSize` |
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
□ font-family
|
|
47
|
+
□ font-size
|
|
48
|
+
□ font-weight
|
|
49
|
+
□ line-height
|
|
50
|
+
□ letter-spacing
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Layout
|
|
54
|
+
|
|
55
|
+
| Check Item | Method |
|
|
56
|
+
|----------|--------|
|
|
57
|
+
| Figma value | Auto Layout → Horizontal/Center/Center |
|
|
58
|
+
| Browser value | DevTools → Layout → Flexbox |
|
|
59
|
+
| Match verification | `getComputedStyle(el).display` |
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
□ display: flex
|
|
63
|
+
□ flex-direction
|
|
64
|
+
□ justify-content
|
|
65
|
+
□ align-items
|
|
66
|
+
□ gap
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Dimensions
|
|
70
|
+
|
|
71
|
+
| Check Item | Method |
|
|
72
|
+
|----------|--------|
|
|
73
|
+
| Figma value | Button → 120x44px |
|
|
74
|
+
| Browser value | DevTools → Layout → width/height |
|
|
75
|
+
| Match verification | `el.getBoundingClientRect()` |
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
□ width
|
|
79
|
+
□ height
|
|
80
|
+
□ min-width/max-width
|
|
81
|
+
□ min-height/max-height
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Assets (Required)
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
□ Use files downloaded from Figma (no AI-generated)
|
|
88
|
+
□ WebP compression completed
|
|
89
|
+
□ public/images/[category]/ structure
|
|
90
|
+
□ Clear filenames (hero-banner.webp)
|
|
91
|
+
□ Appropriate compression quality (hero: 85-90, general: 75-85)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Responsive (Required)
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
□ Mobile (320-767px) layout verified
|
|
98
|
+
□ Grid → List conversion
|
|
99
|
+
□ Font size reduction
|
|
100
|
+
□ Spacing reduction
|
|
101
|
+
□ Hamburger menu
|
|
102
|
+
|
|
103
|
+
□ Tablet (768-1023px) layout verified
|
|
104
|
+
□ 2-column grid
|
|
105
|
+
□ Medium font size
|
|
106
|
+
□ Medium spacing
|
|
107
|
+
|
|
108
|
+
□ Desktop (1024px+) layout verified
|
|
109
|
+
□ 4-column grid
|
|
110
|
+
□ Large font size
|
|
111
|
+
□ Wide spacing
|
|
112
|
+
□ Full menu
|
|
113
|
+
|
|
114
|
+
□ Responsive images (<picture> or srcSet)
|
|
115
|
+
□ Media query breakpoints exact
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Verification Tools
|
|
121
|
+
|
|
122
|
+
### DevTools Shortcuts
|
|
123
|
+
|
|
124
|
+
| Function | Shortcut |
|
|
125
|
+
|----------|----------|
|
|
126
|
+
| Open DevTools | F12 or Cmd+Opt+I |
|
|
127
|
+
| Device Toolbar | Cmd+Shift+M |
|
|
128
|
+
| Inspect Element | Cmd+Shift+C |
|
|
129
|
+
|
|
130
|
+
### Console Snippets
|
|
131
|
+
|
|
132
|
+
```js
|
|
133
|
+
// Verify color
|
|
134
|
+
const el = document.querySelector('.button')
|
|
135
|
+
console.log(getComputedStyle(el).backgroundColor)
|
|
136
|
+
|
|
137
|
+
// Verify spacing
|
|
138
|
+
const padding = {
|
|
139
|
+
top: getComputedStyle(el).paddingTop,
|
|
140
|
+
right: getComputedStyle(el).paddingRight,
|
|
141
|
+
bottom: getComputedStyle(el).paddingBottom,
|
|
142
|
+
left: getComputedStyle(el).paddingLeft,
|
|
143
|
+
}
|
|
144
|
+
console.table(padding)
|
|
145
|
+
|
|
146
|
+
// Verify typography
|
|
147
|
+
const typography = {
|
|
148
|
+
fontFamily: getComputedStyle(el).fontFamily,
|
|
149
|
+
fontSize: getComputedStyle(el).fontSize,
|
|
150
|
+
fontWeight: getComputedStyle(el).fontWeight,
|
|
151
|
+
lineHeight: getComputedStyle(el).lineHeight,
|
|
152
|
+
letterSpacing: getComputedStyle(el).letterSpacing,
|
|
153
|
+
}
|
|
154
|
+
console.table(typography)
|
|
155
|
+
|
|
156
|
+
// Verify dimensions
|
|
157
|
+
const rect = el.getBoundingClientRect()
|
|
158
|
+
console.log(`Width: ${rect.width}px, Height: ${rect.height}px`)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Visual Comparison
|
|
164
|
+
|
|
165
|
+
### Overlay Tools
|
|
166
|
+
|
|
167
|
+
| Tool | Purpose |
|
|
168
|
+
|------|---------|
|
|
169
|
+
| [PerfectPixel](https://chrome.google.com/webstore/detail/perfectpixel) | Chrome extension |
|
|
170
|
+
| Figma Inspect | Figma Dev Mode → Compare to design |
|
|
171
|
+
|
|
172
|
+
### Usage
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
1. Export Figma as PNG (2x)
|
|
176
|
+
2. Take browser screenshot
|
|
177
|
+
3. Use overlay tool to compare
|
|
178
|
+
4. Fix discrepancies
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Automation
|
|
184
|
+
|
|
185
|
+
### Visual Regression Testing
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# Install Percy
|
|
189
|
+
npm install --save-dev @percy/cli @percy/playwright
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
```js
|
|
193
|
+
// playwright.config.js
|
|
194
|
+
import { percySnapshot } from '@percy/playwright'
|
|
195
|
+
|
|
196
|
+
test('Button matches Figma', async ({ page }) => {
|
|
197
|
+
await page.goto('/components/button')
|
|
198
|
+
await percySnapshot(page, 'Button Component')
|
|
199
|
+
})
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Troubleshooting
|
|
205
|
+
|
|
206
|
+
| Problem | Cause | Solution |
|
|
207
|
+
|---------|-------|----------|
|
|
208
|
+
| Color mismatch | Variables hardcoded instead | Extract Variables |
|
|
209
|
+
| Spacing mismatch | Using Tailwind defaults (`gap-4`) | Use exact value (`gap-[18px]`) |
|
|
210
|
+
| Font mismatch | Letter-spacing conversion error | Verify PERCENT → em conversion |
|
|
211
|
+
| Layout broken | Ignoring Auto Layout | Convert Frame hierarchy directly |
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## References
|
|
216
|
+
|
|
217
|
+
- [Chrome DevTools](https://developer.chrome.com/docs/devtools/)
|
|
218
|
+
- [Percy Visual Testing](https://percy.io/)
|
|
219
|
+
- [Figma Dev Mode](https://help.figma.com/hc/en-us/articles/15023124644247)
|