@su-record/vibe 2.8.17 → 2.8.18

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.
@@ -1,28 +1,76 @@
1
1
  ---
2
2
  name: vibe-figma-rules
3
- description: Figma to Code 분석 및 감지 규칙 — Model Routing, 디자인 분석, 레이어 추출, 스택 감지
3
+ description: Figma to Code 공통 규칙 — Model Routing, 스택 감지, 브레이크포인트, 이미지 분류, 컴포넌트 통합
4
4
  triggers: []
5
5
  tier: standard
6
6
  ---
7
7
 
8
- # Skill: vibe-figma-rules — 분석 감지 규칙
8
+ # Skill: vibe-figma-rules — 공통 규칙 (Single Source of Truth)
9
9
 
10
- 항상 skill을 참조하여 코드를 생성한다.
10
+ 모든 vibe-figma-* 스킬이 참조하는 공통 규칙 정의.
11
+ 중복 방지를 위해 **이 파일에만 정의**하고, 다른 스킬에서는 "vibe-figma-rules R-N 참조"로 사용.
11
12
 
12
13
  ---
13
14
 
14
- ## Model Routing
15
+ ## R-0. 설계 철학
16
+
17
+ > **스크린샷 시각 분석이 핵심이다. 레이어 구조/참조 코드는 보조 수단.**
18
+
19
+ 실무 Figma 파일의 현실:
20
+ ```
21
+ "Frame 633372" ← 의미 없는 자동 이름
22
+ "Frame 633371" ← 중첩된 의미 없는 프레임
23
+ "Frame 633370" ← AI가 구조를 파악할 수 없음
24
+ ```
25
+
26
+ 레이어명이 "Frame 47", "Group 12"이고, Auto Layout 없이 절대 배치된 프레임이 대부분.
27
+ `get_design_context`가 깔끔한 참조 코드를 돌려주지 못하는 것이 **기본 전제**.
28
+
29
+ 이 스킬은 **스토리보드에서 기능/인터랙션/상태를 추출**하고,
30
+ **디자인 프레임 스크린샷에서 스타일/이미지를 시각 분석**하여,
31
+ **원본 디자인 이미지 수준의 완성도**를 달성하는 것이 목적이다.
32
+
33
+ ### 핵심 원칙
34
+
35
+ ```
36
+ 1. 스크린샷이 1차 소스다
37
+ — 모든 시각적 판단(레이아웃, 색상, 간격, 폰트, 이미지 배치)은 스크린샷에서 읽는다
38
+ — get_screenshot으로 섹션별 원본 이미지를 먼저 확보한다
39
+
40
+ 2. 참조 코드는 2차 소스다
41
+ — get_design_context의 참조 코드는 이미지 에셋 URL 추출 + 구조 힌트 용도
42
+ — 참조 코드의 레이아웃/스타일 값은 스크린샷과 대조 후에만 신뢰한다
43
+ — 참조 코드가 부정확해도 스크린샷만으로 코드를 생성할 수 있어야 한다
44
+
45
+ 3. 레이어 구조에 의존하지 않는다
46
+ — 구조화된 레이어는 보너스, 없어도 결과물 품질은 동일해야 한다
47
+ — "Frame 633372" 같은 무의미한 이름이 와도 스크린샷에서 섹션 경계를 파악한다
48
+
49
+ 4. 검증은 항상 시각적 비교로
50
+ — 완료 기준: 원본 스크린샷 vs 생성 코드의 Match Score 95%+, P1=0
51
+ — 코드의 "정확성"이 아니라 "보이는 결과"가 기준이다
52
+ ```
53
+
54
+ ### 분석 우선순위
55
+
56
+ ```
57
+ [1순위] get_screenshot → 시각 분석 (레이아웃, 색상, 간격, 폰트, 배경 이미지)
58
+ [2순위] get_design_context → 에셋 URL 추출 + 구조 힌트 (스크린샷과 대조 필수)
59
+ [3순위] get_metadata → 프레임 목록 + nodeId 확보 (구조 파악이 아닌 탐색 용도)
60
+ ```
61
+
62
+ ---
63
+
64
+ ## R-1. Model Routing
15
65
 
16
66
  | Step | Claude | GPT (Codex) | 이유 |
17
67
  |------|--------|-------------|------|
18
68
  | Step A (스토리보드 + 구조) | **Haiku → Sonnet** | — | MCP 추출 → 구조 설계 |
