# 機能設計書 11-テーマ管理（Theme）

## 概要

本ドキュメントは、Tailwind CSS v4のテーマ管理機能（Themeクラス）の設計について記述する。CSSカスタムプロパティベースのテーマシステムであり、テーマ値の追加・解決・名前空間管理・@keyframes管理を担当する。

### 本機能の処理概要

Theme クラスは、Tailwind CSS のデザインシステムにおけるテーマ値の中央管理を担う。CSSカスタムプロパティ（CSS変数）をキーとしてテーマ値を保持し、ユーティリティクラスの値解決やCSS変数の出力に使用される。

**業務上の目的・背景**：Tailwind CSS v4では、従来のJavaScript設定ファイルベースのテーマ定義から、CSSカスタムプロパティベースのテーマシステムへと大きく移行した。これにより、CSS内で直接テーマ値を定義でき、ブラウザのネイティブCSS変数機能と統合される。Themeクラスはこの新しいテーマアーキテクチャの中核であり、テーマ値のライフサイクル全体（定義・参照・解決・出力）を管理する。

**機能の利用シーン**：CSSの `@theme` ブロック内でテーマ値が定義される際、テーマ値がユーティリティクラスの生成時に参照される際、`theme()` や `--theme()` 関数でテーマ値が解決される際、そしてCSS変数としてテーマ値が出力される際に利用される。

**主要な処理内容**：
1. テーマ値の追加（add）: CSSカスタムプロパティ名をキーとして値を格納する。ワイルドカードによる名前空間クリアにも対応する
2. テーマ値の解決（resolve / resolveValue / resolveWith）: 候補値とテーマキーからテーマ値を参照し、`var()` 関数またはインライン値として返す
3. 名前空間管理（keysInNamespaces / namespace / clearNamespace）: テーマキーの名前空間単位での一覧取得・値取得・クリアを行う
4. プレフィックス管理（prefixKey / entries）: ユーザ定義のプレフィックスを付与したCSS変数名を生成する
5. @keyframes管理（addKeyframes / getKeyframes）: テーマに関連するキーフレーム定義を管理する
6. 使用状況のトラッキング（markUsedVariable）: 実際に使用されたテーマ変数を記録し、未使用変数の除去に活用する

**関連システム・外部連携**：DesignSystem（design-system.ts）から参照され、Utilities・Variants・CSS関数処理などのサブシステムにテーマ値を提供する。v3互換レイヤー（apply-config-to-theme.ts）を通じて旧設定ファイルのテーマ値も統合される。

**権限による制御**：権限による制御は存在しない。ただし、テーマオプション（ThemeOptions）のビットフラグにより、値の振る舞い（INLINE / REFERENCE / DEFAULT / STATIC / USED）が制御される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Appコンポーネント | 補助機能 | text-blue-500のblue-500カラー値をテーマから解決する |
| 6 | トップページ | 補助機能 | text-3xlのフォントサイズ値等をテーマから解決する |

## 機能種別

データ管理 / 値解決処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| key | string | Yes | CSSカスタムプロパティ名（`--` で始まる文字列） | `--` プレフィックスが必須。ワイルドカード `*` は名前空間クリア用 |
| value | string | Yes | テーマ値の文字列表現 | `initial` の場合は値の削除として扱う |
| options | ThemeOptions | No | テーマオプションのビットフラグ | ThemeOptions enumの組み合わせ |
| candidateValue | string / null | Yes（resolve系） | ユーティリティ候補の値部分 | null許容。ドットを含む場合はアンダースコアに変換して再試行 |
| themeKeys | ThemeKey[] | Yes（resolve系） | 解決対象のテーマキー配列 | `--` プレフィックスが必須 |

### 入力データソース

- CSSの `@theme` ブロック内の宣言（コンパイル時にパースされたAST）
- v3互換レイヤー経由の設定ファイル（tailwind.config.js の theme セクション）
- ユーティリティクラスの候補値（parseCandidate の結果）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| resolvedValue | string / null | 解決されたテーマ値。`var(--key)` 形式またはインライン値 |
| keysInNamespace | string[] | 名前空間内のテーマキー一覧 |
| entries | [string, ThemeEntry][] | テーマの全エントリ（プレフィックス付き） |
| keyframes | AtRule[] | 登録されたキーフレーム定義の配列 |

### 出力先

- DesignSystem を通じてユーティリティCSS生成パイプラインに提供
- CSSカスタムプロパティとして最終CSS出力に含まれる

## 処理フロー

### 処理シーケンス

```
1. テーマ値の追加（add）
   ├─ ワイルドカードチェック（`-*` で終わる場合は名前空間クリア）
   ├─ DEFAULT オプションチェック（既存の非DEFAULT値がある場合はスキップ）
   ├─ `initial` 値の場合は既存値を削除
   └─ Map に値・オプション・ソース情報を格納

2. テーマ値の解決（resolve）
   ├─ resolveKey で候補値とテーマキーからキーを特定
   │   ├─ 完全一致を試行
   │   ├─ ドット含む場合はアンダースコア変換で再試行
   │   └─ ignoredThemeKey チェック
   ├─ INLINE オプションの場合は生の値を返す
   └─ それ以外は var(--prefixed-key) 形式で返す

3. 名前空間操作
   ├─ keysInNamespaces: プレフィックスベースのキー一覧取得
   ├─ namespace: 名前空間内の全キー・値ペアを取得
   └─ clearNamespace: 名前空間内の値をクリア
```

