4つのサイトの UI を一人で手入れしていると、いちばん削りたいのは「画面を考える作業」と「それを実装する作業」の往復です。デザインツールで角丸やボタンの余白を決めて、コードに戻って同じ数字を打ち直し、ビルドして見比べて、また少しずれている——この翻訳ロスが、機能そのものより時間を食っていました。
6/17 に発表された Claude Design の更新は、ここに直接効きます。デザインシステムのインポート、Claude Code とのより緊密な連携、キャンバスの直接編集、エクスポート形式の追加が入り、なかでも大きいのが Claude Design がローカルのコードベースを起点に動けるようになった 点です。生成されるアセットに既存プロダクトの要素が反映され、そのまま Claude Code へ受け渡して実装させられます(Pro・Max・Team・Enterprise のベータ機能です)。
ただ、ツールが繋がっただけでは往復は消えません。私自身が個人開発で 4 サイトを回す中で効いたのは、「両方のツールが同じ語彙を見ている」状態を自分で作っておくことでした。本稿はその段取りを、コピーして使えるコードと一緒に整理します。
往復が重くなる本当の理由
デザインツールとコードがずれるのは、センスの問題ではなく 正本(source of truth)が二重化している からです。デザイン側に「角丸 12px・主ボタンは #5B5BD6」があり、コード側にも別の場所に同じ値がハードコードされている。片方を直してももう片方が古いままになり、AI に実装させても「それっぽいけど微妙に違う」結果が返ってきます。
Claude Design がローカルコードベースを読めるようになった意味は、ここにあります。コード側に置いたトークンを Claude Design が参照し、Claude Code も同じトークンを参照する。正本を一つにすれば、両方のツールは翻訳ではなく参照で揃います。 まずやるべきは新機能を触ることではなく、この一本化です。
全体のワークフロー
順番だけ先に示します。後続の各ステップで具体化します。
ステップ やること 正本になるファイル
1 デザイントークンを単一の正本にする design/tokens.json
2 CSS 変数を機械生成する src/styles/tokens.css(生成物)
3 CLAUDE.md にデザイン文脈を固定する CLAUDE.md
4 Claude Design の画面案を Claude Code へ受け渡す 受け渡しプロンプト
5 生成 UI を既存システムに揃え、検証する 検証スクリプト
ポイントは、1〜3 が「環境を整える一度きりの作業」で、4〜5 が「画面ごとに繰り返す作業」だということです。前半に投資するほど、後半の手戻りが減ります。
ステップ1: トークンを単一の正本にする
まず、色・余白・角丸・タイポグラフィを一つの JSON にまとめます。Claude Design のインポートも Claude Code の実装も、最終的にここを見ます。
// design/tokens.json — デザインと実装の唯一の正本
{
"color" : {
"brand" : { "value" : "#5B5BD6" },
"fg" : { "value" : "#1A1A2E" },
"fg-muted" :{ "value" : "#5C5C70" },
"bg" : { "value" : "#FFFFFF" },
"bg-subtle" :{ "value" : "#F5F5FA" },
"border" : { "value" : "#E2E2EC" }
},
"radius" : { "sm" : { "value" : "8px" }, "md" : { "value" : "12px" }, "lg" : { "value" : "20px" } },
"space" : { "1" : { "value" : "4px" }, "2" : { "value" : "8px" }, "3" : { "value" : "12px" }, "4" : { "value" : "16px" }, "6" : { "value" : "24px" } },
"font" : { "size-body" : { "value" : "15px" }, "size-h2" : { "value" : "22px" }, "line-body" : { "value" : "1.8" } }
}
{ "value": ... } という入れ子は冗長に見えますが、後でメタ情報(説明・非推奨フラグなど)を足せる余地を残すためです。私はこの一段を省いて後から全置換する羽目になったことがあるので、最初から入れておくことを推奨します。
ステップ2: CSS 変数を機械生成する
トークンを手でコピーすると、そこで正本が二重化します。生成スクリプトを一本通して、CSS は必ず JSON から作る ようにします。
// scripts/build-tokens.mjs — tokens.json から CSS 変数を生成する
import { readFileSync, writeFileSync } from "node:fs" ;
const tokens = JSON . parse ( readFileSync ( "design/tokens.json" , "utf8" ));
const lines = [];
// ネストしたトークンを再帰的に "--group-key: value;" へ平坦化する
function walk ( node , prefix ) {
for ( const [ key , val ] of Object. entries (node)) {
if (val && typeof val === "object" && "value" in val) {
lines. push ( ` --${ prefix }${ key }: ${ val . value };` );
} else if (val && typeof val === "object" ) {
walk (val, `${ prefix }${ key }-` );
}
}
}
walk (tokens, "" );
const css = `:root { \n ${ lines . join ( " \n " ) } \n } \n ` ;
writeFileSync ( "src/styles/tokens.css" , css);
console. log ( `✅ ${ lines . length } 個のトークンを src/styles/tokens.css に出力しました` );
実行すると、次のような CSS が生成されます。
/* src/styles/tokens.css — 生成物。手で編集しない */
:root {
--color-brand : #5B5BD6 ;
--color-fg : #1A1A2E ;
--color-fg-muted : #5C5C70 ;
--color-bg : #FFFFFF ;
--color-bg-subtle : #F5F5FA ;
--color-border : #E2E2EC ;
--radius-sm : 8 px ;
--radius-md : 12 px ;
--radius-lg : 20 px ;
--space-1 : 4 px ;
/* …以下略… */
}
package.json の prebuild に node scripts/build-tokens.mjs を足しておけば、ビルドのたびに CSS が JSON へ追従します。コンポーネントは var(--color-brand) のように変数だけを参照し、生 16 進数を二度と書かないのが肝心です。
ステップ3: CLAUDE.md にデザイン文脈を固定する
Claude Code は CLAUDE.md を起動時の文脈として読みます。ここに「このプロジェクトのデザイン規約」を短く明文化しておくと、生成される UI のばらつきが目に見えて減ります。
## デザイン規約(実装時の絶対ルール)
- 色・余白・角丸・フォントは必ず src/styles/tokens.css の CSS 変数を使う。
生の 16 進数・px 値をコンポーネントに書かない。
- 角丸はカード=var(--radius-md)、ボタン=var(--radius-sm)、モーダル=var(--radius-lg)。
- 本文は var(--font-size-body) / 行間 var(--font-line-body)。見出し H2 は var(--font-size-h2)。
- 新しい色や余白が必要になったら、コンポーネントに直書きせず design/tokens.json に追加し、
build-tokens.mjs を再実行してから var() で参照する。
- フォーカスリングは省略しない(var(--color-brand) の 2px outline)。
ここで効くのが 6/18 に入った /cd(作業ディレクトリ移動)です。移動先の CLAUDE.md は system prompt を置き換えるのではなくメッセージとして追記され、プロンプトキャッシュも作り直されません。私のように複数リポジトリを横断して UI を直す場合、サイトを切り替えるたびにそのサイトのデザイン規約が文脈へ積まれていくので、サイトごとの色味の取り違えが起きにくくなりました。
ステップ4: 画面案を Claude Code へ受け渡す
ここからが画面ごとに繰り返す部分です。Claude Design でローカルコードベースを起点に画面案を作ると、生成アセットには既存コンポーネントの要素が反映されます。それを Claude Code へ渡すとき、私は「丸ごと作って」ではなく 既存の語彙への翻訳を明示 します。
# Claude Code への受け渡しプロンプト(例)
Claude Design で作成したメンバーシップ案内カードを実装してください。
制約:
- src/styles/tokens.css の CSS 変数のみ使用(生の色・px 禁止)。
- 既存の <Card> と <Button variant="primary"> を再利用し、新規スタイルを増やさない。
- レイアウトは既存の src/components/cards/PlanCard.tsx の構造に合わせる。
- ダークモードは [data-theme="dark"] の既存変数で自動追従させる。
- アクセシビリティ: ボタンは button 要素、価格は見出しではなく強調テキストで。
出力前に、新規に追加した生の色・px 値があれば列挙して報告してください。
最後の一文が地味に効きます。「直書きがあれば自己申告させる」ようにすると、トークン外の値が紛れ込んだときに自分で気づいて、tokens.json への追加か既存変数への置き換えかを判断してくれます。受け渡しは「生成させる」より「既存の部品で組み直させる」と捉えるほうが、結果が安定します。
ステップ5: 既存システムへ揃え、検証する
生成された UI が規約からずれていないかは、目視より機械で見るほうが速いです。コンポーネントに生 16 進数や生 px が紛れていないかを簡単に検出します。
// scripts/check-tokens.mjs — コンポーネント内の直書きを検出する
import { readFileSync } from "node:fs" ;
import { globSync } from "node:fs" ;
const files = globSync ( "src/components/**/*.{tsx,css}" );
const hexRe = /# [0-9a-fA-F] {3,8}\b / ; // 生の 16 進数カラー
const pxRe = /: \s * \d + px/ ; // 生の px 値(var() 経由でない)
let violations = 0 ;
for ( const file of files) {
const lines = readFileSync (file, "utf8" ). split ( " \n " );
lines. forEach (( line , i ) => {
if (line. includes ( "var(--" )) return ; // 変数参照はOK
if (hexRe. test (line) || pxRe. test (line)) {
console. log ( `⚠️ ${ file }:${ i + 1 } ${ line . trim () }` );
violations ++ ;
}
});
}
console. log (violations === 0 ? "✅ 直書きなし" : `🛑 ${ violations } 件の直書きを検出` );
process. exit (violations > 0 ? 1 : 0 );
これを CI かコミット前フックに通しておくと、「Claude Design 由来の微妙な色」が本番へ漏れるのを止められます。私は最初これを目視でやっていて、ダークモードだけ角丸が 1 種類違う状態を 2 週間放置していたことがあります。検証は早いほど安いです。
つまずきやすい点と落とし穴
実際にやってみて引っかかった箇所を共有します。
症状 原因 対処
生成 UI の色が「近いけど違う」 トークンが二重化し、片方が古い 生 16 進数を全廃し var() に統一。check-tokens.mjs で監視
ダークモードだけ崩れる 明示色が data-theme を上書き 色は必ず変数経由にし、テーマ別の値は変数定義側で切り替える
サイトを跨ぐと色味が混ざる 規約が文脈に積まれていない 各リポジトリの CLAUDE.md に規約を置き、/cd で移動して文脈を積む
新しい余白が無限に増える 都度コンポーネントに直書き 新値は tokens.json に追加してから参照。スケール外は使わない
最新モデルを使うかどうかは、この設計とは別の話だと考えています。Fable 5 のような新モデルが Claude Code から使えるようになっても、私は主力を Opus 4.8 に据え置いたまま、実装の一部工程でだけ試す——という落ち着いた使い方をしています。正本を一本化しておけば、どのモデルで生成しても揃う土台ができているので、モデル選定を慌てる必要がなくなります。
次の一歩
まずやるべきは新機能のツアーではありません。いま手元のプロジェクトで生の 16 進数が何箇所あるかを grep -rn '#[0-9a-fA-F]' src/components で数えてみてください。 その数がそのまま、デザインと実装がずれる余地です。一つでも多くを tokens.json 経由の変数に寄せておくほど、Claude Design と Claude Code の連携は素直に効くようになります。私自身もまだ全コンポーネントを移し終えてはいませんが、正本を一本化していく作業は、地味でも確実に往復を減らしてくれています。