@su-record/vibe 2.8.35 → 2.8.36

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,46 +1,81 @@
1
1
  ---
2
2
  name: vibe.figma.convert
3
- description: 참조 코드(React+Tailwind) → 프로젝트 코드 + 외부 스타일 파일
3
+ description: 스크린샷 + 재료함 → 프로젝트 코드 + 외부 스타일 파일
4
4
  triggers: []
5
5
  tier: standard
6
6
  ---
7
7
 
8
- # vibe.figma.convert — 코드 변환
8
+ # vibe.figma.convert — 시각 기반 코드 생성
9
9
 
10
- `get_design_context` 참조 코드를 프로젝트 스택 코드로 변환.
11
- 항상 외부 SCSS 파일에 스타일 작성.
10
+ **스크린샷을 보고** 코드를 작성한다. Figma 데이터는 정확한 수치/에셋 재료로만 사용.
12
11
 
13
- ---
12
+ ```
13
+ ❌ Figma 트리를 HTML로 변환 (실패하는 방식)
14
+ ✅ 스크린샷을 보고 → 시맨틱 HTML 설계 → 재료함에서 정확한 값 가져다 적용
15
+ ```
14
16
 
15
- ## 1. 외부 스타일 파일 생성
17
+ ---
16
18
 
17
- ### 변환 예시
19
+ ## 1. 코드 생성 프로세스
18
20
 
19
21
  ```
20
- 참조 코드 (React+Tailwind):
21
- <div className="h-[1280px] relative w-[720px]"> ← 섹션 컨테이너
22
- <div className="absolute h-[1280px] overflow-clip w-[720px]"> ← BG 레이어
23
- <img src={img21} className="absolute inset-0 object-cover size-full" />
24
- </div>
25
- <div className="absolute flex flex-col items-center top-[130px]"> Content
26
- <div className="h-[174px] w-[620px]"> ← Title 이미지
27
- <img src={imgTitle} className="absolute inset-0 object-cover size-full" />
28
- </div>
29
- <p className="text-[24px] text-white leading-[1.4] text-center"> 텍스트
30
- 참여 대상 : PC 유저 (Steam, Kakao)
31
- </p>
32
- </div>
33
- </div>
22
+ 입력:
23
+ - 섹션 스크린샷 (정답 사진)
24
+ - 재료함: 이미지 목록, 색상 팔레트, 폰트 목록, 텍스트 콘텐츠, CSS 수치
25
+
26
+ 출력:
27
+ - 컴포넌트 파일 (Vue SFC / React TSX)
28
+ - SCSS 파일 (layout/ + components/ + _tokens.scss)
29
+
30
+ 프로세스:
31
+ 1. 스크린샷을 본다 "무엇이 보이는가?" 판단
32
+ - 전면 배경 콘텐츠? 히어로 패턴
33
+ - 카드 N개 반복? → 그리드 패턴
34
+ - 탭 + 내용? → 탭 패턴
35
+ - 리스트 + 버튼? → 인터랙티브 리스트 패턴
36
+
37
+ 2. 시맨틱 HTML 구조를 설계한다 (Figma 레이어 구조 무시)
38
+ - 스크린샷에서 보이는 시각적 관계를 HTML로 표현
39
+ - <section>, <h2>, <ul>, <button> 등 의미에 맞게
40
+
41
+ 3. 재료함에서 정확한 값을 가져온다
42
+ - 이미지: /tmp/{feature}/images/ 에서 해당 파일
43
+ - 색상: tree.json CSS의 정확한 hex/rgba
44
+ - 폰트: 정확한 font-family, size, weight
45
+ - 텍스트: TEXT 노드의 characters 값 그대로
46
+ - 간격: 정확한 padding, gap, margin 값
47
+
48
+ 4. 코드를 작성한다
49
+ - 컴포넌트: 스크린샷처럼 보이도록
50
+ - SCSS: 재료함의 정확한 수치 (× scaleFactor)
51
+ - 추정 금지 — 값이 없으면 tree.json에서 다시 찾는다
34
52
  ```
35
53
 
