zudo-docは3層カラー戦略を採用します。`theme.css`が通常のカスタムプロパティのエイリアスを定義し、zudo-windプリセットが`var(...)`でユーティリティ名を登録します。後続の`:root`宣言で値を上書きできます。

## 3層カラー戦略

カラーは3つの層で構成されています。各層は上位の層のみを参照します：

| 層 | 名前 | 目的 | 定義場所 |
|----|------|------|----------|
| 1 | **ランプ** | スキームの土台となる、共有される OKLCH カラーランプ | `zfb.config.ts` の自作 `colorSchemes` 上書き（任意 — 未設定ならパッケージのデフォルト）→ `ColorSchemeProvider` → `:root` |
| 2 | **セマンティック** | デザイン上の意味 — 各色がUIで何を表すか | パッケージの`@takazudo/zudo-doc/theme.css` `:root`（プロジェクト側の後続の`:root`ブロックでオーバーライド可能） |
| 3 | **コンポーネント** | 特定コンポーネント向けのスコープ付きオーバーライド | `.zd-content`（共有 `content.css`） |

この階層構造により：

- **ランプストップの再調整**（`zfb.config.ts` の `colorSchemes` フィールドを上書き）→ それを土台とするすべてのセマンティックロールが更新
- **セマンティックロールの再マッピング**（例：`accent`を別のランプストップに向ける）→ `accent`を使用するすべてのコンポーネントが更新
- **コンポーネントトークンのオーバーライド** → 他のコンポーネントに影響なし

## Tier 1：ランプ

zudo-docのカラーエンジンは**ランプネイティブ**です。`ColorScheme`は`{ ramps, map }`です — この型は`@takazudo/zudo-doc/color-scheme-utils`から提供されます。

- **`ramps`** — 共有されるソースオブトゥルース：暖色ニュートラルな**base**ランプ（5 ストップ、インデックス`0`が最も明るい）、**accent**ランプ（3 ストップ）、4 つの**state**カラー（`danger`、`success`、`warning`、`info`）。ライトモードとダークモードはこれらのランプ値を**共有**します。
- **`map`** — モードごとの紐付け：各 UI ロールがどのランプストップ（またはリテラル OKLCH オーバーライド）を指すか。

### 共有ランプ

| ランプ | ストップ | CSS カスタムプロパティ |
|---|---|---|
| `base` | 5 — インデックス`0`（最も明るい）→ `4`（最も暗い） | `--palette-base-0` … `--palette-base-4` |
| `accent` | 3 | `--palette-accent-0` … `--palette-accent-2` |
| `state` | 4 つの名前付きロール | `--palette-state-danger`、`--palette-state-success`、`--palette-state-warning`、`--palette-state-info` |

**Default Light**と**Default Dark** — 同梱されるスキームはこの 2 つだけ — は、まったく同じ`base`/`accent`/`state`のランプ値（パッケージの`@takazudo/zudo-doc/color-schemes-defaults`内の 1 つの`ramps`オブジェクト）を共有し、両者の違いはモードごとの`map`だけです。

[Dynamic content unavailable in text export]