19
- | Step B (모바일 추출) | **Haiku** | — | MCP + 이미지 다운로드 |
20
- | Step B (모바일 코드 생성) | **Sonnet** | **gpt-5.3-codex-spark** (병렬) | 섹션별 컴포넌트 생성 |
21
- | Step B (모바일 검증) | **Sonnet** | — | 이미지 비교 + auto-fix |
22
- | Step C (PC 추출) | **Haiku** | — | MCP + 이미지 다운로드 |
23
- | Step C (PC 반응형 반영) | **Sonnet** | — | 기존 코드에 반응형 레이어 추가 |
24
- | Step C (PC 검증) | **Sonnet** | — | 양쪽 뷰포트 비교 |
25
- | Step D (공통화) | **Sonnet** | — | 리팩토링 + 최종 검증 |
69
+ | Step B (디자인 추출) | **Haiku** | — | MCP + 이미지 다운로드 |
70
+ | Step B (코드 생성) | **Sonnet** | **gpt-5.3-codex-spark** (병렬) | 섹션별 컴포넌트 생성 |
71
+ | Step B (검증) | **Sonnet** | — | 이미지 비교 + auto-fix |
72
+ | Step C (추가 뷰포트) | **Haiku → Sonnet** | — | 반응형 레이어 추가 |
73
+ | Step D (공통화 + 검증) | **Sonnet** | — | 리팩토링 + 최종 검증 |
26
74
  | Post (코드 리뷰) | — | **gpt-5.3-codex** | 전체 코드 품질 검증 |
27
75
 
28
76
  ### GPT 모델 선택 기준
@@ -33,227 +81,340 @@ tier: standard
33
81
  | `gpt-5.3-codex` | `models.gptCodex` | 코드 리뷰, 분석 (정확도 우선) |
34
82
  | `gpt-5.3-codex-spark` | `models.gptCodexSpark` | 코드 생성 (속도 우선) |
35
83
 
36
- `~/.vibe/config.json`의 `models` 에서 오버라이드 가능.
84
+ `~/.vibe/config.json`의 `models`에서 오버라이드 가능.
37
85
 
38
86
  ---
39
87
 
40
- ## Phase 1: Design Analysis (Image-First)
88
+ ## R-2. 프로젝트 스택 감지
41
89
 
42
- ### Single mode
90
+ ### 2-1. Detect Stack
43
91
 
44
- Read `figma-output/frame.png` and analyze:
92
+ 1. Read `.claude/vibe/config.json` `stacks` 필드
93
+ 2. config 없으면 프로젝트 파일에서 감지:
45
94
 
46
- | Aspect | What to Extract |
47
- |--------|-----------------|
48
- | Layout | Flex/Grid direction, alignment, wrapping |
49
- | Components | Visual boundaries (cards, buttons, inputs, modals) |
50
- | Spacing | Padding, margins, gaps between elements |
51
- | Typography | Font sizes, weights, line heights, hierarchy |
52
- | Colors | Background, text, border, accent colors |
53
- | States | Hover/active/disabled indicators if visible |
54
- | Responsive hints | Breakpoint indicators, fluid vs fixed widths |
95
+ | 감지 대상 | 파일 패턴 |
96
+ |-----------|----------|
97
+ | React | `package.json` `react` in deps |
98
+ | Vue | `package.json` `vue` in deps |
99
+ | Next.js | `next.config.*` |
100
+ | Nuxt | `nuxt.config.*` |
101
+ | Svelte | `svelte.config.*` |
102
+ | Tailwind | `tailwind.config.*` |
103
+ | CSS Modules | `*.module.css` 패턴 |
104
+ | SCSS | `*.scss` 또는 `sass` in deps |
105
+ | CSS-in-JS | `styled-components` / `@emotion` in deps |
55
106
 
56
- ### Responsive mode
107
+ ### 2-2. 디렉토리 감지
57
108
 
58
- Read **ALL** frame images and analyze **side-by-side**:
109
+ | 용도 | Next.js | Nuxt | React | Vue |
110
+ |------|---------|------|-------|-----|
111
+ | 페이지 | `pages/` or `app/` | `pages/` | `src/pages/` or `src/views/` | `src/views/` |
112
+ | 컴포넌트 | `components/` or `src/components/` | `components/` | `src/components/` | `src/components/` |
113
+ | 스타일 | SCSS: `assets/scss/` or `src/styles/`, CSS: `src/styles/`, Tailwind: `tailwind.config.*` |
59
114
 