### フローチャート

```mermaid
flowchart TD
    A[テーマ値の追加要求] --> B{ワイルドカード key-* ?}
    B -->|Yes| C{--* ?}
    C -->|Yes| D[全テーマ値をクリア]
    C -->|No| E[指定名前空間をクリア]
    B -->|No| F{DEFAULT オプション?}
    F -->|Yes| G{既存の非DEFAULT値あり?}
    G -->|Yes| H[スキップ]
    G -->|No| I{value === initial ?}
    F -->|No| I
    I -->|Yes| J[既存値を削除]
    I -->|No| K[Map に値を格納]

    L[テーマ値の解決要求] --> M[resolveKey でキーを特定]
    M --> N{キーが見つかった?}
    N -->|No| O[null を返す]
    N -->|Yes| P{INLINE オプション?}
    P -->|Yes| Q[生の値を返す]
    P -->|No| R[var関数形式で返す]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-11-01 | DEFAULT優先度 | DEFAULTオプション付きの値は、既存の非DEFAULT値がある場合に上書きしない | テーマ値追加時にDEFAULTフラグがセットされている場合 |
| BR-11-02 | initial による削除 | 値が `initial` の場合、該当キーをMapから削除する | テーマ値追加時 |
| BR-11-03 | ワイルドカードクリア | `--*` は全テーマ値クリア、`--namespace-*` は当該名前空間のクリア | キーがワイルドカード形式の場合 |
| BR-11-04 | REFERENCE フォールバック | REFERENCE モードの値は `var()` 関数内にフォールバック値を含める | テーマ値がREFERENCEオプションを持つ場合 |
| BR-11-05 | 無視キーマップ | 特定のテーマキー接頭辞に対して、無視すべきキーのリストが定義されている | `--font` に対する `--font-weight` 等 |
| BR-11-06 | ドット変換 | 候補値にドットが含まれる場合、アンダースコアに変換して再検索する | resolveKey実行時に完全一致が見つからなかった場合 |

### 計算ロジック

テーマ値の解決では、`var()` CSS関数を生成する。REFERENCEモードでは `var(--key, fallback-value)` 形式で、CSSの変数が未定義の場合でもフォールバック値が使われるようにする。

## データベース操作仕様

### 操作別データベース影響一覧

本機能はデータベースを使用しない。テーマ値はインメモリの `Map<string, ThemeEntry>` で管理される。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | ワイルドカード名前空間に `initial` 以外の値を設定した場合 | `Invalid theme value` エラーをスロー |

### リトライ仕様

リトライ処理は存在しない。

## トランザクション仕様

トランザクション管理は存在しない。Mapの操作は即座に反映される。

## パフォーマンス要件

- テーマ値の検索は `Map.get()` による O(1) のハッシュテーブル参照
- `keysInNamespaces` はMapの全キーを走査するため O(n)
- `clearNamespace` もMapの全キーを走査するため O(n)

## セキュリティ考慮事項

テーマ値はユーザが定義したCSS値であり、CSSインジェクション等のセキュリティリスクはCSS仕様の範囲で処理される。

## 備考

- ThemeOptions は TypeScript の const enum としてビットフラグで定義されており、複数のオプションを組み合わせて使用できる
- ThemeKey 型は `--${string}` 形式のテンプレートリテラル型である
- v3互換レイヤーを通じて、旧来の `tailwind.config.js` のテーマ設定も本クラスに統合される

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、Themeクラスが管理するデータ構造とオプションフラグの定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | theme.ts | `packages/tailwindcss/src/theme.ts` | ThemeOptionsのビットフラグ定義（4-12行目）を理解する。NONE / INLINE / REFERENCE / DEFAULT / STATIC / USED の各フラグの意味を把握する |
| 1-2 | theme.ts | `packages/tailwindcss/src/theme.ts` | ThemeKey型（304行目）が `--${string}` 形式であることを確認する |
| 1-3 | theme.ts | `packages/tailwindcss/src/theme.ts` | ignoredThemeKeyMap（17-33行目）の定義を理解する。`--font` が `--font-weight` や `--font-size` を無視する等のルールを把握する |

**読解のコツ**: TypeScriptの `const enum` はコンパイル時にインライン展開されるため、実行時のオーバーヘッドがない。ビットフラグは `|` で結合し `&` でチェックするパターンで使用される。

#### Step 2: エントリーポイントを理解する

Themeクラスのコンストラクタとメインメソッドを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | theme.ts | `packages/tailwindcss/src/theme.ts` | Themeクラスのコンストラクタ（44-54行目）。values Map と keyframes Set の初期化を確認する |
| 2-2 | theme.ts | `packages/tailwindcss/src/theme.ts` | add メソッド（60-86行目）。テーマ値追加のメインロジック |

**主要処理フロー**:
1. **60-86行目**: `add()` メソッド - ワイルドカード、DEFAULT、initial の各条件分岐
2. **110-119行目**: `get()` メソッド - テーマキー配列から最初にマッチする値を返す
3. **219-235行目**: `resolve()` メソッド - 候補値とテーマキーから解決済み値を返す
4. **237-243行目**: `resolveValue()` メソッド - var() でラップせずに生の値を返す
5. **245-274行目**: `resolveWith()` メソッド - ネストされたサブキーの値も合わせて返す

#### Step 3: 値解決の内部実装を理解する

private メソッドによるキー解決とCSS変数生成の仕組みを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | theme.ts | `packages/tailwindcss/src/theme.ts` | `#resolveKey()` メソッド（168-191行目）。候補値とテーマキーの組み合わせから実際のMapキーを特定するロジック |
| 3-2 | theme.ts | `packages/tailwindcss/src/theme.ts` | `#var()` メソッド（193-208行目）。CSS `var()` 関数の生成。REFERENCEモードでのフォールバック処理 |