ランプサイズの最小化は意図的なものです。5 つの base ストップと 3 つの accent ストップには、「予備」となるニアホワイトやニアブラックのフィラートーンを置く余地がありません。いくつかのセマンティックロールは、それぞれ独自のストップを持つのではなく、意図的に**同じストップにマージ**されています — 後述の[ロールマージの設計思想](https://zudo-doc.takazudomodular.com/ja/docs/reference/color#%E3%83%AD%E3%83%BC%E3%83%AB%E3%83%9E%E3%83%BC%E3%82%B8%E3%81%AE%E8%A8%AD%E8%A8%88%E6%80%9D%E6%83%B3)を参照してください。



### `RampRef` — ロールがランプストップを指す仕組み

```ts
type RampRef =
  | { base: number }     // ramps.base[n]
  | { accent: number }   // ramps.accent[n]
  | { state: StateRole } // ramps.state[role]
  | string;              // a literal OKLCH value, used as-is
```

スキームの`map`は、4 つの base ロール（`bg`、`fg`、`selectionBg`、`selectionFg`）と 23 のセマンティックロールすべてに`RampRef`を使用します。ほとんどのロールは共有ランプストップを参照しますが、一部は代わりに**リテラル OKLCH 文字列**を持ちます — これは、共有ストップでは作り出せない色をロールが必要とする場合（通常はモードごとの AA コントラスト調整）に使われます。[モードごとのリテラルオーバーライド](https://zudo-doc.takazudomodular.com/ja/docs/reference/color#%E3%83%A2%E3%83%BC%E3%83%89%E3%81%94%E3%81%A8%E3%81%AE%E3%83%AA%E3%83%86%E3%83%A9%E3%83%AB%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%A9%E3%82%A4%E3%83%89)を参照してください。

### ランプの注入方法

`ColorSchemeProvider`コンポーネント（`packages/zudo-doc/src/theme/color-scheme-provider.tsx`）がアクティブなスキームを読み取り、ビルド時に`:root`へ CSS カスタムプロパティ — 解決済みの base ロール、素のランプストップ、解決済みの 23 のセマンティックロール — を注入します：

```css
:root {
  --zd-bg: oklch(.185 .005 65);
  --zd-fg: oklch(.965 .004 65);
  --zd-selection-bg: oklch(.480 .008 65);
  --zd-selection-fg: oklch(.965 .004 65);

  --palette-base-0: oklch(.965 .004 65);
  --palette-base-1: oklch(.705 .008 65);
  /* ... through --palette-base-4 */
  --palette-accent-0: oklch(.755 .130 64);
  /* ... through --palette-accent-2 */
  --palette-state-danger: oklch(.640 .170 25);
  --palette-state-success: oklch(.680 .145 145);
  --palette-state-warning: oklch(.760 .135 82);
  --palette-state-info: oklch(.680 .130 245);

  --zd-accent: oklch(.700 .158 62);
  --zd-code-bg: oklch(.300 .006 65);
  /* ... 21 more --zd-{role} semantic properties */
}
```

`--zd-*`プロパティ（base ロール + セマンティックロール）は、下流のすべてが帰結するソースオブトゥルースです。素の`--palette-*`ランププロパティは、[Design Token Panel](https://zudo-doc.takazudomodular.com/ja/docs/reference/design-token-panel)の**Palette**タブとスキーム作者のために存在します — コンテンツとコンポーネントはセマンティックな`--zd-*`トークンを参照します。生のランプストップ用の zudo-wind ユーティリティはありません（[生のランプストップへのアクセス](https://zudo-doc.takazudomodular.com/ja/docs/reference/color#%E7%94%9F%E3%81%AE%E3%83%A9%E3%83%B3%E3%83%97%E3%82%B9%E3%83%88%E3%83%83%E3%83%97%E3%81%B8%E3%81%AE%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9)を参照）。

## Tier 2：セマンティックトークン

パッケージの `@takazudo/zudo-doc/theme.css` は、23 個の名前空間なしのカラーエイリアスと、対応する 23 個の `--color-zd-*` エイリアスを公開します。スキャフォールドでは、独自の `src/styles/global.css` にある `:root` 上書きブロックより前にこのファイルをインポートするため、変更が必要なプロジェクトのエイリアスだけを再定義してください。以下は、出荷される名前空間なしのトークンと名前空間付きトークンのブロックです。ここではカラーエイリアスを示します。

```css title="@takazudo/zudo-doc/theme.css (color aliases)"
:root {
  --color-bg: var(--zd-bg);
  --color-fg: var(--zd-fg);
  --color-sel-bg: var(--zd-selection-bg);
  --color-sel-fg: var(--zd-selection-fg);
  --color-surface: var(--zd-surface);
  --color-muted: var(--zd-muted);
  --color-accent: var(--zd-accent);
  --color-accent-hover: var(--zd-accent-hover);
  --color-code-bg: var(--zd-code-bg);
  --color-code-fg: var(--zd-code-fg);
  --color-success: var(--zd-success);
  --color-danger: var(--zd-danger);
  --color-warning: var(--zd-warning);
  --color-info: var(--zd-info);
  /* The scrim is intentionally theme-independent. */
  --color-overlay: #000;
  --color-image-overlay-bg: var(--zd-image-overlay-bg);
  --color-image-overlay-fg: var(--zd-image-overlay-fg);
  --color-chat-user-bg: var(--zd-chat-user-bg);
  --color-chat-user-text: var(--zd-chat-user-text);
  --color-chat-assistant-bg: var(--zd-chat-assistant-bg);
  --color-chat-assistant-text: var(--zd-chat-assistant-text);
  --color-matched-keyword-bg: var(--zd-matched-keyword-bg);
  --color-matched-keyword-fg: var(--zd-matched-keyword-fg);
  --color-zd-bg: var(--zd-bg);
  --color-zd-fg: var(--zd-fg);
  --color-zd-sel-bg: var(--zd-selection-bg);
  --color-zd-sel-fg: var(--zd-selection-fg);
  --color-zd-surface: var(--zd-surface);
  --color-zd-muted: var(--zd-muted);
  --color-zd-accent: var(--zd-accent);
  --color-zd-accent-hover: var(--zd-accent-hover);
  --color-zd-code-bg: var(--zd-code-bg);
  --color-zd-code-fg: var(--zd-code-fg);
  --color-zd-success: var(--zd-success);
  --color-zd-danger: var(--zd-danger);
  --color-zd-warning: var(--zd-warning);
  --color-zd-info: var(--zd-info);
  --color-zd-overlay: #000;
  --color-zd-image-overlay-bg: var(--zd-image-overlay-bg);
  --color-zd-image-overlay-fg: var(--zd-image-overlay-fg);
  --color-zd-chat-user-bg: var(--zd-chat-user-bg);
  --color-zd-chat-user-text: var(--zd-chat-user-text);
  --color-zd-chat-assistant-bg: var(--zd-chat-assistant-bg);
  --color-zd-chat-assistant-text: var(--zd-chat-assistant-text);
  --color-zd-matched-keyword-bg: var(--zd-matched-keyword-bg);
  --color-zd-matched-keyword-fg: var(--zd-matched-keyword-fg);
}
```

パッケージのwindプリセットがこれらのエイリアスを登録し、`bg-surface`、`text-accent`、`border-muted`を生成します。新しい名前にはCSSの値と`wind.tokens.colors`の両方が必要です。[Design System](https://zudo-doc.takazudomodular.com/ja/docs/reference/design-system)を参照してください。

名前空間なしのエイリアスはプロジェクトのコード向け、`--color-zd-*` は組み込み先のコード向けです。[別の `@theme` との共存](https://zudo-doc.takazudomodular.com/ja/docs/reference/design-system#%E5%88%A5%E3%81%AE-theme-%E3%81%A8%E3%81%AE%E5%85%B1%E5%AD%98)を参照してください。

### セマンティックトークンリファレンス（Default Dark の紐付け）

どちらのスキームも 23 のロールすべてを紐付けます。下の表は Default Dark の`map.semantic` — パッケージの`@takazudo/zudo-doc/color-schemes-defaults`で提供される、作り込まれたリファレンススキーム — を示します。Default Light はこれらのいくつかを別のランプストップやモードごとのリテラルに再度向けます。[モードごとのリテラルオーバーライド](https://zudo-doc.takazudomodular.com/ja/docs/reference/color#%E3%83%A2%E3%83%BC%E3%83%89%E3%81%94%E3%81%A8%E3%81%AE%E3%83%AA%E3%83%86%E3%83%A9%E3%83%AB%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%A9%E3%82%A4%E3%83%89)を参照してください。

| トークン | デフォルトのランプ参照 | 用途 |
|-------|------|-------|
| `bg` | `{ base: 4 }` | ページ背景 |
| `fg` | `{ base: 0 }` | メインテキスト |
| `surface` | `{ base: 4 }`（= `bg`） | パネル/サイドバーのサーフェス — `bg`にマージ、[ロールマージの設計思想](https://zudo-doc.takazudomodular.com/ja/docs/reference/color#%E3%83%AD%E3%83%BC%E3%83%AB%E3%83%9E%E3%83%BC%E3%82%B8%E3%81%AE%E8%A8%AD%E8%A8%88%E6%80%9D%E6%83%B3)を参照 |
| `muted` | `{ base: 1 }` | ミュートテキスト、ボーダー、コメント |
| `accent` | `{ accent: 1 }` | 本文中のリンク、アクティブ状態・現在地の表示、CTA、クロームのリンクのホバー・フォーカス時の色 |
| `accentHover` | `{ accent: 0 }` | accentのホバー状態 |
| `codeBg` | `{ base: 3 }` | コードブロック背景 |
| `codeFg` | `{ base: 0 }` | インラインコードテキスト |
| `success` | `{ state: "success" }` | 成功状態、確認 |
| `danger` | モードごとのリテラル | エラー、破壊的操作 |
| `warning` | `{ state: "warning" }` | 警告メッセージ、Admonition、find-in-pageハイライト |
| `info` | `{ state: "info" }` | 情報ハイライト |
| `mermaidNodeBg` / `mermaidText` / `mermaidLine` / `mermaidLabelBg` / `mermaidNoteBg` | `@takazudo/zudo-doc/color-schemes-defaults`を参照 | Mermaid ダイアグラムの色 |
| `chatUserBg` / `chatUserText` | `{ accent: 1 }` / `{ base: 4 }` | AI チャットのユーザーバブル |
| `chatAssistantBg` / `chatAssistantText` | `{ base: 4 }`（= `bg`） / `{ base: 0 }` | AI チャットのアシスタントバブル — `bg`にマージ |
| `imageOverlayBg` / `imageOverlayFg` | `{ base: 4 }` / `{ base: 0 }` | 画像拡大オーバーレイ — `bg`にマージ |
| `matchedKeywordBg` / `matchedKeywordFg` | 共有リテラル | 検索結果の`<mark>` — 専用トークン、Design Token Panel でライブ編集可能 |

### シンタックスセマンティクス

`ModeMap.syntax` は、9 つのシンタックス固有ロールを持つ optional な partial map です。map 自体がない場合も、個別ロールを省略した場合も、下表の既存セマンティックロールを継承します。そのため、シンタックストークン導入前に作成されたスキームや v3 トークン JSON も引き続き有効で、名前付き variation や一方の mode では必要なロールだけを上書きできます。

| `ModeMap.syntax` のキー | CSS カスタムプロパティ | 継承元 | zfb レンダラーのロール |
|---|---|---|---|
| `syntaxComment` | `--zd-syntax-comment` | `muted` | comment |
| `syntaxString` | `--zd-syntax-string` | `success` | string, escape |
| `syntaxNumber` | `--zd-syntax-number` | `warning` | number, constant |
| `syntaxKeyword` | `--zd-syntax-keyword` | `accent` | keyword, heading |
| `syntaxCallable` | `--zd-syntax-callable` | `info` | function |
| `syntaxType` | `--zd-syntax-type` | `warning` | type, namespace |
| `syntaxName` | `--zd-syntax-name` | `codeFg` | property, variable, tag, attribute |
| `syntaxInserted` | `--zd-syntax-inserted` | `success` | inserted |
| `syntaxDeleted` | `--zd-syntax-deleted` | `danger` | deleted |

残る zfb ロール（operator と punctuation）は `codeFg` を使用します。この圧縮により、zfb の 18 レンダラーロールをすべて公開カラー判断にせず、コンポーネントレベルの詳細として保てます。inserted／deleted の背景もコンポーネントトークンです。2 つの公開ロールを追加する代わりに、対応するシンタックス前景色を `color-mix()` で `codeBg` へ 15% 混ぜて生成します。

たとえば、一方の mode で keyword だけを上書きできます：

```ts
const darkMap: ModeMap = {
  // ...base and semantic mappings...
  syntax: {
    syntaxKeyword: { state: "info" },
  },
};
```

Provider は解決済みの 9 つの `--zd-syntax-*` 変数をすべて出力します。ネイティブなコードフェンス出力と HtmlPreview の遅延 WASM 出力は、どちらも zfb の `--zfb-hi-*` コンポーネントブリッジを通してそれらを使用します。ブリッジは `var()` 参照を維持するため、スキーム切り替えや Design Token Panel の編集では、ハイライトを再実行せず既存の `hi-*` DOM が再配色されます。出荷する前景色／背景色の組み合わせは、実際に描画される inserted／deleted の tint を含め、4.6:1 以上のコントラスト比で検証されます。

## ロールマージの設計思想

パレットは、区別すべきトーンの数を小さく保つために意図的に最小化されています。いくつかのロールは、それぞれ独自のトーンを持つ代わりに、共有ストップにマージされています：

- **`surface`、`codeBg`（ライトモード）、`chatAssistantBg`は`bg`に統合されます。** ヘッダーのバージョンボックス、ドキュメントカード、チャットアシスタントのバブルは、**ページ背景 + ボーダーのみ**でレンダリングされ、別途のグレーの塗りはありません。
- **5 つの base ストップには、繊細なニアホワイト（ライトモード）やニアブラック（ダークモード）のフィラートーンを置く余地がありません。** それを作り出すためにランプを引き伸ばすのではなく、浮上サーフェスは設計上ボーダーのみとしています。
- 結果として、同期を保つべきトーンが減り、パネル・カード・チャットバブル全体でよりフラットで一貫したビジュアル言語になります。

## モードごとのリテラルオーバーライド

すべてのロールが両モードで共有ランプストップだけで満たせるわけではありません。accent と state のカラーはダーク背景を前提に作り込まれています。ライト背景では、いくつかは WCAG AA をクリアするために**より暗い、そのモード専用のリテラル**を必要とします — 共有ランプストップはそのまま維持されるため、Default Dark は影響を受けません：

- **Default Dark** — `danger`は、共有される`state.danger`のランプ値よりわずかに明るく調整したリテラル（`oklch(.655 .170 25)`）を使用し、danger アドモニションのタイトルが 12% ティントの背景上で AA をクリアします。
- **Default Light** — `accentHover`、`success`、`danger`、`warning`、`info`はすべて、ニアホワイトのページ背景に対して AA をクリアするために、モードごとのリテラル（共有ランプ/state カラーを暗くしたもの）を使用します。
- **両モード** — `matchedKeywordBg` / `matchedKeywordFg`（検索結果のハイライト）はランプ参照ではなく共有リテラルのため、琥珀色のハイライトは両モードで同一に見えます。

これらのリテラルの背後にある完全なコントラストペアマトリクス、しきい値、調整手法については、`color-scheme-a11y`スキル（`.claude/skills/color-scheme-a11y/SKILL.md`）を参照してください。

### スキームのセマンティック紐付けの調整

自作の`colorSchemes`上書きモジュール（`zfb.config.ts`の`colorSchemes`フィールドで渡す）の`map.semantic`を編集します。ロールは共有ランプストップまたはリテラル OKLCH 文字列を指すことができます：

```ts
const darkMap: ModeMap = {
  bg: { base: 4 },
  fg: { base: 0 },
  selectionBg: { base: 2 },
  selectionFg: { base: 0 },
  semantic: {
    accent: { accent: 1 },
    // Per-mode AA-tuned literal — shared state.danger is too dark for the
    // danger-admonition title on its 12%-tint dark bg.
    danger: "oklch(.655 .170 25)",
    // ...
  },
  // Optional; omit it entirely when all syntax roles should inherit.
  syntax: {},
};
```

## 生のランプストップへのアクセス

生の`--palette-*`ランプストップ用の zudo-wind ユーティリティはありません — セマンティックトークンが zudo-wind に露出する唯一のカラー面です。一度きりのスタイルがどうしても生のランプストップを必要とする場合（まれ）は、CSS カスタムプロパティを直接参照します：

```html
<div style="background: var(--palette-accent-1)">...</div>
```

これはまれなケースであるべきです。既存のセマンティックトークンを優先するか、同じ生のストップが複数箇所で必要な場合は新しいセマンティックロールを追加してください。

## Tier 3：コンポーネントトークン

一部のコンポーネントは、Tier 2のセマンティックトークンを参照する独自のカラー変数を定義しています。これらは内部的な実装の詳細です。

### コンテンツタイポグラフィ

`.zd-content`クラスはセマンティックトークンを使用した直接的な要素スタイリングを提供します（外部タイポグラフィプラグイン不要）：

```css
.zd-content {
  color: var(--color-fg);
  font-size: var(--text-body);
  line-height: var(--leading-relaxed);
}

.zd-content :where(a) {
  color: var(--color-accent);
}

.zd-content :where(code:not(pre code)) {
  color: var(--color-code-fg);
  background-color: var(--color-code-bg);
}

.zd-content :where(li::marker) {
  color: var(--color-muted);
}
/* ... */
```

[Dynamic content unavailable in text export]

Tier 3のトークンはコンポーネント内部のものです。独自のUIを構築する際は、Tier 2のセマンティックトークンを直接使用してください。



## カラートークンの使い方

標準的なUIパターンにはセマンティックトークンを使用します：

```html
<!-- Text -->
<p class="text-fg">Primary text</p>
<p class="text-muted">Secondary text</p>

<!-- Backgrounds -->
<div class="bg-bg">Page background</div>
<div class="bg-surface">Panel or sidebar</div>

<!-- Borders -->
<div class="border border-muted">Bordered element</div>
```

### リンクの色

リンクの色は、リンクであること自体ではなく、置かれている場所で決まります：

- **本文中のリンク** — 文章の流れの中にあるリンク（`ContentLink`が描画するMarkdownのリンクや、バージョンバナー内のリンクなど）— は`text-accent underline`を使います。
- **クロームのリンク** — ナビのリスト、カード、チップ、ページャー — は`text-fg`（フッターの列、目次、パンくずリストといった補助的なクロームでは`text-muted`）のままにし、ホバー時・フォーカス時、または現在地を示すときにだけ`accent`に変わります。常時表示の下線は付けません。その代わり、目に見えるリスト、カードの枠、先頭のアイコンのいずれかで、リンクだと分かる構造を必ず持たせます。
- **補助的なクロームに並ぶインラインのリンク列** — ホームのヒーロー部分のリンク行と、フッターの著作権表記の行 — はその中間です。`text-fg`に常時の下線を付け、ホバー時に`accent`に変わります。

```html
<!-- Prose link -->
<a class="text-accent underline hover:text-accent-hover">Prose link</a>

<!-- Chrome link -->
<a class="text-fg hover:text-accent hover:underline focus-visible:text-accent focus-visible:underline">Chrome link</a>
```

### 検索とハイライトのトークン（役割を分離）

ハイライトの役割は意図的に専用セマンティックトークンに分離されています。無関係なハイライトUI間でひとつのトークンを使い回すのはアンチパターンです。

- `matched-keyword-bg` / `matched-keyword-fg`は検索パネルの`<mark>`要素に使われます。別の役割の`color-mix()`ではなく専用トークンのため、[Design Token Panel](https://zudo-doc.takazudomodular.com/ja/docs/reference/design-token-panel)のスウォッチがハイライト色の唯一のソースになります。パネルで見えている色＝実際のハイライト色です。
- `warning`はAdmonition（`:::warning`）、find-in-page（`.find-match`、`.find-match-active`）など、意味的に _警告_ にあたるUIで使います。**新しいUIクロム向けのハイライトに`warning`を使い回してはいけません**。

新しいハイライトの役割が出てきたとき（新種の`<mark>`、新しいピル、新しいコールアウト）は、既存の役割過多なトークンに載せるのではなく、専用のセマンティックトークンを追加してください。プロダクトに現れるハイライト色はどれも、パネルのスウォッチに1対1で対応するべきです。

## カラースキーム

デフォルトでは`colorMode`が有効なため、`lightScheme`と`darkScheme`がアクティブなスキームを選び、`colorScheme`より優先されます。`defaultMode`は`"dark"`で、同梱のダークスキームに対応します。`respectPrefersColorScheme: true`では、OSの設定によりもう一方のモードが選ばれることがあります：

```ts title="zfb.config.ts"
import { defineConfig } from "zfb/config";
import { zudoDoc } from "@takazudo/zudo-doc/config";

export default defineConfig(
  zudoDoc({
    colorMode: {
      defaultMode: "dark",
      lightScheme: "Default Light",
      darkScheme: "Default Dark",
      respectPrefersColorScheme: true,
    },
    siteName: "My Docs",
    // ...
  }),
);
```

### 外観の選択

ヘッダーのメニューで選ぶ **Light**、**Dark**、**System** は保存される設定です。ページで解決されるカラースキームはライトまたはダークのままです。デフォルトの `respectPrefersColorScheme: true` では、保存済みの設定がない初回訪問時に System が選ばれ、デバイスに従います。Light または Dark を選ぶと、利用者が再び System を選ぶまでその外観が固定されます。選択中の設定は `localStorage` の `zudo-doc-theme` に保存されます。

コンパクトメニューのアイコンは常に選択中の設定を表します。Light は太陽、Dark は月、System はモニターです。System を選んだ状態でデバイス設定がライトからダークに変わると、ページのカラースキームは変わりますが、選択アイコンはモニターのままです。`defaultMode` は `"light" | "dark"` のフォールバックです。`respectPrefersColorScheme: false` にすると、保存済みの選択がない初回訪問時にこの値が使われます。利用者は System を明示的に選ぶこともでき、その場合はデバイス設定に従います。

ライト／ダークの外観メニューなしで1つの固定スキームを使うには、`colorMode: false`を設定します。この場合は`colorScheme`がスキームを選びます：

```ts title="zfb.config.ts"
export default defineConfig(
  zudoDoc({
    colorMode: false,
    colorScheme: "My Theme",
  }),
);
```

### デフォルトテーマ

zudo-docはちょうど 2 つのカラースキーム — **Default Light**と**Default Dark** — を同梱しており、1 セットのランプを共有します（パッケージの`@takazudo/zudo-doc/color-schemes-defaults`を参照）。どちらも手作業で作り込まれ、その場で AA 調整されています。選べるコミュニティ製やターミナル由来のプリセットカタログはバンドルされていません。以前の Design Token Panel には 50 種類以上のバンドルプリセットをブラウズするための "Scheme…" ドロップダウンがありましたが、ランプネイティブなモデルではこれを廃止しました — [Design Token Panel](https://zudo-doc.takazudomodular.com/ja/docs/reference/design-token-panel)を参照してください。

## カスタムカラースキームの追加

`colorSchemes`は`zudoDoc()`のエスケープハッチの1つです — 省略した場合は上記の2つの同梱スキームがそのまま使われます。新しいスキャフォールドにはカラースキームモジュールがありません。スキームを追加または置き換える場合は、独自のモジュール（例：`src/color-schemes.ts`）を作成して`Record<string, ColorScheme>`を組み立て、`zfb.config.ts`の`colorSchemes`フィールドで渡します。新しいスキームには独自の`ramps`と、必要な各モードの`map`が必要です（`SEMANTIC_RAMP_DEFAULTS`をスプレッドし、異なる必要のあるものだけを上書きします）。2つの同梱スキームも一緒に残したい場合は`defaultColorSchemes`もスプレッドしてください：

```ts title="src/color-schemes.ts"
import { SEMANTIC_RAMP_DEFAULTS } from "@takazudo/zudo-doc/color-scheme-utils";
import { defaultColorSchemes } from "@takazudo/zudo-doc/color-schemes-defaults";
import type { ColorScheme, ModeMap, Ramps } from "@takazudo/zudo-doc/color-scheme-utils";

const myRamps: Ramps = {
  base: [
    "oklch(.97 .01 250)", // 0 — lightest
    "oklch(.72 .02 250)", // 1
    "oklch(.48 .03 250)", // 2
    "oklch(.28 .03 250)", // 3
    "oklch(.15 .02 250)", // 4 — darkest
  ],
  accent: [
    "oklch(.78 .12 30)", // 0
    "oklch(.68 .18 30)", // 1
    "oklch(.48 .16 30)", // 2
  ],
  state: {
    danger: "oklch(.62 .18 25)",
    success: "oklch(.66 .15 145)",
    warning: "oklch(.75 .14 82)",
    info: "oklch(.66 .13 245)",
  },
};

const myMap: ModeMap = {
  bg: { base: 4 },
  fg: { base: 0 },
  selectionBg: { base: 2 },
  selectionFg: { base: 0 },
  semantic: {
    ...SEMANTIC_RAMP_DEFAULTS,
    accent: { accent: 1 }, // only override the roles that need to differ
  },
  syntax: {}, // optional; add only syntax-specific overrides here
};

export const colorSchemes: Record<string, ColorScheme> = {
  ...defaultColorSchemes, // keep "Default Light" / "Default Dark"
  "My Theme": { ramps: myRamps, map: myMap },
};
```

```ts title="zfb.config.ts"
import { colorSchemes } from "./src/color-schemes";

export default defineConfig(
  zudoDoc({
    colorMode: false,
    colorScheme: "My Theme",
    colorSchemes,
    // ...
  }),
);
```

[Dynamic content unavailable in text export]

このショーケースリポジトリでは、同梱スキームを変更するときにコントリビューターが`pnpm contrast:audit`を実行し、`color-scheme-a11y`スキルを使用します。これらはショーケース保守用のツールであり、生成されたスキャフォールド用のコマンドではありません。カスタムスキームを作成する場合は、プロジェクトに適したコントラスト要件を検証してください。



## やってはいけないこと

[Dynamic content unavailable in text export]

**登録済みの色を使用する** — デフォルトパレット名は登録されていません：

```html
<!-- WRONG -->
<div class="bg-gray-800 text-blue-500">No visible color</div>

<!-- RIGHT -->
<div class="bg-surface text-accent">Works correctly</div>
```

**16進数値をハードコードしない** — テーマ切り替えが壊れます：

```html
<!-- WRONG -->
<div class="bg-[#1e1e2e]">Breaks on theme switch</div>

<!-- RIGHT -->
<div class="bg-surface">Adapts to any theme</div>
```

**Tier 3の変数を自分のコンポーネントで参照しない**：

```css
/* WRONG — don't use hardcoded colors */
.my-component {
  color: #3b82f6;
}

/* RIGHT — use semantic tokens */
.my-component {
  color: var(--color-accent);
}
```