wing-ops/docs/DESIGN-SYSTEM.md

25 KiB

WING-OPS 디자인 시스템

개요

WING-OPS UI 디자인 시스템의 비주얼 레퍼런스 카탈로그. 시맨틱 토큰 기반 다크/라이트 테마 전환을 지원한다.


버전 히스토리

v1.1 — 시맨틱 토큰 & 테마 시스템 (2026-03-28~)

브랜치: feature/predict-develop, feature/design-system-font

v1.0의 축약형 토큰 시스템을 시맨틱 네이밍으로 전면 전환하고, 다크/라이트 테마 전환 기능을 도입한 구조적 리팩토링.

변경된 점

항목 v1.0 v1.1
토큰 네이밍 축약형 (--bg0, --t1, --cyan) 시맨틱 (--bg-base, --fg-default, --color-accent)
폰트 Outfit + Noto Sans KR + JetBrains Mono (3종) PretendardGOV 단일 폰트 (4웨이트)
테마 다크 모드 전용 (하드코딩) 다크/라이트 전환 지원 (data-theme 속성)
프리미티브 팔레트 7그룹 11단계 (Navy/Cyan/Blue/Red/Green/Orange/Yellow, 00~100) 6그룹 10단계 (Gray/Blue/Green/Yellow/Red/Purple, 100~1000)
텍스트 대비 --t2: #b0b8cc, --t3: #8690a6 --fg-sub: #c0c8dc, --fg-disabled: #9ba3b8 (대비 향상)
버튼 스타일 .prd-btn.pri 그라데이션 (cyan→blue) 아웃라인/고스트 스타일
Tailwind 컬러 키 하드코딩 hex (bg.0, text.1, primary.cyan) CSS 변수 참조 (bg.base, fg.DEFAULT, color.accent)
폰트 유틸리티 하드코딩 (font-family: 'JetBrains Mono') CSS 변수 경유 (font-family: var(--font-mono))

토큰 마이그레이션 매핑

v1.0 v1.1 설명
--bg0 --bg-base 페이지 배경
--bg1 --bg-surface 사이드바, 패널
--bg2 --bg-elevated 테이블 헤더, 상위 요소
--bg3 --bg-card 카드 배경
--bgH --bg-surface-hover 호버 상태
--bd --stroke-default 기본 구분선
--bdL --stroke-light 연한 구분선
--t1 --fg-default 기본 텍스트
--t2 --fg-sub 보조 텍스트
--t3 --fg-disabled 비활성 텍스트
--cyan --color-accent 주요 강조
--blue --color-info 정보, 링크
--red --color-danger 위험, 삭제
--orange --color-warning 주의
--yellow --color-caution 경고
--green --color-success 성공, 정상
--purple --color-tertiary 3차 강조
--boom --color-boom 오일붐 전용
--fK --font-korean 한국어 폰트 스택
--fM --font-mono 모노 폰트 스택
--rS --radius-sm 소형 border radius
--rM --radius-md 중형 border radius

추가된 기능

  • 다크/라이트 테마 전환: themeStore.ts (Zustand) + data-theme DOM 속성 + FOUC 방지 인라인 스크립트
  • 시맨틱 오버레이 토큰: --hover-overlay, --dropdown-bg (테마별 불투명도 차별화)
  • Navy 액센트 토큰: --color-navy, --color-navy-hover, --color-accent-muted
  • 정적 컬러 토큰: --static-black, --static-white (테마 무관 고정값)
  • 타이포그래피 스케일 (17개 토큰): Display 3종, Heading 3종, Title 6종, Body 2종, Label 2종, Caption 1종
  • Letter-spacing 토큰 5종: --letter-spacing-display (0.06em) ~ --letter-spacing-label (0.04em)
  • Font weight 토큰 4종: thin(300) / regular(400) / medium(500) / bold(700)
  • Line height 토큰 4종: tight(1.3) / snug(1.4) / normal(1.5) / relaxed(1.6)
  • Tailwind tracking 유틸리티: tracking-display, tracking-heading, tracking-body, tracking-navigation, tracking-label
  • 라이트 테마 컴포넌트 오버라이드: CCTV 팝업, 날짜피커, 타임라인, 콤보박스, 좌표 표시 등
  • 폰트 렌더링 최적화: -webkit-font-smoothing: antialiased, text-rendering: optimizeLegibility

