@kood/claude-code 0.3.6 → 0.3.7

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.
Files changed (34) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +1 -1
  3. package/templates/nextjs/CLAUDE.md +228 -0
  4. package/templates/nextjs/docs/design.md +558 -0
  5. package/templates/nextjs/docs/guides/conventions.md +343 -0
  6. package/templates/nextjs/docs/guides/getting-started.md +367 -0
  7. package/templates/nextjs/docs/guides/routes.md +342 -0
  8. package/templates/nextjs/docs/library/better-auth/index.md +541 -0
  9. package/templates/nextjs/docs/library/nextjs/app-router.md +269 -0
  10. package/templates/nextjs/docs/library/nextjs/caching.md +351 -0
  11. package/templates/nextjs/docs/library/nextjs/index.md +291 -0
  12. package/templates/nextjs/docs/library/nextjs/middleware.md +391 -0
  13. package/templates/nextjs/docs/library/nextjs/route-handlers.md +382 -0
  14. package/templates/nextjs/docs/library/nextjs/server-actions.md +366 -0
  15. package/templates/nextjs/docs/library/prisma/cloudflare-d1.md +76 -0
  16. package/templates/nextjs/docs/library/prisma/config.md +77 -0
  17. package/templates/nextjs/docs/library/prisma/crud.md +90 -0
  18. package/templates/nextjs/docs/library/prisma/index.md +73 -0
  19. package/templates/nextjs/docs/library/prisma/relations.md +69 -0
  20. package/templates/nextjs/docs/library/prisma/schema.md +98 -0
  21. package/templates/nextjs/docs/library/prisma/setup.md +49 -0
  22. package/templates/nextjs/docs/library/prisma/transactions.md +50 -0
  23. package/templates/nextjs/docs/library/tanstack-query/index.md +66 -0
  24. package/templates/nextjs/docs/library/tanstack-query/invalidation.md +54 -0
  25. package/templates/nextjs/docs/library/tanstack-query/optimistic-updates.md +77 -0
  26. package/templates/nextjs/docs/library/tanstack-query/use-mutation.md +63 -0
  27. package/templates/nextjs/docs/library/tanstack-query/use-query.md +70 -0
  28. package/templates/nextjs/docs/library/zod/complex-types.md +61 -0
  29. package/templates/nextjs/docs/library/zod/index.md +56 -0
  30. package/templates/nextjs/docs/library/zod/transforms.md +51 -0
  31. package/templates/nextjs/docs/library/zod/validation.md +70 -0
  32. package/templates/tanstack-start/CLAUDE.md +7 -3
  33. package/templates/tanstack-start/docs/guides/hooks.md +28 -0
  34. package/templates/tanstack-start/docs/guides/routes.md +29 -10
