@su-record/vibe 2.8.20 → 2.8.21
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/package.json +1 -1
- package/skills/vibe-figma/SKILL.md +279 -62
- package/skills/vibe-figma-analyze/SKILL.md +4 -338
- package/skills/vibe-figma-codegen/SKILL.md +3 -189
- package/skills/vibe-figma-consolidate/SKILL.md +3 -93
- package/skills/vibe-figma-convert/SKILL.md +284 -0
- package/skills/vibe-figma-extract/SKILL.md +150 -0
- package/skills/vibe-figma-frame/SKILL.md +4 -528
- package/skills/vibe-figma-rules/SKILL.md +3 -456
- package/skills/vibe-figma-style/SKILL.md +3 -207
|
@@ -1,344 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vibe-figma-analyze
|
|
3
|
-
|
|
4
|
-
description: "스토리보드 세밀 분석 → 실제 레이아웃 코드 + 기능 주석 + 컴포넌트 구조 생성. Step A에서 vibe-figma 이후 실행."
|
|
3
|
+
description: "[Merged] → vibe-figma (Phase 1: Storyboard) 참조"
|
|
5
4
|
triggers: []
|
|
5
|
+
tier: standard
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
스토리보드 URL 하나로 **실제 동작하는 레이아웃 코드**를 생성.
|
|
11
|
-
빈 shell이 아니라, 스토리보드에서 파악 가능한 모든 정보를 코드에 반영.
|
|
12
|
-
|
|
13
|
-
> **실행 지시: 이 스킬은 분석만 하는 게 아님. 반드시 Write 도구로 파일을 생성해야 함.**
|
|
14
|
-
> A-1~A-4에서 분석 → A-5에서 **Write 도구로 실제 파일 생성** → A-6에서 인터랙션 테이블 출력.
|
|
15
|
-
|
|
16
|
-
## 입력
|
|
17
|
-
|
|
18
|
-
- 스토리보드 URL의 get_metadata 결과 (전체 프레임 목록)
|
|
19
|
-
- storyboardSpec (브레이크포인트 등, vibe-figma에서 추출)
|
|
20
|
-
|
|
21
|
-
## A-1. 프레임 전수 조사
|
|
22
|
-
|
|
23
|
-
get_metadata에서 얻은 **모든 최상위 프레임**을 분류:
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
SKIP — "개요", "Cover", "변경 이력" (문서 관리용)
|
|
27
|
-
SPEC — "기능 정의", "정책" → 기능 스펙 텍스트 추출 대상
|
|
28
|
-
CONFIG — "해상도", "Media Query", "브라우저" → 설정값 추출
|
|
29
|
-
SHARED — "공통", "GNB", "Footer", "Popup", "Dialog" → 공통 컴포넌트
|
|
30
|
-
FLOW — "Event Flow", "플로우" → 유저 플로우 파악
|
|
31
|
-
ASSET — "OG", "배너", "어셋" → 스킵 (메타 이미지)
|
|
32
|
-
PAGE — "메인", "화면설계" 하위 → 핵심 섹션 (코드 생성 대상)
|
|
33
|
-
|
|
34
|
-
서브 프레임 (3.x.1, 3.x.2 등):
|
|
35
|
-
→ 해당 PAGE 섹션의 상태 변형 / 인터랙션 결과 화면
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## A-2. SPEC 프레임 세밀 분석
|
|
39
|
-
|
|
40
|
-
**기능 정의서 프레임**에 대해 get_design_context 호출:
|
|
41
|
-
|
|
42
|
-
```
|
|
43
|
-
추출 대상:
|
|
44
|
-
- Overview: 개요, 대상, 일정
|
|
45
|
-
- Spec: 각 섹션별 기능 정의 (로직, 조건, 보상 구조)
|
|
46
|
-
- 일정: 시작/종료 시간, 단계별 기간
|
|
47
|
-
|
|
48
|
-
추출한 텍스트를 섹션별로 분리:
|
|
49
|
-
{
|
|
50
|
-
"overview": "...",
|
|
51
|
-
"sections": {
|
|
52
|
-
"hero": "키 비주얼 영역, CTA 버튼...",
|
|
53
|
-
"featureA": "섹션 A 기능 설명...",
|
|
54
|
-
"featureB": "섹션 B 기능 설명..."
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
→ A-5에서 각 컴포넌트의 기능 주석이 됨
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## A-3. SHARED 프레임 분석
|
|
62
|
-
|
|
63
|
-
공통 요소 프레임들의 get_screenshot으로 구조 파악:
|
|
64
|
-
|
|
65
|
-
```
|
|
66
|
-
GNB: 네비게이션 구조, 메뉴 항목, 로그인 버튼
|
|
67
|
-
Footer: 링크, 법적 고지
|
|
68
|
-
Popup: 패턴 분류 (확인/취소, 상세 모달, 알림, 입력 폼)
|
|
69
|
-
|
|
70
|
-
→ 프로젝트에 이미 있는 컴포넌트 확인 (Glob으로 탐색)
|
|
71
|
-
→ 있으면 import 재사용, 없으면 새로 생성
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
## A-4. PAGE 프레임 세밀 분석
|
|
75
|
-
|
|
76
|
-
> **모든 PAGE 프레임을 빠짐없이 분석한다. 일부만 처리하고 넘어가면 안 됨.**
|
|
77
|
-
> A-1에서 PAGE로 분류된 프레임 수 = A-5에서 생성하는 섹션 컴포넌트 수.
|
|
78
|
-
|
|
79
|
-
**각 PAGE 프레임**에 대해 get_screenshot + get_design_context:
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
각 프레임에서 추출:
|
|
83
|
-
|
|
84
|
-
1. 레이아웃 구조 (get_screenshot 비주얼 분석):
|
|
85
|
-
- 섹션 경계 (배경 변화 지점)
|
|
86
|
-
- 요소 배치 방향 (vertical stack / grid / positioned)
|
|
87
|
-
- 이미지 배경 영역 vs 콘텐츠 영역
|
|
88
|
-
|
|
89
|
-
2. 인터랙션 스펙 (우측 주석):
|
|
90
|
-
- 번호 태그 (①②③) → 인터랙션 ID
|
|
91
|
-
- 동작 설명 → 이벤트 타입 + 결과
|
|
92
|
-
- 조건 분기 (로그인 여부, 기간 내/외 등)
|
|
93
|
-
|
|
94
|
-
3. 상태 변형 (서브 프레임):
|
|
95
|
-
- 기본 → 클릭 후 → 성공 → 에러 등
|
|
96
|
-
- 팝업 트리거 조건
|
|
97
|
-
|
|
98
|
-
결과를 섹션별로 저장:
|
|
99
|
-
sections[sectionName] = {
|
|
100
|
-
layout: "vertical-stack, bg-image + overlay + content",
|
|
101
|
-
children: ["Title", "Description", "Grid", "CTAButton"],
|
|
102
|
-
interactions: [
|
|
103
|
-
{ id: "①", trigger: "클릭", action: "처리", result: "결과 표시" }
|
|
104
|
-
],
|
|
105
|
-
states: ["default", "active", "completed"],
|
|
106
|
-
popups: ["ConfirmDialog"]
|
|
107
|
-
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## A-5. 파일 생성 (Write 도구 사용 — 필수)
|
|
111
|
-
|
|
112
|
-
> **Write 도구로 아래 파일들을 실제로 생성한다. 코드를 보여주기만 하면 안 됨.**
|
|
113
|
-
|
|
114
|
-
디렉토리는 **vibe-figma-rules R-2.2** 감지 결과에 따라 결정.
|
|
115
|
-
|
|
116
|
-
### 생성할 파일 목록
|
|
117
|
-
|
|
118
|
-
```
|
|
119
|
-
필수 생성 (Write 도구):
|
|
120
|
-
1. pages/{feature-name}.{vue|tsx} ← 루트 페이지
|
|
121
|
-
2. components/{feature-name}/각섹션.{vue|tsx} ← 섹션별 컴포넌트
|
|
122
|
-
3. components/{feature-name}/popups/각팝업 ← 팝업 컴포넌트
|
|
123
|
-
4. styles/{feature-name}/index.scss ← 스타일 진입점 (빈 import 목록)
|
|
124
|
-
5. styles/{feature-name}/_tokens.scss ← 빈 토큰 파일 (Step B에서 채움)
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### 루트 페이지 구조
|
|
128
|
-
|
|
129
|
-
```
|
|
130
|
-
- 모든 섹션 컴포넌트 import
|
|
131
|
-
- 팝업 조건부 렌더링 (v-if/&&)
|
|
132
|
-
- 개요 JSDoc 주석 (A-2에서 추출한 overview)
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### HARD RULE: 빈 template 금지
|
|
136
|
-
|
|
137
|
-
```
|
|
138
|
-
브라우저에서 열었을 때 화면에 텍스트가 보여야 한다.
|
|
139
|
-
빈 컴포넌트 shell은 Step A 미완성.
|
|
140
|
-
|
|
141
|
-
<template> 안에 반드시:
|
|
142
|
-
- 스토리보드에서 추출한 실제 텍스트 (제목, 설명, 버튼 라벨)
|
|
143
|
-
- 목 데이터가 렌더링되는 리스트 (v-for / .map)
|
|
144
|
-
- 클릭 가능한 버튼/링크
|
|
145
|
-
- 조건부 렌더링 (v-if / &&)
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### 섹션 컴포넌트 — 실제 코드 예시 (Vue)
|
|
149
|
-
|
|
150
|
-
```vue
|
|
151
|
-
<template>
|
|
152
|
-
<section class="dailyCheckInSection">
|
|
153
|
-
<h2 class="dailyCheckInSection__title">일일 출석 미션</h2>
|
|
154
|
-
<p class="dailyCheckInSection__description">매일 출석하고 스노우 토큰을 받으세요!</p>
|
|
155
|
-
|
|
156
|
-
<div class="dailyCheckInSection__calendar">
|
|
157
|
-
<div
|
|
158
|
-
v-for="day in checkInDays"
|
|
159
|
-
:key="day.date"
|
|
160
|
-
class="dailyCheckInSection__day"
|
|
161
|
-
:class="{ 'is-checked': day.checked, 'is-today': day.isToday }"
|
|
162
|
-
@click="handleCheckIn(day)"
|
|
163
|
-
>
|
|
164
|
-
<span class="dailyCheckInSection__dayLabel">{{ day.date }}</span>
|
|
165
|
-
<span class="dailyCheckInSection__dayReward">{{ day.reward }} 토큰</span>
|
|
166
|
-
</div>
|
|
167
|
-
</div>
|
|
168
|
-
|
|
169
|
-
<div class="dailyCheckInSection__milestones">
|
|
170
|
-
<div
|
|
171
|
-
v-for="milestone in milestones"
|
|
172
|
-
:key="milestone.days"
|
|
173
|
-
class="dailyCheckInSection__milestone"
|
|
174
|
-
:class="{ 'is-claimable': milestone.claimable, 'is-claimed': milestone.claimed }"
|
|
175
|
-
@click="handleClaimReward(milestone)"
|
|
176
|
-
>
|
|
177
|
-
<span>{{ milestone.days }}일 달성</span>
|
|
178
|
-
<span>{{ milestone.reward }}</span>
|
|
179
|
-
<button v-if="milestone.claimable && !milestone.claimed">받기</button>
|
|
180
|
-
</div>
|
|
181
|
-
</div>
|
|
182
|
-
</section>
|
|
183
|
-
</template>
|
|
184
|
-
|
|
185
|
-
<script setup lang="ts">
|
|
186
|
-
/**
|
|
187
|
-
* 일일 출석 미션 섹션
|
|
188
|
-
*
|
|
189
|
-
* [기능 정의]
|
|
190
|
-
* - 매일 출석 시 스노우 토큰 즉시 지급
|
|
191
|
-
* - 누적 3/5/7일 달성 시 추가 보상
|
|
192
|
-
*
|
|
193
|
-
* [인터랙션]
|
|
194
|
-
* ① 출석하기 클릭 → 출석 처리 → 토큰 지급 표시
|
|
195
|
-
* ② 누적 보상 클릭 → 보상 수령
|
|
196
|
-
*
|
|
197
|
-
* [상태] default, checked, reward-claimed
|
|
198
|
-
*/
|
|
199
|
-
|
|
200
|
-
interface CheckInDay {
|
|
201
|
-
date: string
|
|
202
|
-
checked: boolean
|
|
203
|
-
isToday: boolean
|
|
204
|
-
reward: number
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
interface Milestone {
|
|
208
|
-
days: number
|
|
209
|
-
claimable: boolean
|
|
210
|
-
claimed: boolean
|
|
211
|
-
reward: string
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// 목 데이터 — 빈 배열 금지!
|
|
215
|
-
const checkInDays = ref<CheckInDay[]>([
|
|
216
|
-
{ date: 'Day 1', checked: true, isToday: false, reward: 10 },
|
|
217
|
-
{ date: 'Day 2', checked: true, isToday: false, reward: 10 },
|
|
218
|
-
{ date: 'Day 3', checked: false, isToday: true, reward: 10 },
|
|
219
|
-
{ date: 'Day 4', checked: false, isToday: false, reward: 10 },
|
|
220
|
-
{ date: 'Day 5', checked: false, isToday: false, reward: 10 },
|
|
221
|
-
{ date: 'Day 6', checked: false, isToday: false, reward: 15 },
|
|
222
|
-
{ date: 'Day 7', checked: false, isToday: false, reward: 20 },
|
|
223
|
-
])
|
|
224
|
-
|
|
225
|
-
const milestones = ref<Milestone[]>([
|
|
226
|
-
{ days: 3, claimable: false, claimed: false, reward: '보상 상자 1개' },
|
|
227
|
-
{ days: 5, claimable: false, claimed: false, reward: '보상 상자 2개' },
|
|
228
|
-
{ days: 7, claimable: false, claimed: false, reward: '스페셜 보상' },
|
|
229
|
-
])
|
|
230
|
-
|
|
231
|
-
function handleCheckIn(day: CheckInDay): void {
|
|
232
|
-
// TODO: 출석 API 호출
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
function handleClaimReward(milestone: Milestone): void {
|
|
236
|
-
// TODO: 누적 보상 수령 API 호출
|
|
237
|
-
}
|
|
238
|
-
</script>
|
|
239
|
-
<!-- 스타일은 외부 파일: styles/{feature}/components/_daily-checkin.scss -->
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
### 필수 포함 사항 체크리스트
|
|
243
|
-
|
|
244
|
-
```
|
|
245
|
-
<template> 안에:
|
|
246
|
-
□ 섹션 제목 <h2> (스토리보드에서 추출한 실제 텍스트)
|
|
247
|
-
□ 설명 텍스트 <p> (스토리보드에서 추출)
|
|
248
|
-
□ 리스트 렌더링 (v-for + 목 데이터, 빈 배열 금지)
|
|
249
|
-
□ 버튼/CTA (실제 라벨 텍스트 + @click 핸들러)
|
|
250
|
-
□ 조건부 렌더링 (상태에 따른 v-if)
|
|
251
|
-
□ 클래스명 (Step B에서 외부 스타일과 매칭)
|
|
252
|
-
|
|
253
|
-
<script> 안에:
|
|
254
|
-
□ JSDoc: [기능 정의] + [인터랙션] + [상태]
|
|
255
|
-
□ TypeScript interface
|
|
256
|
-
□ 목 데이터 (기능 정의서에서 추출, 3~7개 아이템)
|
|
257
|
-
□ 이벤트 핸들러 함수 (body는 // TODO:)
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
### 스타일 분리 규칙
|
|
261
|
-
|
|
262
|
-
```
|
|
263
|
-
컴포넌트 파일에 <style> 블록을 작성하지 않는다.
|
|
264
|
-
스타일은 Step B에서 외부 파일로 생성.
|
|
265
|
-
컴포넌트는 <template> + <script setup> 만 포함.
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
### Step A 완료 기준
|
|
269
|
-
|
|
270
|
-
```
|
|
271
|
-
브라우저에서 열었을 때:
|
|
272
|
-
✅ 각 섹션의 제목/설명 텍스트가 화면에 보인다
|
|
273
|
-
✅ 리스트 아이템이 렌더링된다 (목 데이터)
|
|
274
|
-
✅ 버튼을 클릭하면 핸들러가 실행된다
|
|
275
|
-
✅ 탭/아코디언/모달이 동작한다
|
|
276
|
-
❌ 스타일은 없다 (Step B에서)
|
|
277
|
-
❌ 이미지는 없다 (Step B에서)
|
|
278
|
-
|
|
279
|
-
빈 화면 = Step A 미완성. 다음 단계로 넘어가지 않는다.
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
## A-6. 인터랙션 매핑 테이블
|
|
283
|
-
|
|
284
|
-
코드 생성 후, 전체 인터랙션을 테이블로 출력:
|
|
285
|
-
|
|
286
|
-
```markdown
|
|
287
|
-
| 섹션 | ID | 트리거 | 동작 | 컴포넌트 | 함수 |
|
|
288
|
-
|------|-----|--------|------|---------|------|
|
|
289
|
-
| Hero | ① | 클릭 | 공유하기 팝업 | HeroSection | handleShare() |
|
|
290
|
-
| 섹션A | ① | 클릭 | API 호출 | FeatureASection | handleAction() |
|
|
291
|
-
|
|
292
|
-
→ Step B/C에서 이 함수들의 body를 구현
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
## A-7. Step A 검증
|
|
296
|
-
|
|
297
|
-
> **아래 검증을 도구로 실제 실행해야 함.**
|
|
298
|
-
|
|
299
|
-
### 검증 항목
|
|
300
|
-
|
|
301
|
-
```
|
|
302
|
-
0. 빈 화면 검사 (가장 중요 — 먼저 실행):
|
|
303
|
-
각 컴포넌트 파일을 Read로 열어서 <template> 안에 확인:
|
|
304
|
-
□ <h2> 또는 <h3> 섹션 제목 텍스트 존재
|
|
305
|
-
□ <p> 설명 텍스트 존재
|
|
306
|
-
□ v-for 또는 .map 렌더링 존재 (리스트 있는 섹션)
|
|
307
|
-
□ @click 또는 onClick 이벤트 존재 (인터랙션 있는 섹션)
|
|
308
|
-
<template> 안에 실제 HTML 태그가 없으면 → 빈 컴포넌트 → 재작성
|
|
309
|
-
Grep: "<template>" 다음 줄이 "</template>"이면 → 빈 template
|
|
310
|
-
|
|
311
|
-
1. 파일 존재 확인 (Glob 도구):
|
|
312
|
-
□ 루트 페이지 파일 존재
|
|
313
|
-
□ PAGE 프레임 수 = 컴포넌트 파일 수
|
|
314
|
-
□ styles 디렉토리 존재
|
|
315
|
-
|
|
316
|
-
2. 목 데이터 확인 (Grep 도구):
|
|
317
|
-
□ 빈 배열 (ref([]) 패턴) 검색 → 0건
|
|
318
|
-
→ 발견 시 목 데이터 채움
|
|
319
|
-
|
|
320
|
-
3. 스타일 분리 확인 (Grep 도구):
|
|
321
|
-
□ 컴포넌트 내 <style> 블록 0건
|
|
322
|
-
|
|
323
|
-
4. 빌드 확인 (Bash 도구):
|
|
324
|
-
□ npm run build 성공
|
|
325
|
-
|
|
326
|
-
5. 브라우저 확인:
|
|
327
|
-
□ dev 서버 열어서 실제 화면 확인
|
|
328
|
-
□ 각 섹션에 텍스트가 보이는지
|
|
329
|
-
□ 빈 화면이면 → 해당 컴포넌트 재작성
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
### 완료 조건
|
|
333
|
-
|
|
334
|
-
```
|
|
335
|
-
✅ 빈 template 0개 — 모든 컴포넌트에 실제 HTML 마크업 존재
|
|
336
|
-
✅ 브라우저에서 텍스트/리스트/버튼이 보인다
|
|
337
|
-
✅ 파일 수 = PAGE 프레임 수
|
|
338
|
-
✅ 빈 배열 0개
|
|
339
|
-
✅ <style> 블록 0개
|
|
340
|
-
✅ 빌드 성공
|
|
8
|
+
# vibe-figma-analyze
|
|
341
9
|
|
|
342
|
-
|
|
343
|
-
→ Step B 진행 가능
|
|
344
|
-
```
|
|
10
|
+
이 스킬은 **vibe-figma** (Phase 1: Storyboard)으로 병합되었습니다.
|
|
@@ -1,196 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vibe-figma-codegen
|
|
3
|
-
description:
|
|
3
|
+
description: "[Merged] → vibe-figma-convert 참조"
|
|
4
4
|
triggers: []
|
|
5
5
|
tier: standard
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# vibe-figma-codegen
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
이미지 패턴은 **vibe-figma-rules R-4** + **vibe-figma-frame B-3.4** 참조.
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## C-1. Semantic HTML (필수)
|
|
16
|
-
|
|
17
|
-
모든 요소는 가장 구체적인 semantic 태그를 사용. `<div>`는 최후 수단.
|
|
18
|
-
|
|
19
|
-
| 시각 요소 | 올바른 태그 | 잘못된 태그 |
|
|
20
|
-
|----------|-----------|-----------|
|
|
21
|
-
| 페이지 섹션 | `<section>`, `<article>`, `<aside>` | `<div>` |
|
|
22
|
-
| 네비게이션 | `<nav>` | `<div class="nav">` |
|
|
23
|
-
| 헤더/푸터 | `<header>`, `<footer>` | `<div class="header">` |
|
|
24
|
-
| 제목 계층 | `<h1>`→`<h6>` (순차, 건너뛰기 금지) | `<div class="title">` |
|
|
25
|
-
| 텍스트 | `<p>` | `<div>` or `<span>` |
|
|
26
|
-
| 리스트 | `<ul>`/`<ol>` + `<li>` | `<div>` 반복 |
|
|
27
|
-
| 액션 버튼 | `<button>` | `<div onClick>` |
|
|
28
|
-
| 링크 | `<a href>` | `<span onClick>` |
|
|
29
|
-
| 폼 필드 | `<input>` + `<label>` | `<div contenteditable>` |
|
|
30
|
-
| 이미지 | `<img alt="설명">` | content 이미지에 `background-image` |
|
|
31
|
-
| 시간 | `<time datetime>` | `<span>` |
|
|
32
|
-
|
|
33
|
-
## C-2. Accessibility Checklist
|
|
34
|
-
|
|
35
|
-
```
|
|
36
|
-
- [ ] 모든 인터랙티브 요소 키보드 접근 가능
|
|
37
|
-
- [ ] <button> = 액션, <a> = 네비게이션 (역할 혼용 금지)
|
|
38
|
-
- [ ] <img> alt 설명적 (장식은 alt="" + aria-hidden)
|
|
39
|
-
- [ ] <input> ↔ <label> 연결
|
|
40
|
-
- [ ] 색상 대비 >= 4.5:1 (텍스트), >= 3:1 (큰 텍스트, UI 컨트롤)
|
|
41
|
-
- [ ] 포커스 인디케이터 표시
|
|
42
|
-
- [ ] 아이콘 전용 버튼에 aria-label
|
|
43
|
-
- [ ] 제목 계층 순차적
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## C-3. 래퍼 제거 + 컴포넌트 통합
|
|
47
|
-
|
|
48
|
-
래퍼 제거 및 80% Rule은 **vibe-figma-rules R-5** 참조.
|
|
49
|
-
|
|
50
|
-
### 컴포넌트 구조 제한
|
|
51
|
-
|
|
52
|
-
```
|
|
53
|
-
Max nesting depth: 3 levels
|
|
54
|
-
Max component length: 50 lines
|
|
55
|
-
Max props: 5 per component
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### 분리 트리거
|
|
59
|
-
|
|
60
|
-
| 신호 | 조치 |
|
|
61
|
-
|------|------|
|
|
62
|
-
| 컴포넌트 > 50줄 | 서브 컴포넌트로 분리 |
|
|
63
|
-
| 시각 패턴 2회+ 반복 | 공유 컴포넌트 추출 |
|
|
64
|
-
| 유사도 80%+ | 단일 컴포넌트 + variant prop (R-5) |
|
|
65
|
-
| 명확한 시각 경계 (카드, 모달, 폼) | 자체 컴포넌트 + 스타일 파일 |
|
|
66
|
-
|
|
67
|
-
## C-4. 스토리보드 스펙 + Design Context 적용
|
|
68
|
-
|
|
69
|
-
```
|
|
70
|
-
storyboardSpec → 코드:
|
|
71
|
-
interactions → CSS :hover/:active/:focus + JS 핸들러
|
|
72
|
-
animations → transition, @keyframes (타이밍/이징 스펙대로)
|
|
73
|
-
states → 조건부 렌더링 + 상태별 UI
|
|
74
|
-
colorGuide / typographyGuide → 토큰 검증
|
|
75
|
-
|
|
76
|
-
design-context.json → 코드:
|
|
77
|
-
accessibility = "AAA" → aria-describedby, prefers-reduced-motion
|
|
78
|
-
devices = ["mobile"] → 모바일 전용, touch target >= 44px
|
|
79
|
-
aesthetic.style = "minimal" → 적은 그림자, 얇은 보더
|
|
80
|
-
aesthetic.style = "bold" → 강한 그림자, 두꺼운 보더
|
|
81
|
-
brand.personality → 브랜드 고유 패턴 보존
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## C-5. 스택별 코드 생성 규칙
|
|
85
|
-
|
|
86
|
-
### React / Next.js + TypeScript
|
|
87
|
-
|
|
88
|
-
```
|
|
89
|
-
- 함수형 컴포넌트, 명시적 return type
|
|
90
|
-
- Props interface 정의, named exports
|
|
91
|
-
- <></> Fragment
|
|
92
|
-
- CSS Modules 또는 Tailwind
|
|
93
|
-
- Next.js: 'use client' 필요 시만, Image/Link 컴포넌트 사용
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### Vue 3 / Nuxt
|
|
97
|
-
|
|
98
|
-
```
|
|
99
|
-
- <script setup lang="ts"> composition API
|
|
100
|
-
- defineProps + TypeScript interface
|
|
101
|
-
- <template>로 invisible 그룹핑
|
|
102
|
-
- <style scoped> or <style module>
|
|
103
|
-
- <Teleport> for 모달/오버레이
|
|
104
|
-
- Nuxt: <NuxtLink>, <NuxtImg> 사용
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### Svelte
|
|
108
|
-
|
|
109
|
-
```
|
|
110
|
-
- <script lang="ts">
|
|
111
|
-
- export let + 타입
|
|
112
|
-
- {#if}/{#each}/{#await} 블록
|
|
113
|
-
- <slot>, transition: directive
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### SCSS (공통)
|
|
117
|
-
|
|
118
|
-
```
|
|
119
|
-
- @use 'figma-tokens' as figma — 네임스페이스 import
|
|
120
|
-
- @include figma.figma-pc { } — @media 직접 사용 금지
|
|
121
|
-
- figma-fluid($mobile, $desktop) — 수동 clamp() 금지
|
|
122
|
-
- Nesting max 3 levels
|
|
123
|
-
- & for BEM-like modifiers
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
## C-6. 반응형 코드 생성
|
|
127
|
-
|
|
128
|
-
### 원칙: Fluid First, Breakpoint Second
|
|
129
|
-
|
|
130
|
-
```
|
|
131
|
-
1. Typography & Spacing → clamp() fluid 토큰 (브레이크포인트 불필요)
|
|
132
|
-
2. 레이아웃 방향 변경 → @media at breakpoint
|
|
133
|
-
3. 가시성 토글 → @media display toggle
|
|
134
|
-
4. 컴포넌트 교체 → 조건부 렌더링 또는 CSS
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### Anti-Patterns (금지)
|
|
138
|
-
|
|
139
|
-
| 잘못됨 | 올바름 |
|
|
140
|
-
|--------|--------|
|
|
141
|
-
| 모바일/데스크탑 별도 컴포넌트 파일 | 단일 컴포넌트 + 반응형 CSS |
|
|
142
|
-
| font-size에 @media | clamp() fluid 토큰 |
|
|
143
|
-
| 하드코딩 `@media (min-width: 768px)` | 프로젝트 브레이크포인트 사용 |
|
|
144
|
-
| px 값 직접 사용 | 토큰 변수 사용 |
|
|
145
|
-
| window.innerWidth JS 체크 | CSS-only 반응형 |
|
|
146
|
-
|
|
147
|
-
## C-7. Correction Notes
|
|
148
|
-
|
|
149
|
-
코드 생성 후 출력:
|
|
150
|
-
|
|
151
|
-
```markdown
|
|
152
|
-
### Generation Mode
|
|
153
|
-
- Mode: default / --new / responsive
|
|
154
|
-
- Output directory: {path}
|
|
155
|
-
|
|
156
|
-
### Files Generated
|
|
157
|
-
| File | Type | Description |
|
|
158
|
-
|
|
159
|
-
### Responsive Summary (responsive mode only)
|
|
160
|
-
| Token | Mobile | Desktop | Strategy |
|
|
161
|
-
|
|
162
|
-
### Markup Quality
|
|
163
|
-
- Semantic tags: {list}
|
|
164
|
-
- Accessibility: {pass/fail}
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
## C-8. Refine Mode (`--refine`)
|
|
168
|
-
|
|
169
|
-
이전 생성 코드의 완성도가 부족할 때 사용. **새로 만들지 않고 기존 코드를 수정만.**
|
|
170
|
-
|
|
171
|
-
```
|
|
172
|
-
1. URL 재입력 (또는 "이전과 동일")
|
|
173
|
-
2. 기존 코드 스캔 (pages/, components/ 내 피처 폴더)
|
|
174
|
-
3. Figma 원본 재추출 (get_design_context + get_screenshot)
|
|
175
|
-
4. Side-by-side 비교 → Diff 기반 최소 수정
|
|
176
|
-
5. 검증 루프 (vibe-figma-rules R-6, P1=0 될 때까지)
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### Refine 수정 범위
|
|
180
|
-
|
|
181
|
-
| 수정함 | 수정 안 함 |
|
|
182
|
-
|--------|-----------|
|
|
183
|
-
| 누락 에셋, 레이아웃/타이포/색상 불일치 | 파일 구조 변경 |
|
|
184
|
-
| 누락 컴포넌트, 인터랙션 누락 | 컴포넌트 분리/통합 |
|
|
185
|
-
| 반응형 누락, 이미지 경로 | 토큰 파일 재생성 |
|
|
186
|
-
|
|
187
|
-
## Important
|
|
188
|
-
|
|
189
|
-
```
|
|
190
|
-
- Never guess colors — 추출 값만 사용
|
|
191
|
-
- Never invent spacing — 토큰 스케일에 매핑
|
|
192
|
-
- Never hardcode values — 토큰 변수 참조
|
|
193
|
-
- Image is truth — 레이어 구조 혼란 시 이미지 우선
|
|
194
|
-
- No console.log, No div soup
|
|
195
|
-
- Component 50줄 초과 시 분리
|
|
196
|
-
```
|
|
10
|
+
이 스킬은 **vibe-figma-convert**으로 병합되었습니다.
|
|
@@ -1,100 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vibe-figma-consolidate
|
|
3
|
-
description:
|
|
3
|
+
description: "[Merged] → vibe-figma (Phase 4: Verification) 참조"
|
|
4
4
|
triggers: []
|
|
5
5
|
tier: standard
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# vibe-figma-consolidate
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
## D-1. 스타일 공통화
|
|
13
|
-
|
|
14
|
-
```
|
|
15
|
-
1. 모바일/PC에서 동일한 값 → 공통 토큰으로 추출
|
|
16
|
-
2. 중복 CSS/SCSS 규칙 통합
|
|
17
|
-
3. 컴포넌트 내 중복 로직 제거
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
| 유형 | 처리 방법 |
|
|
21
|
-
|------|----------|
|
|
22
|
-
| 색상 (동일) | 공통 CSS custom property |
|
|
23
|
-
| 타이포 (동일 scale) | 공통 토큰 유지 |
|
|
24
|
-
| 간격 (다름) | clamp() fluid 토큰 (계산: vibe-figma-rules R-3) |
|
|
25
|
-
| 레이아웃 방향 (다름) | @media 분기 유지 |
|
|
26
|
-
| 컴포넌트 구조 (동일) | 하나로 통합 |
|
|
27
|
-
|
|
28
|
-
## D-2. 컴포넌트 통합
|
|
29
|
-
|
|
30
|
-
80% Rule 및 variant 통합 기준은 **vibe-figma-rules R-5** 참조.
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
1. 유사 컴포넌트 (80%+) → variant prop 통합
|
|
34
|
-
2. 중복 sub-component → 공유 컴포넌트 추출
|
|
35
|
-
3. 불필요한 래퍼 → Fragment/template 제거
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## D-3. 최종 검증
|
|
39
|
-
|
|
40
|
-
검증 공통 프로세스는 **vibe-figma-rules R-6** 참조.
|
|
41
|
-
|
|
42
|
-
### Step D 추가 검증
|
|
43
|
-
|
|
44
|
-
```
|
|
45
|
-
양쪽 뷰포트 동시 검증:
|
|
46
|
-
- 모바일 Figma vs 코드 (mobile viewport)
|
|
47
|
-
- PC Figma vs 코드 (desktop viewport)
|
|
48
|
-
- 양쪽 모두 P1=0, Match Score 95%+
|
|
49
|
-
- 이미지 에셋 전부 정상 표시
|
|
50
|
-
- 공통 토큰으로 중복 제거 완료
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### Model Routing (Step D)
|
|
54
|
-
|
|
55
|
-
| 작업 | 모델 |
|
|
56
|
-
|------|------|
|
|
57
|
-
| 공통화 리팩토링 + 최종 검증 | **Sonnet** |
|
|
58
|
-
| Post — 코드 리뷰 | **gpt-5.3-codex** (Codex 미설치 시 스킵) |
|
|
59
|
-
|
|
60
|
-
## D-4. Design Quality Pipeline (후처리)
|
|
61
|
-
|
|
62
|
-
Step D 완료 후 사용자에게 다음 단계를 제시.
|
|
63
|
-
|
|
64
|
-
### Pre-requisite check
|
|
65
|
-
|
|
66
|
-
`.claude/vibe/design-context.json`이 없으면:
|
|
67
|
-
```
|
|
68
|
-
디자인 컨텍스트가 없습니다. /design-teach 를 먼저 실행하면
|
|
69
|
-
브랜드, 접근성, 타겟 디바이스에 맞춘 더 정확한 코드를 생성할 수 있습니다.
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### Quick (기본 추천)
|
|
73
|
-
|
|
74
|
-
```
|
|
75
|
-
/design-normalize → /design-audit
|
|
76
|
-
```
|
|
77
|
-
- Normalize: 하드코딩 값 → MASTER.md 토큰으로 치환
|
|
78
|
-
- Audit: A11Y + 성능 + 반응형 + AI Slop 검출
|
|
79
|
-
|
|
80
|
-
### Thorough (프로덕션 추천)
|
|
81
|
-
|
|
82
|
-
```
|
|
83
|
-
/design-normalize → /design-audit → /design-critique → /design-polish
|
|
84
|
-
```
|
|
85
|
-
- + Critique: Nielsen 10 휴리스틱 + 페르소나 분석
|
|
86
|
-
- + Polish: 인터랙션 상태 보완 (hover/focus/loading/error)
|
|
87
|
-
|
|
88
|
-
### 출력 포맷
|
|
89
|
-
|
|
90
|
-
```markdown
|
|
91
|
-
## Design Quality Pipeline
|
|
92
|
-
|
|
93
|
-
생성된 파일: {file list}
|
|
94
|
-
|
|
95
|
-
추천 다음 단계:
|
|
96
|
-
1. /design-normalize — 토큰 정렬
|
|
97
|
-
2. /design-audit — 기술 품질 검사
|
|
98
|
-
3. /design-critique — UX 휴리스틱 리뷰
|
|
99
|
-
4. /design-polish — 최종 인터랙션 보완
|
|
100
|
-
```
|
|
10
|
+
이 스킬은 **vibe-figma** (Phase 4: Verification)으로 병합되었습니다.
|