# 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에 프롬프트로 입력하세요.