ダークモードのカラーシステム:午前2時に機能するパレットの作り方
ダークモードのカラーシステム実践ガイド。サーフェスのエレベーションモデル、彩度を落とすルール、アクセントの調整、そして2026年に最もクリーンなダークモードパレットを出荷している7つのブランド。

ダークモードのカラーシステム:午前2時に機能するパレットの作り方
ダークモードは並列システムです。ライトのスイッチをひっくり返しただけのプロダクトは、照明が消えた途端に壊れて見えます。
これが記事の全体を一文にしたものです。ほとんどのダークモードが失敗する理由はもっと具体的です。デザイナーは「ライトのパレットを反転させる」に手を伸ばし、結果として灰色の上に灰色が載っただけの平坦な世界か、網膜を焼く電気的なコーラルにたどり着きます。解決策は見た目の話ではなく、設計の話です。独自のエレベーションモデル、独自の彩度を落とすルールセット、独自のアクセント調整を備えた並列システムを作れば、仕上がりは意図的に見えます。実際に意図的だからです。
ダークモードは反転ではなく、並列システムである
ライトのパレットには background、surface、border、text、accent のトークンがあります。ダークのパレットにも同じトークンがすべて必要で、その値はライトの値の反転ではありません。低い明度ではクロマの振る舞いが変わります。色相のずれは知覚の境界で起こります。ライトモードで L 0.62 のきれいなコーラルに見える色は、ほぼ黒のサーフェスの上で L 0.72 のダークモードに置くと、チカチカ振動するネオンに膨らみます。
クリーンなダークモードを出荷するチームは、トグルには手を触れません。2つ目のパレットを設計し、同じセマンティックトークンの層にマッピングし、テーマのルートでモード切り替えによって両者をつなぎます。手間は増えます。しかし、恥をかかない唯一の方法です。
サーフェスのエレベーションモデル
Background。Surface。Surface-elevated。Surface-overlay。実際に機能するダークモードデザインのUIには、この4つの階層があります。3つ目の階層を飛ばすことが、ダークUIが平板に感じられる最も多い原因です。
ライトモードでは、エレベーションは明白です。白いカードがグレーの背景に載り、影は安上がりで、奥行きはタダで手に入ります。ダークモードでは、影は暗いサーフェスに溶けて消えます。エレベーションはサーフェス自体の明度に宿らせるしかありません。各階層は、ジャンプではなく、小さく意図的な明度の一段上がりです。
この4階層は美的な選択ではありません。荷重を支える構造です。システム内のあらゆるコンポーネントはこのいずれかの階層に載り、サーフェス上のテキストの読みやすさは、スタックのどこに置くかで決まります。
Background が床を決める
Background は最も深い階層です。ルールは、彩度の高い純黒(oklch(0 0 0))は決して使わないこと。明度8〜10パーセント前後の、わずかに色味のあるほぼ黒を使います。色味はほぼ必ずウォーム寄りにします。クールな黒は、プロダクトにふさわしい以上に安っぽく冷たく見えるからです。
oklch(0.10 0.012 30) のような値なら、どのディスプレイでも「黒」に見えつつ、純黒の死んだ真空のような感じを避けたダークなウォームチャコールが得られます。クロマ0.012と色相角30度(わずかにウォーム寄り)で十分です。これ以上だと濁って見え、これ以下だと生気がなくなります。
Surface がコンテンツを載せる
Surface はコンテンツの大半が載る階層で、background よりわずかに持ち上がっています。background から surface への明度のステップは、OKLCH で通常3〜5ポイントです。この差が、目が最初に読み取る合図になります。ここがコンテンツの居場所で、背景はその後ろにある、というサインです。
oklch(0.14 0.010 30) を oklch(0.10 0.012 30) の上に置けば、ボーダーも影もなしで十分な視覚的分離が得られます。クロマが少し下がるのは、暗いサーフェスで明度が上がるにつれ、背景への濁った滲みを避けるためにクロマを引く必要があるからです。描画時には微妙な差ですが、これを飛ばすと完全に間違った見た目になります。
Surface-elevated と surface-overlay
Elevated サーフェスにはカードやパネルが載ります。Overlay サーフェスにはモーダルやシートが載ります。明度の進行は続き、surface-elevated はおよそ oklch(0.18 0.008 30)、surface-overlay は oklch(0.22 0.007 30) です。段を上がるごとにクロマは下がります。スタックの上にあるほど見る人に近く、それらのサーフェスはクリーンに感じられる必要があるからです。
ほとんどのダークUIが平坦な灰色のおかゆに崩れる理由は、デザイナーが background と surface の2階層しか使わないことにあります。カードは background に載り、テキストは surface に載り、すべてが同じ奥行きで読まれます。3階層目と4階層目を足せば、ドロップシャドウを1つも使わずに、UIはたちまち読みやすくなります。
彩度を落とすルール
ライトで機能する高彩度の色は、夜には目を焼きます。ルールは、アクセントの彩度を15〜25パーセント落とし、テキストとボーダーのクロマはさらに下げること。これはブランドを暗くする話ではありません。周囲が暗いときに目がクロマをどう処理するかの話です。
周囲が明るい場所(正午のオフィス)では、鮮やかなクロマは活気あるものとして読めます。周囲が暗い場所(真夜中のデスク)では、同じクロマが攻撃的で、ハロー(光の滲み)を起こし、身体的に不快なものとして読まれます。解決策は色を恐れることではありません。調整することです。ブランドは認識できるまま、プロダクトが痛くなくなります。
なぜ純白のテキストは間違いなのか
ほぼ黒の上の純白は、高コントラストではなく、コントラストが強すぎます。明るい文字が暗い周囲に滲んで見えるハロー効果は、記録されている光学現象であり、ダークUIを読みやすくするどころか読みにくくします。
ダークモードのプライマリテキストの適切な値は、明度90〜95パーセント前後に、ほんのりウォームな色味を足したものです。oklch(0.93 0.005 60) は「白」に見えるのにハローを起こしません。セカンダリテキストは oklch(0.70 0.010 60) まで下げます。本文サイズでも読め、プライマリテキストに対しては視覚的に控えめです。このオフホワイトは、デザイナーが最も間違えやすい値です。妥協のように感じられますが、実はそれが正解の値なのです。
アクセント調整がブランドの認識性を保つ
ブランドのアクセントは、アイデンティティを失わずにダークモードで読める必要があります。調整は明度を上げてクロマを下げることで、色相のシフトではありません。ライトモードのアクセントが oklch(0.62 0.22 25) なら、ダークモードのアクセントは oklch(0.72 0.17 25) です。色相は同じ。暗いサーフェスの上で映えるよう明度は高く。ハローを起こさないようクロマは低く。
よくある間違いは、ダークモードをアクセントを暗くする場所として扱うことです。暗くするとブランドの認識性が死にます。明度を上げてクロマを下げれば、視覚的な焼けを防ぎつつ、ブランドカラーパレットの雰囲気を保てます。ユーザーは調整には気づきません。気づくのは、プロダクトが良く見えるということだけです。

