
連載:AIエージェントチームと編み上げるデジタルクラフト共同開発記②
第2回:CSS変数×Tailwind CSS:破綻しない二層構造トークン設計の美学
現代のフロントエンド開発において、スタイリングの生産性を支える存在となったTailwind CSS。しかし、その手軽さゆえに、クラス名に直接カラーコードをハードコーディングしてしまうケースが少なくありません。
例えば、text-[#24646d] のように、デザインシステムで定義されたブランドカラーをそのまま即値としてクラス名に散布してしまう設計です。これは、開発の初期段階では迅速に動作するものの、プロジェクトが成長するにつれて大きな保守性の課題を引き起こします。
今回は、FTF Flowプロジェクトが京都とイスタンブールという二つの強烈なデザインテーマを切り替える中で辿り着いた、「破綻しない二層構造トークン設計」と「CSSマテリアルオーバーライド」の美学について、客観的な実装コードを交えて解説します。
ハードコーディングがもたらす「保守性の摩擦」
個別の要素に対して bg-[#f9f9f7] や text-[#1a3a3a] のように直接値を書き込むアプローチは、コードの可読性を下げ、デザイン変更時の手戻りコストを大幅に増加させます。
例えば、ブランドのプライマリーカラーを微調整する場合や、ダークモードなどの新しいテーマを導入する場合、無数のファイルから該当するカラーコードを検索・置換しなければならず、不整合の発生リスクが高まります。
プレミアムなデジタルクラフトにおいては、カラーやフォントといったデザインの構成要素は「即値」ではなく、「システム(トークン)」として中央管理されるべきです。

Tailwind CSS v4 で実現する「二層構造トークン」の合理性
FTF Flowサイトの構築では、Tailwind CSS v4(tailwindcss および @tailwindcss/vite 4.1.14)を採用しています。これにより、従来の tailwind.config.js によるJavaScriptベースの設定ではなく、メインCSSファイル内の @theme ディレクティブを使用した洗練されたデザインシステムを構築しています。
本設計の真髄は、「生のCSS変数(第一層)」と「Tailwind CSSのユーティリティマッピング(第二層)」を結合した二層構造トークンにあります。
この二層構造トークンは、エンジニアだけでなくプロダクト全体のデザイン管理において強力な恩恵をもたらします。非エンジニアの方にもイメージしやすいよう、「ホテルの照明システム」に例えてみましょう。
・第一層:大元の主電源・集中管理パネル(生のCSS変数)
ホテルの管理室にある、建物全体の電気や照明設定を司るマスターコントロールです。ここでは「ロビーの標準的な明るさはこれ」「客室のベース光量はこれ」という大元の基準値(カラーやフォントの具体的な値)を決定します。
・第二層:客室のベッドサイドにある個別の調光リモコン(Tailwindユーティリティ)
宿泊客が実際に操作するリモコンです。このリモコンは、大元の主電源から配線を引き込んでおり、ユーザーは「暗め」「標準」「明るめ」といった使いやすい選択肢(bg-cc-primary などのクラス)を選ぶだけで、適切な照明が得られます。
この二層構造がなぜ合理的なのでしょうか。例えば、ホテルのコンセプトを「京都の静謐な灯り」から「イスタンブールのエキゾチックな光」へと変更する場合を考えてみます。 大元の集中管理パネル(第一層)の設定値を差し替えるだけで、各部屋にあるリモコン(第二層)の物理的な配線やボタンのラベルは一切変更することなく、すべての客室の光の挙動が即座に切り替わります。
この「配線(実装コード)を変えずに、大元(変数)を変えるだけで全体の雰囲気を一変できる」というメリットこそが、二層構造トークン設計がもたらす価値です。
第一層:意図を宿す生のCSS変数
まずは、プロダクトの共通CSSファイルにおいて、デザインシステムから書き出された生のCSS変数を定義します。ここでは、カラー、フォント、シャドウ、角丸などのデザイントークンを、純粋なCSSのカスタムプロパティとして定義します。
/* src/index.css より抜粋 */
@theme {
--color-cc-primary: #24646d; /* ブランドの主色 */
--color-cc-primary-container: #407d86; /* コンテナ用の主色 */
--color-cc-surface: #f9f9f7; /* 基本背景色 */
--color-cc-surface-low: #f0f0eb; /* やや暗い背景色 */
--color-cc-on-surface: #1a3a3a; /* 背景上の主要文字色 */
--color-cc-accent: #90463a; /* アクセントカラー */
--font-serif: "Noto Serif JP", ui-serif, Georgia, serif;
--font-sans: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
--shadow-ambient: 0 12px 32px -4px rgba(26, 58, 58, 0.08);
--radius-xl: 1.5rem;
}
第二層:Tailwind CSSユーティリティへの自動マッピング
Tailwind CSS v4の仕様により、--color- で始まるカスタムプロパティは、自動的に bg-cc-primary、text-cc-primary、border-cc-primary といったユーティリティクラスへマッピングされます。
同様に、--font-serif は font-serif、--shadow-ambient は shadow-ambient として機能します。これにより、インラインクラスの簡潔さと、CSSカスタムプロパティが持つ動的で標準的な制御能力がシームレスに融合します。
Viteの再ビルドを伴わない、動的テーマ切り替えの美学
この二層構造トークン設計が真価を発揮するのが、テーマの動的切り替えです。一般的なフレームワークでは、テーマの切り替えにビルドプロセスの再実行やJavaScriptによるスタイルオブジェクトの再計算を伴うことがあります。
しかし、生のCSS変数を第一層に配置しているため、HTMLのルート要素(<html> や <body>)に theme-kyoto や theme-istanbul といったクラスを付与し、その配下でCSS変数の値のみを上書きするだけで、クライアント側で即座にサイト全体のテーマが切り替わります。
図解①:二層構造トークンの伝播フロー

CSSマテリアルオーバーライド:共通HTML骨格とテクスチャの分離
FTF Flowのもう一つの独自基盤が、「HTML構造(共通骨格)」と「CSS背景テクスチャ表現(マテリアル)」の分離設計です。
これを日常の例で例えるなら、**「マンションの共通の間取り(骨格)」と「それぞれの部屋の壁紙やインテリア装飾(マテリアル)」**の関係に似ています。
共通HTML骨格(マンションの骨組み・間取り)
柱の位置や部屋の間取りは、すべての住戸で共通して設計されています。これがHTMLのマークアップに相当します。
CSS背景テクスチャ(壁紙やインテリア)
同じ間取りでありながら、ある部屋は「京都の伝統的な和紙」の壁紙を貼り、別の部屋は「イスタンブールのエキゾチックなモザイクタイル」の壁紙を貼ります。これがCSSのグラデーション数式による背景表現に相当します。
この骨組みと装飾を分離するアプローチにより、開発チームは「部屋の間取り(HTML)」を一度定義してしまえば、それ以降は骨組みに手を加えることなく、CSSという「壁紙」を貼り替えるだけで、世界観を自在に分岐させることが可能になります。これにより、デザインの再現性と開発効率が向上します。
同一の共通マークアップ骨格(.washi や .tile などのクラス)を維持したまま、京都テーマとイスタンブールテーマのそれぞれが、CSSのグラデーション数式をオーバーライドすることで、異なる情緒のテクスチャを描き出します。
1. 和紙 (washi):静寂の繊維とトルコのモザイク
京都テーマでは、複数の円形グラデーションと微細なリピートグラデーションを重ね、和紙の温かみある繊維質をシミュレートしています。
/* 京都テーマ:和紙(washi) */
.washi {
background:
radial-gradient(circle at 20% 18%, rgba(255,255,255,0.85), transparent 45%),
radial-gradient(circle at 72% 66%, rgba(219, 205, 178, 0.55), transparent 48%),
repeating-radial-gradient(circle at 45% 55%, rgba(255,255,255,0.16) 0 1px, transparent 2px 6px),
#f1e8d8;
}
一方でイスタンブールテーマでは、トルコ伝統の幾何学モザイクを想起させる複数の楕円・円錐グラデーション(repeating-conic-gradient)を重ね、さらに ::after 擬似要素によってアラベスク調の境界模様を精緻に重ね合わせています。
/* イスタンブールテーマ:和紙(washi)の一部 */
.washi {
background:
radial-gradient(circle at 50% 50%, #a85d4f 0 4px, transparent 5px),
repeating-conic-gradient(from 45deg at 50% 50%, rgba(29, 47, 79, 0.28) 0deg 13deg, transparent 13deg 28deg),
linear-gradient(135deg, #f7f3ea 0%, #e9e2d4 100%);
background-size: 76px 76px, 76px 76px, cover;
}
2. 木目 (wood):直線美と寄木細工の交差
京都テーマでは、2度の緩やかな傾斜を持たせた線形リピートグラデーション(repeating-linear-gradient)によって、伝統的な杉の柾目を直線的に引き立てます。
イスタンブールテーマでは、異なる角度(28度と118度)のグラデーションを交差させ、光の当たる階調を加えることで、複雑な寄木細工のような立体感と深みを表現しています。
/* イスタンブールテーマ:木目(wood) */
.wood {
background:
radial-gradient(circle at 25% 24%, rgba(255,255,255,0.42), transparent 28%),
repeating-linear-gradient(118deg, transparent 0 12px, rgba(255,255,255,0.18) 12px 14px, transparent 14px 26px),
repeating-linear-gradient(28deg, #8e6032 0 3px, #d7a154 3px 6px, #a86d37 6px 9px, #f0c875 9px 12px);
}
3. タイル (tile):和瓦の陰影と釉薬の透明反射レイヤー
京都テーマでは、京瓦(平瓦・鱗瓦)の重なりを意識した、半円形(repeating-radial-gradient)のリピート背景を組み合わせ、日本の瓦が持つリズミカルな陰影を表現しています。
対するイスタンブールテーマでは、イズニック・タイルの鮮烈なブルーと碧のグラデーションの上に、::before でモザイクタイルの目地を描き、::after の mix-blend-mode: screen によって釉薬(うわぐすり)の滑らかな光沢感と透明な反射レイヤーを表現しています。
/* イスタンブールテーマ:タイル(tile)の光沢レイヤー */
.tile::after {
content: "";
position: absolute;
inset: 0;
background:
repeating-linear-gradient(172deg, transparent 0 16px, rgba(255,255,255,0.24) 17px 19px, transparent 20px 37px),
linear-gradient(90deg, rgba(255,255,255,0.08), rgba(29,47,79,0.18));
mix-blend-mode: screen;
}
4. 金箔 (goldleaf) & 友禅・アラベスク (yuzen) の対比
京都テーマの金箔は、上品なきらめきと不均等な陰影による静かな風格を持たせています。イスタンブールテーマの金箔は、ビザンツ帝国の金モザイクのように赤紫・金色・ターコイズをダイナミックにブレンドし、格子状の細かな幾何学ラインを重ねることで、オリエンタルな絢爛さを描いています。
また、京都テーマの友禅(yuzen)は流水紋や花筏を想起させる朱・金・鶯色の楕円グラデーションを散布し、イスタンブールテーマのアラベスクは、宮廷模様を連想させる深い藍色と赤銅色をベースに、二層の同心円グラデーションによってモスクのドーム天井のような吸い込まれるような意匠を完成させています。
図解②:共通マークアップ骨格とCSSオーバーライドの相関図

イージング共通規格とマイクロアニメーション:「時の手触り」をデザインする
Webにおけるユーザー体験の心地よさは、静的な美しさだけでなく、操作した瞬間に伝わる「時間軸のデザイン」によって深まります。
FTF Flowプロジェクトでは、過度な視覚的刺激を抑えつつ、情緒的で洗練された高級感を与えるため、あえて時間を引き延ばしたマイクロインタラクションと、長尺の背景揺らぎを採用しています。
このアプローチは、単に「遅く動かす」ことだけが目的ではありません。25秒〜30秒の背景の呼吸や、3秒のスローズームといった時の流れを設定することで、ユーザーに「時の手触り、静謐さ、丁寧な手仕事のような高級感」という感性的なメリットを届けます。
情報があふれ、目まぐるしく変化する現代のWebにおいて、コンマ数秒でコンテンツが切り替わる挙動は、ユーザーを急かす焦燥感を生みがちです。しかし、伝統工芸品を鑑賞するときのように「時間がゆっくりと流れる感覚」を画面上にデザインすることで、プロダクトの品格を高め、ブランドが持つ静謐で洗練された世界観へ引き込みます。

1. 25秒〜30秒周期の「背景の呼吸」
大自然と都市の緩やかな呼吸を表現するために、25秒周期のキーフレームアニメーション(subtle-breath)とオーロラを模したグラデーション(neural-aurora)を実装しています。
/* 呼吸するようにゆっくりと伸縮・移動する背景 */
@keyframes subtle-breath {
0% { transform: scale(1.03) translate(0, 0); }
50% { transform: scale(1.06) translate(-0.5%, 0.5%); }
100% { transform: scale(1.03) translate(0, 0); }
}
.animate-breath {
animation: subtle-breath 25s ease-in-out infinite;
}
一般的なWebサイトのアニメーションが0.3秒前後で終わるのに対し、25秒という長尺の時間をかけることで、ユーザーにアニメーションであることを意識させず、無意識下で情緒的で落ち着いた印象を与えています。
これは、トップページ(Homeポータル)を訪れた瞬間に広がる、メインビジュアル(ヒーローエリア)の背景の動きです。巨大なグラデーション光球が、深海の中でゆらゆらと揺れる神秘的な海の呼吸を表現しています。
2. 2.2秒のスクロールインジケーター
スクロールインジケーターには、2.2秒周期の滑らかな伸縮イージングを適用し、線の伸縮開始点と終了点を transform-origin で制御することで、上から下へと光が通り抜ける流動的な挙動を数行のCSSで表現しています。
@keyframes scroll-line {
0% { transform: scaleY(0); transform-origin: top; }
50% { transform: scaleY(1); transform-origin: top; }
50.1% { transform: scaleY(1); transform-origin: bottom; }
100% { transform: scaleY(0); transform-origin: bottom; }
}
.animate-scroll-line {
animation: scroll-line 2.2s cubic-bezier(0.15, 0.85, 0.35, 1) infinite;
}
これは、トップページのファーストビュー最下部に静かに佇む、『Scroll Down』を促す極細のインジケーター線の動きです。上から下へとスッと光の糸が通り抜けて消えるような上品な挙動で、ユーザーの視線を次のセクションへと誘います。
3. 情緒を揺さぶる「3秒のスローズーム」
キュレーション記事カードでは、ホバー時に急激に拡大するのではなく、duration-[3000ms](3秒)という、一般的なWebサイトと比較して極めてスローなトランジションを設定し、カバー画像を極めてゆっくりと scale-[1.02] にズームさせます。
これは、日本の伝統工芸を展示する『Curation(キュレーション)』ページの各作品カードで採用されています。カードにマウスを重ねた際、急に拡大するのではなく、3秒という極めて長い時間をかけてじわーっと拡大し、色づいていく演出です。
この「あえてゆっくり見せる時間のデザイン」が、静謐で丁寧な手仕事のような佇まいを生み出し、プレミアムブランドにふさわしい心地よいインタラクションを実現しています。
結び
デザイントークンを二層構造で整理し、CSSの力によってHTML構造からテクスチャを高度に分離します。
このアプローチは、単なるコードの保守性向上にとどまりません。デザイナーとエンジニア、さらには開発に参加する複数のAIエージェントにとって、共通の「言葉」としてデザインシステムが機能するための強力なインフラとなります。
論理と感性が融合したとき、Webサイトは単なる情報伝達のツールを超えて、手触りを持つ「デジタルクラフト」になるのだと思います。
連載予告
次回|第3回:京都×イスタンブール:CSSマテリアルオーバーライドによる多文化的テーマ切り替えの実践
同一のHTML構造を維持しながら、京都の和紙や京瓦、イスタンブールのモザイクタイルやアラベスクといった全く異なる情緒をCSSのグラデーション数式のみで切り替える動的テーマ実装の裏側を、JavaScriptの実装コードと共に詳しく解説します。
次々回|第4回:React×TypeScriptで組む:変更に強く型安全なコンポーネント設計
デザインシステムは作ってからが本番。画面の部品を増やしていくうちに「少しのデザイン違いでコードが複雑になり、修正するだけでバグが出る……」といった罠に陥りがちです。 第4回では、そうしたプログラムの複雑化(Prop地獄)を防ぎ、デザインシステムが持つ美しさをエンジニアの手で破綻なく保ち続けるための、型安全で柔軟なコンポーネントの設計手法を解説します。初心者でもコンポーネントがレゴブロックのように美しく組み上がるイメージが湧く、持続可能なコード設計の旅へご案内します。
この連載「AIエージェントチームと編み上げるデジタルクラフト:FTF Flow共同開発記」は、FTF Flow開発チームがお届けしています。