# ThemeProvider · ThemeFade

화면 모드(시스템·라이트·다크)와 글자 크기 설정을 앱 전체에 적용하는 도구다. 모드가 바뀌는 순간 새 배경색 덮개로 화면을 가렸다가 걷어서 깜빡임을 줄인다.

- 분류: 면과 목록
- 가져오기: `import { ThemeProvider, ThemeFade } from '@/ui/theme'`
- 코드 위치: `apps/mobile/src/ui/theme.tsx:117` (Mordy 저장소 60df633)
- 웹 페이지: https://developers.moring.co/tds/components/theme

## 미리보기

실제 컴포넌트를 그린 화면은 https://developers.moring.co/tds/components/theme 에서 볼 수 있다. 서비스 색 선택기로 Mordy, Morit 색을 바꿔 볼 수 있다.

## 언제 쓰는가

### 쓴다
- `ThemeProvider`로 앱 맨 바깥을 감싼다. "시스템 설정" 모드일 때 기기의 다크 모드를 따라간다.
- `ThemeFade`를 앱 루트에 한 번 둔다. 모드가 바뀔 때만 보인다.
- 컴포넌트는 `useTheme()`을 호출해 모드가 바뀌면 다시 그려지게 한다. 안 쓰는 화면(탭 뒤에 있는 화면)은 다시 돌아올 때 한꺼번에 갱신된다.

### 쓰지 않는다
- 모드를 컴포넌트 안에서 직접 판단해 색을 고르지 않는다. 토큰(`color.*`)이 모드를 이미 따른다.
- `useAppearance`로 저장하는 값(모드, 글자 크기, 자동 다음, 채점 방식) 말고 새 설정을 여기에 섞지 않는다.

## 종류

| 이름 | 설명 |
| --- | --- |
| 화면 모드 | `"system"`(시스템 설정, 기본), `"light"`(라이트), `"dark"`(다크). |
| 글자 크기 | 0.92(작게), 1(기본), 1.12(크게), 1.24(아주 크게). |

## 크기

크기가 없다.

## 상태

| 상태 | 모습과 동작 |
| --- | --- |
| 모드 바뀜 | 1) 새 배경색 덮개가 90ms 동안 나타난다. 2) 한 프레임 뒤 토큰이 바뀌고 모든 화면이 다시 그려진다. 3) 60ms 기다렸다가 300ms 동안 덮개가 사라진다. |
| 처음 열림 | 저장된 설정을 읽어 애니메이션 없이 바로 적용한다(스플래시 화면이 사라지기 전). |

## 사용 방법

### 앱 루트

```tsx
import { ThemeFade, ThemeProvider } from '@/ui/theme';

<ThemeProvider>
  <Slot />
  <ThemeFade />
</ThemeProvider>
```

### 설정 바꾸기

```tsx
import { useAppearance } from '@/ui/theme';

const { mode, setMode, fontScale, setFontScale } = useAppearance();

setMode('dark');
setFontScale(1.12);
```

### 컴포넌트에서

```tsx
import { useTheme } from '@/ui/theme';

const { isDark, fontScale } = useTheme();
```

### 속성(props)

#### ThemeProvider

| 이름 | 타입 | 기본값 | 필수 | 설명 |
| --- | --- | --- | --- | --- |
| `children` | `ReactNode` | — | 필수 | 앱 전체. |

#### ThemeFade

속성이 없다.

`ThemeFade`는 속성이 없다. 설정은 `useAppearance()`(저장소), 읽기는 `useTheme()`로 한다.

## 치수와 토큰

| 항목 | 값 |
| --- | --- |
| 저장 | 기기의 로컬 저장소 `ui.appearance` |
| 덮개 | 나타남 90ms, 걷힘 300ms(60ms 지연) |
| 글자 크기 | `FONT_STEPS` 4단계. 글자 페이지의 표를 본다. |

## 접근성

- 기기의 글자 크기와 다크 모드 설정을 따른다.
- 앱 설정의 글자 크기 단계에는 "작게, 기본, 크게, 아주 크게"라는 이름이 있다.

## 잘한 예와 잘못한 예

- 잘한 예: 모드에 따른 색은 토큰으로만 쓴다.
- 잘못한 예: 컴포넌트 안에서 `isDark`로 HEX를 고르지 않는다.

## 함께 보는 컴포넌트

- [AppText](https://developers.moring.co/tds/components/app-text.md): 앱의 모든 글자를 그리는 컴포넌트다. 글자 스타일 11종 중 하나를 `variant`로 고르면 크기, 줄 높이, 굵기, 자간이 정해진다.
- [PillTabs](https://developers.moring.co/tds/components/pill-tabs.md): 알약 모양의 탭 모음이다. 하나를 고르면 그 칸이 짙은 색(네이비, 다크 모드는 주색)으로 채워진다.
- [SettingsGroup](https://developers.moring.co/tds/components/settings-list.md): 설정 화면의 목록이다. 작은 구역 이름, 행이 든 흰 패널, 아래 안내 글로 이루어진다.