60
- | Aspect | What to Compare |
61
- |--------|-----------------|
62
- | Layout shift | Which elements reflow? (e.g., horizontal → vertical stack) |
63
- | Visibility | Which elements hide/show per viewport? |
64
- | Typography scale | Font size ratio between viewports |
65
- | Spacing scale | Padding/gap ratio between viewports |
66
- | Component shape | Does the component change form? (e.g., drawer → sidebar) |
67
- | Navigation | Does nav change? (e.g., hamburger ↔ full nav bar) |
115
+ ### 2-3. Design Context 로드
68
116
 
69
- Build a **viewport diff table**:
117
+ 순서대로 읽음 (나중 소스가 우선):
70
118
 
71
- ```
72
- | Element | Mobile (375px) | Desktop (1440px) | Strategy |
73
- |---------------|------------------------|------------------------|-------------------|
74
- | Nav | hamburger + drawer | horizontal bar | component swap |
75
- | Hero title | 24px | 48px | fluid: clamp() |
76
- | Card grid | 1 column | 3 columns | grid auto-fit |
77
- | Sidebar | hidden | visible | display toggle |
78
- | Body text | 14px | 16px | fluid: clamp() |
79
- | Padding | 16px | 48px | fluid: clamp() |
80
- ```
119
+ 1. **`.claude/vibe/design-context.json`** — 브랜드, 접근성, 디바이스 제약
120
+ 2. **`.claude/vibe/design-system/{project}/MASTER.md`** 토큰 정의
121
+
122
+ **결정 규칙**: Figma 토큰 기존 MASTER.md 토큰 (색상 ΔE < 5 또는 간격 ±2px) → 기존 토큰 사용, 중복 생성 금지.
81
123
 
82
124
  ---
83
125
 
84
- ## Phase 2: Layer Data Extraction
126
+ ## R-3. 브레이크포인트 + 스케일 팩터
85
127
 
86
- ### Single mode
128
+ ### 소스 우선순위
87
129
 
88
- Read `figma-output/layers.json` and extract:
130
+ | 순위 | 소스 | 방법 |
131
+ |------|------|------|
132
+ | 1 | **스토리보드** | Step A에서 추출한 `storyboardSpec.breakpoints` |
133
+ | 2 | **`~/.vibe/config.json`** | `figma.breakpoints` (CLI로 커스터마이즈) |
134
+ | 3 | **프로젝트 CSS/Tailwind** | `tailwind.config.*` → `theme.screens`, 또는 `@media` 패턴 |
135
+ | 4 | **기본값** | 아래 테이블 |
89
136
 
90
- 1. **Component hierarchy** — Map nested layers to component tree
91
- 2. **Design tokens** — Colors (fill, stroke), font properties, spacing values, border radius, shadows
92
- 3. **Auto-layout** — Direction, gap, padding (maps directly to flex/grid)
93
- 4. **Constraints** — Fixed vs fluid sizing
94
- 5. **Component instances** — Identify reusable patterns
95
- 6. **Image fills** — Identify layers with `type: "IMAGE"` fills (see Phase 2-A)
137
+ ### 기본 브레이크포인트
96
138
 
97
- ### Responsive mode
139
+ ```
140
+ breakpoint: 1024px ← PC↔Mobile 경계 (@media min-width)
141
+ pcTarget: 1920px ← PC 메인 타겟
142
+ mobilePortrait: 480px ← Mobile portrait max
143
+ mobileMinimum: 360px ← Mobile 최소 지원
144
+ designPc: 2560px ← Figma PC 아트보드 (디자인 2x 스케일)
145
+ designMobile: 720px ← Figma Mobile 아트보드 (디자인 2x 스케일)
146
+ ```
98
147
 
99
- Read **ALL** `layers.{N}.json` files and extract **per-viewport**:
148
+ ### 스케일 팩터 계산
100
149
 
101
- 1. **Per-viewport tokens** — Record exact values for each viewport:
102
- ```
103
- { "mobile": { "h1": 24, "body": 14, "padding": 16 },
104
- "desktop": { "h1": 48, "body": 16, "padding": 48 } }
105
- ```
106
- 2. **Layout differences** — Auto-layout direction changes (e.g., HORIZONTAL → VERTICAL)
107
- 3. **Visibility map** — Which layers exist in one viewport but not the other
108
- 4. **Shared tokens** — Values identical across all viewports (colors, border-radius, shadows are usually shared)
150
+ ```
151
+ PC: scaleFactor.pc = pcTarget / designPc (기본: 1920/2560 = 0.75)
152
+ Mobile: scaleFactor.mobile = mobilePortrait / designMobile (기본: 480/720 = 0.667)
109
153
 
110
- ### Phase 2-A: Image Fill Classification
154
+ 적용: 코드 = Figma 추출 값 × scaleFactor
155
+ - 색상 hex → 스케일 불필요
156
+ - 타이포 (font-size, line-height) → 스케일 적용
157
+ - 간격 (padding, gap, margin) → 스케일 적용
158
+ ```
111
159
 
