# UI Design System — Corporate Navy

> 어떤 스택에서든 동일한 톤을 이식하기 위한 단일 소스.
>
> **한 줄 정의**: 딥 네이비(`#002c5f`) 프라이머리와 정밀한 뉴트럴 그레이 스케일 위에, **역할(role) × 강도(intensity) 2축의 시맨틱 토큰**으로 구축된 **엔터프라이즈 코퍼레이트** 시스템. 모든 색은 `primary / secondary / surface / outline` 4개 역할과 `lowest → ultimate` 강도 단계의 조합으로만 존재하며, 컴포넌트는 원시 색상값을 절대 참조하지 않는다.

---

## 목차

1. [디자인 원칙](#1-디자인-원칙)
2. [색상 토큰](#2-색상-토큰)
3. [타이포그래피](#3-타이포그래피)
4. [그림자 & 엘리베이션](#4-그림자--엘리베이션)
5. [버튼 (시그니처 컴포넌트)](#5-버튼-시그니처-컴포넌트)
6. [컴포넌트 카탈로그](#6-컴포넌트-카탈로그)
7. [인터랙션](#7-인터랙션)
8. [다크 모드](#8-다크-모드)
9. [접근성](#9-접근성)
10. [안티패턴](#10-안티패턴)
11. [프레임워크 어댑터](#11-프레임워크-어댑터)
12. [이식 가이드](#12-이식-가이드)

---

## 1. 디자인 원칙

| 원칙 | 정의 |
|---|---|
| **Role × Intensity 토큰** | 색은 `역할_강도` 조합(`primary_low`, `surface_high` 등)으로만 명명. 시각적 이름(`blue-500`) 금지. |
| **On-pair 강제** | 배경 역할마다 대응하는 `on_*` 토큰이 반드시 존재. 배경과 전경을 항상 쌍으로 사용해 대비 실패를 구조적으로 차단. |
| **Container 분리** | 면(배경) 위에 얹히는 면은 `*_container` 토큰을 사용. 표면 계층이 깊어져도 토큰 체계가 유지된다. |
| **Navy는 절제** | 프라이머리 네이비는 핵심 액션·브랜드 포인트에만. 본문 UI의 90%는 뉴트럴 그레이 스케일로 구성. |
| **필 버튼은 뉴트럴** | 채움(filled) 버튼 배경은 네이비가 아닌 뉴트럴 최고 강도(`#252527`). 네이비 채움은 최상위 CTA 하나로 제한. |
| **작은 라운드** | `border-radius`는 기본 4px, 버튼류 2px. 큰 라운드(8px+)는 모달·팝오버 표면에만. |
| **이중 그림자 엘리베이션** | 그림자는 항상 2겹(윤곽 + 방향광)으로 조합된 `dp` 단계 시스템 사용. 임의 그림자 금지. |
| **절제된 모션** | 상태 전환은 `background-color, border, color`에 한해 `0.2s`. 레이아웃 속성 애니메이션 금지. |

---

## 2. 색상 토큰

모든 색은 **CSS 커스텀 프로퍼티**가 원천이다. 역할(primary/secondary/surface/outline) × 강도(lowest → ultimate) 매트릭스가 시스템의 뼈대다.

### 2-1. Primary — 딥 네이비

```css
:root {
  --primary:                 #002c5f;  /* 브랜드 네이비 — 핵심 액션 */
  --primary_lowest:          #f7f8fa;
  --primary_low:             #e0e5ed;
  --primary_mid:             #cbd3e1;
  --primary_high:            #96a2c0;
  --primary_highest:         #314372;
  --primary_ultimate:        #263866;

  --on_primary:              #ffffff;  /* primary 배경 위 전경 */
  --on_primary_low:          #314372;
  --on_primary_high:         #96a2c0;

  --primary_container:       #f7f8fa;  /* 네이비 계열 옅은 면 */
  --on_primary_container:    #002c5f;
}
```

### 2-2. Secondary — 미드 블루

```css
:root {
  --secondary:               #2d67a8;  /* 보조 액션·정보성 강조 */
  --secondary_lowest:        #cbdbee;
  --secondary_low:           #96bde8;
  --secondary_mid:           #4279b8;
  --secondary_high:          #1a4e8a;
  --secondary_highest:       #164275;
  --secondary_ultimate:      #11345c;

  --on_secondary:            #ffffff;
  --secondary_container:     #cbdbee;
  --on_secondary_container:  #001a39;
}
```

### 2-3. Surface & Outline — 뉴트럴 스케일

```css
:root {
  --surface:                 #ffffff;  /* 페이지 배경 */
  --surface_lowest:          #fafafb;
  --surface_low:             #f5f5f5;  /* 섹션 분리 배경 */
  --surface_mid:             #eaeaeb;
  --surface_high:            #ceced0;
  --surface_highest:         #929296;
  --surface_ultimate:        #121416;

  --on_surface:              #121416;  /* 기본 텍스트 */
  --on_surface_mid:          #929296;  /* 플레이스홀더·비활성 */
  --on_surface_high:         #535356;  /* 보조 텍스트 */
  --on_surface_highest:      #3a3a3c;

  --surface_container:          #ffffff;  /* 카드·시트 표면 */
  --surface_container_ultimate: #252527;  /* 필 버튼·강조 면 */
  --on_surface_container:       #121416;

  --outline:                 #121416;  /* 강한 테두리 */
  --outline_lowest:          #efeff0;
  --outline_low:             #eaeaeb;  /* 기본 구분선 */
  --outline_mid:             #ceced0;  /* 입력 필드 테두리 */
  --outline_high:            #929296;
  --outline_highest:         #69696e;
}
```

### 2-4. Point & Variant — 의미 색상

```css
:root {
  --point_yellow:            #b55e00;  /* 주의 */
  --point_red:               #ed0c1b;  /* 오류·삭제 */
  --point_blue:              #1874dd;  /* 정보·링크 */

  --badge_container:         #f0f6fc;  /* 뱃지 배경 */
  --badge_on_container:      #2d67a8;  /* 뱃지 텍스트 */
  --variant_tooltip:         #3a3a3c;  /* 툴팁·스낵바 배경 */
  --variant_shadow:          #222222;  /* 그림자 기저색 (알파와 조합) */
}
```

### 2-5. 사용 규칙

| 역할 | 토큰 |
|---|---|
| 기본 텍스트 | `var(--on_surface)` |
| 보조 텍스트 | `var(--on_surface_high)` |
| 플레이스홀더·비활성 | `var(--on_surface_mid)` |
| 페이지 배경 | `var(--surface)` |
| 섹션·입력 배경 | `var(--surface_low)` |
| 카드 표면 | `var(--surface_container)` |
| 기본 구분선 | `var(--outline_low)` 1px |
| 입력 필드 테두리 | `var(--outline_mid)` 1px |
| 핵심 CTA | `var(--primary)` + `var(--on_primary)` |
| 보조 강조·뱃지 | `var(--secondary)` 계열 |

> **핵심 규칙**: 컴포넌트는 `#002c5f` 같은 원시 값을 절대 쓰지 않는다. 배경 토큰을 바꾸면 반드시 대응 `on_*` 토큰으로 전경도 함께 바꾼다.

---

## 3. 타이포그래피

### 3-1. 폰트

```css
:root {
  --font-sans: 'Noto Sans KR', 'Malgun Gothic', '맑은고딕',
               'Apple SD Gothic Neo', Dotum, sans-serif;
}

body {
  font-family: var(--font-sans);
  color: var(--on_surface);
  background: var(--surface);
}

/* 한국어 문서: 어절 단위 줄바꿈 */
html[lang="ko"] body {
  word-break: keep-all;
  overflow-wrap: break-word;
}
```

```html
<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700&display=swap"
/>
```

- 단일 산세리프 패밀리로 통일. weight는 400 / 500 / 700 세 단계만 사용.
- `word-break: break-word`는 비표준이므로 금지 — `overflow-wrap: break-word`를 사용한다.

### 3-2. 타입 스케일 — Headline / Title / Body / Label

역할 기반 4계층 스케일. `letter-spacing`은 전 단계 `0`.

| 역할 | 토큰 | `font-size` | `font-weight` | `line-height` |
|---|---|---|---|---|
| Headline | `headline_xlarge` | 36px | 400 | 54px |
| Headline | `headline_large` | 28px | 500 | 42px |
| Headline | `headline_medium` | 28px | 400 | 42px |
| Headline | `headline_small` | 24px | 500 | 36px |
| Headline | `headline_xsmall` | 20px | 500 | 30px |
| Title | `title_xlarge` | 18px | 500 | 26px |
| Title | `title_large` | 16px | 500 | 24px |
| Title | `title_medium` | 15px | 500 | 22px |
| Title | `title_small` | 14px | 500 | 22px |
| Body | `body_xlarge` | 18px | 400 | 26px |
| Body | `body_large` | 16px | 400 | 24px |
| Body | `body_medium` | 15px | 400 | 22px |
| Body | `body_small` | 14px | 400 | 22px |
| Label | `label_large` | 12px | 500 | 18px |
| Label | `label_medium` | 12px | 400 | 18px |
| Label | `label_small` | 11px | 500 | 16px |

```css
.headline_large { font-size: 28px; font-weight: 500; line-height: 42px; }
.title_large    { font-size: 16px; font-weight: 500; line-height: 24px; }
.body_medium    { font-size: 15px; font-weight: 400; line-height: 22px; }
.label_medium   { font-size: 12px; font-weight: 400; line-height: 18px; }
```

- Typo 클래스에는 크기·굵기·행간 외의 스타일을 추가하지 않는다. 색·여백은 컴포넌트 책임.
- Headline과 Body가 같은 크기로 겹치는 구간(28px 등)은 **weight 차이**로 위계를 만든다.

---

## 4. 그림자 & 엘리베이션

그림자는 **윤곽(ambient) + 방향광(key)** 2겹 조합의 `dp` 단계로만 사용한다. 기저색 `#222222`.

| 단계 | 용도 | CSS |
|---|---|---|
| `shadow_2dp` | 낮은 표면, 미세한 깊이감 | `0 0 2px rgba(34,34,34,.1), 0 2px 2px rgba(34,34,34,.05)` |
| `shadow_4dp` | 카드 | `0 0 2px rgba(34,34,34,.1), 0 4px 2px rgba(34,34,34,.05)` |
| `shadow_8dp` | 팝오버·드롭다운 | `0 0 2px rgba(34,34,34,.1), 0 8px 6px rgba(34,34,34,.05)` |
| `shadow_12dp` | 스낵바·피드백 | `0 0 2px rgba(34,34,34,.1), 0 12px 20px rgba(34,34,34,.05)` |
| `shadow_24dp` | 모달 | `0 0 2px rgba(34,34,34,.1), 0 24px 22px rgba(34,34,34,.05)` |

```css
:root {
  --shadow_2dp:  0 0 2px rgba(34,34,34,.1), 0 2px 2px rgba(34,34,34,.05);
  --shadow_4dp:  0 0 2px rgba(34,34,34,.1), 0 4px 2px rgba(34,34,34,.05);
  --shadow_8dp:  0 0 2px rgba(34,34,34,.1), 0 8px 6px rgba(34,34,34,.05);
  --shadow_12dp: 0 0 2px rgba(34,34,34,.1), 0 12px 20px rgba(34,34,34,.05);
  --shadow_24dp: 0 0 2px rgba(34,34,34,.1), 0 24px 22px rgba(34,34,34,.05);
}
```

- 임의의 `box-shadow` 값 작성 금지 — 반드시 5단계 중 선택.
- 다크 모드에서는 알파를 30%로 올리고 blur를 키운다 (§8).

---

## 5. 버튼 (시그니처 컴포넌트)

**Outlined가 기본형**이고 Filled는 강조형이라는 점이 이 시스템의 특징. 라운드는 2px로 절제한다.

### 5-1. 변형(Variants)

| 변형 | 클래스 | 스타일 |
|---|---|---|
| Outlined (기본) | `.btn.btn_outline` | `surface_container` 배경 + `outline_mid` 1px 테두리 |
| Outlined Secondary | `.btn.btn_outline_secondary` | 옅은 테두리, 보조 배치용 |
| Filled | `.btn.btn_fill` | `surface_container_ultimate`(#252527) 배경 + 흰 텍스트 |
| Text | `.btn.btn_text` | 배경·테두리 없음, Typo 클래스로 크기 결정 |
| Filter | `.btn.btn_filter` | 아이콘 결합 필터 트리거 |

```css
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  border-radius: 4px;
  transition-property: background-color, border, color;
  transition-duration: 0.2s;
  word-break: break-all;
  cursor: pointer;
}

.btn_outline {
  background: var(--surface_container);
  border: 1px solid var(--outline_mid);
  border-radius: 2px;
  color: var(--on_surface);
}
.btn_outline:hover { background: var(--surface_low); }

.btn_fill {
  background: var(--surface_container_ultimate);
  border-radius: 2px;
  color: var(--on_primary);
}
.btn_fill:hover { background: var(--on_surface_highest); }

/* 최상위 CTA 한 곳에만 네이비 채움 허용 */
.btn_fill--primary { background: var(--primary); }

.btn_disabled,
.btn:disabled {
  color: var(--on_surface_mid);
  pointer-events: none;
}
```

### 5-2. 크기

| 크기 | 클래스 | 비고 |
|---|---|---|
| xxSmall | `.btn_xxsmall` | `min-width: 48px`, 필터·태그형 |
| xSmall | `.btn_xsmall` | 인라인 액션 |
| Small | `.btn_small` | 기본 인라인 |
| Medium | `.btn_medium` | 폼 제출 |
| xLarge | `.btn_xlarge` | `font-weight: 700`, 페이지 CTA |

### 5-3. 상태

모든 버튼은 `Enabled / Hovered / Pressed / Focused / Disabled / Loading` 6개 상태를 갖는다.

```css
/* Loading: 텍스트 대신 스피너 */
.btn_loading { color: transparent; pointer-events: none; }
.btn_loading::after {
  content: '';
  position: absolute;
  width: 16px; height: 16px;
  border: 2px solid var(--outline_mid);
  border-top-color: var(--on_surface);
  border-radius: 50%;
  animation: btn-spin 0.8s linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
```

- 아이콘은 텍스트를 `<span class="btn_inner_text">`로 감싸고 그 앞뒤에 배치한다.

---

## 6. 컴포넌트 카탈로그

카테고리 구조 자체가 시스템의 정보 설계다. 새 컴포넌트는 반드시 아래 5개 분류 중 하나에 소속시킨다.

| 카테고리 | 컴포넌트 |
|---|---|
| **Inputs** | Button, Button Group, Checkbox, Radio, Select, Text Field, Date Picker |
| **Data Display** | Badge, Divider, List, Tooltip |
| **Feedback** | Backdrop, Dialog, Snackbar, Progress |
| **Surface** | Card, Empty State, Error State, Accordion |
| **Navigation** | Link, Menu, Pagination, Navigation, Stepper, Tabs, Footer, Scroll |

### 대표 패턴

```css
/* Card — 4dp 표면 */
.card {
  background: var(--surface_container);
  border: 1px solid var(--outline_low);
  border-radius: 4px;
  box-shadow: var(--shadow_4dp);
  padding: 20px;
}

/* Badge — 옅은 블루 면 + 시맨틱 텍스트 */
.badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 2px;
  background: var(--badge_container);
  color: var(--badge_on_container);
  font-size: 12px;
  font-weight: 500;
  line-height: 18px;
}

/* Tooltip / Snackbar — 다크 뉴트럴 면 */
.tooltip, .snackbar {
  background: var(--variant_tooltip);
  color: #ffffff;
  border-radius: 4px;
  padding: 8px 12px;
  font-size: 12px;
  line-height: 18px;
}
.snackbar { box-shadow: var(--shadow_12dp); }

/* Text Field */
.text_field {
  background: var(--surface);
  border: 1px solid var(--outline_mid);
  border-radius: 2px;
  padding: 10px 12px;
  font-size: 15px;
  line-height: 22px;
  color: var(--on_surface);
}
.text_field::placeholder { color: var(--on_surface_mid); }
.text_field:focus {
  outline: none;
  border-color: var(--primary);
}
.text_field[aria-invalid="true"] { border-color: var(--point_red); }
```

---

## 7. 인터랙션

```css
/* 허용: 색상 계열만 0.2s 전환 */
.interactive {
  transition-property: background-color, border, color;
  transition-duration: 0.2s;
}
```

- `transform`, `width`, `height` 등 레이아웃 속성 애니메이션 금지. 모달·스낵바 등장은 `opacity` 0.2s까지만 허용.
- 링크 기본색은 `var(--point_blue)`, 호버 시 `var(--secondary_high)`.
- 포커스 링: `outline: 2px solid var(--secondary); outline-offset: 2px` — 모든 인터랙티브 요소 공통.

---

## 8. 다크 모드

`.dark` 클래스로 오버라이드한다. 역할 구조는 그대로, 강도 축만 반전한다.

```css
.dark {
  color-scheme: dark;

  --primary:                 #96a2c0;  /* 네이비는 어두운 배경에서 밝은 단계로 */
  --on_primary:              #002c5f;
  --primary_container:       #263866;
  --on_primary_container:    #e0e5ed;

  --secondary:               #96bde8;
  --on_secondary:            #001a39;

  --surface:                 #121416;
  --surface_lowest:          #1a1a1d;
  --surface_low:             #252527;
  --surface_mid:             #3a3a3c;
  --surface_high:            #535356;
  --surface_ultimate:        #ffffff;

  --on_surface:              #eaeaeb;
  --on_surface_mid:          #929296;
  --on_surface_high:         #ceced0;

  --surface_container:          #1e1e21;
  --surface_container_ultimate: #eaeaeb;
  --on_surface_container:       #eaeaeb;

  --outline_low:             #2c2c2f;
  --outline_mid:             #3a3a3c;
  --outline_high:            #69696e;

  --point_yellow:            #e0a44c;
  --point_red:               #ff6b6b;
  --point_blue:              #6aaef5;

  --badge_container:         #11345c;
  --badge_on_container:      #96bde8;
  --variant_tooltip:         #535356;

  /* 다크 그림자: 알파 30%, blur 확대 */
  --shadow_2dp:  0 0 5px rgba(34,34,34,.3), 0 2px 5px rgba(34,34,34,.3);
  --shadow_4dp:  0 0 5px rgba(34,34,34,.3), 0 4px 5px rgba(34,34,34,.3);
  --shadow_8dp:  0 0 5px rgba(34,34,34,.3), 0 8px 20px rgba(34,34,34,.3);
  --shadow_12dp: 0 0 5px rgba(34,34,34,.3), 0 12px 30px rgba(34,34,34,.3);
  --shadow_24dp: 0 0 5px rgba(34,34,34,.3), 0 24px 40px rgba(34,34,34,.3);
}
```

- **on-pair 원칙 유지**: 배경 토큰을 반전했으면 대응 `on_*` 토큰도 반드시 함께 반전한다.
- 다크에서 그림자는 옅어지는 대신 **진하고 넓게** — 표면 자체가 어두워 대비가 약해지기 때문.

---

## 9. 접근성

- 기본 텍스트 `#121416` / 흰 배경 대비 18.1:1, 보조 텍스트 `#535356` 7.4:1 — AA 이상.
- `--on_surface_mid`(#929296)는 플레이스홀더·비활성 전용. 정보 전달 텍스트에 사용 금지 (대비 2.8:1).
- 모든 배경/전경 조합은 정의된 on-pair만 사용 — 임의 조합이 대비 실패의 주원인.
- 비활성 상태는 색상만이 아니라 `disabled` 속성 + `pointer-events: none`을 함께 적용.
- 포커스 링(§7)은 어떤 경우에도 제거하지 않는다.
- 한국어 본문은 `word-break: keep-all`로 어절 단위 줄바꿈을 보장한다.

---

## 10. 안티패턴

| 금지 | 이유 |
|---|---|
| 원시 색상값 하드코딩 (`#002c5f` 등) | 토큰 변수만 참조 — 테마 전환·브랜드 교체가 깨진다 |
| 배경만 바꾸고 `on_*` 미변경 | on-pair 원칙 위반 — 대비 실패 |
| 시각적 색 이름 도입 (`blue-500`) | 역할 기반 명명 체계 붕괴 |
| 임의 `box-shadow` 값 | 5단계 dp 시스템만 사용 |
| 네이비 채움 버튼 남용 | 필 버튼은 뉴트럴이 기본, 네이비는 최상위 CTA 1곳 |
| `border-radius` 8px 초과 (모달 제외) | 절제된 라운드가 코퍼레이트 톤의 핵심 |
| `word-break: break-word` | 비표준 — `overflow-wrap: break-word` 사용 |
| Typo 클래스에 색·여백 추가 | 타이포 토큰은 크기·굵기·행간만 담당 |
| `transform`·레이아웃 속성 애니메이션 | 색상 전환 0.2s만 허용 |
| 카테고리 외 컴포넌트 추가 | Inputs/Data Display/Feedback/Surface/Navigation 중 소속 필수 |

---

## 11. 프레임워크 어댑터

### 11-1. 순수 HTML/CSS

§2의 `:root { ... }` 블록과 §8의 `.dark { ... }` 블록을 전역 CSS에 복사하면 끝.

### 11-2. Tailwind CSS v4

```css
@import "tailwindcss";

@theme {
  --color-primary:            #002c5f;
  --color-on-primary:         #ffffff;
  --color-secondary:          #2d67a8;
  --color-surface:            #ffffff;
  --color-surface-low:        #f5f5f5;
  --color-on-surface:         #121416;
  --color-on-surface-high:    #535356;
  --color-outline-low:        #eaeaeb;
  --color-outline-mid:        #ceced0;
  --color-point-red:          #ed0c1b;
  --color-point-blue:         #1874dd;
}

@custom-variant dark (&:where(.dark, .dark *));
```

### 11-3. Tailwind CSS v3

```js
// tailwind.config.js
module.exports = {
  darkMode: 'class',
  theme: {
    extend: {
      colors: {
        primary:          'var(--primary)',
        'on-primary':     'var(--on_primary)',
        secondary:        'var(--secondary)',
        surface:          'var(--surface)',
        'surface-low':    'var(--surface_low)',
        'on-surface':     'var(--on_surface)',
        'on-surface-high':'var(--on_surface_high)',
        'outline-low':    'var(--outline_low)',
        'outline-mid':    'var(--outline_mid)',
      },
      boxShadow: {
        '2dp':  'var(--shadow_2dp)',
        '4dp':  'var(--shadow_4dp)',
        '8dp':  'var(--shadow_8dp)',
        '12dp': 'var(--shadow_12dp)',
        '24dp': 'var(--shadow_24dp)',
      },
    },
  },
};
```

### 11-4. React / Vue / Svelte

CSS 변수가 원천이므로 프레임워크별 특수 처리는 다크 모드 토글뿐이다. `document.documentElement.classList.toggle('dark', isDark)` 한 줄로 전 컴포넌트가 전환된다. 컴포넌트 스타일(styled-components, CSS Modules, `<style scoped>` 등)에서는 항상 `var(--토큰)`만 참조한다.

---

## 12. 이식 가이드

### Step 1 — 토큰 복사

§2 `:root` + §8 `.dark` 블록을 전역 CSS에 붙인다.

### Step 2 — 폰트 연결

Noto Sans KR CDN 링크를 `<head>`에 추가하고 `--font-sans`를 설정한다 (§3-1).

### Step 3 — 시그니처 3종 적용

| 패턴 | 핵심 CSS |
|---|---|
| **Outlined 버튼** | `background: var(--surface_container); border: 1px solid var(--outline_mid); border-radius: 2px` |
| **dp 그림자 카드** | `box-shadow: var(--shadow_4dp); border-radius: 4px` |
| **on-pair 텍스트** | 배경 토큰과 짝이 되는 `on_*` 토큰만 전경색으로 사용 |

### Step 4 — 타입 스케일 클래스 생성

§3-2 표의 16개 클래스를 그대로 생성한다. 크기·굵기·행간 외 속성 추가 금지.

### Step 5 — 컴포넌트 분류 준수

새 컴포넌트는 §6의 5개 카테고리 중 하나에 소속시키고, 상태 6종(Enabled/Hovered/Pressed/Focused/Disabled/Loading)을 모두 정의한다.

### 신규 컴포넌트 결정 트리

```
새 컴포넌트가 필요하다
  → 기존 5개 카테고리에 들어가는가?
    yes → 해당 카테고리 규칙(표면 dp, 라운드, on-pair)을 상속
    no  → 정말 새 카테고리인가? (대부분 아님 — 기존 컴포넌트 조합 재검토)
  → 색이 필요한가?
    → 역할(primary/secondary/surface/outline)로 표현 가능한가?
      yes → 기존 토큰 사용
      no  → 의미 색상(point_*)인가? → 맞으면 point 토큰, 아니면 디자인 재고
```
