# UI Design System — KT Seamless Flow

> 어떤 스택에서든 동일한 톤을 이식하기 위한 단일 소스. KT UX 디자인 시스템 "Seamless Flow" 공개 문서의 톤을 웹 이식용으로 재해석한 문서다.
>
> **한 줄 정의**: 딥 차콜(`#191a1b`) 표면을 기본으로 하는 **다크 퍼스트** 시스템. 브랜드 레드(`#e0282f`)는 핵심 액션과 브랜드 순간에만 등장하고, 정보 전달은 밝은 그레이 텍스트 계층과 기능색(틸·퍼플·블루)이 맡는다. 화면 간 이동이 "끊김 없이 흐르는" 경험이 이름의 유래다.

---

## 목차

1. [디자인 원칙](#1-디자인-원칙)
2. [색상 토큰](#2-색상-토큰)
3. [타이포그래피](#3-타이포그래피)
4. [레이아웃 & 라운드](#4-레이아웃--라운드)
5. [핵심 컴포넌트](#5-핵심-컴포넌트)
6. [인터랙션](#6-인터랙션)
7. [라이트 모드](#7-라이트-모드)
8. [접근성](#8-접근성)
9. [안티패턴](#9-안티패턴)
10. [프레임워크 어댑터](#10-프레임워크-어댑터)
11. [이식 가이드](#11-이식-가이드)

---

## 1. 디자인 원칙

| 원칙 | 정의 |
|---|---|
| **Dark First** | 기본 테마가 다크. 라이트는 파생 테마다. 다크에서 먼저 설계하고 라이트로 번역한다. |
| **Seamless Flow** | 화면 전환·상태 변화가 끊기지 않고 이어진다. 급격한 색 반전·깜빡임 금지, 전환은 짧고 부드럽게. |
| **레드는 브랜드 순간에만** | `#e0282f`는 주 CTA·브랜드 식별·핵심 알림에만. 다크 배경에서 레드는 강렬하므로 면적을 최소화한다. |
| **밝기 계층 = 정보 계층** | 텍스트 위계는 밝기(`#e9eaee` → `#9a9ea4` → `#55585d`)로 표현. 다크에서 표면은 위로 갈수록 밝아진다. |
| **기능색 분리** | 성공/정보 계열은 틸(`#007f7f`)·블루, 프리미엄·AI 맥락은 퍼플(`#6941ff`). 레드와 역할을 섞지 않는다. |
| **중간 라운드** | 8px 기본. 강한 라운드·직각 모두 지양 — 절제된 소프트함 유지. |

---

## 2. 색상 토큰

### 2-1. 표면 & 텍스트 (다크 기본)

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

  --surface-0:   #191a1b;  /* 페이지 배경 */
  --surface-1:   #232527;  /* 카드·패널 */
  --surface-2:   #2c2f31;  /* 부상 표면(팝오버·시트) */
  --surface-3:   #35383b;  /* 최상위 표면(모달) */

  --text:        #e9eaee;  /* 기본 텍스트 */
  --text-sub:    #9a9ea4;  /* 보조 텍스트 */
  --text-hint:   #55585d;  /* 힌트·비활성 */

  --border:      #3a3d40;  /* 기본 구분선 */
  --border-weak: #2c2f31;  /* 약한 구분선 */
}
```

### 2-2. 브랜드 & 기능색

```css
:root {
  --brand:        #e0282f;  /* KT 레드 — 주 CTA·브랜드 */
  --brand-hover:  #ea474d;
  --brand-press:  #c22127;
  --brand-surface:#fce9e9;  /* 라이트 모드 알림 면 */

  --func-teal:    #007f7f;  /* 성공·안정 상태 */
  --func-teal-bg: #e1f5f5;
  --func-blue:    #1e90d4;  /* 정보 */
  --func-blue-bg: #d9f2ff;
  --func-purple:  #6941ff;  /* 프리미엄·AI 맥락 */
  --func-purple-bg:#efebff;
}
```

### 2-3. 사용 규칙

| 역할 | 토큰 |
|---|---|
| 본문·제목 | `var(--text)` |
| 보조 설명 | `var(--text-sub)` |
| 힌트·비활성 | `var(--text-hint)` |
| 페이지 배경 | `var(--surface-0)` |
| 카드 | `var(--surface-1)` |
| 팝오버·시트 | `var(--surface-2)` |
| 주 CTA | `var(--brand)` + 흰 텍스트 |
| 성공 상태 | `var(--func-teal)` |
| AI·프리미엄 강조 | `var(--func-purple)` |

> **핵심 규칙**: 다크에서 엘리베이션은 그림자가 아니라 **표면 밝기 단계(surface-0→3)** 로 표현한다. 그림자는 라이트 모드 전용.

---

## 3. 타이포그래피

### 3-1. 폰트

원 시스템은 KT 전용 서체를 사용하나, 공개 환경에서는 Noto Sans KR로 대체한다.

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

body {
  font-family: var(--font-sans);
  color: var(--text);
  background: var(--surface-0);
  word-break: keep-all;
}
```

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

### 3-2. 타입 스케일

| 역할 | `font-size` | `font-weight` | `line-height` |
|---|---|---|---|
| Display | 32px | 700 | 1.3 |
| Heading 1 | 24px | 700 | 1.35 |
| Heading 2 | 20px | 700 | 1.4 |
| Subtitle | 17px | 500 | 1.5 |
| Body | 15px | 400 | 1.6 |
| Body Small | 13px | 400 | 1.55 |
| Caption | 12px | 400 | 1.5 |

- 다크 배경에서는 같은 크기라도 얇은 웨이트가 더 가늘어 보인다 — **300 이하 웨이트 금지**.
- 본문 행간은 1.6으로 라이트 시스템보다 넉넉하게 (다크 가독성 보정).

---

## 4. 레이아웃 & 라운드

```css
:root {
  --radius:       0.5rem;   /* 8px — 버튼·입력·카드 */
  --radius-large: 1rem;     /* 16px — 시트·모달 */
  --spacing:      0.25rem;  /* 4px 배수 */
}

.container { max-width: 64rem; margin-inline: auto; padding-inline: 1.25rem; }
```

- 카드 사이 간격은 12px 이상 — 다크에서 표면끼리 붙으면 경계가 사라진다.
- 구분선보다 **표면 단차**(surface-0 위 surface-1)로 그룹을 표현.

---

## 5. 핵심 컴포넌트

### 5-1. 버튼

```css
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.75rem 1.5rem;
  border-radius: var(--radius);
  font-size: 0.9375rem;
  font-weight: 500;
  border: none;
  cursor: pointer;
  transition: background-color 0.2s ease;
}

/* Primary — 브랜드 레드 */
.btn--primary { background: var(--brand); color: #ffffff; }
.btn--primary:hover  { background: var(--brand-hover); }
.btn--primary:active { background: var(--brand-press); }

/* Secondary — 표면 단차 */
.btn--secondary {
  background: var(--surface-2);
  color: var(--text);
}
.btn--secondary:hover { background: var(--surface-3); }

/* Ghost — 보더만 */
.btn--ghost {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
}

.btn:disabled {
  background: var(--surface-1);
  color: var(--text-hint);
  cursor: default;
}
```

### 5-2. 카드

```css
.card {
  background: var(--surface-1);
  border-radius: var(--radius);
  padding: 1.25rem;
}
.card--interactive:hover { background: var(--surface-2); }
```

### 5-3. 상태 칩

```css
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem 0.625rem;
  border-radius: 62.4375rem;
  font-size: 0.75rem;
  font-weight: 500;
}
.chip--success { background: rgba(0, 127, 127, 0.18); color: #33b3b3; }
.chip--info    { background: rgba(30, 144, 212, 0.18); color: #5db6e8; }
.chip--premium { background: rgba(105, 65, 255, 0.18); color: #a58eff; }
.chip--alert   { background: rgba(224, 40, 47, 0.18);  color: #f0757a; }
```

### 5-4. 입력 필드

```css
.field {
  width: 100%;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.75rem 1rem;
  color: var(--text);
  font-size: 0.9375rem;
  transition: border-color 0.2s ease;
}
.field::placeholder { color: var(--text-hint); }
.field:focus { outline: none; border-color: var(--text-sub); }
.field[aria-invalid="true"] { border-color: var(--brand); }
```

---

## 6. 인터랙션

- 상태 전환은 `background-color`·`border-color`·`color`에 한해 `0.2s ease`.
- 화면 전환은 페이드+슬라이드 0.25s — "끊김 없는 흐름"의 핵심. 하드 컷 금지.
- 호버는 표면 한 단계 상승(surface-1→2), 프레스는 유지 또는 미세 축소(`scale(0.99)`).
- `prefers-reduced-motion` 설정 시 전환 시간을 0으로.

---

## 7. 라이트 모드

`.light` 클래스로 오버라이드한다. 다크가 기본이므로 라이트가 파생 테마다.

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

  --surface-0:   #ffffff;
  --surface-1:   #f8f8f8;
  --surface-2:   #f3f4f6;
  --surface-3:   #e9eaee;

  --text:        #191a1b;
  --text-sub:    #55585d;
  --text-hint:   #9a9ea4;

  --border:      #e0e2e5;
  --border-weak: #eceef0;

  /* 브랜드·기능색은 동일 유지 */
}

/* 라이트에서만 그림자로 엘리베이션 보강 */
.light .card { box-shadow: 0 1px 4px rgba(25, 26, 27, 0.08); }
```

- 표면 단차 방향이 반전된다: 라이트에서는 위로 갈수록 **어두워지는** 대신 그림자를 병용.
- 기능색 배경 칩은 라이트에서 `--func-*-bg` 파스텔 면 + 진한 텍스트 조합으로 전환.

---

## 8. 접근성

- `--text`(#e9eaee) / `--surface-0`(#191a1b) 대비 13.9:1 — AAA.
- `--text-sub`(#9a9ea4) 대비 6.0:1 — AA 통과. `--text-hint`(#55585d)는 비활성 전용 (대비 2.6:1).
- 브랜드 레드 위 흰 텍스트 대비 4.9:1 — 버튼 텍스트는 15px 이상 유지.
- 다크 배경에서 순수 검정(#000)·순수 흰색(#fff) 텍스트를 쓰지 않는다 — 헤일레이션(번짐) 방지.
- 포커스 링: `outline: 2px solid var(--text-sub); outline-offset: 2px`.

---

## 9. 안티패턴

| 금지 | 이유 |
|---|---|
| 레드를 넓은 면(배경·섹션)에 사용 | 브랜드 순간 전용 — 다크에서 과자극 |
| 오류와 브랜드 레드 혼용 | 오류는 레드 계열이되 아이콘+메시지 병기로 구분 |
| 다크에서 box-shadow 엘리베이션 | 표면 밝기 단계로 표현 |
| 순수 #000 배경 / #fff 텍스트 | 헤일레이션·눈부심 |
| 300 이하 폰트 웨이트 | 다크 가독성 붕괴 |
| 하드 컷 화면 전환 | Seamless Flow 원칙 위반 |
| 표면 단계 건너뛰기 (surface-0 위 surface-3) | 계층 인지 붕괴 — 인접 단계만 쌓는다 |
| 라이트 모드에서 먼저 설계 | 다크 퍼스트 — 라이트는 번역본 |

---

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

### 10-1. Tailwind CSS v4

```css
@import "tailwindcss";

@theme {
  --color-surface-0: #191a1b;
  --color-surface-1: #232527;
  --color-surface-2: #2c2f31;
  --color-text:      #e9eaee;
  --color-text-sub:  #9a9ea4;
  --color-border:    #3a3d40;
  --color-brand:     #e0282f;
  --color-teal:      #007f7f;
  --color-purple:    #6941ff;
  --radius:          0.5rem;
}

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

### 10-2. Tailwind CSS v3

```js
module.exports = {
  darkMode: 'class',   /* 여기서는 .light가 오버라이드 클래스 */
  theme: {
    extend: {
      colors: {
        'surface-0': 'var(--surface-0)',
        'surface-1': 'var(--surface-1)',
        'surface-2': 'var(--surface-2)',
        text:        'var(--text)',
        'text-sub':  'var(--text-sub)',
        border:      'var(--border)',
        brand:       'var(--brand)',
      },
      borderRadius: { DEFAULT: '0.5rem', large: '1rem' },
    },
  },
};
```

### 10-3. React / Vue / Svelte

CSS 변수가 원천. 테마 전환은 루트에 `.light` 클래스 토글 — 기본이 다크임에 유의.

---

## 11. 이식 가이드

### Step 1 — 다크 토큰 복사

§2의 표면/텍스트 + 브랜드/기능색 블록을 `:root`에, §7 라이트 블록을 `.light`에 붙인다.

### Step 2 — 폰트 연결

Noto Sans KR 링크 추가, `word-break: keep-all` 설정.

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

| 패턴 | 핵심 CSS |
|---|---|
| **표면 단차 카드** | `background: var(--surface-1)` — 그림자 없이 밝기 차이로 |
| **레드 CTA** | `background: #e0282f; color: #fff` — 화면당 1개 원칙 |
| **기능색 칩** | 반투명 배경(`rgba(색, 0.18)`) + 밝은 텍스트 |

### Step 4 — 흐름 검증

페이지 전환·모달 등장이 하드 컷 없이 이어지는지, `prefers-reduced-motion` 대응이 되는지 확인한다.

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

```
새 컴포넌트가 필요하다
  → 어느 표면 단계에 놓이는가? (surface-0~3 중 인접 단계 선택)
  → 색이 필요한가?
    → 브랜드 순간인가? → 레드 (화면당 1개)
    → 상태 표현인가? → 틸/블루/퍼플 기능색
    → 그 외 → 밝기 계층만 사용
```
