Web サイトやアプリケーションの設計・開発において、「一度決めたデザインやカラーテーマを後から変更すると莫大な手戻り工数がかかる」という前提で意思決定を先送りしてしまうケースは少なくありません。

特に外部へ開発を発注する立場や、プロジェクトを推進する技術リーダーにとって、デザインの大幅なトーン変更やリブランディングは「できれば避けたい重い決定」と捉えられがちです。

しかし、実際の変更コストは何によって決まるのでしょうか。

設計決定の撤回コスト(Reversal Cost)とは、下した決定を覆す際に必要となる実装の修正工数およびリスクの総量であり、決定自体の重要度ではなく、その決定に関する値がコードベース全体にどれだけ散らばっているか(集約度)によって決定されます。

本記事では、当サイト Meetsource のリニューアル時に「ブログはダークトーンを維持する」と決定した方針を、その日の深夜(約 12 時間後)に全面撤回して明るいトーンへ統一した際の実体験を取り上げます。面全体のトーン反転という大きな方針転換でありながら、変更 diff はわずか 5 ファイル・35 行 で完了しました。

なぜ方針の撤回が 35 行で済んだのか、そしてその 35 行の内訳は何だったのか。実測データをもとに、変更容易性(Modifiability)を支えるミニマムなトークン設計の要点を解説します。

はじめに: 「後から変えると高くつく」という思い込み

設計決定の撤回コストと変更容易性

ソフトウェア工学の国際規格である ISO/IEC 25010 では、ソフトウェア製品品質の主特性の一つである「保守性(Maintainability)」の副特性として「修正性/変更容易性(Modifiability)」を定義しています1。変更容易性とは、「欠陥を混入させることなく、また既存の製品品質を低下させることなく、製品やシステムが効果的かつ効率的に修正され得る度合い」を指します。

変更容易性の本質は「影響範囲の局所化(Localization of Change)」にあります。将来の変更要求に対して、修正すべき箇所が単一のモジュールや設定に閉じているかどうかが、保守コストを左右します。

また、Amazon 創業者のジェフ・ベゾスは有名な株主への手紙の中で、意思決定を次の 2 つのタイプに分類しました2

  1. Type 1(不可逆な決定 / One-way doors): 一度通り抜けると後戻りできない、重大かつ不可逆な決定。時間をかけて慎重に合議・検討すべきもの。
  2. Type 2(可逆的な決定 / Two-way doors): 下した決定が最適でなくても、ドアを開けて再び戻れる可逆的な決定。迅速に小さなチームで決定を下すべきもの。

多くのプロジェクトで意思決定が滞る根本的な原因は、本来なら Type 2(可逆的)であるはずの UI や配色の決定が、実装上の「値の散らばり」によって Type 1(不可逆・高コスト)へ変質してしまうことにあります。

「ブログはダーク維持」の決定から 12 時間後に起きた全面撤回

当サイトのリニューアルを進めていた際、まさにこの「方針の撤回」が起きました。