@@ -0,0 +1,558 @@
1
+ # UI/UX & Tailwind 가이드라인
2
+
3
+ > TanStack Start + Tailwind CSS v4 + iOS Safe Area
4
+
5
+ ---
6
+
7
+ <forbidden>
8
+
9
+ | 분류 | 금지 |
10
+ |------|------|
11
+ | **Spacing** | 임의값 (`mt-[13px]`), theme 외 값 |
12
+ | **컴포넌트** | 동일 요소에 다른 스타일 조합 |
13
+ | **@apply** | 개별 화면에서 사용, base 컴포넌트 외 |
14
+ | **반응형** | 데스크탑 우선 작성 |
15
+ | **Safe Area** | 컴포넌트 내부 적용, `env(safe-area-inset-*)` 직접 사용 |
16
+ | **그림자** | `shadow-lg` 이상 (특별한 경우 제외) |
17
+ | **폰트** | 4개 이상, `text-xs` 남용 |
18
+ | **색상** | Primary를 일반 텍스트/배경에 사용, 진한 보더 |
19
+ | **접근성** | 색상만으로 구분, `outline-none`, placeholder만 레이블 |
20
+ | **에러** | 기술 용어 메시지 ("code: 500") |
21
+ | **버튼** | 화면당 Primary 2개 이상 |
22
+
23
+ </forbidden>
24
+
25
+ ---
26
+
27
+ <required>
28
+
29
+ | 분류 | 필수 |
30
+ |------|------|
31
+ | **Spacing** | Tailwind 기본 스케일만 (4px 단위) |
32
+ | **반응형** | 모바일 퍼스트 → `sm:` → `md:` → `lg:` |
33
+ | **Safe Area** | `tailwindcss-safe-area` 사용, 레이아웃 단위 적용 |
34
+ | **Viewport** | `viewport-fit=cover` 설정 |
35
+ | **접근성** | 대비 4.5:1 이상, 레이블 필수, 키보드 접근 |
36
+ | **버튼 상태** | Default/Hover/Active/Disabled/Loading 명확히 구분 |
37
+ | **에러** | 사용자 행동 중심 메시지 |
38
+ | **포커스** | `focus:ring-2` 등 명확한 표시 |
39
+ | **로딩** | 주요 액션에 로딩 상태, 중복 클릭 방지 |
40
+ | **클래스 순서** | 레이아웃 → 박스 → 타이포 → 색상 → 상태 |
41
+
42
+ </required>
43
+
44
+ ---
45
+
46
+ <design_tokens>
47
+
48
+ ## 디자인 토큰 (Tailwind @theme)
49
+
50
+ ```css
51
+ @import "tailwindcss";
52
+ @import "tailwindcss-safe-area";
53
+
54
+ @theme {
55
+ /* 색상 (60-30-10 규칙) */
56
+ --color-primary-500: oklch(0.55 0.2 250);
57
+ --color-primary-600: oklch(0.48 0.22 250);
58
+ --color-primary-700: oklch(0.42 0.2 250);
59
+
60
+ /* 폰트 (최대 2-3개) */
61
+ --font-sans: "Pretendard", "Inter", system-ui, sans-serif;
62
+ --font-mono: "JetBrains Mono", monospace;
63
+
64
+ /* 반경 */
65
+ --radius: 0.5rem; /* 8px */
66
+
67
+ /* 그림자 */
68
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
69
+ --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
70
+ }
71
+ ```
72
+
73
+ | 토큰 | 값 |
74
+ |------|-----|
75
+ | Spacing | 4px 그리드 (`gap-2`=8px, `p-4`=16px) |
76
+ | 색상 | Primary(액션), Neutral(배경), Semantic(상태) |
77
+ | 폰트 크기 | `text-2xl`(제목), `text-base`(본문), `text-sm`(보조) |
78
+ | 컨테이너 | `max-w-md`(폼), `max-w-3xl`(블로그), `max-w-7xl`(대시보드) |
79
+
80
+ </design_tokens>
81
+
82
+ ---
83
+
84
+ <patterns>
85
+
86
+ ## Tailwind 패턴
87
+
88
+ ### 버튼
89
+
90
+ ```tsx
91
+ // Primary
92
+ <button className="px-4 py-2 text-sm font-medium text-white bg-primary-600 rounded-lg
93
+ hover:bg-primary-700 focus:ring-2 focus:ring-primary-500 focus:ring-offset-2
94
+ disabled:opacity-50 disabled:cursor-not-allowed">
95
+ 저장하기
96
+ </button>
97
+
98
+ // Secondary
99
+ <button className="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg
100
+ hover:bg-gray-50 focus:ring-2 focus:ring-gray-300">
101
+ 취소
102
+ </button>
103
+
104
+ // Destructive
105
+ <button className="px-4 py-2 text-sm font-medium text-white bg-red-600 rounded-lg hover:bg-red-700">
106
+ 삭제
107
+ </button>
108
+
109
+ // 로딩 상태
110
+ <button disabled={isLoading} className="flex items-center gap-2">
111
+ {isLoading && <Spinner className="w-4 h-4 animate-spin" />}
112
+ {isLoading ? '저장 중...' : '저장하기'}
113
+ </button>
114
+ ```
115
+
116
+ | 크기 | 클래스 |
117
+ |------|--------|
118
+ | Small | `px-3 py-1.5 text-sm` |
119
+ | Medium | `px-4 py-2 text-base` |
120
+ | Large | `px-6 py-3 text-lg` |
121
+
122
+ ### 입력 필드
123
+
124
+ ```tsx
125
+ // 기본
126
+ <div>
127
+ <label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-1">
128
+ 이메일
129
+ </label>
130
+ <input
131
+ id="email"
132
+ type="email"
133
+ className="w-full px-3 py-2 text-base border border-gray-300 rounded-lg
134
+ focus:ring-2 focus:ring-blue-500 focus:border-blue-500
135
+ placeholder:text-gray-400"
136
+ placeholder="example@email.com"
137
+ />
138
+ </div>
139
+
140
+ // 에러 상태
141
+ <input
142
+ className="w-full px-3 py-2 border border-red-500 rounded-lg
143
+ focus:ring-2 focus:ring-red-500"
144
+ aria-invalid="true"
145
+ aria-describedby="email-error"
146
+ />
147
+ <p id="email-error" className="mt-1 text-sm text-red-600" role="alert">
148
+ 올바른 이메일을 입력하세요
149
+ </p>
150
+
151
+ // 아이콘 포함
152
+ <div className="relative">
153
+ <SearchIcon className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" />
154
+ <input className="pl-10 pr-3 py-2 w-full border border-gray-300 rounded-lg" />
155
+ </div>
156
+ ```
157
+
158
+ ### 카드
159
+
160
+ ```tsx
161
+ <div className="bg-white rounded-lg border border-gray-200 shadow-sm overflow-hidden">
162
+ <div className="px-6 py-4 border-b border-gray-200">
163
+ <h3 className="text-lg font-semibold text-gray-900">제목</h3>
164
+ </div>
165
+ <div className="px-6 py-4">
166
+ <p className="text-base text-gray-600">본문 내용</p>
167
+ </div>
168
+ <div className="px-6 py-4 bg-gray-50 border-t border-gray-200">
169
+ <button>푸터 버튼</button>
170
+ </div>
171
+ </div>
172
+ ```
173
+
174
+ ### 모달
175
+
176
+ ```tsx
177
+ <div className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4">
178
+ <div className="bg-white rounded-lg shadow-xl w-full max-w-md">
179
+ <div className="px-6 py-4 border-b border-gray-200 flex items-center justify-between">
180
+ <h2 className="text-lg font-semibold text-gray-900">제목</h2>
181
+ <button><XIcon className="w-5 h-5" /></button>
182
+ </div>
183
+ <div className="px-6 py-4">본문</div>
184
+ <div className="px-6 py-4 bg-gray-50 flex justify-end gap-3">
185
+ <button className="px-4 py-2 border border-gray-300 rounded-lg">취소</button>
186
+ <button className="px-4 py-2 bg-primary-600 text-white rounded-lg">확인</button>
187
+ </div>
188
+ </div>
189
+ </div>
190
+ ```
191
+
192
+ ### 알림
193
+
194
+ ```tsx
195
+ // 성공
196
+ <div className="p-4 bg-green-50 border border-green-200 rounded-lg flex gap-3">
197
+ <CheckCircleIcon className="w-5 h-5 text-green-600 flex-shrink-0" />
198
+ <p className="text-sm text-green-800">저장되었습니다</p>
199
+ </div>
200
+
201
+ // 에러
202
+ <div className="p-4 bg-red-50 border border-red-200 rounded-lg flex gap-3">
203
+ <XCircleIcon className="w-5 h-5 text-red-600 flex-shrink-0" />
204
+ <p className="text-sm text-red-800">서버에 문제가 발생했어요. 잠시 후 다시 시도해주세요.</p>
205
+ </div>
206
+
207
+ // 경고
208
+ <div className="p-4 bg-yellow-50 border border-yellow-200 rounded-lg flex gap-3">
209
+ <AlertIcon className="w-5 h-5 text-yellow-600 flex-shrink-0" />
210
+ <p className="text-sm text-yellow-800">확인이 필요합니다</p>
211
+ </div>
212
+ ```
213
+
214
+ ### 빈 상태
215
+
216
+ ```tsx
217
+ <div className="py-12 text-center">
218
+ <InboxIcon className="mx-auto w-12 h-12 text-gray-400" />
219
+ <h3 className="mt-4 text-lg font-medium text-gray-900">아직 항목이 없어요</h3>
220
+ <p className="mt-2 text-sm text-gray-600">첫 항목을 추가해보세요</p>
221
+ <button className="mt-6 px-4 py-2 bg-primary-600 text-white rounded-lg">
222
+ 추가하기
223
+ </button>
224
+ </div>
225
+ ```
226
+
227
+ </patterns>
228
+
229
+ ---
230
+
231
+ <safe_area>
232
+
233
+ ## iOS Safe Area
234
+
235
+ ### 설치 & 설정
236
+
237
+ ```bash
238
+ yarn add tailwindcss-safe-area
239
+ ```
240
+
241
+ ```tsx
242
+ // __root.tsx
243
+ export const Route = createRootRoute({
244
+ head: () => ({
245
+ meta: [{
246
+ name: 'viewport',
247
+ content: 'width=device-width, initial-scale=1, viewport-fit=cover',
248
+ }],
249
+ }),
250
+ })
251
+ ```
252
+
253
+ ### 유틸리티 클래스
254
+
255
+ | 클래스 | 용도 |
256
+ |--------|------|
257
+ | `pt-safe` | 상단 safe area (노치) |
258
+ | `pb-safe` | 하단 safe area (홈 인디케이터) |
259
+ | `px-safe` | 좌우 safe area |
260
+ | `h-screen-safe` | safe area 제외 높이 |
261
+ | `min-h-screen-safe` | 최소 높이 |
262
+ | `pt-safe-or-4` | safe area 또는 1rem (더 큰 값) |
263
+ | `pb-safe-offset-4` | safe area + 1rem |
264
+
265
+ ### 레이아웃 패턴
266
+
267
+ ```tsx
268
+ // 기본 앱 레이아웃
269
+ <div className="min-h-screen-safe flex flex-col">
270
+ <header className="pt-safe-or-2 px-safe-or-4 bg-white border-b">
271
+ <nav className="h-14 flex items-center">헤더</nav>
272
+ </header>
273
+
274
+ <main className="flex-1 px-safe-or-4 py-6">
275
+ {children}
276
+ </main>
277
+
278
+ <footer className="pb-safe-or-2 px-safe-or-4 bg-white border-t">
279
+ <nav className="h-14 flex items-center justify-around">탭바</nav>
280
+ </footer>
281
+ </div>
282
+
283
+ // 고정 하단 버튼
284
+ <div className="fixed bottom-0 left-0 right-0 pb-safe-or-4 px-safe-or-4 bg-white border-t">
285
+ <button className="w-full h-12 bg-primary-600 text-white rounded-lg">
286
+ 확인
287
+ </button>
288
+ </div>
289
+
290
+ // 전체 화면 모달
291
+ <div className="fixed inset-0 bg-white z-50">
292
+ <div className="h-screen-safe flex flex-col p-safe">
293
+ {children}
294
+ </div>
295
+ </div>
296
+ ```
297
+
298
+ ### ✅ / ❌ Safe Area
299
+
300
+ ```tsx
301
+ // ❌ 노치에 가려짐
302
+ <header className="fixed top-0">
303
+
304
+ // ✅ Safe area 적용
305
+ <header className="fixed top-0 pt-safe">
306
+
307
+ // ❌ 홈 인디케이터와 겹침
308
+ <button className="fixed bottom-4">
309
+
310
+ // ✅ Safe area 적용
311
+ <div className="fixed bottom-0 pb-safe-or-4">
312
+ <button>...</button>
313
+ </div>
314
+
315
+ // ❌ 컴포넌트 내부에 적용
316
+ <Button className="pb-safe">버튼</Button>
317
+
318
+ // ✅ 레이아웃에서 적용
319
+ <div className="pb-safe-or-4">
320
+ <Button>버튼</Button>
321
+ </div>
322
+ ```
323
+
324
+ </safe_area>
325
+
326
+ ---
327
+
328
+ <guidelines>
329
+
330
+ ## 핵심 원칙
331
+
332
+ | 원칙 | 설명 |
333
+ |------|------|
334
+ | **일관성** | 동일 역할 = 동일 스타일 |
335
+ | **단순함** | 불필요한 요소 제거 |
336
+ | **반응형** | 모바일 퍼스트 |
337
+ | **접근성** | WCAG AA (대비 4.5:1+) |
338
+
339
+ ### 색상 (60-30-10)
340
+
341
+ | 비율 | 용도 | 예시 |
342
+ |------|------|------|
343
+ | 60% | 배경 | `bg-white`, `bg-gray-50` |
344
+ | 30% | 보조 | 카드, 섹션 |
345
+ | 10% | 강조 | Primary 버튼, CTA |
346
+
347
+ ### 타이포그래피
348
+
349
+ | 용도 | 클래스 | 크기 |
350
+ |------|--------|------|
351
+ | 제목 | `text-2xl` | 24px |
352
+ | 부제목 | `text-xl` | 20px |
353
+ | 본문 | `text-base` | 16px |
354
+ | 보조 | `text-sm` | 14px |
355
+
356
+ ### Spacing
357
+
358
+ | 용도 | 클래스 | 크기 |
359
+ |------|--------|------|
360
+ | 아이콘-텍스트 | `gap-1` | 4px |
361
+ | 인라인 요소 | `gap-2` | 8px |
362
+ | 카드 내부 | `p-4` | 16px |
363
+ | 카드 간격 | `gap-6` | 24px |
364
+ | 섹션 간격 | `py-12` | 48px |
365
+
366
+ ### 반응형
367
+
368
+ ```tsx
369
+ <div className="p-4 md:p-6 lg:p-8">
370
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
371
+ ```
372
+
373
+ | 브레이크포인트 | 크기 | 용도 |
374
+ |--------------|------|------|
375
+ | `sm` | 640px | 모바일 가로 |
376
+ | `md` | 768px | 태블릿 |
377
+ | `lg` | 1024px | 노트북 |
378
+ | `xl` | 1280px | 데스크탑 |
379
+
380
+ </guidelines>
381
+
382
+ ---
383
+
384
+ <accessibility>
385
+
386
+ ## 접근성 체크리스트
387
+
388
+ ```tsx
389
+ // ✅ 명확한 레이블
390
+ <label htmlFor="email">이메일</label>
391
+ <input id="email" />
392
+
393
+ // ✅ 에러 연결
394
+ <input aria-invalid={hasError} aria-describedby="error" />
395
+ {hasError && <p id="error" role="alert">오류</p>}
396
+
397
+ // ✅ 포커스 표시
398
+ <button className="focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
399
+
400
+ // ✅ 색상 + 아이콘 병행
401
+ <span className="text-red-600 flex items-center gap-1">
402
+ <XCircleIcon className="w-4 h-4" />
403
+ 오류
404
+ </span>
405
+
406
+ // ✅ 키보드 접근
407
+ <div tabIndex={0} onKeyDown={handleKeyDown}>
408
+
409
+ // ❌ 포커스 제거 금지
410
+ <button className="outline-none focus:outline-none">
411
+ ```
412
+
413
+ | 항목 | 기준 |
414
+ |------|------|
415
+ | 텍스트 대비 | 4.5:1 이상 |
416
+ | 큰 텍스트 (18px+) | 3:1 이상 |
417
+ | 터치 영역 | 44px × 44px 이상 |
418
+ | 포커스 표시 | 항상 visible |
419
+
420
+ </accessibility>
421
+
422
+ ---
423
+
424
+ <examples>
425
+
426
+ ## 실전 예시
427
+
428
+ ### 폼 레이아웃
429
+
430
+ ```tsx
431
+ <form className="max-w-md mx-auto space-y-6">
432
+ {/* 입력 필드 */}
433
+ <div>
434
+ <label htmlFor="name" className="block text-sm font-medium text-gray-700 mb-1">
435
+ 이름
436
+ </label>
437
+ <input
438
+ id="name"
439
+ type="text"
440
+ className="w-full px-3 py-2 border border-gray-300 rounded-lg
441
+ focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
442
+ />
443
+ </div>
444
+
445
+ {/* 에러가 있는 입력 */}
446
+ <div>
447
+ <label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-1">
448
+ 이메일
449
+ </label>
450
+ <input
451
+ id="email"
452
+ type="email"
453
+ className="w-full px-3 py-2 border border-red-500 rounded-lg
454
+ focus:ring-2 focus:ring-red-500"
455
+ aria-invalid="true"
456
+ aria-describedby="email-error"
457
+ />
458
+ <p id="email-error" className="mt-1 text-sm text-red-600" role="alert">
459
+ 올바른 이메일을 입력하세요
460
+ </p>
461
+ </div>
462
+
463
+ {/* 버튼 그룹 */}
464
+ <div className="flex gap-3">
465
+ <button
466
+ type="button"
467
+ className="flex-1 px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50"
468
+ >
469
+ 취소
470
+ </button>
471
+ <button
472
+ type="submit"
473
+ className="flex-1 px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700"
474
+ >
475
+ 저장
476
+ </button>
477
+ </div>
478
+ </form>
479
+ ```
480
+
481
+ ### 카드 리스트
482
+
483
+ ```tsx
484
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
485
+ {items.map((item) => (
486
+ <div key={item.id} className="bg-white rounded-lg border border-gray-200 shadow-sm overflow-hidden">
487
+ <img src={item.image} className="w-full h-48 object-cover" />
488
+ <div className="p-4">
489
+ <h3 className="text-lg font-semibold text-gray-900">{item.title}</h3>
490
+ <p className="mt-2 text-sm text-gray-600">{item.description}</p>
491
+ <button className="mt-4 w-full px-4 py-2 bg-primary-600 text-white rounded-lg">
492
+ 자세히 보기
493
+ </button>
494
+ </div>
495
+ </div>
496
+ ))}
497
+ </div>
498
+ ```
499
+
500
+ ### 대시보드 레이아웃
501
+
502
+ ```tsx
503
+ <div className="min-h-screen-safe bg-gray-50">
504
+ {/* 헤더 */}
505
+ <header className="pt-safe-or-2 px-safe-or-4 bg-white border-b border-gray-200">
506
+ <div className="h-16 flex items-center justify-between">
507
+ <h1 className="text-xl font-bold">대시보드</h1>
508
+ <button>메뉴</button>
509
+ </div>
510
+ </header>
511
+
512
+ {/* 메인 */}
513
+ <main className="px-safe-or-4 py-6">
514
+ <div className="max-w-7xl mx-auto space-y-6">
515
+ {/* 통계 카드 */}
516
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
517
+ <div className="bg-white p-6 rounded-lg border border-gray-200">
518
+ <p className="text-sm text-gray-600">총 사용자</p>
519
+ <p className="mt-2 text-3xl font-bold text-gray-900">1,234</p>
520
+ </div>
521
+ {/* ... */}
522
+ </div>
523
+
524
+ {/* 차트 */}
525
+ <div className="bg-white p-6 rounded-lg border border-gray-200">
526
+ <h2 className="text-lg font-semibold text-gray-900">활동</h2>
527
+ {/* 차트 컴포넌트 */}
528
+ </div>
529
+ </div>
530
+ </main>
531
+ </div>
532
+ ```
533
+
534
+ </examples>
535
+
536
+ ---
537
+
538
+ <claude_requirements>
539
+
540
+ ## Claude Code 요구사항
541
+
542
+ **새 화면/컴포넌트 작성 시:**
543
+
544
+ 1. **Tailwind 스케일만 사용** - 임의값 금지
545
+ 2. **모바일 퍼스트** - 기본 스타일 → `sm:` → `md:` → `lg:`
546
+ 3. **Safe area 레이아웃에서 처리** - 컴포넌트 내부 금지
547
+ 4. **접근성 필수** - 레이블, 대비, 포커스, 키보드
548
+ 5. **일관된 패턴** - 같은 요소는 항상 같은 클래스 조합
549
+ 6. **로딩/에러 상태** - 주요 액션에 필수
550
+ 7. **마이크로카피** - 버튼/에러 메시지 함께 제안
551
+
552
+ **예외 발생 시:**
553
+ - 코드 주석으로 이유 설명
554
+
555
+ **Theme 확장 필요 시:**
556
+ - 임의값 대신 `@theme` 확장 제안
557
+
558
+ </claude_requirements>