Claude 보고서/모듈형 테마 시스템
현재는 라이트/다크 2종이 빌드 타임에 고정됩니다. **여러 테마(테마 패밀리)를 추가·전환**할 수 있는 모듈형 시스템을 만들기 위해 필요한 것을 정리합니다. 상위 문서: [[Claude 보고서]].
## 현재 구조 진단
정보: 현황
- 테마링은 `--wiki-*` CSS custom property 단일 계층으로 구성되고, 값은 `light-dark(라이트, 다크)` 함수로 분기.
- 브랜딩(이름/로고/레이아웃/사이드바/푸터)은 `scripts/branding.mjs` 가 **빌드 타임에 베이킹**.
- 컬러 팔레트는 D1 기반(`palettes`)이지만 **본문 색상 전용**이며 UI 크롬 토큰은 제어하지 않음.
- 라이트/다크 + `auto`(OS `prefers-color-scheme`) 3-state, `localStorage('themeMode')` + `<head>` 인라인으로 FOUC 방지.
주의: 모듈화의 핵심 제약
`light-dark()` 는 **정확히 2개 스킴(light/dark)만** 표현합니다. N개 테마를 지원하려면 테마별로 변수를 재정의하는 `[data-theme-name="..."]` 선택자 블록 또는 `@layer` 구조로 전환해야 합니다.
## 필요한 아키텍처
### 토큰 3계층 분리
현재는 시맨틱 토큰만 평면적으로 존재합니다. 다음 3계층으로 재구성:
| 계층 | 예시 | 설명 |
| --- | --- | --- |
| Primitive | `--c-blue-500`, `--c-zinc-900` | 원시 팔레트(테마가 정의) |
| Semantic | `--wiki-bg`, `--wiki-primary` | 의미 토큰(primitive 참조) |
| Component | `--wiki-callout-info-tint`, `--wiki-btn-bg` | 컴포넌트 토큰(현재 일부는 `render.ts` 에서 계산) |
> 콜아웃 틴트 불투명도, 버튼/배지 색 등 **현재 코드(render.ts)에서 계산되는 값을 토큰으로 승격**해야 테마가 완전히 외부에서 제어됩니다.
### 테마 매니페스트 포맷
하나의 테마 = 색상·폰트·radius·shadow·motion·spacing 토큰 집합 + (선택) Prism 토큰 맵 + 콜아웃 불투명도. JSON/CSS 스키마로 정의하고 각 테마는 자체 light/dark 쌍을 가질 수 있게 합니다.
```jsonc
// themes/ocean.json (예시)
{
"name": "ocean",
"light": { "--wiki-bg": "#f0f9ff", "--wiki-primary": "#0369a1", "...": "..." },
"dark": { "--wiki-bg": "#020617", "--wiki-primary": "#38bdf8", "...": "..." },
"prism": { "keyword": "#0369a1", "...": "..." },
"fonts": { "base": "'Inter', sans-serif" }
}
```
### 빌드 파이프라인
`scripts/branding.mjs` 와 같은 방식의 **테마 베이커**가 매니페스트를 읽어 `public/dist/themes/<name>.css` 를 생성하고, Vite multi-entry 에 등록. `BaseLayout.astro` 가 기본 테마 CSS 를 인라인하고 비활성 테마는 지연 로드.
### 런타임 선택 + FOUC
- `wrangler.toml` `THEME`(빌드 기본값) + 사용자 선택(`localStorage('themeName')`).
- `<html data-theme-name="ocean" data-theme="dark">` 2축 속성으로 분기.
- `<head>` FOUC 인라인 스크립트를 **테마명 + 모드 둘 다** 적용하도록 확장.
- `auto` 모드는 "현재 테마의 light/dark 쌍" 으로 매핑.
### 관리자 테마 에디터
팔레트 관리 UI 를 확장해 **시맨틱 토큰 편집 + 실시간 미리보기 + WCAG 대비 검증**(이미 `palettes.ts`/`admin/palettes.ts` 에 대비 계산 로직 보유 → 재사용) 을 제공.
## 구현 단계
1. 토큰 계층 리팩터링
`light-dark()` 의존을 줄이고 primitive/semantic/component 3계층으로 분리. render.ts 계산값을 토큰으로 승격.
2. 매니페스트 스키마 확정
테마 JSON 스키마와 검증기(`isSafeCssColor` 재사용) 정의.
3. 테마 베이커 + 빌드 통합
매니페스트 → CSS 생성, Vite/Astro 파이프라인 연결, 기본 테마 인라인·나머지 지연 로드.
4. 런타임 전환 + FOUC
`data-theme-name` 도입, head 인라인·`common.ts` 토글 확장, 사용자 설정 저장.
5. 관리자 테마 에디터
팔레트 UI 확장, WCAG 검증·미리보기.
팁: 하위 호환
라이트/다크를 **2개의 기본 내장 테마**로 유지하면 기존 동작이 깨지지 않으면서 N-테마로 확장됩니다. 구체적 테마 컨셉은 [[Claude 보고서/디자인 개선과 테마 아이디어]] 참조.