generated from gc/template-java-maven
- 디자인 시스템 CSS 변수 토큰 적용 (success/warning/danger/info) - PeriodFilter 공통 컴포넌트 생성 및 통계 페이지 적용 - SERVICE_BADGE_VARIANTS 공통 상수 추출 - 통계/요청로그/키관리/관리자 페이지 레퍼런스 디자인 반영 - 테이블 규격 통일 (h-8/h-7, px-3 py-1, text-xs, Button xs) - 타이틀 아이콘 전체 페이지 통일 - 카드 테두리 디자인 통일 (border + rounded-xl) - FHD 1920x1080 최적화
517 lines
19 KiB
Markdown
517 lines
19 KiB
Markdown
# SNP Connection Monitoring — 디자인 시스템 적용 프롬프트
|
|
|
|
아래 프롬프트를 Claude Code에 붙여넣어 실행하세요.
|
|
|
|
---
|
|
|
|
```
|
|
해양 데이터 시스템(SNP Connection Monitoring) 프로젝트에 디자인 시스템을 적용해줘.
|
|
프로젝트 규칙(.claude/rules/)과 CLAUDE.md를 반드시 읽고 따라줘.
|
|
|
|
## 0. 사전 준비
|
|
|
|
- develop 브랜치에서 `feature/design-system` 브랜치를 생성해서 작업
|
|
- 커밋 메시지는 Conventional Commits 형식 (프로젝트 git-workflow.md 참조)
|
|
|
|
## 1. 디자인 가이드 문서 생성
|
|
|
|
`docs/design/` 디렉토리 아래에 아래 파일들을 생성해줘.
|
|
|
|
### 1-1. docs/design/colors.md
|
|
|
|
해양 데이터 시스템 컬러 시스템. 내용:
|
|
|
|
**브랜드 컬러 원본:**
|
|
| 역할 | HEX | 설명 |
|
|
|------|-----|------|
|
|
| Primary | #6D94C5 | Slate Blue — 신뢰, 전문성 |
|
|
| Secondary | #CBDCEB | Powder Blue — 부드러운 보조 |
|
|
| Accent | #E8DFCA | Warm Sand — 따뜻한 포인트 |
|
|
| Background | #F5EFE6 | Warm Cream — 배경색 |
|
|
|
|
**브랜드 컬러 스케일 (50~950):**
|
|
|
|
Primary (Slate Blue, hue≈213°):
|
|
- 50: #F5F7F9, 100: #E5EBF2, 200: #D2DAE5, 300: #B7C5D7, 400: #8AA5C7
|
|
- 500: #6D94C5, 600: #507FB9, 700: #3B669C, 800: #2D507B, 900: #1B2C41, 950: #0E1A2B
|
|
|
|
Secondary (Powder Blue, hue≈210°):
|
|
- 50: #F5F7F9, 100: #E6EDF5, 200: #D1DAE5, 300: #B7C8D7, 400: #89AAC8
|
|
- 500: #CBDCEB, 600: #6B9AC8, 700: #4E88BB, 800: #396E9D, 900: #1B2F41, 950: #0E1A2B
|
|
|
|
Accent (Warm Sand, hue≈38°):
|
|
- 50: #F9F8F6, 100: #F2EDE4, 200: #E4E0D7, 300: #D5CDB9, 400: #C4B48C
|
|
- 500: #E8DFCA, 600: #B59854, 700: #9A7E3E, 800: #786230, 900: #3F351D, 950: #2B2312
|
|
|
|
**디자인 토큰 (CSS 변수 — Light / Dark):**
|
|
|
|
| 토큰 | Light | Dark |
|
|
|------|-------|------|
|
|
| --color-primary | #507FB9 | #B7C5D7 |
|
|
| --color-primary-hover | #3B669C | #D2DAE5 |
|
|
| --color-primary-active | #2D507B | #8AA5C7 |
|
|
| --color-primary-subtle | #F5F7F9 | #1B2C41 |
|
|
| --color-primary-text | #2D507B | #D2DAE5 |
|
|
| --color-secondary | #CBDCEB | #B7C8D7 |
|
|
| --color-secondary-hover | #89AAC8 | #D1DAE5 |
|
|
| --color-secondary-active | #4E88BB | #89AAC8 |
|
|
| --color-secondary-subtle | #F5F7F9 | #1B2F41 |
|
|
| --color-secondary-text | #396E9D | #D1DAE5 |
|
|
| --color-accent | #E8DFCA | #D5CDB9 |
|
|
| --color-accent-hover | #C4B48C | #E4E0D7 |
|
|
| --color-accent-active | #B59854 | #C4B48C |
|
|
| --color-accent-subtle | #F9F8F6 | #3F351D |
|
|
| --color-accent-text | #786230 | #E4E0D7 |
|
|
|
|
**시멘틱 컬러 (Light / Dark):**
|
|
|
|
| 역할 | Light | Dark |
|
|
|------|-------|------|
|
|
| Success | #059669 | #34D399 |
|
|
| Warning | #D97706 | #FBBF24 |
|
|
| Danger | #DC2626 | #FCA5A5 |
|
|
| Info | #0284C7 | #38BDF8 |
|
|
|
|
**뉴트럴 (Blue-tinted warm gray):**
|
|
|
|
| 토큰 | Light | Dark |
|
|
|------|-------|------|
|
|
| --color-bg-base | #F5EFE6 | #131416 |
|
|
| --color-bg-surface | #FFFFFF | #1E2023 |
|
|
| --color-bg-elevated | #FFFFFF | #282A2E |
|
|
| --color-border | #D5D2CC | #3A3C41 |
|
|
| --color-border-strong | #9198A1 | #5C6570 |
|
|
| --color-text-primary | #1E2329 | #F4F5F5 |
|
|
| --color-text-secondary | #5C6570 | #9198A1 |
|
|
| --color-text-tertiary | #9198A1 | #5C6570 |
|
|
|
|
**다크모드 토큰 사용 가이드:**
|
|
다크모드 시멘틱 토큰(--color-primary, --color-secondary, --color-accent)은 텍스트/아이콘용 밝은 톤이다.
|
|
버튼/뱃지처럼 배경색이 필요한 인터랙티브 요소는 다크모드에서 스케일 값(600~700)을 직접 사용해야 한다.
|
|
- 텍스트/아이콘: `text-[--color-primary]` → 다크모드에서 자동으로 밝은 톤 적용 (OK)
|
|
- 버튼 배경: `bg-[--color-primary]` → 다크모드에서 `dark:bg-[--color-primary-600]`으로 오버라이드 (필수)
|
|
|
|
**차트 팔레트 (6색 Hue 분산, Cool+Warm 교차):**
|
|
|
|
Light (흰 배경):
|
|
1. #507FB9 — Slate Blue (213°, 브랜드 Primary)
|
|
2. #B59854 — Warm Gold (38°, 브랜드 Accent)
|
|
3. #B5607D — Rose (340°)
|
|
4. #3D998A — Teal (168°)
|
|
5. #8B6DB5 — Lavender (270°)
|
|
6. #C07850 — Coral (22°)
|
|
|
|
Dark (어두운 배경, 밝기 강화):
|
|
1. #6D94C5 — Slate Blue
|
|
2. #C4B48C — Warm Sand
|
|
3. #D4839B — Rose
|
|
4. #5BB5A6 — Teal
|
|
5. #B79FD4 — Lavender
|
|
6. #D4956B — Coral
|
|
|
|
### 1-2. docs/design/typography.md
|
|
|
|
타이포그래피 시스템:
|
|
- 기본 폰트: Pretendard (한글), Inter (영문/숫자)
|
|
- 8단계 타입 스케일: Display 48px, H1 36px, H2 30px, H3 24px, Body-lg 18px, Body 16px, Caption 14px, Overline 12px
|
|
- line-height: heading 1.2~1.3, body 1.5~1.6
|
|
- font-weight: 300(light), 400(regular), 500(medium), 600(semibold), 700(bold)
|
|
- 한국어 word-break: keep-all 규칙
|
|
|
|
### 1-3. docs/design/spacing.md
|
|
|
|
스페이싱 시스템:
|
|
- 4px 기반 스케일: 0(0px), 0.5(2px), 1(4px), 1.5(6px), 2(8px), 3(12px), 4(16px), 5(20px), 6(24px), 8(32px), 10(40px), 12(48px), 16(64px), 20(80px), 24(96px)
|
|
- 컴포넌트별 내부 여백: Button(px-4 py-2), Card(p-4~p-6), Input(px-3 py-2), Modal(p-6)
|
|
- 반응형 브레이크포인트: sm 640px, md 768px, lg 1024px, xl 1280px, 2xl 1536px
|
|
- 그리드: 12컬럼, gap-4~gap-6
|
|
|
|
### 1-4. docs/design/components.md
|
|
|
|
컴포넌트 스펙:
|
|
|
|
**Button 변형 (Light 모드):**
|
|
- primary: bg-[--color-primary] text-white hover:bg-[--color-primary-hover]
|
|
- secondary: bg-[--color-secondary] text-[--color-secondary-text] hover:bg-[--color-secondary-hover]
|
|
- accent: bg-[--color-accent] text-[--color-accent-text] hover:bg-[--color-accent-hover]
|
|
- outline: border border-[--color-border-strong] text-[--color-text-primary] hover:bg-[--color-primary-subtle]
|
|
- ghost: text-[--color-text-secondary] hover:bg-[--color-primary-subtle]
|
|
- danger: bg-danger-600 text-white hover:bg-danger-700
|
|
|
|
**Button 변형 (Dark 모드) — 채도/대비 강화:**
|
|
다크모드에서 시멘틱 토큰(--color-primary 등)은 연한 파스텔 톤이라 버튼 배경으로 부적합.
|
|
스케일 값(600~700)을 직접 사용하여 선명한 대비를 확보한다.
|
|
- primary: dark:bg-[--color-primary-600] dark:text-white dark:hover:bg-[--color-primary-500]
|
|
- secondary: dark:bg-[--color-secondary-700] dark:text-white dark:hover:bg-[--color-secondary-600]
|
|
- accent: dark:bg-[--color-accent-600] dark:text-white dark:hover:bg-[--color-accent-500]
|
|
- outline: dark:border-[--color-primary-400] dark:text-[--color-primary-300] dark:hover:bg-primary-600/15
|
|
- ghost: dark:text-[--color-primary-300] dark:hover:bg-primary-600/12
|
|
- danger: dark:bg-[#EF4444] dark:text-white dark:hover:bg-[#DC2626]
|
|
|
|
**Button 사이즈:** sm(h-8 px-3 text-sm), md(h-10 px-4 text-sm), lg(h-12 px-6 text-base)
|
|
|
|
**Badge shape:**
|
|
- pill (기본): rounded-full — 상태 표시, 카테고리 태그에 사용
|
|
- filled (버튼 스타일): rounded-md — 강조 라벨, 카운트 뱃지에 사용
|
|
|
|
**Badge 변형 (pill):** default, primary, secondary, accent, success, warning, danger, info
|
|
- 연한 배경(subtle) + 색상 텍스트
|
|
|
|
**Badge 변형 (filled):** Chart Palette 1:1 맵핑, 연한 배경(subtle) + 색상 텍스트, shape rounded-md
|
|
- default (neutral)
|
|
- blue = Chart 1 (#507FB9 / dark #6D94C5)
|
|
- gold = Chart 2 (#B59854 / dark #C4B48C)
|
|
- rose = Chart 3 (#B5607D / dark #D4839B)
|
|
- teal = Chart 4 (#3D998A / dark #5BB5A6)
|
|
- lavender = Chart 5 (#8B6DB5 / dark #B79FD4)
|
|
- coral = Chart 6 (#C07850 / dark #D4956B)
|
|
- 라이트: rgba(색상, 0.12~0.14) 배경 + 진한 텍스트 / 다크: rgba(색상, 0.14) 배경 + 밝은 텍스트
|
|
- ⚠️ success, warning, danger, info는 Pill 전용 — Filled에 사용 금지
|
|
- ⚠️ primary, secondary, accent, navy는 Filled에 사용 금지 (Chart 맵핑 색상만 사용)
|
|
**Card:** bg-[--color-bg-surface] border border-[--color-border] rounded-lg shadow-sm
|
|
**Input:** border-[--color-border] focus:ring-2 focus:ring-[--color-primary]/30 focus:border-[--color-primary]
|
|
**Modal:** bg-[--color-bg-surface] rounded-xl shadow-2xl, overlay bg-black/50
|
|
**Toast:** success(green), error(red), warning(amber), info(blue) — 시멘틱 컬러 사용
|
|
|
|
### 1-5. docs/design/icons.md
|
|
|
|
아이콘 시스템:
|
|
- Lucide React 사용
|
|
- 사이즈: xs(14px), sm(16px), md(20px), lg(24px), xl(32px)
|
|
- 색상: 시멘틱 토큰 사용 (text-[--color-text-secondary] 기본)
|
|
- 인터랙티브 아이콘: hover 상태 시 text-[--color-primary]
|
|
|
|
### 1-6. docs/design/motion.md
|
|
|
|
모션 시스템:
|
|
- Duration: fast(100ms), normal(200ms), slow(300ms), slower(500ms)
|
|
- Easing: ease-out(진입), ease-in(퇴장), ease-in-out(이동)
|
|
- 패턴: fade-in, slide-up, scale, collapse
|
|
- prefers-reduced-motion: reduce 시 애니메이션 비활성화
|
|
|
|
### 1-7. docs/design/code-conventions.md
|
|
|
|
코드 컨벤션:
|
|
- 파일명: PascalCase(컴포넌트), camelCase(유틸/훅), kebab-case(CSS)
|
|
- Tailwind 클래스 순서: layout → sizing → spacing → border → bg → text → effect → transition
|
|
- cn() 유틸리티 사용 (clsx + twMerge)
|
|
- import 순서: react → 외부 → 내부(@/) → 타입 → 스타일
|
|
- forwardRef 패턴: DOM 래핑 컴포넌트에 적용
|
|
|
|
### 1-8. docs/design/do-dont.md
|
|
|
|
Do/Don't 가이드:
|
|
- DO: CSS 변수 토큰 사용 (bg-[--color-primary])
|
|
- DON'T: 하드코딩 HEX (#6D94C5, #507FB9, #5C6570, #9198A1, #D5D2CC, #1E2329 등)
|
|
- DO: 시멘틱 컬러로 상태 표현
|
|
- DON'T: 임의 색상으로 상태 표현
|
|
- DO: spacing 스케일 사용 (p-4, gap-6)
|
|
- DON'T: 임의 px값 (p-[13px])
|
|
- DO: cn() 유틸리티로 조건부 클래스
|
|
- DON'T: 삼항연산자로 className 문자열 조합
|
|
- DO: 다크모드 버튼에 스케일 값 사용 (dark:bg-[--color-primary-600])
|
|
- DON'T: 다크모드 버튼에 시멘틱 토큰 그대로 사용 (dark:bg-[--color-primary] → 연한 파스텔톤으로 구분 안됨)
|
|
|
|
### 1-9. docs/design/prompts/new-component.md
|
|
|
|
새 컴포넌트 생성 프롬프트 템플릿:
|
|
```
|
|
[컴포넌트명] 컴포넌트를 만들어줘.
|
|
- docs/design/ 가이드 참조
|
|
- Props interface 정의
|
|
- 변형(variant), 사이즈(size) 지원
|
|
- 다크모드 대응 (CSS 변수 토큰)
|
|
- forwardRef 적용 (DOM 래핑 시)
|
|
- cn() 유틸리티 사용
|
|
```
|
|
|
|
### 1-10. docs/design/prompts/review-checklist.md
|
|
|
|
디자인 리뷰 체크리스트 (9개 카테고리):
|
|
1. 컬러: CSS 변수 토큰 사용 여부, 하드코딩 HEX 없는지
|
|
2. 타이포그래피: 타입 스케일 준수
|
|
3. 스페이싱: 4px 스케일 준수
|
|
4. 반응형: 브레이크포인트 대응
|
|
5. 다크모드: .dark 클래스 + CSS 변수 동작
|
|
6. 접근성: color contrast 4.5:1 이상
|
|
7. 컴포넌트: variant/size 시스템 준수
|
|
8. 모션: duration/easing 스케일 준수
|
|
9. 코드: cn(), forwardRef, import 순서
|
|
|
|
### 1-11. docs/design/prompts/refactor-style.md
|
|
|
|
스타일 리팩토링 프롬프트 템플릿:
|
|
```
|
|
[파일/컴포넌트] 스타일을 디자인 시스템으로 리팩토링해줘.
|
|
- 하드코딩 색상 → CSS 변수 토큰
|
|
- Tailwind 기본 색상(bg-gray-*, text-blue-*) → 커스텀 토큰
|
|
- spacing 임의값 → 스케일 값
|
|
- docs/design/ 가이드 기준으로 검증
|
|
```
|
|
|
|
## 2. frontend/src/index.css 수정
|
|
|
|
현재 내용 유지하면서, `@import 'tailwindcss';` 뒤에 `@theme` 블록과 다크모드 블록을 추가해줘:
|
|
|
|
```css
|
|
@import 'tailwindcss';
|
|
|
|
@custom-variant dark (&:where(.dark, .dark *));
|
|
|
|
@theme {
|
|
/* === Brand: Primary (Slate Blue) === */
|
|
--color-primary-50: #F5F7F9;
|
|
--color-primary-100: #E5EBF2;
|
|
--color-primary-200: #D2DAE5;
|
|
--color-primary-300: #B7C5D7;
|
|
--color-primary-400: #8AA5C7;
|
|
--color-primary-500: #6D94C5;
|
|
--color-primary-600: #507FB9;
|
|
--color-primary-700: #3B669C;
|
|
--color-primary-800: #2D507B;
|
|
--color-primary-900: #1B2C41;
|
|
--color-primary-950: #0E1A2B;
|
|
|
|
/* === Brand: Secondary (Powder Blue) === */
|
|
--color-secondary-50: #F5F7F9;
|
|
--color-secondary-100: #E6EDF5;
|
|
--color-secondary-200: #D1DAE5;
|
|
--color-secondary-300: #B7C8D7;
|
|
--color-secondary-400: #89AAC8;
|
|
--color-secondary-500: #CBDCEB;
|
|
--color-secondary-600: #6B9AC8;
|
|
--color-secondary-700: #4E88BB;
|
|
--color-secondary-800: #396E9D;
|
|
--color-secondary-900: #1B2F41;
|
|
--color-secondary-950: #0E1A2B;
|
|
|
|
/* === Brand: Accent (Warm Sand) === */
|
|
--color-accent-50: #F9F8F6;
|
|
--color-accent-100: #F2EDE4;
|
|
--color-accent-200: #E4E0D7;
|
|
--color-accent-300: #D5CDB9;
|
|
--color-accent-400: #C4B48C;
|
|
--color-accent-500: #E8DFCA;
|
|
--color-accent-600: #B59854;
|
|
--color-accent-700: #9A7E3E;
|
|
--color-accent-800: #786230;
|
|
--color-accent-900: #3F351D;
|
|
--color-accent-950: #2B2312;
|
|
|
|
/* === Semantic === */
|
|
--color-success: #059669;
|
|
--color-warning: #D97706;
|
|
--color-danger: #DC2626;
|
|
--color-info: #0284C7;
|
|
|
|
/* === Neutral (Light defaults) === */
|
|
--color-bg-base: #F5EFE6;
|
|
--color-bg-surface: #FFFFFF;
|
|
--color-bg-elevated: #FFFFFF;
|
|
--color-border: #D5D2CC;
|
|
--color-border-strong: #9198A1;
|
|
--color-text-primary: #1E2329;
|
|
--color-text-secondary: #5C6570;
|
|
--color-text-tertiary: #9198A1;
|
|
|
|
/* === Design Tokens (Light defaults) === */
|
|
--color-primary: #507FB9;
|
|
--color-primary-hover: #3B669C;
|
|
--color-primary-active: #2D507B;
|
|
--color-primary-subtle: #F5F7F9;
|
|
--color-primary-text: #2D507B;
|
|
--color-secondary: #CBDCEB;
|
|
--color-secondary-hover: #89AAC8;
|
|
--color-secondary-active: #4E88BB;
|
|
--color-secondary-subtle: #F5F7F9;
|
|
--color-secondary-text: #396E9D;
|
|
--color-accent: #E8DFCA;
|
|
--color-accent-hover: #C4B48C;
|
|
--color-accent-active: #B59854;
|
|
--color-accent-subtle: #F9F8F6;
|
|
--color-accent-text: #786230;
|
|
|
|
/* === Chart Palette === */
|
|
--color-chart-1: #507FB9;
|
|
--color-chart-2: #B59854;
|
|
--color-chart-3: #B5607D;
|
|
--color-chart-4: #3D998A;
|
|
--color-chart-5: #8B6DB5;
|
|
--color-chart-6: #C07850;
|
|
|
|
/* === Typography === */
|
|
--font-sans: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, system-ui, Roboto, 'Helvetica Neue', 'Segoe UI', 'Apple SD Gothic Neo', 'Noto Sans KR', 'Malgun Gothic', 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', sans-serif;
|
|
--font-mono: 'JetBrains Mono', 'Fira Code', Consolas, Monaco, 'Courier New', monospace;
|
|
}
|
|
|
|
/* === Dark Mode === */
|
|
@media (prefers-color-scheme: dark) {
|
|
:root:not(.light) {
|
|
--color-success: #34D399;
|
|
--color-warning: #FBBF24;
|
|
--color-danger: #FCA5A5;
|
|
--color-info: #38BDF8;
|
|
|
|
--color-bg-base: #131416;
|
|
--color-bg-surface: #1E2023;
|
|
--color-bg-elevated: #282A2E;
|
|
--color-border: #3A3C41;
|
|
--color-border-strong: #5C6570;
|
|
--color-text-primary: #F4F5F5;
|
|
--color-text-secondary: #9198A1;
|
|
--color-text-tertiary: #5C6570;
|
|
|
|
--color-primary: #B7C5D7;
|
|
--color-primary-hover: #D2DAE5;
|
|
--color-primary-active: #8AA5C7;
|
|
--color-primary-subtle: #1B2C41;
|
|
--color-primary-text: #D2DAE5;
|
|
--color-secondary: #B7C8D7;
|
|
--color-secondary-hover: #D1DAE5;
|
|
--color-secondary-active: #89AAC8;
|
|
--color-secondary-subtle: #1B2F41;
|
|
--color-secondary-text: #D1DAE5;
|
|
--color-accent: #D5CDB9;
|
|
--color-accent-hover: #E4E0D7;
|
|
--color-accent-active: #C4B48C;
|
|
--color-accent-subtle: #3F351D;
|
|
--color-accent-text: #E4E0D7;
|
|
|
|
--color-chart-1: #6D94C5;
|
|
--color-chart-2: #C4B48C;
|
|
--color-chart-3: #D4839B;
|
|
--color-chart-4: #5BB5A6;
|
|
--color-chart-5: #B79FD4;
|
|
--color-chart-6: #D4956B;
|
|
}
|
|
}
|
|
|
|
.dark {
|
|
--color-success: #34D399;
|
|
--color-warning: #FBBF24;
|
|
--color-danger: #FCA5A5;
|
|
--color-info: #38BDF8;
|
|
|
|
--color-bg-base: #131416;
|
|
--color-bg-surface: #1E2023;
|
|
--color-bg-elevated: #282A2E;
|
|
--color-border: #3A3C41;
|
|
--color-border-strong: #5C6570;
|
|
--color-text-primary: #F4F5F5;
|
|
--color-text-secondary: #9198A1;
|
|
--color-text-tertiary: #5C6570;
|
|
|
|
--color-primary: #B7C5D7;
|
|
--color-primary-hover: #D2DAE5;
|
|
--color-primary-active: #8AA5C7;
|
|
--color-primary-subtle: #1B2C41;
|
|
--color-primary-text: #D2DAE5;
|
|
--color-secondary: #B7C8D7;
|
|
--color-secondary-hover: #D1DAE5;
|
|
--color-secondary-active: #89AAC8;
|
|
--color-secondary-subtle: #1B2F41;
|
|
--color-secondary-text: #D1DAE5;
|
|
--color-accent: #D5CDB9;
|
|
--color-accent-hover: #E4E0D7;
|
|
--color-accent-active: #C4B48C;
|
|
--color-accent-subtle: #3F351D;
|
|
--color-accent-text: #E4E0D7;
|
|
|
|
--color-chart-1: #6D94C5;
|
|
--color-chart-2: #C4B48C;
|
|
--color-chart-3: #6B9AC8;
|
|
--color-chart-4: #B59854;
|
|
--color-chart-5: #8AA5C7;
|
|
--color-chart-6: #D5CDB9;
|
|
}
|
|
|
|
/* Dark mode date input calendar icon */
|
|
.dark input[type="date"]::-webkit-calendar-picker-indicator {
|
|
filter: invert(1);
|
|
}
|
|
```
|
|
|
|
## 3. cn() 유틸리티 생성
|
|
|
|
`frontend/src/utils/cn.ts` 파일을 생성:
|
|
```ts
|
|
import { type ClassValue, clsx } from 'clsx';
|
|
import { twMerge } from 'tailwind-merge';
|
|
|
|
export const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs));
|
|
```
|
|
|
|
clsx와 tailwind-merge 패키지가 없으면 설치해줘:
|
|
```bash
|
|
cd frontend && npm install clsx tailwind-merge
|
|
```
|
|
|
|
## 4. 차트 팔레트 상수 파일 생성
|
|
|
|
`frontend/src/constants/chart.ts`:
|
|
```ts
|
|
export const CHART_COLORS = [
|
|
'var(--color-chart-1)',
|
|
'var(--color-chart-2)',
|
|
'var(--color-chart-3)',
|
|
'var(--color-chart-4)',
|
|
'var(--color-chart-5)',
|
|
'var(--color-chart-6)',
|
|
] as const;
|
|
|
|
/** CSS computed value가 필요한 경우 (Recharts 등) */
|
|
export const CHART_COLORS_HEX = {
|
|
light: ['#507FB9', '#B59854', '#B5607D', '#3D998A', '#8B6DB5', '#C07850'],
|
|
dark: ['#6D94C5', '#C4B48C', '#D4839B', '#5BB5A6', '#B79FD4', '#D4956B'],
|
|
} as const;
|
|
```
|
|
|
|
## 5. CLAUDE.md에 디자인 가이드 참조 추가
|
|
|
|
CLAUDE.md의 `## 팀 규칙` 섹션 아래에 다음을 추가:
|
|
|
|
```markdown
|
|
## 디자인 시스템
|
|
|
|
- 컬러 시스템: `docs/design/colors.md`
|
|
- 타이포그래피: `docs/design/typography.md`
|
|
- 스페이싱/레이아웃: `docs/design/spacing.md`
|
|
- 컴포넌트 스펙: `docs/design/components.md`
|
|
- 아이콘: `docs/design/icons.md`
|
|
- 모션: `docs/design/motion.md`
|
|
- 코드 컨벤션: `docs/design/code-conventions.md`
|
|
- Do/Don't: `docs/design/do-dont.md`
|
|
|
|
### 프롬프트 템플릿
|
|
- 새 컴포넌트: `docs/design/prompts/new-component.md`
|
|
- 리뷰 체크리스트: `docs/design/prompts/review-checklist.md`
|
|
- 스타일 리팩토링: `docs/design/prompts/refactor-style.md`
|
|
|
|
### 핵심 규칙
|
|
- 색상은 반드시 CSS 변수 토큰 사용 (하드코딩 HEX 금지)
|
|
- 브랜드 컬러: Primary #6D94C5(Slate Blue), Secondary #CBDCEB(Powder Blue), Accent #E8DFCA(Warm Sand), BG #F5EFE6(Warm Cream)
|
|
- 다크모드: `.dark` 클래스 + CSS 변수 자동 전환
|
|
- 차트: CHART_COLORS_HEX 상수 사용 (Cool+Warm 교차 배치)
|
|
- Tailwind 기본 색상(gray-*, blue-* 등) 대신 커스텀 토큰 사용
|
|
```
|
|
|
|
## 6. 빌드 검증
|
|
|
|
모든 파일 생성 후:
|
|
1. `cd frontend && npm run build` 로 프론트엔드 빌드 성공 확인
|
|
2. 에러 없으면 커밋:
|
|
- 1차 커밋: `docs(design): 디자인 시스템 가이드 문서 추가`
|
|
- 2차 커밋: `feat(frontend): 디자인 토큰 및 테마 시스템 적용`
|
|
|
|
## 주의사항
|
|
|
|
- 기존 컴포넌트의 하드코딩 색상(bg-gray-900, text-blue-500 등)은 이번 작업에서는 변경하지 않는다 (별도 리팩토링 예정)
|
|
- ThemeContext.tsx는 이미 존재하므로 수정하지 않는다
|
|
- `@theme` 블록은 반드시 `@import 'tailwindcss';` 뒤, `@custom-variant` 뒤에 위치해야 한다
|
|
- npm 레지스트리는 frontend/.npmrc에 설정된 Nexus 프록시를 사용한다
|
|
```
|
|
|
|
---
|
|
|
|
**사용법:** 위의 ` ``` ` 블록 안의 전체 내용을 복사하여 Claude Code에 프롬프트로 입력하세요.
|