112
- Figma에서 이미지는 레이어의 `fills` 배열에 `type: "IMAGE"`로 들어옴. 이를 **용도별로 분류**해야 코드에서 올바른 패턴을 생성할 수 있음.
160
+ ### clamp() 계산 공식
113
161
 
114
- #### 감지 방법
162
+ ```
163
+ Step 1: Figma 값 → 타겟 값
164
+ targetMobile = figmaMobileValue × scaleFactor.mobile
165
+ targetPc = figmaPcValue × scaleFactor.pc
166
+
167
+ Step 2: clamp() 생성
168
+ minVw = mobileMinimum (360px)
169
+ maxVw = pcTarget (1920px)
170
+ slope = (targetPc - targetMobile) / (maxVw - minVw)
171
+ intercept = targetMobile - slope × minVw
172
+ → clamp({targetMobile/16}rem, {intercept/16}rem + {slope×100}vw, {targetPc/16}rem)
173
+ ```
115
174
 
116
- `layers.json`에서 아래 패턴을 탐색:
175
+ ### CLI 커스터마이즈
117
176
 
177
+ ```bash
178
+ vibe figma breakpoints # 현재 값 확인
179
+ vibe figma breakpoints --set breakpoint=768 # PC↔Mobile 경계 변경
118
180
  ```
119
- fills: [{ type: "IMAGE", scaleMode: "FILL" | "FIT" | "CROP" | "TILE", imageRef: "..." }]
120
- ```
121
181
 
122
- #### 분류 기준
182
+ ---
183
+
184
+ ## R-4. 이미지 분류 + Multi-Layer 패턴
185
+
186
+ ### 분류 기준
123
187
 
124
188
  | 판별 조건 | 분류 | 코드 패턴 |
125
189
  |----------|------|----------|
126
- | 레이어가 프레임/섹션의 **직계 배경**이고, 위에 텍스트/UI 요소가 겹침 | **Background Image** | `background-image` + `background-size` |
127
- | 레이어가 독립적이고, 위에 겹치는 요소 없음 | **Content Image** | `<img>` 또는 `<picture>` |
128
- | 레이어 이름에 `icon`, `logo`, `avatar` 포함 | **Inline Asset** | `<img>` (작은 크기) |
129
- | 레이어가 반복 패턴(`scaleMode: "TILE"`) | **Pattern/Texture** | `background-image` + `background-repeat` |
130
- | 레이어가 전체 프레임을 덮고 opacity < 1 또는 blendMode 적용 | **Overlay Image** | `background-image` + overlay `::before`/`::after` |
190
+ | 프레임 배경이고 위에 텍스트/UI 겹침 | **Background** | `background-image` + `background-size` |
191
+ | 독립 레이어, 겹치는 요소 없음 | **Content** | `<img>` 또는 `<picture>` |
192
+ | 이름에 `icon`/`logo`/`avatar` | **Inline Asset** | `<img>` (작은 크기) |
193
+ | `scaleMode: "TILE"` 반복 패턴 | **Pattern** | `background-repeat` |
194
+ | 전체 덮음 + opacity < 1 또는 blendMode | **Overlay** | `background-image` + overlay |
131
195
 
132
- #### 이미지-텍스트 겹침 판별 (Background vs Content)
196
+ ### Multi-Layer 패턴 (배경 이미지 섹션 필수 구조)
133
197
 
134
198
  ```