54
+ ---
55
+
56
+ ## 2. 외부 SCSS 파일 구조
57
+
58
+ ### layout vs components 구분
59
+
36
60
  ```
37
- 변환 styles/{feature}/layout/_hero.scss:
61
+ layout/ position, display, flex/grid, width, height, padding, margin,
62
+ gap, overflow, z-index, background-image, inset
63
+ components/ → font-size, font-weight, color, line-height, letter-spacing,
64
+ text-align, border, border-radius, box-shadow, opacity
65
+ ```
66
+
67
+ ### layout 예시 (스크린샷 기반으로 작성)
68
+
69
+ ```scss
70
+ // 스크린샷에서 보이는 구조:
71
+ // - 전면 배경 이미지 위에 중앙 정렬된 콘텐츠
72
+ // 재료함에서 가져온 값: width=720, height=1280 (→ ×0.75)
38
73
 
39
74
  @use '../tokens' as t;
40
75
 
41
76
  .heroSection {
42
77
  position: relative;
43
- height: 960px; // 1280 × 0.75
78
+ height: 960px; // 재료: 1280 × 0.75
44
79
  width: 100%;
45
80
  overflow: clip;
46
81
  }
@@ -58,129 +93,91 @@ tier: standard
58
93
  display: flex;
59
94
  flex-direction: column;
60
95
  align-items: center;
61
- padding-top: 98px; // 130 × 0.75
96
+ padding-top: 98px; // 재료: 130 × 0.75
62
97
  }
63
98
  ```
64
99
 
65
- ```
66
- 변환 → styles/{feature}/components/_hero.scss:
100
+ ### components 예시
101
+
102
+ ```scss
103
+ // 스크린샷에서 보이는 요소:
104
+ // - 큰 타이틀 이미지, 그 아래 흰색 텍스트
105
+ // 재료함: fontSize=24, color=#ffffff, width=620, height=174
67
106
 
68
107
  @use '../tokens' as t;
69
108
 
70
109
  .heroTitle {
71
- width: 465px; // 620 × 0.75
72
- height: 131px; // 174 × 0.75
110
+ width: 465px; // 재료: 620 × 0.75
111
+ height: 131px; // 재료: 174 × 0.75
73
112
  img { width: 100%; height: 100%; object-fit: cover; }
74
113
  }
75
114
 
