@su-record/vibe 2.8.19 → 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.
@@ -1,196 +1,10 @@
1
1
  ---
2
2
  name: vibe-figma-codegen
3
- description: Code generation markup quality, stack rules, responsive, verification
3
+ description: "[Merged] vibe-figma-convert 참조"
4
4
  triggers: []
5
5
  tier: standard
6
6
  ---
7
7
 
8
- # Skill: vibe-figma-codegen — 코드 생성 규칙
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: Step D 모바일/PC 스타일 공통화, 컴포넌트 통합, 최종 검증, 후처리 파이프라인
3
+ description: "[Merged] vibe-figma (Phase 4: Verification) 참조"
4
4
  triggers: []
5
5
  tier: standard
6
6
  ---
7
7
 
8
- # Skill: vibe-figma-consolidate — Step D: 공통화 + 최종 검증
8
+ # vibe-figma-consolidate
9
9
 
10
- > **실행 지시: Edit 도구로 기존 파일을 실제 수정한다.**
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)으로 병합되었습니다.
@@ -0,0 +1,284 @@
1
+ ---
2
+ name: vibe-figma-convert
3
+ description: 참조 코드(React+Tailwind) → 프로젝트 코드 + 외부 스타일 파일
4
+ triggers: []
5
+ tier: standard
6
+ ---
7
+
8
+ # vibe-figma-convert — 코드 변환
9
+
10
+ `get_design_context` 참조 코드를 프로젝트 스택 코드 + 외부 SCSS 파일로 변환.
11
+
12
+ ---
13
+
14
+ ## 1. 외부 스타일 파일 생성
15
+
16
+ ### 변환 예시
17
+
18
+ ```
19
+ 참조 코드 (React+Tailwind):
20
+ <div className="h-[1280px] relative w-[720px]"> ← 섹션 컨테이너
21
+ <div className="absolute h-[1280px] overflow-clip w-[720px]"> ← BG 레이어
22
+ <img src={img21} className="absolute inset-0 object-cover size-full" />
23
+ </div>
24
+ <div className="absolute flex flex-col items-center top-[130px]"> ← Content
25
+ <div className="h-[174px] w-[620px]"> ← Title 이미지
26
+ <img src={imgTitle} className="absolute inset-0 object-cover size-full" />
27
+ </div>
28
+ <p className="text-[24px] text-white leading-[1.4] text-center"> ← 텍스트
29
+ 참여 대상 : PC 유저 (Steam, Kakao)
30
+ </p>
31
+ </div>
32
+ </div>
33
+ ```
34
+
35
+ ```
36
+ 변환 → styles/{feature}/layout/_hero.scss:
37
+
38
+ @use '../tokens' as t;
39
+
40
+ .heroSection {
41
+ position: relative;
42
+ height: 960px; // 1280 × 0.75
43
+ width: 100%;
44
+ overflow: clip;
45
+ }
46
+
47
+ .heroBg {
48
+ position: absolute;
49
+ inset: 0;
50
+ z-index: 0;
51
+ img { width: 100%; height: 100%; object-fit: cover; }
52
+ }
53
+
54
+ .heroContent {
55
+ position: relative;
56
+ z-index: 10;
57
+ display: flex;
58
+ flex-direction: column;
59
+ align-items: center;
60
+ padding-top: 98px; // 130 × 0.75
61
+ }
62
+ ```
63
+
64
+ ```
65
+ 변환 → styles/{feature}/components/_hero.scss:
66
+
67
+ @use '../tokens' as t;
68
+
69
+ .heroTitle {
70
+ width: 465px; // 620 × 0.75
71
+ height: 131px; // 174 × 0.75
72
+ img { width: 100%; height: 100%; object-fit: cover; }
73
+ }
74
+
75
+ .heroParticipation {
76
+ font-size: t.$text-sub; // 24px × 0.75 = 18px
77
+ color: t.$color-white;
78
+ line-height: 1.4;
79
+ text-align: center;
80
+ white-space: nowrap;
81
+ }
82
+ ```
83
+
84
+ ### layout vs components 구분
85
+
86
+ ```
87
+ layout/ → position, display, flex/grid, width, height, padding, margin,
88
+ gap, overflow, z-index, background-image, inset
89
+ components/ → font-size, font-weight, color, line-height, letter-spacing,
90
+ text-align, border, border-radius, box-shadow, opacity
91
+ ```
92
+
93
+ ### _tokens.scss 업데이트
94
+
95
+ ```
96
+ 섹션을 처리할 때마다 새로운 고유값을 토큰에 추가:
97
+
98
+ // Colors
99
+ $color-white: #FFFFFF;
100
+ $color-bg-dark: #0A1628;
101
+ $color-heading: #1B3A1D;
102
+ $color-text-body: #333333;
103
+ $color-period-label: #003879;
104
+ $color-grayscale-950: #171716;
105
+
106
+ // Typography (Figma px × scaleFactor)
107
+ $text-hero: 36px; // 48 × 0.75
108
+ $text-sub: 18px; // 24 × 0.75
109
+ $text-body: 16px; // 21 × 0.75
110
+ $text-period: 21px; // 28 × 0.75
111
+
112
+ // Font families
113
+ $font-pretendard: 'Pretendard', sans-serif;
114
+ $font-roboto-condensed: 'Roboto Condensed', sans-serif;
115
+
116
+ // Spacing
117
+ $space-section: 98px; // 130 × 0.75
118
+ $space-content: 18px; // 24 × 0.75
119
+
120
+ // Breakpoints
121
+ $bp-pc: 1024px;
122
+ ```
123
+
124
+ ---
125
+
126
+ ## 2. 컴포넌트 파일 변환
127
+
128
+ ### Vue / Nuxt
129
+
130
+ ```vue
131
+ <template>
132
+ <section class="heroSection">
133
+ <!-- BG Layer -->
134
+ <div class="heroBg">
135
+ <img src="/images/{feature}/bg.webp" alt="" aria-hidden="true" />
136
+ </div>
137
+
138
+ <!-- Content Layer -->
139
+ <div class="heroContent">
140
+ <div class="heroTitle">
141
+ <img src="/images/{feature}/title.webp" alt="추운 겨울, 따뜻한 보상이 펑펑" />
142
+ </div>
143
+ <div class="heroSubTitle">
144
+ <img src="/images/{feature}/sub-title.webp" alt="겨울을 녹일 보상, 지금 PC방에서 획득하세요!" />
145
+ </div>
146
+
147
+ <!-- Period Info (참조 코드 data-name="Period") -->
148
+ <div class="heroPeriod">
149
+ <p class="heroPeriodTarget">참여 대상 : PC 유저 (Steam, Kakao)</p>
150
+ <div class="heroPeriodDetails">
151
+ <div class="heroPeriodItem">
152
+ <p class="heroPeriodLabel">이벤트 기간</p>
153
+ <p class="heroPeriodValue">{{ eventPeriod }}</p>
154
+ </div>
155
+ <div class="heroPeriodItem">
156
+ <p class="heroPeriodLabel">교환/응모 종료일</p>
157
+ <p class="heroPeriodValue">{{ exchangeDeadline }}</p>
158
+ </div>
159
+ </div>
160
+ </div>
161
+ </div>
162
+
163
+ <!-- Share Button (참조 코드 data-name="BTN_Share") -->
164
+ <button class="heroShareBtn" @click="handleShare">
165
+ <img src="/images/{feature}/share.webp" alt="공유하기" />
166
+ </button>
167
+ </section>
168
+ </template>
169
+
170
+ <script setup lang="ts">
171
+ /**
172
+ * Hero 섹션 — 키비주얼 + 이벤트 기간 정보
173
+ *
174
+ * [인터랙션] 공유 버튼 클릭 → 공유하기 팝업
175
+ * [상태] 로그인 전/후
176
+ */
177
+
178
+ defineProps<{
179
+ eventPeriod: string
180
+ exchangeDeadline: string
181
+ }>()
182
+
183
+ const emit = defineEmits<{
184
+ share: []
185
+ }>()
186
+
187
+ function handleShare(): void {
188
+ emit('share')
189
+ }
190
+ </script>
191
+ <!-- 스타일: styles/{feature}/layout/_hero.scss + components/_hero.scss -->
192
+ ```
193
+
194
+ ### JSX 변환 규칙 (React+Tailwind → Vue/Nuxt)
195
+
196
+ | React JSX | Vue SFC |
197
+ |-----------|---------|
198
+ | `className="..."` | `class="..."` |
199
+ | `{condition && <X/>}` | `<X v-if="condition" />` |
200
+ | `{items.map(i => <X key={i.id}/>)}` | `<X v-for="i in items" :key="i.id" />` |
201
+ | `onClick={handler}` | `@click="handler"` |
202
+ | `src={변수}` | `src="/images/{feature}/파일.webp"` (imageMap으로 교체) |
203
+ | `style={{ maskImage: ... }}` | `:style="{ maskImage: ... }"` |
204
+ | `<img alt="" />` (장식) | `<img alt="" aria-hidden="true" />` |
205
+
206
+ ### JSX 변환 규칙 (React+Tailwind → React/Next.js)
207
+
208
+ | React+Tailwind | React/Next.js + SCSS |
209
+ |----------------|---------------------|
210
+ | `className="text-[48px] font-black"` | `className={styles.heroTitle}` |
211
+ | `<img src={변수}` | `<Image src="/images/{feature}/파일.webp"` |
212
+ | Tailwind 클래스 | CSS Module 또는 외부 SCSS 클래스 |
213
+
214
+ ---
215
+
216
+ ## 3. 이미지 배치 패턴
217
+
218
+ ### 배경 이미지 (참조 코드에서 absolute + inset-0 + object-cover)
219
+
220
+ ```
221
+ 참조 코드에 이 패턴이 있으면 → 배경 이미지:
222
+ <div className="absolute ...">
223
+ <img src={imgXxx} className="absolute inset-0 object-cover size-full" />
224
+ </div>
225
+
226
+ → Multi-Layer 변환:
227
+ .{section}Bg → position: absolute; inset: 0; z-index: 0;
228
+ .{section}Content → position: relative; z-index: 10;
229
+ ```
230
+
231
+ ### 콘텐츠 이미지 (참조 코드에서 독립적 img)
232
+
233
+ ```
234
+ → <img src="/images/{feature}/파일.webp" alt="설명" width={스케일적용} height={스케일적용} />
235
+ ```
236
+
237
+ ### 장식 이미지 (참조 코드에서 mix-blend, opacity, blur)
238
+
239
+ ```
240
+ → <img ... alt="" aria-hidden="true" /> (접근성: 장식은 비표시)
241
+ → CSS: mix-blend-mode, opacity, filter: blur() 등 참조 코드 값 그대로
242
+ ```
243
+
244
+ ---
245
+
246
+ ## 4. 반응형 추가 (데스크탑 URL)
247
+
248
+ ```
249
+ 같은 섹션에 대해 데스크탑 참조 코드 추출 후:
250
+
251
+ 같은 값 → 유지
252
+ 다른 px 값:
253
+ @include pc {
254
+ .heroSection { height: 1440px; } // 데스크탑 스케일
255
+ }
256
+ 또는 clamp(모바일, calc, 데스크탑) 사용
257
+
258
+ 다른 배경 이미지:
259
+ .heroBg img { content: url('/images/{feature}/hero-mobile.webp'); }
260
+ @include pc {
261
+ .heroBg img { content: url('/images/{feature}/hero-pc.webp'); }
262
+ }
263
+
264
+ 다른 레이아웃:
265
+ .heroContent { flex-direction: column; }
266
+ @include pc { .heroContent { flex-direction: row; } }
267
+
268
+ 기존 모바일 코드 삭제 금지. @media 또는 mixin으로 추가만.
269
+ ```
270
+
271
+ ---
272
+
273
+ ## 5. Semantic HTML 최소 규칙
274
+
275
+ ```
276
+ - 섹션 래퍼: <section>
277
+ - 제목: <h1>~<h6> (순차, 건너뛰기 금지)
278
+ - 텍스트: <p>
279
+ - 버튼: <button> (@click 있으면)
280
+ - 링크: <a> (href 있으면)
281
+ - 리스트: <ul>/<ol> + <li> (반복 패턴)
282
+ - 장식 이미지: alt="" + aria-hidden="true"
283
+ - 콘텐츠 이미지: alt="설명적 텍스트"
284
+ ```