135
- frame의 fills에 IMAGE가 있고, children에 TEXT 레이어가 있으면:
136
- Background Image (텍스트 아래 깔리는 배경)
199
+ .{section}Section ← 레이아웃 (position: relative, overflow: hidden)
200
+ .{section}Bg ← 배경 이미지 z-index: 0
201
+ .{section}BgOverlay ← 오버레이 (선택) — z-index: 1
202
+ .{section}Character ← 캐릭터/일러스트 (선택) — z-index: 2
203
+ .{section}Content ← 텍스트/버튼/UI — z-index: 최상위
204
+ ```
137
205
 
138
- 독립 레이어의 fills에 IMAGE가 있고, 형제 레이어와 겹치지 않으면:
139
- Content Image
206
+ ```css
207
+ .{section}Section { position: relative; overflow: hidden; }
208
+ .{section}Bg {
209
+ position: absolute; inset: 0; z-index: 0;
210
+ background-image: url('/images/{feature}/{name}.webp');
211
+ background-size: cover; background-position: center;
212
+ }
213
+ .{section}BgOverlay {
214
+ position: absolute; inset: 0; z-index: 1;
215
+ background: linear-gradient(to bottom, rgba(0,0,0,0.3), rgba(0,0,0,0.7));
216
+ }
217
+ .{section}Content { position: relative; z-index: 2; }
140
218
  ```
141
219
 
142
- #### 이미지 소스 추출
220
+ ### 배경 이미지 클래스 분리 원칙
143
221
 
144
- - `imageRef` 값으로 Figma API의 이미지 렌더링 사용 (`/images/{fileKey}`)
145
- - 추출된 이미지는 `figma-output/assets/` 디렉토리에 저장
146
- - 파일명은 레이어 이름 기반: `hero-bg.png`, `product-photo.jpg`
222
+ | 유형 | 클래스 예시 | 분리 이유 |
223
+ |------|-----------|----------|
224
+ | 섹션 전면 배경 | `.heroBg` | 시즌/이벤트별 이미지 교체 |
225
+ | 오버레이 | `.heroBgOverlay` | 투명도/그라데이션 독립 조절 |
226
+ | 패턴/텍스처 | `.sectionPattern` | repeat/size 별도 제어 |
227
+ | 캐릭터/일러스트 | `.heroCharacter` | 콜라보별 교체, position 조절 |
228
+ | 그라데이션 | `.sectionGradient` | 테마별 색상 변경 |
147
229
 
148
- ### Responsive Scaling Calculation
230
+ ### 반응형 배경 이미지
149
231
 
150
- Per-viewport 토큰 쌍에서 clamp() 값을 계산. 공식은 **Phase 4-3** 참조.
232
+ ```css
233
+ .heroBg { background-image: url('/images/hero-mobile.webp'); }
234
+ @media (min-width: var(--breakpoint)) {
235
+ .heroBg { background-image: url('/images/hero-pc.webp'); }
236
+ }
237
+ ```
151
238
 
152
- 핵심: Figma 디자인이 2x 스케일(2560px/720px)이므로, 반드시 타겟 해상도(1920px/480px)로 환산 후 clamp를 계산해야 함.
239
+ ### 이미지 공통 규칙
153
240
 
154
- **Correction rule**: When image and JSON disagree, **image wins**. The image shows designer intent; JSON may have structural artifacts.
241
+ | 규칙 | 설명 |
242
+ |------|------|
243
+ | format | `.webp` 우선 (fallback: `.png`/`.jpg`) |
244
+ | alt | 레이어 이름에서 파생, 장식은 `alt=""` + `aria-hidden="true"` |
245
+ | width/height | 항상 명시 (CLS 방지), 스케일 팩터 적용 |
246
+ | loading | 뷰포트 상단 → `eager`, 나머지 → `lazy` |
247
+ | object-fit | `cover` (배경), `contain` (로고/아이콘), `fill` 금지 |
155
248
 
156
249
  ---
157
250
 
158
- ## Phase 3: Project Stack Detection + Mode Resolution
251
+ ## R-5. 컴포넌트 통합 규칙 (80% Rule)
159
252
 
160
- ### 3-1. Detect Stack
253
+ ### 유사도 판단
161
254
 
162
- 1. Read `.claude/vibe/config.json` → check `stacks` field
163
- 2. If no config, detect from project files:
164
- - `package.json` React, Vue, Svelte, Angular, etc.
165
- - `tailwind.config.*` → Tailwind CSS
166
- - `next.config.*` → Next.js
167
- - `nuxt.config.*` → Nuxt
168
- - `*.module.css` → CSS Modules pattern
169
- - `*.scss` / `sass` in deps → SCSS
170
- - `styled-components` / `@emotion` in deps → CSS-in-JS
255
+ ```
256
+ 구조 80%+ 동일 (색상/크기/텍스트만 다름)
257
+ 하나의 컴포넌트 + variant prop으로 통합
171
258
 