76
- .heroParticipation {
77
- font-size: t.$font-size-md; // 24px × 0.667 = 16px
78
- color: t.$color-text-primary; // semantic → $color-white
115
+ .heroText {
116
+ font-size: t.$font-size-md; // 재료: 24px × 0.667 = 16px
117
+ color: t.$color-text-primary; // 재료: #ffffff
79
118
  line-height: 1.4;
80
119
  text-align: center;
81
- white-space: nowrap;
82
120
  }
83
121
  ```
84
122
 
85
- ### layout vs components 구분
86
-
87
- ```
88
- layout/ → position, display, flex/grid, width, height, padding, margin,
89
- gap, overflow, z-index, background-image, inset
90
- components/ → font-size, font-weight, color, line-height, letter-spacing,
91
- text-align, border, border-radius, box-shadow, opacity
92
- ```
93
-
94
123
  ### _tokens.scss 구조 (primitive/semantic 분리)
95
124
 
96
- ```
97
- // ─── Primitive (Figma 원시 값) ────────────────
98
- // Colors
125
+ ```scss
126
+ // ─── Primitive (재료함의 원시 값) ────────────────
99
127
  $color-white: #ffffff;
100
128
  $color-black: #000000;
101
129
  $color-navy-dark: #0a1628;
102
130
  $color-navy-medium: #00264a;
103
131
 
104
- // Font families
105
132
  $font-pretendard: 'Pretendard', sans-serif;
106
- $font-roboto-condensed: 'Roboto Condensed', sans-serif;
107
133
 
108
- // Font sizes (scaled)
109
- $font-size-xs: 11px; // 16 × 0.667
110
- $font-size-sm: 13px; // 20 × 0.667
111
- $font-size-md: 16px; // 24 × 0.667
112
- $font-size-lg: 19px; // 28 × 0.667
134
+ $font-size-xs: 11px; // 재료: 16 × 0.667
135
+ $font-size-sm: 13px; // 재료: 20 × 0.667
136
+ $font-size-md: 16px; // 재료: 24 × 0.667
137
+ $font-size-lg: 19px; // 재료: 28 × 0.667
113
138
 
114
- // Font weights
115
139
  $font-weight-regular: 400;
116
140
  $font-weight-medium: 500;
117
141
  $font-weight-bold: 700;
118
142
 
119
- // Spacing (scaled)
120
143
  $space-xs: 5px;
121
144
  $space-sm: 11px;
122
145
  $space-md: 16px;
123
146
  $space-lg: 21px;
124
147
 
125
148
  // ─── Semantic (용도별) ────────────────────────
126
- // Text
127
149
  $color-text-primary: $color-white;
128
150
  $color-text-secondary: #dadce3;
129
- $color-text-label: #003879;
130
- $color-text-link: #419bd3;
131
-
132
- // Background
133
151
  $color-bg-primary: $color-navy-dark;
134
152
  $color-bg-section: $color-navy-medium;
135
-
136
- // Border
137
153
  $color-border-primary: #203f6c;
138
-
139
- // Breakpoint
140
154
  $bp-desktop: 1024px;
141
155
 
142
- 규칙:
143
- - primitive: 고유 값 (hex, 폰트명, px)
144
- - semantic: primitive 참조로 용도별 이름 ($color-text-primary: $color-white)
145
- - 같은 값 중복 금지 — 기존 토큰 재사용
146
- ```
147
-
148
- ### CSS 변수 패턴 처리
149
-
150
- ```
151
- 참조 코드에 Figma 디자인 토큰이 CSS 변수로 포함될 수 있음:
152
- font-[family-name:var(--font/family/pretendard,...)]
153
- text-[length:var(--font/size/heading/24,24px)]
154
- text-[color:var(--color/grayscale/950,#171716)]
155
-
156
- → var() 안의 fallback 값(24px, #171716)을 사용.
157
- → CSS 변수명은 프로젝트 토큰 네이밍에 참고.
156
+ // 규칙:
157
+ // - primitive: 재료함의 고유 값 (hex, 폰트명, px)
158
+ // - semantic: primitive 참조로 용도별 이름
159
+ // - 같은 값 중복 금지 — 기존 토큰 재사용
158
160
  ```
159
161
 
160
162
  ---
161
163
 
162
- ## 2. 컴포넌트 파일 변환
164
+ ## 3. 컴포넌트 작성
163
165
 
164
- ### Vue / Nuxt
166
+ ### Vue / Nuxt 예시
165
167
 
166
168
  ```vue
169
+ <!-- 스크린샷 기반: 전면 배경 + 중앙 타이틀 + 기간 정보 + 공유 버튼 -->
167
170
  <template>
168
171
  <section class="heroSection">
169
- <!-- BG Layer -->
170
172
  <div class="heroBg">
171
173
  <img src="/images/{feature}/bg.webp" alt="" aria-hidden="true" />
172
174
  </div>
173
175
 
174
- <!-- Content Layer -->
175
176
  <div class="heroContent">
176
177
  <div class="heroTitle">
177
178
  <img src="/images/{feature}/title.webp" alt="추운 겨울, 따뜻한 보상이 펑펑" />
178
179
  </div>
179
- <div class="heroSubTitle">
180
- <img src="/images/{feature}/sub-title.webp" alt="겨울을 녹일 보상, 지금 PC방에서 획득하세요!" />
181
- </div>
182
180
 
183
- <!-- Period Info (참조 코드 data-name="Period") -->
184
181
  <div class="heroPeriod">
185
182
  <p class="heroPeriodTarget">참여 대상 : PC 유저 (Steam, Kakao)</p>
186
183
  <div class="heroPeriodDetails">
@@ -188,15 +185,10 @@ $bp-desktop: 1024px;
188
185
  <p class="heroPeriodLabel">이벤트 기간</p>
189
186
  <p class="heroPeriodValue">{{ eventPeriod }}</p>
190
187
  </div>
191
- <div class="heroPeriodItem">
192
- <p class="heroPeriodLabel">교환/응모 종료일</p>
193
- <p class="heroPeriodValue">{{ exchangeDeadline }}</p>
194
- </div>
195
188
  </div>
196
189
  </div>
197
190
  </div>
198
191
 
199
- <!-- Share Button (참조 코드 data-name="BTN_Share") -->
200
192
  <button class="heroShareBtn" @click="handleShare">
201
193
  <img src="/images/{feature}/share.webp" alt="공유하기" />
202
194
  </button>
@@ -204,21 +196,11 @@ $bp-desktop: 1024px;
204
196
  </template>
205
197
 
206
198
  <script setup lang="ts">
207
- /**
208
- * Hero 섹션 — 키비주얼 + 이벤트 기간 정보
209
- *
210
- * [인터랙션] 공유 버튼 클릭 → 공유하기 팝업
211
- * [상태] 로그인 전/후
212
- */
213
-
214
199
  defineProps<{
215
200
  eventPeriod: string
216
- exchangeDeadline: string
217
201
  }>()
218
202
 
219
- const emit = defineEmits<{
220
- share: []
221
- }>()
203
+ const emit = defineEmits<{ share: [] }>()
222
204
 
223
205
  function handleShare(): void {
224
206
  emit('share')
@@ -227,93 +209,62 @@ function handleShare(): void {
227
209
  <!-- 스타일: styles/{feature}/layout/_hero.scss + components/_hero.scss -->
228
210
  ```
229
211
 
230
- ### JSX 변환 규칙 (React+Tailwind → Vue/Nuxt)
231
-
232
- | React JSX | Vue SFC |
233
- |-----------|---------|
234
- | `className="..."` | `class="..."` |
235
- | `{condition && <X/>}` | `<X v-if="condition" />` |
236
- | `{items.map(i => <X key={i.id}/>)}` | `<X v-for="i in items" :key="i.id" />` |
237
- | `onClick={handler}` | `@click="handler"` |
238
- | `src={변수}` | `src="/images/{feature}/파일.webp"` (imageMap으로 교체) |
239
- | `style={{ maskImage: ... }}` | `:style="{ maskImage: ... }"` |
240
- | `<img alt="" />` (장식) | `<img alt="" aria-hidden="true" />` |
212
+ ### 스택별 변환 규칙
241
213
 
242
- ### JSX 변환 규칙 (React+Tailwind → React/Next.js)
243
-
244
- | React+Tailwind | React/Next.js + SCSS |
245
- |----------------|---------------------|
246
- | `className="text-[48px] font-black"` | `className={styles.heroTitle}` |
247
- | `<img src={변수}` | `<Image src="/images/{feature}/파일.webp"` |
248
- | Tailwind 클래스 | CSS Module 또는 외부 SCSS 클래스 |
214
+ | Vue/Nuxt | React/Next.js |
215
+ |----------|---------------|
216
+ | `class="..."` | `className={styles.xxx}` (CSS Module) |
217
+ | `v-if="condition"` | `{condition && <X/>}` |
218
+ | `v-for="i in items" :key="i.id"` | `{items.map(i => <X key={i.id}/>)}` |
219
+ | `@click="handler"` | `onClick={handler}` |
220
+ | `<img src="/images/..."` | `<Image src="/images/..."` |
249
221
 
250
222
  ---
251
223
 
252
- ## 3. 이미지 배치 패턴
253
-
254
- ### 배경 이미지 (참조 코드에서 absolute + inset-0 + object-cover)
224
+ ## 4. 이미지 배치 패턴 (스크린샷에서 판단)
255
225
 
256
226
  ```
257
- 참조 코드에 이 패턴이 있으면 → 배경 이미지:
258
- <div className="absolute ...">
259
- <img src={imgXxx} className="absolute inset-0 object-cover size-full" />
260
- </div>
261
-
262
- → Multi-Layer 변환:
263
- .{section}Bg → position: absolute; inset: 0; z-index: 0;
264
- .{section}Content → position: relative; z-index: 10;
265
- ```
227
+ 스크린샷에서 판단하는 패턴:
266
228
 
267
- ### 콘텐츠 이미지 (참조 코드에서 독립적 img)
229
+ 배경 이미지 (화면 전체를 덮는 큰 이미지):
230
+ → absolute + inset-0 + object-cover
231
+ → .{section}Bg (z-index: 0) + .{section}Content (z-index: 10)
268
232
 
269
- ```
270
- → <img src="/images/{feature}/파일.webp" alt="설명" width={스케일적용} height={스케일적용} />
271
- ```
272
-
273
- ### 장식 이미지 (참조 코드에서 mix-blend, opacity, blur)
233
+ 콘텐츠 이미지 (독립적 요소):
234
+ → <img src="..." alt="설명" /> + 고정 width/height
274
235
 
275
- ```
276
- → <img ... alt="" aria-hidden="true" /> (접근성: 장식은 비표시)
277
- CSS: mix-blend-mode, opacity, filter: blur() 참조 코드 그대로
236
+ 장식 이미지 (분위기용, 반투명, 블러):
237
+ → <img ... alt="" aria-hidden="true" />
238
+ → mix-blend-mode, opacity 등 재료함적용
278
239
  ```
279
240
 
280
241
  ---
281
242
 
282
- ## 4. 반응형 추가 (데스크탑 URL)
243
+ ## 5. 반응형 추가 (데스크탑 URL)
283
244
 
284
245
  ```
285
- 같은 섹션에 대해 데스크탑 참조 코드 추출 후:
246
+ 번째 URL의 재료를 확보한 후:
247
+
248
+ 기존 모바일 코드 유지 + @media 오버라이드만 추가.
286
249
 
287
250
  같은 값 → 유지
288
- 다른 px 값:
289
- @include pc {
290
- .heroSection { height: 1440px; } // 데스크탑 스케일
291
- }
292
- 또는 clamp(모바일, calc, 데스크탑) 사용
293
-
294
- 다른 배경 이미지:
295
- .heroBg img { content: url('/images/{feature}/hero-mobile.webp'); }
296
- @include pc {
297
- .heroBg img { content: url('/images/{feature}/hero-pc.webp'); }
298
- }
299
-
300
- 다른 레이아웃:
301
- .heroContent { flex-direction: column; }
302
- @include pc { .heroContent { flex-direction: row; } }
303
-
304
- 기존 모바일 코드 삭제 금지. @media 또는 mixin으로 추가만.
251
+ 다른 px 값 → @include pc { ... } 오버라이드
252
+ 다른 레이아웃 → @include pc { flex-direction: row; }
253
+ 다른 배경 이미지 → @include pc { content: url(...) }
254
+
255
+ 기존 코드 삭제 금지.
305
256
  ```
306
257
 
307
258
  ---
308
259
 
309
- ## 5. Semantic HTML 최소 규칙
260
+ ## 6. Semantic HTML 규칙
310
261
 
311
262
  ```
312
263
  - 섹션 래퍼: <section>
313
264
  - 제목: <h1>~<h6> (순차, 건너뛰기 금지)
314
265
  - 텍스트: <p>
315
- - 버튼: <button> (@click 있으면)
316
- - 링크: <a> (href 있으면)
266
+ - 버튼: <button>
267
+ - 링크: <a>
317
268
  - 리스트: <ul>/<ol> + <li> (반복 패턴)
318
269
  - 장식 이미지: alt="" + aria-hidden="true"
319
270
  - 콘텐츠 이미지: alt="설명적 텍스트"
@@ -1,22 +1,51 @@
1
1
  ---
2
2
  name: vibe.figma.extract
3
- description: Figma REST API로 노드 트리, CSS, 이미지 추출
3
+ description: Figma REST API로 재료 확보 — 스크린샷, 이미지, CSS, 트리, 텍스트
4
4
  triggers: []
5
5
  tier: standard
6
6
  ---
7
7
 
8
- # vibe.figma.extract — 데이터 추출
8
+ # vibe.figma.extract — 재료 확보
9
9
 
10
- Figma REST API(`src/infra/lib/figma/`)를 사용하여 노드 트리, CSS, 이미지를 추출.
10
+ Figma REST API(`src/infra/lib/figma/`)를 사용하여 **퍼즐 조립에 필요한 모든 재료**를 추출.
11
+ 추출한 데이터는 코드 변환용이 아닌 **재료함(material inventory)**으로 사용된다.
11
12
 
12
13
  ---
13
14
 
14
- ## 1. 노드 트리 + CSS 추출
15
+ ## 1. 스크린샷 정답 사진
15
16
 
16
17
  ```
18
+ 가장 먼저 확보. 이것이 "만들어야 할 결과물"의 기준.
19
+
20
+ 전체 스크린샷:
21
+ node "[FIGMA_SCRIPT]" screenshot {fileKey} {nodeId} --out=/tmp/{feature}/full-screenshot.png
22
+
23
+ 섹션별 스크린샷 (1depth 자식 프레임 각각):
24
+ node "[FIGMA_SCRIPT]" screenshot {fileKey} {child.nodeId} --out=/tmp/{feature}/sections/{name}.png
25
+ ```
26
+
27
+ ---
28
+
29
+ ## 2. 이미지 에셋 — 시각 재료
30
+
31
+ ```
32
+ 트리에서 imageRef 수집 → Figma API로 다운로드:
33
+
17
34
  Bash:
18
- # [FIGMA_SCRIPT] = ~/.vibe/hooks/scripts/figma-extract.js
19
- node "[FIGMA_SCRIPT]" tree {fileKey} {nodeId} --depth=10
35
+ node "[FIGMA_SCRIPT]" images {fileKey} {nodeId} --out=/tmp/{feature}/images/ --depth=10
36
+
37
+ 반환: { total: N, images: { "imageRef": "/path/to/file.png", ... } }
38
+
39
+ 검증: total = refs.size (누락 0), 0byte 파일 없음
40
+ ```
41
+
42
+ ---
43
+
44
+ ## 3. 노드 트리 + CSS — 수치 재료
45
+
46
+ ```
47
+ Bash:
48
+ node "[FIGMA_SCRIPT]" tree {fileKey} {nodeId} --depth=10
20
49
 
21
50
  반환 (FigmaNode JSON):
22
51
  {
@@ -29,11 +58,18 @@ node "[FIGMA_SCRIPT]" tree {fileKey} {nodeId} --depth=10
29
58
  imageRef: "abc123" (이미지 fill이 있는 노드만),
30
59
  children: [...]
31
60
  }
61
+
62
+ ⚠️ 주의: 이 트리는 HTML 구조로 변환하지 않는다.
63
+ 용도는 오직:
64
+ - 정확한 CSS 수치 참조 (색상, 크기, 간격)
65
+ - 텍스트 콘텐츠 추출
66
+ - 이미지 참조 매핑
67
+ - 디자인 토큰 추출
32
68
  ```
33
69
 
34
70
  ### Figma 속성 → CSS 변환표
35
71
 
36
- 도구가 자동으로 변환하는 속성:
72
+ 도구가 자동으로 변환하는 속성 (재료로 활용):
37
73
 
38
74
  | Figma 속성 | CSS | 스케일 적용 |
39
75
  |-----------|-----|-----------|
@@ -49,7 +85,7 @@ node "[FIGMA_SCRIPT]" tree {fileKey} {nodeId} --depth=10
49
85
  | `style.fontFamily` | `font-family` | ❌ |
50
86
  | `style.fontSize` | `font-size` | ✅ |
51
87
  | `style.fontWeight` | `font-weight` | ❌ |
52
- | `style.lineHeightPx` | `line-height` | ❌ (px이지만 상대값으로 취급) |
88
+ | `style.lineHeightPx` | `line-height` | ❌ |
53
89
  | `style.letterSpacing` | `letter-spacing` | ✅ |
54
90
  | `style.textAlignHorizontal` | `text-align` | ❌ |
55
91
  | `fills[].color` (TEXT) | `color` | ❌ |
@@ -66,47 +102,50 @@ node "[FIGMA_SCRIPT]" tree {fileKey} {nodeId} --depth=10
66
102
 
67
103
  ---
68
104
 
69
- ## 2. 이미지 다운로드
105
+ ## 4. 재료함 정리 (material-inventory)
70
106
 
71
107
  ```
72
- 트리에서 imageRef 수집 Figma API로 다운로드:
108
+ 추출 완료 재료를 카테고리별로 정리:
73
109
 
74
- Bash:
75
- node "[FIGMA_SCRIPT]" images {fileKey} {nodeId} --out={outDir} --depth=10
110
+ 이미지 목록:
111
+ 파일명 | 크기 | 용도 추정
112
+ hero-bg.png | 720×1280 | 배경 (큰 사이즈, BG 레이어)
113
+ title.png | 620×174 | 타이틀 이미지
114
+ btn-share.png | 48×48 | 아이콘 (작은 사이즈)
76
115
 
77
- 반환: { total: N, images: { "imageRef": "/path/to/file.png", ... } }
116
+ 색상 팔레트 (tree.json에서 고유값 추출):
117
+ #0a1628, #00264a, #ffffff, #dadce3, #003879, #419bd3, ...
78
118
 
79
- 파일명: imageRef 앞 16자 + .png
80
- 검증: total = refs.size (누락 0), 0byte 파일 없음
119
+ 폰트 목록:
120
+ Pretendard: 400/500/700, 16px~48px
121
+ Roboto Condensed: 700, 24px~36px
122
+
123
+ 텍스트 콘텐츠 (모든 TEXT 노드):
124
+ "겨울 이벤트", "12.1 ~ 12.31", "참여 대상 : PC 유저", ...
125
+
126
+ 간격 패턴 (빈도 높은 값):
127
+ gap: 8px, 16px, 24px, 32px
128
+ padding: 16px, 24px, 32px
81
129
  ```
82
130
 
83
131
  ---
84
132
 
85
- ## 3. 스크린샷
86
-
87
- ```
88
- Bash:
89
- node "[FIGMA_SCRIPT]" screenshot {fileKey} {nodeId} --out={path}
133
+ ## 5. 노드 참조 (보조)
90
134
 
91
- 시각 검증용. 노드를 PNG로 렌더링하여 저장.
92
135
  ```
136
+ 트리의 name/type은 재료 분류에만 사용:
93
137
 
94
- ---
138
+ name 패턴 → 용도 힌트:
139
+ "BG" → 배경 이미지 (스크린샷에서 확인)
140
+ "Title", "Txt_*" → 텍스트 영역
141
+ "Btn_*", "CTA" → 버튼/인터랙티브
142
+ "Icon_*" → 아이콘
143
+ "Step1", "Item_*" → 반복 요소
95
144
 
96
- ## 4. 노드 구조 참조
145
+ type 재료 종류:
146
+ TEXT → 텍스트 콘텐츠 제공
147
+ RECTANGLE/VECTOR + imageRef → 다운로드 대상 이미지
148
+ INSTANCE → 반복 사용 가능성 (컴포넌트 후보)
97
149
 
98
- ```
99
- 트리의 name 속성으로 레이어 용도 파악:
100
- name="BG" → 배경 레이어 (position:absolute, imageRef 포함)
101
- name="Contents" → 콘텐츠 영역
102
- name="Title" → 제목
103
- name="Step1", "Step2" → 하위 섹션
104
- name="Btn_Login" → 버튼
105
-
106
- type으로 노드 종류 구분:
107
- FRAME → 컨테이너 (div)
108
- TEXT → 텍스트 (p/span)
109
- INSTANCE → 컴포넌트 인스턴스 (자식 있음)
110
- RECTANGLE/VECTOR with imageRef → 이미지 (img)
111
- GROUP → 그룹 (div)
150
+ ⚠️ 이 정보로 HTML을 생성하지 않는다. 스크린샷을 보고 판단한다.
112
151
  ```