WCAG が見逃すコントラストのチェック
WCAG 2.1のコントラスト比は、多くの醜いダークUIを通してしまいます。暗いサーフェスと落ち着いたグレーのテキストの間の4.5:1という比率は、WCAGを通過しながら、実際の環境光の下では本当に読みにくいことがあります。2回目のチェックはAPCAで、特にライトオンダークの区別で、明度の知覚をより正確にモデル化します。
APCAの後は、目視テストをします。シマーとは、明度が近くクロマが異なる2色が並んだときに見える振動です。ハローとは、明るい要素が暗い周囲に滲み出すことです。ブルームとは、高彩度のアクセントに知覚される光のにじみです。これらのどれかが出ていれば、比率に関係なくそのペアは不合格です。直すのは比率ではなく値です。アクセシブルな色のコントラストの仕組みをさらに掘り下げるなら、完全な方法論が、ライトモードの監査では出てこないエッジケースまでカバーしています。
クリーンなダークパレットを出荷する7つのブランド
Linear、Notion、Vercel、Stripe、GitHub、Arc、Raycast は、それぞれ違う方法でダークモードを解いています。彼らに共通するパターンこそ、盗む価値があるものです。
| ブランド | サーフェスモデル | アクセント戦略 | 何が優れているか |
|---|---|---|---|
| Linear | 正統な4階層、細かいステップ | パープルの明度を上げ、クロマは約0.15 | ステップが細かく、奥行きがシームレスに読める |
| Notion | オーバーレイ付きの3階層 | ダークではアクセントを最小限に | クロマはほぼゼロ、奥行きだけ |
| Vercel | バイナリ(background + elevated) | 白のみ | 容赦なくシンプル。貫くから成立する |
| Stripe | 4階層、ウォームな色味 | ブルーは調整のみ、減らさない | 密なデータがどの階層でもクリーンに読める |
| GitHub | 3つの名前付きテーマ(dark、dimmed、high-contrast) | ブルーグリーン、彩度を落とす | 「Dimmed」こそ正しいデフォルト |
| Arc | スペースごとのカスタム着色 | 色相はユーザーが完全に定義 | エレベーションは明度ではなく色相シフトから |
| Raycast | 強いブラーを使った2階層 | オレンジのアクセント、大胆に明度アップ | ブラーが暗黙のエレベーションを生む |
Linear はリファレンス実装です。サーフェスのステップは十分に狭く、UIは本物の奥行きを持つ1枚のダークなフィールドとして読めます。パープルのアクセントは、焼けることなく、ひと目で Linear のパープルだと分かります。タイポグラフィの階層は、サイズだけでなく、テキストトークンの明度ステップにも頼っています。
Vercel は、完全に貫けばバイナリモデルも成立することを証明しています。3つ目のサーフェスはなし。グレーの状態もなし。すべてが深い背景か、わずかに持ち上がったサーフェスのどちらかで、モノクロを貫く姿勢が、制約ではなくデザインの決断に感じさせます。ほとんどのチームにはこれができません。ステータスカラー、イラスト、エレベーションが必要なブランドの見せ場があるからです。
GitHub の「Dimmed」オプションは、正しい洞察を誤ったスコープに当てはめたものです。彼らはそれをテーマのバリエーションとして作りましたが、本当の教訓は、ウォームな色味のダークサーフェスの方が、クールなデフォルトより長時間の読書に快適だということです。すべてのダークモードは、デフォルトでウォームにすべきです。
正午に反転しただけのものではなく、午前2時に意図的に見えるダークモードがほしいですか? Brainy は、エレベーションモデル、アクセント調整、そして Figma と CSS にそのまま落とせる OKLCH トークンマップを備えた、並列のダークカラーシステムを設計します。Brainy に依頼する。
実戦で使えるダークモードのトークンマップ
以下のトークンマップは、OKLCHカラー座標で本物のダークモードを出荷します。プリミティブは生の値、セマンティクスは役割です。プリミティブは生の値として Figma の variable collection に入れます。セマンティクスはエイリアスとしてプリミティブにマッピングします。この2層構造がトークンシステムのすべてです。
| トークン | 役割 | OKLCH値 | Hex近似 |
|---|---|---|---|
--color-bg | 背景の床 | oklch(0.10 0.012 30) | #191512 |
--color-surface | デフォルトのコンテンツサーフェス | oklch(0.14 0.010 30) | #221e1a |
--color-surface-elevated | カード、パネル | oklch(0.18 0.008 30) | #2c2723 |
--color-surface-overlay | モーダル、メニュー、シート | oklch(0.22 0.007 30) | #35302c |
--color-text-primary | 本文、見出し | oklch(0.93 0.005 60) | #edeae5 |
--color-text-secondary | キャプション、ラベル、メタ情報 | oklch(0.70 0.010 60) | #b0a89e |
--color-text-disabled | 無効状態 | oklch(0.45 0.005 60) | #6e6860 |
--color-border-subtle | 区切り線、ヘアライン | oklch(0.22 0.008 30) | #36302b |
--color-border-default | 入力欄のボーダー、カードのボーダー | oklch(0.28 0.010 30) | #433d37 |
--color-accent | プライマリCTA、アクティブ状態 | oklch(0.72 0.17 25) | #e0816a |
--color-accent-muted | ホバー、セカンダリアクセント | oklch(0.65 0.12 25) | #c27060 |
--color-accent-subtle | アクセント要素の背後の色付き背景 | oklch(0.16 0.04 25) | #2a1e1a |
色相は全体を通して25〜30度(ウォームなコーラルの領域)です。床から天井まで色温度が一貫しているから、システムがまとまります。色相を250度に替えれば Linear 風のパレットになり、200度に替えれば Vercel に近いパレットになります。構造は変わりません。変わるのは色相だけです。
実装では、この表全体が :root[data-theme="dark"] 上の CSS カスタムプロパティにマッピングされます。Figma では、各行が「Dark」モードコレクション内の variable になります。この2コレクション構造こそが、デザインシステムを複数のサーフェスにまたがってスケールさせます。