업데이트된 부분

  • 92개+ 컴포넌트 파일의 토큰 마이그레이션 (축약형 → 시맨틱)
  • Stitch MCP 프로젝트 참조 제거 (독립 토큰 시스템으로 전환)
  • DESIGN-SYSTEM.md 문서 전면 재작성

v1.0 — 초기 디자인 시스템 (2026-03-24~25)

브랜치: feature/stitch-mcp | 도구: Google Stitch MCP

WING-OPS 전용 디자인 시스템의 첫 구축. CSS 변수 기반 토큰 시스템, .wing-* 컴포넌트 클래스, 라이브 카탈로그 뷰어를 도입.

컬러 시스템

  • 프리미티브 팔레트: 7개 그룹 (Navy/Cyan/Blue/Red/Green/Orange/Yellow), 각 11단계 스케일 (00~100)
  • 시맨틱 컬러: 축약형 CSS 변수 — Background(--bg0~--bgH), Text(--t1~--t3), Border(--bd, --bdL)
  • 액센트 컬러: --cyan(#06b6d4), --blue(#3b82f6), --red, --green, --orange, --yellow, --purple
  • 특수 컬러: --boom(#f59e0b) — 오일붐 전용 Amber

타이포그래피

  • 3종 폰트 패밀리: Outfit (영문 본문), Noto Sans KR (한국어), JetBrains Mono (좌표/수치)
  • 10개 .wing-* 타이포 클래스: .wing-title(15px) ~ .wing-badge(9px)

컴포넌트 클래스

카테고리 클래스
레이아웃 셸 .wing-panel, .wing-panel-scroll, .wing-header-bar, .wing-sidebar
컨테이너 .wing-card, .wing-card-sm, .wing-section
버튼 .wing-btn, .wing-btn-primary (cyan→blue 그라데이션), -secondary, -outline, -pdf, -danger
입력 .wing-input (cyan 포커스 링)
테이블 .wing-table, .wing-th, .wing-td, .wing-tr-hover
.wing-tab-bar, .wing-tab (cyan 틴트 + 보더 활성)
모달 .wing-overlay (블러 백드롭), .wing-modal, .wing-modal-header
유틸리티 .wing-divider, .wing-kv-row, .wing-kv-label, .wing-kv-value
뱃지/아이콘 .wing-badge, .wing-icon-badge, .wing-icon-badge-sm

특수 컴포넌트

영역 클래스 접두사 설명
예측 패널 .prd-* 폼 입력, 버튼, 맵 버튼
콤보박스 .combo-* 커스텀 드롭다운 (검색 + 리스트)
타임라인 .tlb, .tlt, .tlr, .tlth 지도 하단 재생 컨트롤
레이어 트리 .lyr-* 3단계 접이식 레이어 (색상 스와치 + 투명도)
오일붐 .boom-* 오일붐 드로잉 인디케이터
역추적 .bt-* 역추적 리플레이 마커 + 속도 버튼
HNS .hns-scn-card HNS 시나리오 선택 카드
모델 칩 .prd-mc 모델 선택 칩 (활성 인디케이터)

레이아웃

  • 데스크톱 전용 (≥ 1280px), Tablet/Mobile 미지원
  • 7단계 z-index 레이어: Base(0) ~ Tooltip(60)
  • Spacing: Tailwind 기본 스케일 사용 (gap-1~gap-8)

Border Radius

  • rounded-sm: 6px (커스텀 오버라이드)
  • rounded-md: 10px (커스텀 오버라이드)
  • 나머지 Tailwind 기본값 유지

애니메이션

fadeIn, fadeSlideDown, pulse-dot, pulse-border, comboIn, lyrPopIn, bt-collision-pulse

디자인 카탈로그

/design 라우트에 라이브 카탈로그 뷰어 배포:

  • Foundations 탭: Color Palette, Typography, Radius, Layout, Overview
  • Components 탭: Button, TextField, Overview (Button Catalog, Card, Icon Badge 섹션)
  • 다크/라이트 모드 토글 내장
  • 테마 엔진: designTheme.ts — 타입 안전한 DesignTheme 인터페이스

SVG 아이콘 에셋

23개 커스텀 아이콘 (wing- 접두사): wing-anchor, wing-cargo, wing-chart-bar, wing-color-palette, wing-documentation, wing-elevation, wing-foundations, wing-layout-grid, wing-notification, wing-pdf-file, wing-settings, wing-typography, wing-wave-graph

Stitch MCP 연동

Google Stitch 프로젝트 7개 스크린 참조:

  • Design Tokens, Component Catalog (Buttons/Badges), Form Components
  • Table & List Patterns, Modal Catalog, Operational Shell (Layout)
  • Container & Navigation

테마 (Theme)

테마 전환 메커니즘

다크(기본)/라이트 2벌 테마를 CSS 변수 오버라이드 방식으로 지원한다.

[플래시 방지]  index.html 인라인 스크립트
       ↓       localStorage → <html data-theme="dark|light">
[상태 관리]    themeStore.ts (Zustand)
       ↓       toggleTheme() / setTheme()
[CSS 적용]     base.css :root (dark) / [data-theme="light"] (light)
       ↓       CSS 변수 오버라이드
[UI 반영]      모든 컴포넌트가 var(--*) 참조 → 즉시 전환

1단계 — FOUC 방지 (index.html)

<script>
  document.documentElement.setAttribute(
    'data-theme',
    localStorage.getItem('wing-theme') || 'dark'
  );
</script>

HTML 파싱 즉시 data-theme 속성을 설정하여 테마 깜빡임을 방지한다.

2단계 — Zustand 스토어 (themeStore.ts)

type ThemeMode = 'dark' | 'light';

interface ThemeState {
  theme: ThemeMode;
  toggleTheme: () => void;   // dark ↔ light 토글
  setTheme: (mode: ThemeMode) => void;  // 직접 지정
}
  • 초기값: localStorage.getItem('wing-theme') || 'dark'
  • toggleTheme(): localStorage 갱신 → DOM 속성 변경 → Zustand 상태 갱신

3단계 — CSS 변수 오버라이드 (base.css)

  • :root — 다크 테마 (기본값)
  • [data-theme="light"] — 라이트 테마 오버라이드

시맨틱 토큰(--bg-*, --fg-*, --stroke-*)만 테마별 오버라이드하고, 프리미티브 토큰(--gray-*, --blue-* 등)과 액센트 컬러(--color-*)는 테마 간 동일 값을 유지한다.

UI 진입점

TopBar 퀵메뉴에서 toggleTheme() 호출로 전환.


Foundations

색상 (Color Palette)

토큰 아키텍처

Primitive Tokens (정적)        Semantic Tokens (테마 반응형)
──────────────────────        ────────────────────────────
--gray-100 ~ --gray-1000     --bg-base, --bg-surface, ...
--blue-100 ~ --blue-1000     --fg-default, --fg-sub, ...
--red-100  ~ --red-1000      --stroke-default, --stroke-light
--green-100 ~ --green-1000   --hover-overlay, --dropdown-bg
--yellow-100 ~ --yellow-1000
--purple-100 ~ --purple-1000
                              Accent Tokens (테마 불변)
                              ─────────────────────────
                              --color-accent, --color-info, ...

Semantic Colors — Background

CSS 변수 Tailwind 클래스 Dark Light 용도
--bg-base bg-bg-base #0a0e1a #f8fafc 페이지 배경
--bg-surface bg-bg-surface #0f1524 #ffffff 사이드바, 패널
--bg-elevated bg-bg-elevated #121929 #f1f5f9 테이블 헤더, 상위 요소
--bg-card bg-bg-card #1a2236 #ffffff 카드 배경
--bg-surface-hover bg-bg-surface-hover #1e2844 #e2e8f0 호버 상태

Semantic Colors — Foreground (Text)

CSS 변수 Tailwind 클래스 Dark Light 용도
--fg-default text-fg #edf0f7 #0f172a 기본 텍스트, 아이콘
--fg-sub text-fg-sub #c0c8dc #475569 보조 텍스트
--fg-disabled text-fg-disabled #9ba3b8 #94a3b8 비활성, 플레이스홀더

Semantic Colors — Border (Stroke)

CSS 변수 Tailwind 클래스 Dark Light 용도
--stroke-default border-stroke #1e2a42 #cbd5e1 기본 구분선
--stroke-light border-stroke-light #2a3a5c #e2e8f0 연한 구분선

Semantic Colors — Overlay

CSS 변수 Dark Light 용도
--hover-overlay rgba(255,255,255,0.06) rgba(0,0,0,0.04) 호버 오버레이
--dropdown-bg rgba(18,25,41,0.97) rgba(255,255,255,0.97) 드롭다운 배경

Accent Colors (테마 불변)

CSS 변수 Tailwind 클래스 Hex 용도
--color-accent text-color-accent #06b6d4 주요 강조 (Cyan)
--color-accent-muted bg-color-accent-muted #0e7490 / #0891b2(light) 차분한 강조 (버튼 배경 등)
--color-info text-color-info #3b82f6 정보, 링크 (Blue)
--color-tertiary text-color-tertiary #a855f7 3차 강조 (Purple)
--color-danger text-color-danger #ef4444 위험, 삭제 (Red)
--color-warning text-color-warning #f97316 주의 (Orange)
--color-caution text-color-caution #eab308 경고 (Yellow)
--color-success text-color-success #22c55e 성공, 정상 (Green)
--color-boom text-color-boom #f59e0b 오일붐 전용 (Amber)
--color-boom-hover #fbbf24 오일붐 호버
--color-navy bg-color-navy #1e40af / #1d4ed8(light) Navy 버튼 배경
--color-navy-hover bg-color-navy-hover #1d4ed8 / #2563eb(light) Navy 호버

Static Colors

CSS 변수 Hex 용도
--static-black #131415 테마 무관 고정 검정
--static-white #ffffff 테마 무관 고정 흰색

Primitive Colors

UI 전반에서 직접 참조하거나 시맨틱 토큰의 원천으로 사용하는 기본 팔레트. 100~1000 (10단계).

Gray

100 200 300 400 500 600 700 800 900 1000
#f1f5f9 #e2e8f0 #cbd5e1 #94a3b8 #64748b #475569 #334155 #1e293b #0f172a #020617

Blue

100 200 300 400 500 600 700 800 900 1000
#dbeafe #bfdbfe #93c5fd #60a5fa #3b82f6 #2563eb #1d4ed8 #1e40af #1e3a8a #172554

Green

100 200 300 400 500 600 700 800 900 1000
#dcfce7 #bbf7d0 #86efac #4ade80 #22c55e #16a34a #15803d #166534 #14532d #052e16

Yellow

100 200 300 400 500 600 700 800 900 1000
#fef9c3 #fef08a #fde047 #facc15 #eab308 #ca8a04 #a16207 #854d0e #713f12 #422006

Red

100 200 300 400 500 600 700 800 900 1000
#fee2e2 #fecaca #fca5a5 #f87171 #ef4444 #dc2626 #b91c1c #991b1b #7f1d1d #450a0a

Purple

100 200 300 400 500 600 700 800 900 1000
#f3e8ff #e9d5ff #d8b4fe #c084fc #a855f7 #9333ea #7e22ce #6b21a8 #581c87 #3b0764

타이포그래피 (Typography)

Font Family

CSS 변수 Tailwind 클래스 용도
--font-korean font-korean 기본 UI 텍스트, 한국어/영문 콘텐츠
--font-mono font-mono 좌표, 수치, 데이터 값
font-sans body 기본 (PretendardGOV)

모든 폰트 패밀리가 PretendardGOV 우선 스택으로 통일. @font-face: Regular(400), Medium(500), SemiBold(600), Bold(700) — /fonts/PretendardGOV-*.otf

Typography Categories

5가지 용도 카테고리로 타이포그래피를 구성합니다.

카테고리 토큰 설명
Display Display 1, Display 2, Display 3 배너, 마케팅 등 최대 크기 텍스트
Heading Heading 1, Heading 2, Heading 3 페이지/모듈 단위 제목, 계층 설정
Body Body 1, Body 2, Caption 본문/콘텐츠 텍스트
Navigation Title 1~6 사이트 내 이정표 역할 (패널 제목, 탭 버튼, 메뉴 항목 등)
Label Label 1, Label 2 컴포넌트 label, placeholder, 버튼 텍스트

Navigation 카테고리의 토큰은 CSS 변수명 --font-size-title-* / Tailwind text-title-*을 유지합니다.

Font Size Tokens

CSS 변수와 Tailwind 유틸리티가 1:1 매핑된 타이포그래피 스케일. text-* 클래스 사용 시 font-size, line-height, letter-spacing이 함께 적용됩니다.

Display — 배너, 마케팅, 랜딩 영역

CSS 변수 Tailwind px Weight Line-H Spacing
--font-size-display-1 text-display-1 60px 700 1.3 0.06em
--font-size-display-2 text-display-2 40px 700 1.3 0.06em
--font-size-display-3 text-display-3 36px 500 1.4 0.06em

Heading — 페이지/모듈 제목

CSS 변수 Tailwind px Weight Line-H Spacing
--font-size-heading-1 text-heading-1 32px 700 1.4 0.02em
--font-size-heading-2 text-heading-2 24px 700 1.4 0.02em
--font-size-heading-3 text-heading-3 22px 500 1.4 0.02em

Body — 본문/콘텐츠

CSS 변수 Tailwind px Weight Line-H Spacing
--font-size-body-1 text-body-1 14px 400 1.6 0em
--font-size-body-2 text-body-2 13px 400 1.6 0em
--font-size-caption text-caption 11px 400 1.5 0em

Navigation — 패널 제목, 탭 버튼, 메뉴 항목, 소형 네비게이션

CSS 변수 Tailwind px Weight Line-H Spacing
--font-size-title-1 text-title-1 18px 700 1.5 0.02em
--font-size-title-2 text-title-2 16px 500 1.5 0.02em
--font-size-title-3 text-title-3 14px 500 1.5 0.02em
--font-size-title-4 text-title-4 13px 500 1.5 0.02em
--font-size-title-5 text-title-5 12px 500 1.5 0.02em
--font-size-title-6 text-title-6 11px 500 1.5 0.02em

Label — 레이블, 플레이스홀더, 버튼

CSS 변수 Tailwind px Weight Line-H Spacing
--font-size-label-1 text-label-1 12px 500 1.5 0.04em
--font-size-label-2 text-label-2 11px 500 1.5 0.04em

Font Weight Tokens

CSS 변수 용도
--font-weight-thin 300 얇은 텍스트
--font-weight-regular 400 본문 기본
--font-weight-medium 500 중간 강조
--font-weight-bold 700 제목, 강조

Line Height Tokens

CSS 변수 용도
--line-height-tight 1.3 Display
--line-height-snug 1.4 Heading
--line-height-normal 1.5 Navigation, Label, Caption
--line-height-relaxed 1.6 Body

Letter Spacing Tokens

카테고리별 자간 토큰. text-* 클래스에 자동 포함되며, tracking-* 클래스로 개별 사용도 가능합니다.

CSS 변수 Tailwind 카테고리
--letter-spacing-display tracking-display 0.06em Display
--letter-spacing-heading tracking-heading 0.02em Heading
--letter-spacing-body tracking-body 0em Body
--letter-spacing-navigation tracking-navigation 0.02em Navigation
--letter-spacing-label tracking-label 0.04em Label

Typography Tokens (.wing-* 클래스)

클래스 Size Font Weight 용도 샘플
.wing-title 15px font-korean Bold (700) 패널 제목 확산 예측 시뮬레이션
.wing-section-header 13px font-korean Bold (700) 섹션 헤더 기본 정보 입력
.wing-label 11px font-korean Semibold (600) 필드 레이블 유출량 (kL)
.wing-btn 11px font-korean Semibold (600) 버튼 텍스트 시뮬레이션 실행
.wing-value 11px font-mono Semibold (600) 수치 / 데이터 값 35.1284° N, 129.0598° E
.wing-input 11px font-korean Normal (400) 입력 필드 서해 대산항 인근 해역
.wing-section-desc 10px font-korean Normal (400) 섹션 설명 예측 결과는 기상 조건에 따라...
.wing-subtitle 10px font-korean Normal (400) 보조 설명 최근 업데이트: 2026-03-24 09:00 KST
.wing-meta 9px font-korean Normal (400) 메타 정보 v2.1 | 해양환경공단
.wing-badge 9px font-korean Bold (700) 뱃지 / 태그 진행중

Border Radius

Radius Tokens

Tailwind 클래스 비고
rounded-sm 6px Custom (Tailwind 기본값 오버라이드)
rounded 4px (0.25rem) Tailwind 기본
rounded-md 10px Custom (Tailwind 기본값 오버라이드)
rounded-lg 8px (0.5rem) Tailwind 기본
rounded-xl 12px (0.75rem) Tailwind 기본
rounded-2xl 16px (1rem) Tailwind 기본
rounded-full 9999px Tailwind 기본

컴포넌트 매핑

Radius 적용 컴포넌트
rounded-sm 6px .wing-btn, .wing-input, .wing-card-sm
rounded 4px .wing-badge
rounded-md 10px .wing-card, .wing-section, .wing-tab
rounded-lg 8px .wing-tab-bar
rounded-xl 12px .wing-modal

레이아웃 (Layout)

Breakpoints

Name Prefix Min Width 사용 비고
sm sm: 640px -
md md: 768px -
lg lg: 1024px -
xl xl: 1280px 사용 중 TopBar 탭 레이블/아이콘 토글
2xl 2xl: 1536px -

Desktop(≥ 1280px)만 지원. Tablet/Mobile 미지원.

Device Width Columns Gutter Margin
Desktop ≥ 1280px flex 기반 가변 gap-2 ~ gap-6 px-5 ~ px-8
Tablet 768px ~ 1279px - - -
Mobile < 768px - - -

Spacing Scale

Scale rem px 용도
0.5 0.125rem 2px 미세 간격
1 0.25rem 4px 최소 간격 (gap-1)
1.5 0.375rem 6px 컴팩트 간격 (gap-1.5)
2 0.5rem 8px 기본 간격 (gap-2, p-2)
2.5 0.625rem 10px 중간 간격
3 0.75rem 12px 표준 간격 (gap-3, p-3)
4 1rem 16px 넓은 간격 (p-4, gap-4)
5 1.25rem 20px 패널 패딩 (px-5, py-5)
6 1.5rem 24px 섹션 간격 (gap-6, p-6)
8 2rem 32px 큰 간격 (px-8, gap-8)
16 4rem 64px 최대 간격

Z-Index Layers

Layer z-index Color 설명
Tooltip 60 #a855f7 툴팁, 드롭다운 메뉴
Popup 50 #f97316 팝업, 지도 오버레이
Modal 40 #ef4444 모달 다이얼로그, 백드롭
TopBar 30 #3b82f6 상단 네비게이션 바
Sidebar 20 #06b6d4 사이드바, 패널
Content 10 #22c55e 메인 콘텐츠 영역
Base 0 #8690a6 기본 레이어, 배경

App Shell Classes

클래스 역할 Tailwind 스타일
.wing-panel 탭 콘텐츠 패널 flex flex-col h-full overflow-hidden
.wing-panel-scroll 패널 내 스크롤 영역 flex-1 overflow-y-auto
.wing-header-bar 패널 헤더 flex items-center justify-between shrink-0 px-5 border-b
.wing-sidebar 사이드바 flex flex-col border-r border-border

CSS 레이어 아키텍처

index.css
├── @import base.css       → @layer base     (CSS 변수, reset, body, @font-face)
├── @import components.css → @layer components (MapLibre, scrollbar, prd-*, combo-*)
├── @import wing.css       → @layer components (wing-* 디자인 시스템 클래스)
├── @tailwind base
├── @tailwind components
└── @tailwind utilities

Tailwind 시맨틱 토큰 매핑 요약

카테고리 CSS 변수 Tailwind 클래스 예시
Background --bg-base ~ --bg-surface-hover bg-bg-base, bg-bg-surface, ...
Foreground --fg-default, --fg-sub, --fg-disabled text-fg, text-fg-sub, text-fg-disabled
Border --stroke-default, --stroke-light border-stroke, border-stroke-light
Accent --color-accent ~ --color-success text-color-accent, bg-color-info, ...
Font Size --font-size-display-1 ~ --font-size-caption text-display-1, text-body-1, ...
Font Family --font-korean, --font-mono font-korean, font-mono, font-sans