172
- ### 3-2. Load Design Context (Design Skill Integration)
259
+ 구조 자체가 다름 (요소 추가/제거, 레이아웃 방향 변경)
260
+ → 별도 컴포넌트 유지
261
+ ```
173
262
 
174
- Read these files **in order** — later sources override earlier ones:
263
+ ### 스택별 variant 구현
175
264
 
176
- 1. **`.claude/vibe/design-context.json`** brand personality, aesthetic direction, constraints
177
- - `aesthetic.style` → guides visual weight (minimal vs bold)
178
- - `aesthetic.colorMood` warm/cool/vibrant tone for token selection
179
- - `brand.personality` preserve brand-expressive elements
180
- - `constraints.accessibility` AA or AAA level (affects contrast, focus, ARIA depth)
181
- - `constraints.devices` responsive breakpoints priority
182
- 2. **`.claude/vibe/design-system/{project}/MASTER.md`** — authoritative token definitions
183
- - If MASTER.md exists: **map Figma tokens to MASTER.md tokens first**, only create new tokens for values with no match
184
- - If no MASTER.md: generate `figma-tokens.css` as standalone token source
265
+ | Stack | 방법 |
266
+ |-------|------|
267
+ | React / Next.js | `variant` prop + 조건부 className |
268
+ | Vue / Nuxt | `variant` prop + `<slot>` |
269
+ | Svelte | `variant` prop + `<slot>` |
270
+ | React Native | `variant` prop + StyleSheet 조건 |
185
271
 
186
- **Decision rule**: When Figma token ≈ existing MASTER.md token (within 10% color distance or ±2px spacing), **use the existing token** — do not duplicate.
272
+ ### Fragment / 래퍼 제거
187
273
 
188
- ### 3-3. Load Breakpoints
274
+ 스타일이나 이벤트가 없는 래핑 요소 → 프레임워크 제공 투명 래퍼 사용:
189
275
 
190
- Breakpoints are loaded from multiple sources in priority order:
276
+ | Stack | 투명 래퍼 |
277
+ |-------|----------|
278
+ | React / Next.js | `<>...</>` |
279
+ | Vue / Nuxt | `<template>` (컴포넌트 루트 이외) |
280
+ | Svelte | `{#if}`, `{#each}` 블록 |
191
281
 
192
- #### Source Priority
282
+ ---
193
283
 
194
- | Priority | Source | How |
195
- |----------|--------|-----|
196
- | 1 | **Storyboard** | Phase 0-1에서 추출한 `storyboardSpec.breakpoints` |
197
- | 2 | **`~/.vibe/config.json`** | `figma.breakpoints` — user-customized via `vibe figma breakpoints --set` |
198
- | 3 | **Project CSS/Tailwind** | Grep `tailwind.config.*` → `theme.screens`, or `@media.*min-width` patterns in codebase |
199
- | 4 | **Defaults** | Built-in values (breakpoint: 1024px, etc.) |
284
+ ## R-6. 검증 루프 공통 규칙
200
285
 
201
- #### Default Breakpoints (built-in)
286
+ 모든 Step에서 사용하는 스크린샷 기반 검증 프로세스.
202
287
 
203
- Based on game industry responsive storyboard standards:
288
+ ### 6-1. 원본 스크린샷 확보
204
289
 
205
290
  ```
206
- breakpoint: 1024px ← PC↔Mobile boundary (@media min-width)
207
- pcTarget: 1920px ← PC main target resolution
208
- mobilePortrait: 480px ← Mobile portrait max width
209
- mobileMinimum: 360px ← Mobile minimum supported width
210
- designPc: 2560px ← Figma PC artboard width (design is 2x scale)
211
- designMobile: 720px ← Figma Mobile artboard width (design is 2x scale)
291
+ Step A에서 get_screenshot으로 확보한 섹션별 원본 이미지를 기준으로 사용.
292
+ 없으면 해당 섹션의 nodeId로 get_screenshot 재호출.
293
+
294
+ 원본 = Figma 디자인 스크린샷 (디자이너 의도)
212
295
  ```
213
296
 
214
- #### How to use in code generation
297
+ ### 6-2. 생성 코드 렌더링 확보
215
298
 
216
299
  ```
217
- @media breakpoint:
218
- - Single breakpoint model: @media (min-width: {breakpoint}px)
219
- - Mobile-first: styles below breakpoint = mobile, above = PC
300
+ 방법 (우선순위):
301
+ 1. /vibe.utils --preview 브라우저 렌더링 스크린샷 자동 생성
302
+ 2. dev 서버 실행 중이면 해당 페이지 스크린샷 (Playwright/Puppeteer)
303
+ 3. 둘 다 불가능하면 → 생성된 코드를 직접 읽고 시각적 결과를 추론
220
304
 
221
- clamp() range:
222
- - minVw = mobileMinimum (360px) smallest supported viewport
223
- - maxVw = pcTarget (1920px) — largest target viewport
224
- - Values scale linearly between these bounds
305
+ ⚠️ 방법 3(코드 읽기 추론) 최후 수단.
306
+ 가능한 실제 렌더링 결과를 확보해야 정확한 비교 가능.
307
+ ```
225
308
 
226
- Design scale factor:
227
- - PC design at {designPc}px targets {pcTarget}px → scale = pcTarget/designPc
228
- - Mobile design at {designMobile}px targets {mobilePortrait}px → scale = mobilePortrait/designMobile
229
- - Apply scale to convert Figma pixel values to target pixel values
309
+ ### 6-3. 섹션별 비교 (전체 페이지가 아닌 섹션 단위)
310
+
311
+ ```
312
+ 섹션 컴포넌트를 개별로 비교:
313
+ 원본: Figma 섹션 스크린샷 (get_screenshot per section)
314
+ 생성: 렌더링된 섹션 스크린샷 (또는 코드 추론)
315
+
316
+ 섹션별로 비교해야 하는 이유:
317
+ - 전체 페이지 비교는 스크롤 길이 차이로 오차가 큼
318
+ - 섹션 단위가 수정 범위를 좁힐 수 있음
319
+ - P1 발견 시 해당 섹션만 수정 → 재비교
230
320
  ```
231
321
 
232
- #### User customization
322
+ ### 6-4. 비교 항목 + P1/P2 분류
233
323
 
234
- Users can override any value via CLI:
324
+ | 비교 항목 | P1 (필수 수정) | P2 (권장 수정) |
325
+ |----------|---------------|---------------|
326
+ | **레이아웃** | 요소 배치 방향 다름, 섹션 순서 다름 | 미세 정렬 차이 |
327
+ | **배경 이미지** | 누락, 완전히 다른 이미지 | 크기/위치 미세 차이 |
328
+ | **색상** | 배경/텍스트색 완전히 다름 | 미세한 톤 차이 (ΔE < 10) |
329
+ | **타이포** | 제목/본문 크기 비율 다름, 굵기 다름 | ±2px 차이 |
330
+ | **간격** | 섹션 간 간격 크게 다름, 요소 겹침 | ±4px 차이 |
331
+ | **이미지 에셋** | 다운로드 실패, 경로 깨짐 | 크기/비율 미세 차이 |
332
+ | **누락 요소** | 스크린샷에 보이는 요소가 코드에 없음 | — |
333
+ | **오버레이** | 배경 위 텍스트 가독성 확보 안 됨 | 투명도 미세 차이 |
235
334
 
236
- ```bash
237
- vibe figma breakpoints # Show current values
238
- vibe figma breakpoints --set breakpoint=768 # Change PC↔Mobile boundary
239
- vibe figma breakpoints --set mobileMinimum=320 # Change mobile minimum
335
+ ### 6-5. Diff Report 출력
336
+
337
+ ```markdown
338
+ ## Visual Diff Report {섹션명}
339
+
340
+ 원본: Figma {섹션} 스크린샷
341
+ 생성: 렌더링 결과 (또는 코드 추론)
342
+
343
+ ### Match Score: {N}%
344
+
345
+ | # | 항목 | 원본 | 생성 코드 | 심각도 |
346
+ |---|------|------|----------|--------|
347
+ | 1 | 배경 이미지 | 눈 테마 + 그라데이션 | 누락 | P1 |
348
+ | 2 | 제목 font-size | ~36px (스케일 후) | 24px | P1 |
349
+ | 3 | 카드 border-radius | ~12px | 8px | P2 |
240
350
  ```
241
351
 
242
- Stored in `~/.vibe/config.json` `figma.breakpoints`. Partial overrides merge with defaults.
352
+ ### 6-6. Auto-Fix Loop
243
353
 
244
- ### 3-4. Resolve Generation Mode
354
+ ```
355
+ P1이 있으면:
356
+ 1. 해당 섹션의 컴포넌트/스타일 파일 수정
357
+ 2. 수정 후 렌더링 재확보 (가능하면)
358
+ 3. 원본 스크린샷과 재비교
359
+ 4. P1=0 될 때까지 반복 — 횟수 제한 없음
360
+
361
+ 같은 P1이 반복될 때:
362
+ - 이전과 동일한 수정을 반복하지 않는다
363
+ - 접근 방식을 바꿔서 시도한다 (다른 CSS 속성, 다른 레이아웃 전략)
364
+ - 접근을 바꿔도 해결 안 되면 → 사용자에게 해당 항목을 보여주고 방향 확인
365
+ - 사용자 확인 후에도 루프는 계속된다 — P1=0이 될 때까지 멈추지 않음
366
+ ```
367
+
368
+ ### 6-7. 완료 조건
369
+
370
+ ```
371
+ ✅ 모든 섹션 Match Score 95%+
372
+ ✅ P1 = 0 (전 섹션)
373
+ ✅ 모든 이미지 에셋 표시 + Figma 임시 URL 잔존 0건
374
+ ✅ (반응형) 각 뷰포트 독립 검증 통과
375
+ ```
376
+
377
+ ---
378
+
379
+ ## R-7. 스크린샷 중심 분석 프로세스
245
380
 
246
- **Both modes use the project's existing directory structure.** Never create `figma-output/generated/`.
381
+ ### 섹션별 분석 순서
247
382
 
248
383
  ```
249
- if --new flag:
250
- detect project's page/component/style directories (same as default)
251
- generate self-contained token file (no MASTER.md dependency)
252
- → components are self-contained (own tokens, no external design system imports)
253
- placed in project's standard directories with feature-named subfolder
384
+ Step 1: get_screenshot(섹션 nodeId)
385
+ 원본 디자인 이미지 확보
386
+ 시각 분석: 레이아웃 구조, 색상 팔레트, 폰트 크기/굵기, 간격, 배경 이미지 유무
387
+
388
+ Step 2: get_design_context(섹션 nodeId)
389
+ → 이미지 에셋 URL 추출 (const xxxImage = 'https://figma.com/api/mcp/asset/...')
390
+ → 참조 코드에서 구조 힌트 확인 (HTML 계층, 컴포넌트 분리 방식)
391
+ → ⚠️ 참조 코드의 스타일 값은 스크린샷과 대조 후에만 채택
392
+
393
+ Step 3: 스크린샷 기반 코드 생성
394
+ → 스크린샷에서 읽은 시각 정보로 스타일 작성
395
+ → 참조 코드의 에셋 URL을 로컬 경로로 교체
396
+ → 참조 코드 구조가 스크린샷과 다르면 → 스크린샷 기준으로 재구성
397
+ ```
398
+
399
+ ### 스크린샷에서 읽어야 하는 것
254
400
 
255
- default (no flag):
256
- → scan existing component directories, theme files, token definitions
257
- map output to project's conventions (file location, naming, imports)
258
- add only NEW tokens that don't exist yet
401
+ | 항목 | 읽는 방법 |
402
+ |------|----------|
403
+ | 레이아웃 | 섹션 경계, flex/grid 방향, 요소 배치, 중첩 관계 |
404
+ | 배경 | 이미지 배경 vs 단색 vs 그라데이션, 오버레이 유무 |
405
+ | 색상 | 배경색, 텍스트색, 버튼색, 보더색 (hex 추정) |
406
+ | 타이포 | 제목/본문 크기 비율, 굵기, 줄간격 (스케일 팩터 적용) |
407
+ | 간격 | 섹션 패딩, 요소 간 gap, 마진 (스케일 팩터 적용) |
408
+ | 이미지 배치 | Background vs Content vs Overlay (R-4 분류) |
409
+ | 시각적 계층 | z-index 관계, 겹침 구조, 투명도 |
410
+
411
+ ### 참조 코드에서 읽어야 하는 것 (보조)
412
+
413
+ ```
414
+ ✅ 이미지 에셋 URL (다운로드용) — 이것이 참조 코드의 핵심 가치
415
+ ✅ 정확한 hex 색상값 (스크린샷 추정보다 정확할 때)
416
+ ✅ 폰트 패밀리명
417
+ ✅ 정확한 border-radius, shadow 값
418
+ ⚠️ 레이아웃 구조 — 스크린샷과 대조 후 채택
419
+ ❌ px 값 그대로 사용 — 반드시 스케일 팩터 적용
259
420
  ```