モード切り替え、ちらつかない実装
間違ったテーマが一瞬映ってしまうことなくモードを切り替えるには、JavaScript が走る前に html 要素にカラースキームを設定します。それ以外のアプローチは、少なくとも1つのエッジケースで間違いです。
パターンはこうです。<head> 内のブロッキングなインライン <script> タグで、localStorage から保存された設定を読みます。カスタムプロパティを参照する CSS が描画される前に、同期的に html 要素へ data-theme="dark" か data-theme="light" を適用します。React は使わない。useEffect も使わない。ちらつきなし。
<script>
const saved = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
document.documentElement.dataset.theme = saved ?? (prefersDark ? 'dark' : 'light');
</script>
このスクリプトは意図的にブロッキングです。レンダリングの前に走ります。スタイルなしコンテンツのフラッシュは、最初のペイントの後に JavaScript でテーマを適用することで起こり、このブロッキングスクリプト1本でそれを完全に解消できます。
システム設定、デフォルト、オーバーライド
デフォルトは OS の設定に従うべきです。ユーザーのオーバーライドは localStorage に保存します。トグルは、system、light、dark の3つの状態を公開すべきです。
2状態のトグルはデザインのミスです。OS をダークに設定していて、アプリにも追従してほしいユーザーは、2つ目のスイッチを管理したくありません。トグルには、保存されたオーバーライドを消して OS の設定に主導させる「system」状態が必要です。ほとんどのアプリは2状態で作り、誰かが OS のテーマを変えてアプリが追従しない理由を不思議に思うたびに、サポートチケットが届きます。
FAQ
ダークモードでアクセントカラーを使うと、OLED のバッテリー持ちに悪影響がありますか?
一般的な UI では、アクセントカラーが占める面積は小さいです。OLED でダークモードによって得られるバッテリー節約は、ほぼ完全に暗いサーフェスの面積から来ています。暗い背景の上のコーラルの CTA ボタンは、消費電力を意味のある形では変えません。効くのは純黒の背景です。効くのは高彩度の全画面イラストです。ボタンではありません。
ライトモードのブランドカラーを、そのままダークモードのアクセントとして使えますか?
調整なしでは使えません。ライトモードのブランドカラーが OKLCH で L 0.55〜0.65 の場合、暗いサーフェスにそのまま使うと、力不足(暗すぎて映えない)か、ハロー(暗い周囲に対して鮮やかすぎる)のどちらかになります。明度を8〜12ポイント上げ、クロマを20〜30パーセント下げ、色相は保ちます。それが調整済みのダークモードのアクセントです。
まだダークモードがないシステムにとって、最小限のダークモードとは何ですか?
Background、surface、surface-elevated、プライマリテキスト、セカンダリテキスト、アクセント。6トークンです。完全ではありませんが、システムです。あらゆるコンポーネントをこの6つの値のどれかにマッピングでき、拡張のためのエレベーションモデルも整っていて、恥ずかしくなく出荷できます。構造のない100個のトークンからではなく、ここから始めましょう。
自動生成のダークモードが許容されることはありますか?
プロトタイプ、社内ツール、アクティブなデザイナーが1人のプロダクトなら、彩度調整つきの自動反転は出発点として許容できます。ブランド基準と実際のユーザーがいるプロダクトの、出荷用ダークモードとしては、ノーです。自動生成のダークモードは、アクセントカラーで失敗し、イラストで失敗し、コンポーネントの状態で失敗します。それは最初のスケッチであって、完成したシステムではありません。
OKLCH はダークモードの構築を楽にしますか?
劇的に楽になります。OKLCH は明度の軸が知覚的に均一なので、エレベーション階層間の明度ステップが、どの色相でも期待どおりに振る舞います。HSL では、オレンジでの5ポイントのステップと、ブルーでの5ポイントのステップは違って見えます。OKLCH では違いません。エレベーションモデルを OKLCH で組めば、アクセントの色相に関係なくステップが一貫して感じられます。OKLCHカラーの詳しい根拠は、その数理を深く解説しています。
セマンティックトークンはライトとダークで異なるべきですか、それともプリミティブだけですか?
違うのはプリミティブです。セマンティクスは同じままです。--color-surface は両方のモードで「デフォルトのコンテンツサーフェス」を意味します。それが指すプリミティブがダークモードでは異なるだけです。これが2層構造のポイントです。コンポーネントはセマンティクスを参照し、セマンティクスはプリミティブを参照します。モード切り替えはプリミティブを再割り当てします。コンポーネントは自動的に、正しく更新されます。
ダークモードシステムが本当に解き放つ変化
本物のダークモードは、並列のデザインサーフェスです。後付けではありません。設定のトグルでもありません。独自の構造、独自の制約、独自のクラフトの判断を持つ、2つ目のサーフェスです。そう扱うチームは、午前2時に意図的に見えるプロダクトを出荷します。スイッチをひっくり返すだけのチームは、誰かが仕上げを忘れたように見えるプロダクトを出荷します。
エレベーションモデルは土台です。彩度を落とすルールとアクセント調整は、クラフトの層です。OKLCH のトークンマップは実装です。ちらつかないモード切り替えを備えた3状態トグルは、出荷の条件です。すべてがつながっています。良い結果がほしいなら、どれも省けません。
並列システムを作りましょう。マップを出荷しましょう。違いは見えてきます。
正午に反転しただけのものではなく、午前2時に意図的に見えるダークモードがほしいですか? Brainy は、エレベーションモデル、アクセント調整、そして Figma と CSS にそのまま落とせる OKLCH トークンマップを備えた、並列のダークカラーシステムを設計します。Brainy に依頼する。
drafts/dark-mode-color-systems.md に保存します。
Want a dark mode that looks intentional at 2 a.m. instead of inverted at noon? Brainy designs parallel dark color systems with the elevation model, accent calibration, and the OKLCH token map ready to drop into Figma and CSS.
Get Started




