wing-ops/docs/DESIGN-SYSTEM.md

17 KiB

WING-OPS 디자인 시스템

개요

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


테마 (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-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 오일붐 호버

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