# Do & Don't

디자인 시스템 적용 시 자주 발생하는 실수와 올바른 방법.

---

## CSS 변수 토큰

### 색상

**DO** — CSS 변수 토큰 사용

```tsx
<div className="bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] border border-[var(--color-border)]" />
```

**DON'T** — HEX 하드코딩

```tsx
// 다크 모드 전환 불가, 토큰 변경 시 전부 수정 필요
<div className="bg-white text-gray-900 border border-gray-200" />
```

**DON'T** — Tailwind 기본 팔레트로 브랜드 컬러 표현

```tsx
// 브랜드 컬러(#6D94C5)와 blue-500(#3B82F6)은 다른 색상
<div className="bg-blue-500 text-blue-900" />
```

---

## 시멘틱 컬러

**DO** — 의미에 맞는 시멘틱 컬러 사용

```tsx
// 성공 상태
<Badge className="bg-[var(--color-success)]/10 text-[var(--color-success)]">완료</Badge>

// 오류 메시지
<p className="text-[var(--color-danger)] text-sm">{errorMessage}</p>

// 경고 알림
<div className="border-l-4 border-[var(--color-warning)] bg-[var(--color-warning)]/10 p-4" />
```

**DON'T** — 브랜드 컬러를 시멘틱 용도로 사용

```tsx
// Primary 컬러는 성공/오류를 표현하지 않음
<p className="text-[var(--color-primary)]">저장에 실패했습니다</p>
```

**DON'T** — 시멘틱 컬러를 장식 목적으로 사용

```tsx
// danger 컬러는 위험/오류 상황 전용
<Badge className="bg-[var(--color-danger)]">인기</Badge>
```

---

## Spacing 스케일

**DO** — 4px 단위 스케일 사용

```tsx
<div className="p-4 gap-2 mt-6" />   // 16px / 8px / 24px
<div className="px-3 py-1.5" />       // 12px / 6px (sm 버튼)
```

**DON'T** — 임의의 px 값

```tsx
<div className="p-[13px] gap-[7px] mt-[22px]" />
```

**DON'T** — 인라인 스타일로 여백 지정

```tsx
<div style={{ padding: '13px', marginTop: '22px' }} />
```

---

## cn() 유틸리티

**DO** — 조건부 클래스에 `cn()` 사용

```tsx
<button
  className={cn(
    'px-4 py-2 rounded-lg font-medium transition-colors',
    isActive ? 'bg-[var(--color-primary)] text-white' : 'text-[var(--color-text-secondary)]',
    disabled && 'opacity-50 cursor-not-allowed',
    className,
  )}
/>
```

**DON'T** — 템플릿 리터럴로 조건부 클래스 조합

```tsx
// Tailwind 클래스 충돌 가능, purge 미적용 위험
<button className={`px-4 py-2 ${isActive ? 'bg-blue-500' : ''} ${disabled ? 'opacity-50' : ''}`} />
```

**DON'T** — 동적 클래스 문자열 조합

```tsx
// Tailwind는 전체 클래스 문자열을 스캔 — 동적 조합 시 purge에서 제거될 수 있음
const color = 'primary';
<div className={`text-[var(--color-${color})]`} />  // 위험
```

**DO** — 객체 맵 사용

```tsx
const colorMap = {
  primary: 'text-[var(--color-primary)]',
  danger: 'text-[var(--color-danger)]',
} as const;

<div className={cn(colorMap[color])} />
```

---

## 컴포넌트 Props

**DO** — className prop 허용 + cn() 병합

```tsx
const Card = ({ className, children }: CardProps) => (
  <div className={cn('rounded-xl border border-[var(--color-border)] p-6', className)}>
    {children}
  </div>
);
```

**DON'T** — className prop 미제공 (재사용성 저하)

```tsx
const Card = ({ children }: { children: React.ReactNode }) => (
  <div className="rounded-xl border border-[var(--color-border)] p-6">
    {children}
  </div>
);
```

---

## 다크 모드

**DO** — CSS 변수 토큰 사용으로 자동 전환

```tsx
// --color-bg-surface는 Light: #FFF, Dark: #1E2023으로 자동 전환
<div className="bg-[var(--color-bg-surface)]" />
```

**DON'T** — `dark:` 클래스로 각각 지정 (토큰이 있는 색상에)

```tsx
// 중복 관리 부담, 토큰과 불일치 가능
<div className="bg-white dark:bg-gray-900" />
```

단, CSS 변수 토큰이 없는 케이스(투명도, 그라디언트 등)에는 `dark:` 사용 허용.

---

## 타이포그래피

**DO** — 타입 스케일 클래스 사용

```tsx
<h1 className="text-4xl font-bold leading-tight text-[var(--color-text-primary)]">페이지 제목</h1>
<p className="text-base leading-relaxed text-[var(--color-text-secondary)]">설명 텍스트</p>
```

**DON'T** — 임의 폰트 크기

```tsx
<h1 className="text-[22px] font-bold">페이지 제목</h1>
```

---

## 아이콘

**DO** — Lucide React + 색상 토큰

```tsx
import { ChevronRight } from 'lucide-react';

<ChevronRight className="size-5 text-[var(--color-text-secondary)]" aria-hidden="true" />
```

**DON'T** — 다른 라이브러리 혼용

```tsx
// Font Awesome, Material Icons 등 혼용 금지
import { FaChevronRight } from 'react-icons/fa';
```

**DON'T** — 아이콘에 color prop으로 HEX 지정

```tsx
<ChevronRight color="#6D94C5" />  // CSS 변수 토큰을 사용할 수 없음
```
