# 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]`으로 오버라이드 (필수)

**차트 팔레트 (Cool+Warm 교차):**

Light:
1. #507FB9 (Primary 600)
2. #B59854 (Accent 600)
3. #4E88BB (Secondary 700)
4. #9A7E3E (Accent 700)
5. #3B669C (Primary 700)
6. #C4B48C (Accent 400)

Dark (채도 강화 — 400~500 스케일 사용):
1. #6D94C5 (Primary 500)
2. #C4B48C (Accent 400)
3. #6B9AC8 (Secondary 600)
4. #B59854 (Accent 600)
5. #8AA5C7 (Primary 400)
6. #D5CDB9 (Accent 300)

### 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 변형:** default, primary, secondary, accent, success, warning, danger
**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: #4E88BB;
  --color-chart-4: #9A7E3E;
  --color-chart-5: #3B669C;
  --color-chart-6: #C4B48C;

  /* === 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: #6B9AC8;
    --color-chart-4: #B59854;
    --color-chart-5: #8AA5C7;
    --color-chart-6: #D5CDB9;
  }
}

.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', '#4E88BB', '#9A7E3E', '#3B669C', '#C4B48C'],
  dark: ['#6D94C5', '#C4B48C', '#6B9AC8', '#B59854', '#8AA5C7', '#D5CDB9'],
} 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에 프롬프트로 입력하세요.
