管理画面でボタンを1つ押したら、サイト全体の見た目がガラッと変わった。
「着せ替え」と呼んでいるこの機能を、Agent と一緒に30分で作った話を書く。
BEFORE — 色がハードコードされた状態
もともとの my-blog は Warm テーマ1種類だけだった。背景の `#f6f4ee` やテキストの `#1a1a1a` がコード中に直接書かれていて、「ダークモードにしたいな」と思っても簡単には変えられない。

温かみのあるベージュ系の配色。これはこれで気に入っていたが、夜に見ると少し眩しい。
AFTER — Night テーマに切り替えた瞬間
管理画面でテーマを Night に切り替えると、同じページがこうなる。

背景は `#1a1b1e`、テキストは `#e4e5e7`。アクセントカラーもシアン系に自動で切り替わる。夜の閲覧が格段に楽になった。
管理画面 — ワンクリックで切替
テーマの切り替えは `/admin/theme` から行う。Light / Warm / Night の3カードが並んでいて、押すだけで即反映。

各カードにはカラーパレットのプレビューが表示されている。「Warm(デフォルト)(現在)」のように、今どのテーマが適用されているかも一目でわかる。次回ページ読み込み時に全訪問者に反映される仕組みだ。
ちなみに Admin ページ自体にも変化があった。テーマ機能を実装したことで「テーマ設定」ボタンが追加された。
Agent との協働プロセス
実装は以下の6ステップで進めた。
1. **Supabase テーブル設計** — `site_settings` テーブルを作成。`key = 'theme'` で `light / warm / night` の値を管理する
2. **CSS変数定義** — 3テーマ × 8色を `globals.css` に定義。`:root` は Warm をデフォルトにした
3. **FOUC防止** — `<head>` 内の inline script で `localStorage` からテーマを即座に適用。ページ読み込み時のちらつきを防ぐ
4. **ThemeSync コンポーネント** — Supabase から最新テーマを取得し、`localStorage` と `data-theme` 属性を更新する
5. **管理画面UI** — 3つのカード形式で、クリック → `site_settings` テーブルに upsert → 即反映
6. **15ファイルの色移行** — ハードコードされた Tailwind 色 (`text-gray-600`, `bg-white` など) を CSS変数 (`var(--muted)`, `var(--surface)`) に置き換え
Agent には「Warm テーマをデフォルトにして、Light と Night を追加したい。管理画面から切り替えられるようにして」と伝えた。テーブル設計から CSS 定義、FOUC 対策まで一気に提案してくれた。
Codex レビューでは blocking 指摘が5件出た。RLS の設定漏れ、import パスの不一致、FOUC 対策の不備など。全件修正して再レビューで pass した。
## 困った具体例
| # | 状況 | 困りごと | 解消 |
|---|------|---------|------|
| 1 | FOUC(ちらつき) | テーマ適用前に一瞬白背景が見える | `<head>` 内の inline script + `localStorage` キャッシュで防止 |
| 2 | RLS 設定漏れ | 全ユーザーがテーマを変更できてしまう | `auth.uid()` で管理者 UUID に限定 |
| 3 | ハードコード色の見落とし | Night テーマで一部のテキストが見えない | 15ファイルを総点検して CSS変数に統一 |
特に3番目が地味に大変だった。Night テーマに切り替えたら「あれ、ここのテキストが見えない」というのが次々出てくる。`text-gray-600` のように Tailwind で直接指定していた箇所が、黒背景に対してコントラスト不足になっていた。Agent と一緒に15ファイルを洗い出して、すべて `var(--muted)` や `var(--ink)` に置き換えた。
結果
- **実装時間**: Agent との協働で約30分
- **変更ファイル数**: 15ファイル以上
- **テーマ数**: 3(Light / Warm / Night)、追加も容易
- **FOUC**: inline script + `localStorage` で抑制済み
CSS変数の設計がベースにあったから、テーマの追加は `globals.css` に変数セットを1つ足すだけで済む。将来4番目のテーマを作りたくなっても、数分で対応できる。
次の1歩
- ユーザーごとのテーマ選択(訪問者が自分の好みで切り替えられる機能)
- テーマのカスタムカラー対応
- 切り替え時のトランジションアニメーション
まずは管理者が全体のトーンを決める仕組みができた。ここから先は「訪問者自身が選べる」方向に進化させていきたい