@su-record/vibe 2.8.35 → 2.8.37

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