# 06. 스타일링 가이드

> **대상**: 프론트엔드 개발자, 디자이너
> **버전**: 1.0.0
> **최종 수정**: 2026-03-09

---

## 1. 기술 스택

| 도구 | 역할 |
|------|------|
| **Tailwind CSS 4** | 유틸리티 클래스 기반 스타일링 |
| **shadcn/ui** | Radix UI 기반 컴포넌트 라이브러리 |
| **CSS Variables** | 테마 토큰 (다크모드 대비) |
| **lucide-react** | 아이콘 |

---

## 2. 기본 규칙

### 사용
```typescript
// ✅ Tailwind 클래스 사용
<div className="flex items-center gap-2 p-4 bg-muted rounded-lg">

// ✅ shadcn/ui 컴포넌트
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
```

### 금지
```typescript
// ❌ 인라인 스타일
<div style={{ display: 'flex', padding: '16px' }}>

// ❌ CSS 모듈 / styled-components
import styles from './Component.module.css';

// ❌ 전역 CSS (globals.css 외)
```

---

## 3. 레이아웃 패딩 규칙

```
AuthenticatedLayout (<main>) → 패딩 없음
  └── PageLayout → p-0 md:space-y-6 (패딩 담당)
       └── 콘텐츠 영역
```

**핵심**: page.tsx에서 추가 패딩 래퍼 금지 (이중 패딩 방지)

```typescript
// ✅ 올바름
<PageLayout>
  <PageHeader title="..." />
  <Card>...</Card>
</PageLayout>

// ❌ 이중 패딩
<div className="p-6">  {/* ← 금지 */}
  <PageLayout>
    ...
  </PageLayout>
</div>
```

---

## 4. 간격 시스템

| 용도 | 클래스 | 값 |
|------|--------|-----|
| 섹션 간 간격 | `space-y-6` | 24px |
| 카드 내부 간격 | `space-y-4` | 16px |
| 인라인 요소 간격 | `gap-2` | 8px |
| 폼 필드 간격 | `space-y-4` | 16px |
| 그리드 갭 | `gap-4` 또는 `gap-6` | 16px / 24px |

---

## 5. 반응형 패턴

```typescript
// 그리드: 모바일 1열 → 데스크톱 2~4열
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">

// 숨기기/보이기
<div className="hidden md:block">  {/* 데스크톱만 */}
<div className="block md:hidden">  {/* 모바일만 */}

// 폰트 크기 반응형
<h1 className="text-lg md:text-2xl font-bold">
```

### 브레이크포인트

| 접두사 | 최소 너비 | 대상 |
|--------|----------|------|
| (없음) | 0px | 모바일 |
| `sm:` | 640px | 소형 태블릿 |
| `md:` | 768px | 태블릿 |
| `lg:` | 1024px | 데스크톱 |
| `xl:` | 1280px | 넓은 화면 |

---

## 6. 색상 시스템

shadcn/ui CSS 변수 기반 — 다크모드 자동 대응:

| 용도 | 클래스 | 설명 |
|------|--------|------|
| 배경 | `bg-background` | 페이지 배경 |
| 카드 | `bg-card` | 카드 배경 |
| 강조 | `bg-muted` | 연한 배경 (테이블 호버 등) |
| 텍스트 | `text-foreground` | 기본 텍스트 |
| 보조 텍스트 | `text-muted-foreground` | 설명, 플레이스홀더 |
| 테두리 | `border` | 기본 테두리 |
| 위험 | `text-destructive` | 삭제, 에러 |

### 상태 색상

| 상태 | 텍스트 | 배경 |
|------|--------|------|
| 입금/증가 | `text-blue-600` | `bg-blue-50` |
| 출금/감소 | `text-red-600` | `bg-red-50` |
| 성공/완료 | `text-green-600` | `bg-green-50` |
| 경고/대기 | `text-orange-500` | `bg-orange-50` |
| 비활성 | `text-gray-400` | `bg-gray-50` |

---

## 7. 컴포넌트 스타일 규칙

### 버튼
```typescript
// 주요 액션
<Button size="sm">등록</Button>

// 보조 액션
<Button variant="outline" size="sm">취소</Button>

// 위험 액션 (삭제)
<Button variant="destructive" size="sm">삭제</Button>
```

### 테이블
```typescript
// 기본 셀 정렬
<TableCell className="text-center">  {/* 날짜, 상태, 번호 */}
<TableCell className="text-right">   {/* 금액 */}
<TableCell className="text-left">    {/* 텍스트 (기본) */}

// 합계 행
<TableRow className="bg-muted/50 font-medium">
```

### Badge
```typescript
<Badge variant="outline">기본</Badge>
<Badge variant="default">활성</Badge>
<Badge variant="destructive">에러</Badge>
```

---

## 8. 팝업/모달 규칙

| 용도 | 컴포넌트 | 비고 |
|------|---------|------|
| 확인/취소 | AlertDialog (Radix) | `alert()`, `confirm()` 금지 |
| 데이터 입력 | Dialog (Radix) | `prompt()` 금지 |
| 알림 | `toast` (sonner) | 성공/에러 피드백 |
| 검색+선택 | SearchableSelectionModal | 커스텀 Dialog 조합 금지 |

```typescript
// ✅ 토스트 사용
import { toast } from 'sonner';
toast.success('저장되었습니다.');
toast.error('저장에 실패했습니다.');

// ❌ alert 금지
alert('저장되었습니다.');
```

---

## 9. 아이콘

**lucide-react** 사용:

```typescript
import { FileText, Settings, Search, Plus, Trash2 } from 'lucide-react';

// 인라인 아이콘
<FileText className="h-4 w-4" />

// 버튼 내 아이콘
<Button size="sm">
  <Plus className="h-4 w-4 mr-1" />
  등록
</Button>
```

---

## 10. 금액 표시

```typescript
import { formatNumber } from '@/lib/utils/amount';

formatNumber(1234567)    // "1,234,567"
formatNumber(0)          // "0"
formatNumber(undefined)  // "0"
```

테이블에서:
```typescript
<TableCell className="text-right text-blue-600">
  {formatNumber(item.amount)}
</TableCell>
```