**主要処理フロー**:
- **168-191行目**: `#resolveKey()` - 候補値とテーマキーの組み合わせでMapを検索。ドット含む値はアンダースコアに変換して再試行
- **193-208行目**: `#var()` - プレフィックス付きキーで `var()` 関数を生成。REFERENCEモードではフォールバック値を追加

#### Step 4: 名前空間管理とプレフィックス処理を理解する

テーマキーの名前空間操作とプレフィックス付与の仕組みを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | theme.ts | `packages/tailwindcss/src/theme.ts` | `keysInNamespaces()` メソッド（88-108行目）。IntelliSenseの補完候補生成に使用 |
| 4-2 | theme.ts | `packages/tailwindcss/src/theme.ts` | `prefixKey()` / `#unprefixKey()` メソッド（139-147行目）。ユーザ定義プレフィックスの付与・除去 |
| 4-3 | theme.ts | `packages/tailwindcss/src/theme.ts` | `namespace()` メソッド（276-293行目）。名前空間ベースの値取得 |

### プログラム呼び出し階層図

```
DesignSystem (design-system.ts)
    │
    ├─ Theme.resolve(candidateValue, themeKeys, options)
    │      ├─ Theme.#resolveKey(candidateValue, themeKeys)
    │      │      └─ isIgnoredThemeKey(themeKey, namespace)
    │      └─ Theme.#var(themeKey)
    │             └─ Theme.prefixKey(key)
    │
    ├─ Theme.resolveValue(candidateValue, themeKeys)
    │      └─ Theme.#resolveKey(candidateValue, themeKeys)
    │
    ├─ Theme.resolveWith(candidateValue, themeKeys, nestedKeys)
    │      ├─ Theme.#resolveKey(candidateValue, themeKeys)
    │      └─ Theme.#var(nestedKey)
    │
    ├─ Theme.add(key, value, options)
    │      └─ Theme.clearNamespace(namespace)
    │
    ├─ Theme.keysInNamespaces(themeKeys)
    │      └─ isIgnoredThemeKey(key, namespace)
    │
    └─ Theme.entries()
           └─ Theme.prefixKey(key)
```

### データフロー図

```
[入力]                          [処理]                         [出力]

@theme ブロックの宣言  ───▶  Theme.add()            ───▶  values Map に格納
                              (key, value, options)

ユーティリティ候補値   ───▶  Theme.resolve()         ───▶  CSS var() 関数 or インライン値
                              (candidateValue,              "var(--color-blue-500)"
                               themeKeys)

IntelliSense要求      ───▶  Theme.keysInNamespaces() ───▶  補完候補キー配列
                              (themeKeys)                   ["blue-50", "blue-100", ...]

CSS出力要求            ───▶  Theme.entries()          ───▶  プレフィックス付き全エントリ
                                                           [["--tw-color-blue-500", ...], ...]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| theme.ts | `packages/tailwindcss/src/theme.ts` | ソース | Themeクラスの本体。テーマ値の管理・解決を担当 |
| design-system.ts | `packages/tailwindcss/src/design-system.ts` | ソース | DesignSystem型定義。Theme・Utilities・Variantsを統合する |
| index.ts | `packages/tailwindcss/src/index.ts` | ソース | コンパイルエントリポイント。@themeブロックの解析とThemeへの値追加を行う |
| css-functions.ts | `packages/tailwindcss/src/css-functions.ts` | ソース | theme() / --theme() 関数の値解決でThemeを参照 |
| utilities.ts | `packages/tailwindcss/src/utilities.ts` | ソース | ユーティリティ生成時のテーマ値解決でThemeを参照 |
| apply-config-to-theme.ts | `packages/tailwindcss/src/compat/apply-config-to-theme.ts` | ソース | v3設定ファイルのテーマ値をThemeに適用 |
| escape.ts | `packages/tailwindcss/src/utils/escape.ts` | ソース | CSSカスタムプロパティ名のエスケープ・アンエスケープ |
| ast.ts | `packages/tailwindcss/src/ast.ts` | ソース | AtRule・Declaration型の定義。Themeが参照する型 |