午前中の意思決定ログでは、コーポレートサイト(トップ、サービス、実績)の明度を上げた事業側トーン(#dde4f2 基調)に寄せる一方で、「技術ブログは読者層が異なるため、従来のダーク・エンジニアトーンを維持する」と明示的に決定しました。

しかし同日の深夜、サイト全体の統一感やブランドの視認性を考慮し、「ブログも含めて全面を事業側トーンに統一したい」という方針転換が行われました。午前に決定した方針を、わずか 12 時間後に全面撤回することになったのです。

通常であれば「全記事テンプレートのスタイル書き直し」「コールアウトやコードブロックの配色再設計」「CSS の大掛かりなリファクタリング」が必要になりそうな場面ですが、実際の実装は一瞬で完了しました。

実測: 決定を覆した日の diff はわずか 35 行だった

撤回コミットにおける修正ファイルの内訳(5 ファイル・35 行)

ブログのダーク限定方針を撤回し、面全体を明るいトーンへ統一したコミットの diff 統計は以下の通りです。

 astro.config.mjs               |  5 +++++
 src/layouts/Layout.astro       |  2 +-
 src/pages/blog/[...slug].astro | 13 +++++++------
 src/pages/blog/index.astro     |  2 +-
 src/styles/global.css          | 13 ++++++++++---
 5 files changed, 24 insertions(+), 11 deletions(-)

合計 5 ファイル、24 挿入 / 11 削除(合計 35 行の差分)でした。

この 35 行の変更だけで、ブログ一覧画面、全 47 本の個別記事、記事内の見出し・本文・引用・コールアウト・コードブロックに至るまで、すべての面が明るい配色へ反転しました。個別の記事ファイル(Markdown)には 1 行も手を加えていません。

面全体を反転させた CSS 変数のカスケード構造

面全体のトーン反転が 35 行で完了した最大の理由は、サイト全体のスタイルが CSS カスタムプロパティ(CSS 変数) を介して設計されていたためです34

ベースとなるレイアウトテンプレート(Layout.astro)において、最上位の <html> タグに data-tone="business" 属性を付与できるように構成されていました。

<!-- src/layouts/Layout.astro -->
<html lang="ja" data-tone={tone}>

そしてグローバル CSS 側で、この属性セレクタをスコープとして配色トークンを上書き定義しています。

/* src/styles/global.css */
:root {
  --color-bg: #1e1e2e;
  --color-text-main: #cdd6f4;
  --color-border: #45475a;
}

[data-tone="business"] {
  --color-bg: #dde4f2;
  --color-text-main: #1e2030;
  --color-border: #bcc8e2;
}

ブログの個別ページ([...slug].astro)や一覧ページ(index.astro)で <Layout tone="business"> を渡すだけで、CSS のカスケード(継承)規則に従って DOM ツリー配下の全要素が参照する変数値が一括で再評価されます。

コンポーネント側の CSS クラスや HTML 構造を一切書き換えることなく、最上位スコープの 1 属性を切り替えるだけで面全体のトーンが反転したのです。

露呈: 35 行の内訳は「集約し損ねていた直書き値」だった

無修正で反転した面と、露出した直書き色

では、なぜ 35 行の diff が必要だったのでしょうか。

内訳を精査すると、そのほとんどは「CSS 変数に集約し損ねていた直書き値」の回収作業でした。

記事詳細テンプレート([...slug].astro)には、過去の実装で Catppuccin Mocha(ダーク用パレット)の色コードが直接記述(ハードコード)されていた箇所が存在していました5

/* 修正前の [...slug].astro */
.post-content {
  color: #bac2de; /* Mocha Subtext 1(薄い青灰色) */
}
.post-content :global([data-callout='tip']) {
  border-left-color: #a6e3a1; /* Mocha Green(薄い黄緑) */
}
.post-content :global([data-callout='warning']) {
  border-left-color: #f9e2af; /* Mocha Yellow(薄い黄色) */
}
.post-content :global(mark) {
  background-color: rgba(249, 226, 175, 0.25);
}

ダーク背景(#1e1e2e)では綺麗に見えていたこれらの色も、背景色が明るいトーン(#dde4f2)に反転した瞬間、コントラストが極端に低下して文字が読めなくなるという破綻が発生しました。

方針を変更したまさにその瞬間に、過去の「直書き」という設計の手抜きが白日の下に晒されたのです。

修正では、これらの直書き値を排除し、グローバル CSS に新設した --color-success / --color-warning / --color-text-muted というセマンティックトークンへ置き換えました。

/* 修正後の [...slug].astro */
.post-content {
  color: var(--color-text-muted);
}
.post-content :global([data-callout='tip']) {
  border-left-color: var(--color-success);
}
.post-content :global([data-callout='warning']) {
  border-left-color: var(--color-warning);
}
.post-content :global(mark) {
  background-color: rgba(var(--color-warning-rgb), 0.25);
}

35 行の diff の大半は、トーン反転そのものの作業ではなく、「集約できていなかった負債をトークン体系へ回収する作業」だったのです。

Shiki シンタックスハイライターのテーマ切り替え

本文色と並んで課題となったのが、技術ブログの核であるコードブロックのシンタックスハイライトでした。

当サイトで採用している静的サイトジェネレーター Astro では、ビルド時に Shiki を用いてコードブロックを静的解析し、HTML を生成しています67

既定の github-dark テーマはダーク背景専用であるため、明るい背景ではコードの可読性が著しく低下します。そこで、Astro の設定ファイル(astro.config.mjs)に以下の 5 行の設定を追加し、ダークパレット(Catppuccin Mocha)と対を成すライトパレット catppuccin-latte を指定しました。

// astro.config.mjs
markdown: {
  shikiConfig: {
    theme: 'catppuccin-latte',
  },
}

この設定変更だけで、全 47 記事に含まれるすべてのコードブロックが、ビルド時に一括で明るい背景に適した配色へ変換されました。

設計: 大掛かりなツールなしで始める「2層トークン」のミニマム集約

プリミティブ層とセマンティック層の分離

デザイントークンの運用と聞くと、Figma Variables と Style Dictionary を CI/CD で連携させるような大規模な仕組みを想像しがちです。しかし、W3C Design Tokens Community Group (DTCG) が策定する標準仕様の思想は、はるかにシンプルです89

本質は、 「プリミティブ(具体的な値)」と「セマンティック(役割・意味)」の 2 層を分離すること にあります。

/* 1. プリミティブ層(生の値) */
:root {
  --color-catppuccin-green: #a6e3a1;
  --color-forest-green: #106b2e;
}

/* 2. セマンティック層(役割と文脈) */
:root {
  --color-success: var(--color-catppuccin-green); /* ダーク時の成功色 */
}

[data-tone="business"] {
  --color-success: var(--color-forest-green);     /* ライト時の成功色 */
}

コンポーネント側は常に --color-success(セマンティック層)だけを参照します。これにより、将来テーマを追加したり配色方針を変更したりする場合でも、セマンティック層が指す参照先を差し替えるだけで、全コンポーネントの挙動を安全に制御できます。

ヘッドレス Chrome によるコントラスト実機検証

トーン反転を行う際、感覚や見た目だけに頼らず、Web Content Accessibility Guidelines (WCAG) 2.1 のアクセシビリティ基準を満たしているかを客観的に検証しました1011

WCAG 2.1 達成基準 1.4.3 (Level AA) では、通常の本文テキストに対して 4.5:1 以上 のコントラスト比を要求しています。

「相対輝度」とは色の明るさを 0(黒)〜 1(白)の数値で表したもので、この値の比率からコントラスト比が決まります。事業側トーンの地色 #dde4f2 の相対輝度は $L \approx 0.7736$(かなり明るい)で、これに対して新設したトークン値が基準を満たすかを計算して選定しました。

  • --color-success: #106b2e(相対輝度 $L \approx 0.1079$ の緑): コントラスト比は約 5.215:1 で、基準の 4.5:1 を上回ります
  • --color-warning: #6e5410(相対輝度 $L \approx 0.0966$ の黄土色): コントラスト比は約 5.618:1 で、基準の 4.5:1 を上回ります

さらに、Google Chrome をヘッドレスモード(Google Chrome.app --headless=new --screenshot)で駆動させ、トップページ、ブログ一覧、記事詳細(コードブロックやコールアウトを含む)のレンダリングキャプチャを取得して実機での視認性を検証しました。

数値的な根拠と実機キャプチャを組み合わせることで、方針転換後も品質を損なうことなく安全にリリースできました。

比較と考察: 決定を重くする構造 vs 軽くする構造

直書きスタイルとトークン集約スタイルの比較

値が実装各所に散らばっている構造と、トークンに集約された構造の違いを整理すると以下のようになります。

評価軸直書きスタイル(値が分散)トークン集約スタイル(値が集約)
撤回時の修正規模全コンポーネント・CSS(数十〜数百ファイル)スコープ定義・トークン定義(数ファイル・数十行)
意思決定への心理的影響「後から変えられない」ため決定を先送り・長期化「違ったらすぐ戻せる」ため初期決定が迅速化
手戻りリスク・修正漏れ高(直書きの見落としやコントラスト崩れの多発)極小(1箇所の変更がシステム全体に安全に波及)
導入に必要な初期コストゼロ(その場限りの記述)極小(CSS変数による2層の命名ルール定義のみ)

スタイル値をトークンに集約する設計は、単なるコードの綺麗さの問題ではなく、チームの意思決定の先送りを防ぎ、開発のアジリティを高めるための事業戦略的投資です。

可逆的な決定(Two-way doors)を支える設計アーキテクチャ

ジェフ・ベゾスが提唱した「Type 2 の決定(Two-way doors: 可逆的な決定)」を組織で実践するためには、それを支える技術的アーキテクチャが不可欠です2

「一度決めたら変えられない」と感じるとき、原因は意思決定の内容そのものの重さにあるのではなく、実装の結合度と分散度にあります。

設計の初期段階で値をトークンに集約しておけば、配色の決定やデザインの試行錯誤はいつでも通り抜け直せる「Two-way door」に留まります。撤回コストが 35 行で済むと分かっていれば、チームは合議に時間を浪費することなく、確信を持った意思決定を素早く下すことができます。

よくある質問(FAQ)

Q1: 小規模なサイトや個人開発でもデザイントークンを導入する価値はありますか?

はい、大いにあります。

Figma との自動連携ツールや複雑なビルドパイプラインを構築する必要はありません。CSS ファイルの冒頭に CSS 変数を用いてプリミティブとセマンティックの 2 層を定義するだけで十分な恩恵が得られます。

本記事の実例のように、たった 1 つの属性切り替えでサイト全体のトーンを反転できるようになり、将来の仕様変更やリブランディングに伴う修正工数を劇的に削減できます。

Q2: 既にコード内に直書き値が散らばっている既存プロジェクトは、どこから改善すべきですか?

最も頻繁に変更される「色」と「背景色」の 2 系統から段階的にトークン化することをおすすめします。

余白(spacing)やフォントサイズ、角丸など、すべてのプロパティを一括でトークン化しようとすると作業が肥大化し、途中で頓挫しやすくなります。

まずはベース背景色、本文テキスト色、プライマリブランド色の 3 つを :root の CSS 変数に切り出し、コンポーネント側の直書きを var() 参照へ順次置き換えていくアプローチが最も効果的です。

おわりに: 「後から変えられる安心感」が意思決定を速くする

意思決定の撤回コストは、決定の重さではなく、値の散らばり具合(集約度)で決まります。

もし現在進行中のプロジェクトで「仕様やデザインを後から変えられない」と感じているなら、システムの構造上本当に変えられないのか、それとも単に値が各ファイルに散らかっているだけなのかを点検してみてください。

変更容易性の高い設計があれば、完璧な正解が出るまで議論を先送りする必要はありません。まず決めて実装し、違っていれば最小の diff で修正すればよいのです。

後から覆せる柔軟なフロントエンド設計やリファクタリングのご相談は、コンタクトフォーム よりお気軽にお問い合わせください。

Footnotes

  1. ISO/IEC 25010:2011 Systems and software engineering ISO/IEC, 2011年3月1日制定(2023年改定)。修正性・変更容易性(Modifiability)の定義。

  2. Amazon.com, Inc. 2015 Letter to Shareholders Jeff Bezos (Amazon.com, Inc.), 2016年4月5日公開 (SEC Form 8-K/A Exhibit 99.1)。Type 1(不可逆な決定)と Type 2(可逆的な決定・Two-way doors)の意思決定フレームワーク。 2

  3. CSS Custom Properties for Cascading Variables Module Level 1 W3C Recommendation, Tab Atkins Jr. / David Baron 監修, 2015年12月3日公開。CSS カスタムプロパティの構文定義およびカスケード規則。

  4. CSS カスタムプロパティ(変数)の使用 MDN Web Docs, Mozilla, 2024年更新。:root および属性セレクタスコープでの変数宣言とコンポーネントへの動的波及。

  5. Catppuccin Palette Specifications Catppuccin Org, 2023年公開。Catppuccin Mocha(Subtext 1 #bac2de, Green #a6e3a1, Yellow #f9e2af)と Latte パレット仕様。

  6. Shiki: Themes Shiki Org (Pine Wu), 2024年公開。Shiki のシンタックスハイライトテーマ一覧および catppuccin-latte の適用仕様。

  7. Markdown & Shiki Astro Core Team, 2024年更新。Astro の astro.config.mjs における shikiConfig.theme 設定構文と静的生成。

  8. Design Tokens Format Module W3C Design Tokens Community Group, 2025年10月仕様公開。トークンの $type / $value 仕様およびエイリアス(参照)による多層トークン構造の標準規約。

  9. W3C Design Tokens Community Group W3C Community Group, 2021年設立。ツール・プラットフォーム非依存のデザイントークン標準化活動。

  10. Web Content Accessibility Guidelines (WCAG) 2.1 W3C Recommendation, 2018年6月5日公開(2023年9月21日改定)。達成基準 1.4.3 (Contrast Minimum: Level AA 4.5:1) の仕様および相対輝度計算式。

  11. WAIC 達成基準 1.4.3: コントラスト (最低限) を理解する ウェブアクセシビリティ基盤委員会 (WAIC), 2018年公開。コントラスト比 4.5:1 の実務的解釈と本文テキストへの適用基準。