📈

Claude Design ↔ Claude Code を行き来して作った資産ポートフォリオダッシュボード

に公開
9
2

はじめに

一枚で資産を見渡すダッシュボード

自分の資産がいま全体でいくらで、どんな構成なのか。それをひと目で見られる場所がほしくて、資産ポートフォリオのダッシュボードを作ってみました。

https://unsolublesugar.github.io/investment-portfolio

国内株・米国株・投資信託・金(ゴールド)と、資産が複数の口座に散らばっていると、その合計額・内訳・増減をまとめて把握するのは意外と難しいものです。

証券会社のアプリは口座ごとに分断されているうえ、残高を見るたびにログインし直す手間や、興味のないキャンペーン・おすすめ銘柄といったノイズも目に入ります。これまでは家計簿アプリで全口座をまとめて見ていましたが、投資の内訳まで知りたくなると結局は各証券アプリを開くことになり、この手間とノイズは付いて回りました。

そういう余計なものを取り払って、自分の資産だけを静かに眺められる場所がほしい、というのが本プロダクト開発の出発点でした。

PC画面で見た資産ポートフォリオダッシュボードのファーストビュー
完成したダッシュボード。推移推移、評価損益率の上位/下位、資産構成などを一枚で見渡せる

つくって公開しようと思った、もう少し詳しい背景

自分用に作るだけでなく、いっそ公開してみたい、という気持ちもありました。新NISAをきっかけに投資に興味を持つ人が増えて、成功者のポートフォリオを紹介する動画なんかもよく見かけます。ただ中身は「国内株が何割、米国株が何割、債券や金も少々」くらいのざっくりした話か、億り人の参考にしづらい持論が多い印象でした。

具体的な保有数量や、割合の変遷、投資額の推移まで、シンプルかつオープンにする人がもっといてもいいのでは、と前から思っていたので、まずは自分が先陣を切ってみることにしました。

昔から投資系ブログでこうした情報を公開している人はいましたが、どうにも無骨で、パッと見では参考にしづらい。パッと見られて、画面を触りながら「お、この銘柄をこれだけ持ってる理由は何だろう?」と、見る人の興味をちょっと刺激するような形にできないか。それに適したかたちを模索した結果が、このプロダクトです。

前述のとおり、家計簿アプリや証券アプリでも総合的に見ること自体はできますが、API連携やアカウントログインの煩わしさ、自分好みにカスタマイズしづらい、といった点は残ります。そのあたりの煩雑さを排して、運用コストも最小限に抑えたデータの取得・更新・公開のやり方を、けっこう真面目に考えました。

自分の場合は、元手30万円ほどの規模から軽い気持ちで株式投資を始めました。それが気づけば5年くらいの運用実績になっていて、ちょうど証券口座に置いている資産が1,000万円を超え、評価損益も+300万円前後に達したところ。これくらいの期間と規模になれば、それなりに参考になるものもあるかもと思い、開発と公開を進めることにしました。

きっかけは Claude Design を試したかったこと

こうした課題はずっと解決したかったのですが、自分でサイトやアプリを一から作るとなると、正直なところ腰が重い。そんなとき、「Claude Design が使いやすくなったらしい」と聞いて、さっそく試してみよう、と思い立ちました。

https://www.youtube.com/watch?v=t_LBECIQQqs

これまで Claude Design は web 版だけで提供されていましたが、直近のアップデートで Claude デスクトップアプリに統合され、ローカルの Claude Code と行き来しやすくなりました。

https://claude.com/blog/claude-design-stays-on-brand-for-daily-work

ちゃんと触るのは初めてだったので、まずは小さく動かして「だいたいこう使えばいいのかな?」という感触を掴むのが狙いです。なのでいきなり重い大規模なプロジェクトに使うのではなく、シンプルで機能を絞ったテーマとして、この資産ポートフォリオのダッシュボードを選びました。

進め方:Claude Design と Claude Code の二段構え

この記事で書きたいのは、作り方の段取りの話です。今回は次の二段構えで進めました。

  • Claude Design
    • 大枠のデザインと動くプロトタイプを作る
    • 配色・レイアウト・コンポーネントの方向性をここで固める
  • Claude Code
    • プロトタイプを実データで動く本番へ仕上げる
    • 内部実装のリファクタ、データ設計、CI、実機を見ての細かな挙動調整

デザインの大枠は Claude Design でさくっと、細部の作り込みは Claude Code で。この分担が思いのほか気持ちよくハマったので、その利用事例として開発記録を残しておきます。

完成したダッシュボードの機能

主な画面デザイン、機能はこんな感じです。

自動生成されたOGP画像
SNSシェア時に出るOGP画像。その日の資産構成ドーナツと区分別の割合・損益が入る

資産構成の推移を示す積み上げ棒グラフ
資産推移グラフ(資産構成の積み上げ棒)。区分ごとの割合の変遷を月次/年次で追える

銘柄テーブル
銘柄テーブル。現在値・前日比・前月比・評価額・評価損益を並べ、ヘッダ/チップで並び替え

  • 資産構成ドーナツ(円グラフ)+凡例
    • 区分(国内株・米国株・投資信託・金)別の評価額・構成比・評価損益
    • カテゴリを選ぶと銘柄内訳へドリルダウン
    • 中央が空いた円グラフを本記事では「ドーナツ」と呼びます
  • 資産推移グラフ
    • 評価額の推移と、資産構成の積み上げ棒
    • 評価額は1年/3年/5年/全期間、積み上げ棒は月次/年次で切り替え
    • 日次スナップショット履歴から描画
  • 銘柄テーブル
    • 銘柄ごとの現在値・前日比・前月比・評価額・評価損益
    • PCはヘッダクリック、モバイルはチップで並び替え
  • 損益率ランキング
    • 評価損益率の上位3/下位3銘柄
  • 自動更新
    • 株価・為替・金をキー不要のAPIで取得
    • 国内株・米国株:GitHub Actions が毎日 Yahoo Finance から取得
    • 為替(USD/JPY)・金スポット:ブラウザからライブ取得
  • OGP画像の自動生成
    • SNSシェア用のカード画像を毎日生成
    • その日のドーナツと区分別の割合・損益をカードに載せる

今回はあくまで「自分の資産ポートフォリオを簡易的に確認・公開する」のがコンセプトなので、あえて入れなかったものもあります。実際の銘柄売買や発注、各銘柄から企業のIR・ニュースへ飛ばす導線、証券口座とのAPI連携といった機能は、最初から対象外にしました。

保有データは自分の取引台帳CSVで管理し、外部APIの利用も株価・為替・金スポットの取得だけにとどめています。やることを絞ったぶん、土台をシンプルに保てました。


Claude Design で動くプロトタイプを作る

出発点は Claude Design でした。

Claude Designのスタート画面
Claude Design のスタート画面。ここから自然言語の指示でプロトタイプ作りが始まる

まず投げたのは「iGrow みたいに」の一言から

最初の指示は、かなりざっくりしたものでした。要点はこれくらいです。

  • 国内株・米国株・投資信託・金(ゴールド)の保有を可視化したい
  • トップに円グラフ(ドーナツ)でカテゴリ比率を出す
  • 各銘柄の詳細(銘柄名・ティッカー・現在値・前日比・前月比)も見られるように
  • 見た目は楽天証券の iGrow みたいに、シンプルで見やすく

参考にしたい既存サービスのURLを1本渡して、あとは欲しい要素を箇条書きで伝えただけ。細かい仕様は決めていません。この「方向の種」だけ渡すと、配色・レイアウト・コンポーネントの粒度まで含んだ動くUIが返ってくる、というのが Claude Design の入り口でした。

https://igrow.rakuten-sec.co.jp/

Claude Design は作る前に質問してくる

面白かったのが、いきなり作り始めるのではなく、先に確認の質問を返してきたことです。しかも選択式で、ポチポチ答えるだけのフォーム形式。このとき詰めた論点が、そのまま後半の判断軸になりました。

Claude Designが作成前に選択式で要件を確認してくる画面
Claude Design が作成前に出してきた選択式の確認画面

  • 誰に見せるか … SNS等で公開する「見せる用」ページ
  • どれくらい動かすか … ドーナツのホバー/クリックで詳細を出す、しっかりインタラクティブな方向
  • 通貨表示 … 米国株はドル、それ以外は円で併記
  • 出す指標 … 現在値・前日比・前月比・評価額・保有数量
  • 騰落の色 … 国内の証券サービスで見慣れた並び(プラス=赤、マイナス=緑)
  • 案の数 … 2〜3案を見比べたい

「とりあえず作ってみて」だと、こちらの前提を相手が勝手に埋めてしまう。先に選択肢で問い返してくれると、自分でも言語化できていなかった要件(たとえば騰落色を国内の証券アプリに合わせるか)がその場で固まります。仕様書を書くより速く、認識がそろった状態でプロトタイプに入れました。

実データを入れてみる

方向が決まったので、サンプルではなく実際の保有データを渡すことにしました。ここはわりと泥臭かったです。

証券会社からエクスポートしたCSVを渡したら、文字コードが Shift-JIS で、そのままだと盛大に文字化けします。Claude Design 側でデコードして読み直してもらい、ようやく銘柄名や数量が正しく入りました。

まず国内株、次に米国株、最後に投資信託、と分けてアップロード。金(ゴールド)だけはエクスポートに無かったので、保有グラム数をテキストで直接伝えています。

実データを入れると、サンプルでは気づけないことも見えます。

  • 米国株はドル建てなので円換算が要る
  • 投信は口数表示で桁が大きい
  • 金はグラム単位、と区分ごとに単位がバラバラ

こうした「実物の歪み」をプロトタイプ段階で踏めたのは大きかったです。

3案を並べて選ぶ

そのうえで、方向性を1案に絞らず複数出してくれました。このときは次の3案です。

  • 案A クラシック … カード+極薄影で情報を区切る、証券ダッシュボード然とした正統派
  • 案B カード … 区分ごとに大きめのカードを並べる構成
  • 案C 一覧 … 表ベースで密度を上げた構成

実物を並べて見比べられるので、「これは自分の用途だと密度が高すぎる」「これは余白が気持ちいいけどスクロールが長い」といった判断が、文字の仕様書を読むよりずっと速いです。最終的に案A クラシックを採用しました。

実際に並んだ3案がこちらです。

Claude Designで案A クラシックを表示している画面
案A クラシック:カード+極薄影で情報を区切る正統派

案B カードのプロトタイプ画面
案B カード:区分ごとに大きめのカードを並べる構成

案C 一覧のプロトタイプ画面
案C 一覧:表ベースで密度を上げた構成

プロトタイプの段階でインタラクションも詰める

案Aをベースに、動きの部分もこの段階で何度か往復しました。デザインの初稿で終わりではなく、触りながら直せるのがプロトタイプの強みです。

  • ドーナツのドリルダウン … カテゴリ(国内株や米国株)をクリックしたら、ドーナツがそのカテゴリ内の銘柄構成に切り替わってほしい、と注文しました。全体の比率と、カテゴリの中の内訳を、同じドーナツで行き来できるように。
  • ドーナツに%ラベル … セグメントの上に割合の数字を載せて、ホバーしなくても比率が読めるように。
  • 間延びした棒グラフを詰める … カテゴリ構成を示す横棒が画面いっぱいに伸びて間延びして見えたので、横幅を抑えて読みやすく整えてもらいました。
  • 為替のライブ更新 … 米国株の円換算に使う USD/JPY を、開いている間に自動更新する形に。

この辺りはもう Claude Code フェーズに近い詰め方ですが、プロトタイプのまま手早く試せるので「触ってみて違ったら戻す」ループが高速で回せます。方向決めと初期の作り込みが地続きでできるのは、動くプロトタイプならではでした。

ドーナツのドリルダウンと%ラベル表示
カテゴリをクリックすると内訳に切り替わるドリルダウン

デザインの方針:色は意味にだけ使う

Claude Design とのやりとりで固まったトンマナ(トーン&マナー。配色や装飾の一貫した方針のこと)が、楽天証券 iGrow 寄りの「明るい白基調・低彩度・情報密度高め」です。装飾は最小限で、色は意味づけ(カテゴリ識別・騰落)にだけ使う、というルールを初期段階で明確にできたのは大きかったです。

  • 騰落色は国内標準に合わせる
    • プラス=赤、マイナス=緑、変化なし=グレー
    • 日経平均・為替テロップや楽天・SBIの値動き表示と同じ並びで、国内ユーザーには見慣れた配色(海外は赤・緑が指す向きが逆で、上げ=緑/下げ=赤)
    • ドーナツ中央からテーブル・ランキングまで全画面で一貫させる
  • カテゴリ色の一貫運用
    • 国内株・米国株・投信・金の4色を全要素で同一色に
    • ドーナツ・凡例・積み上げ棒・明細のアクセントで結び、視線移動のコストを下げる
  • 飾りの色は足さない
    • グラデーションを使うのはロゴだけ
    • きれいに飾るより、意味のない色・数字・装飾を足さない方向で密度を上げる

この方針がプロトタイプの段階で乗っていたおかげで、後の Claude Code フェーズで何度も細部をいじっても、判断の軸がぶれませんでした。

新しい要素を足すたびに「これは意味のある色か?」と問い直せます。デザインの羅針盤を先に作るという意味で、Claude Design はこの手のプロジェクトと相性が良かったです。

評価損益率の上位3/下位3銘柄ランキング
評価損益率ランキング(上位3/下位3)。プラス=赤・マイナス=緑の騰落色が一目で見分けられる


Claude Code に持ち込んで作り込む

プロトタイプ段階で、ある程度ちゃんと動くものができました。あとは細かい部分を Claude Code でゴリゴリ詰めていくフェーズです。実際の保有データを流し、CIで毎日更新し、スマホでも崩れないようにして、ようやく毎日見る道具になります。

Claude DesignとClaude Code・gitリポジトリを行き来する開発セッション
Claude Design と Claude Code+git を行き来しながら進めた開発セッション

最初の依頼はこの2つでした。

  1. 「案A クラシックを採用するので、案B・案C 用の実装を削除して」。プロトタイプの分岐を畳んで本筋に絞るための依頼です。
  2. 「PC表示とスマホ表示の中間くらいの横幅で、ヒーロー(画面最上部の主役表示領域)の評価損益テキストがはみ出ることがあるので直して」。新機能ではなく、作りかけの取りこぼしから潰す一手です。

派手な新機能より、まず今あるものを正しく動かす。この地味な2手から本番化が始まりました。

以降はほぼすべて Claude Code フェーズの記録です。


技術スタックの選定

本番化にあたって最初に決めたのが土台です。このダッシュボードは保有資産を閲覧するだけで、ログインも書き込みもいりません。データは自分で管理します。そこで、フレームワークを使わずビルド工程のない静的サイトにしました。

プロトタイプに付いてきたランタイム(dc-runtime)をそのまま引き継ぐかどうかも、この段階での判断です(理由と既定/自前の切り分けは、後述の「生成物のランタイムを土台にする」で詳しく扱います)。

  • ランタイム: dc-runtime(Claude Design 由来の生成物 support.js)の <x-dc> テンプレート+薄い Component
  • 言語: Vanilla JS(依存パッケージなし)
  • スタイル: 素の CSS(pf- プレフィックスのクラス)
  • ホスティング: GitHub Pages
  • CI/CD: GitHub Actions(株価取得・スナップショット・OGP生成・デプロイ)
  • 外部API: 為替・金・株価いずれもキー不要のものを採用
用語メモ:dc-runtime

dc-runtime は、<x-dc> というカスタム要素でテンプレートと Component クラスを結びつけ、ビルド工程なしで画面を組み立てる軽量ランタイムです。support.js はその生成物で、Claude Design で作ったプロトタイプに同梱されていたものをそのまま土台にしています。なぜ作り直さずに引き継いだのか、どこまでがランタイム既定でどこからが自前かは、後述の「生成物のランタイムを土台にする」で掘り下げます。
https://zenn.dev/tenchijin/articles/20240618_runtime

用語メモ:Vanilla JS

Vanilla JS は、ライブラリやフレームワークを使わない「素の JavaScript」を指す呼び方です。
https://zenn.dev/seya/articles/66809b3d59151c

一番大事にしたのは、メンテナンスコストを極力抑えることです。「数年後の自分がメンテできる」というより、「そもそもメンテにかかる手間を最初から小さくしておきたい」気持ちのほうが強かったからです。

個人で長く使う道具だと、この差があとからじわじわ効いてきます。フレームワークのメジャーバージョン更新、バンドラの設定、依存ツリーの腐敗。こうしたものは時間が経つほど、動かすまでの手間を重くします。

その点、ビルドレスにしておけば、python3 -m http.server で開くだけ、file:// で直接開いても動きます。CI が複雑な依存を抱える必要もありません。

python3 -m http.server 8000   # → http://localhost:8000/dashboard.dc.html

dashboard.dc.html./styles.css./js/*.js を相対パスで読み込むだけの構成なので、ローカルでも GitHub Pages でもそのまま動作します。

ロジックを mixin で分離する

プロトタイプは1枚のHTMLに全部入りでした。これだと変更箇所の区分がしづらく、メンテしにくい。そこで Claude Code に「関係する部分をカプセル化して、追加・変更を把握しやすい形にリファクタして」と頼みました。

ランタイムの制約上、Component 本体はインラインの <script> に置く必要があります(外部 src に切り出すと textContent が空になってしまう)。とはいえ全ロジックをHTMLに詰めると見通しが悪い。

そこで実装の大半を js/*.js に出し、window.PortfolioLogic というメソッド集へ登録しておいて、Component の末尾で合成する形にしました。ここで言う mixin は、独立して定義したメソッド群を既存クラスに混ぜ込む手法のことです。

// js/format.js などの末尾(冪等パターンで登録)
window.PortfolioLogic = Object.assign(window.PortfolioLogic || {}, {
  yen(n) { return '¥' + Math.round(n).toLocaleString('en-US'); },
  // ...
});

// dashboard.dc.html のインライン Component 末尾
Object.assign(Component.prototype, window.PortfolioLogic);

インラインに残すのは、ランタイムが名前で呼ぶ契約面だけです(constructor・ライフサイクル・renderVals)。これで見た目は styles.css、ロジックは js/、画面構造は <x-dc> テンプレート、という住み分けができました。

dashboard.dc.html   アプリ本体(テンプレート+薄いComponent)
styles.css          スタイル(pf- クラス)
js/
  format.js         整形(金額・%・色)
  data.js           取得・保存・既定保有データ
  model.js          集計(評価額・損益、ドーナツ/凡例、サマリー)
  chart.js          推移グラフのビューモデル
support.js          ランタイム(生成物・編集しない)

この住み分けが、後半の「実機を見ては直す」往復を支えてくれます。


生成物のランタイムを土台にする

技術スタックの話で support.js(dc-runtime)を土台にしたと書きましたが、ここは少し補足が要ります。普通なら「プロトタイプはプロトタイプ、本番は React なりで作り直す」と考えるところを、今回はあえてランタイムごと引き継ぎました。

その判断の中身と、どこまでがランタイム既定の仕様で、どこからが自分で決めた実装なのかを切り分けておきます。ここを曖昧にすると、後から「これは触っていいのか?」が分からなくなるからです。

support.js は手書きではなく生成物

support.js は自分が書いたコードではありません。Claude Design が出力したプロトタイプに同梱されていたランタイムで、ファイル冒頭にこう書いてあります。

// GENERATED from dc-runtime/src/*.ts — do not edit. Rebuild with `cd dc-runtime && bun run build`.

TypeScript で書かれた dc-runtime のソースを、依存なしで動く1枚の JS にバンドルした生成物、という意味です。元の .ts は手元には来ません。こちらに渡されるのはビルド済みの support.js だけです。

なので編集対象にはせず、.claude/rules/ でも「生成物・編集しない」と明記しています。これは中を読んで挙動を把握するのは構いませんが、直接いじっても次に再生成されれば上書きされる、という前提のファイルです。

作り直さず引き継いだ理由

このランタイムを捨てて使い慣れたフレームワークに載せ替える手もありました。やらなかったのは、それが冒頭の「メンテナンスコストを極力抑える」という方針と正面からぶつかるからです。

  • support.js依存ゼロ・ビルドレス<script src> で読むだけで、バンドラもインストールも要りません。求めていた性質そのものでした。
  • すでにプロトタイプがそのまま動いている。React + Vite などへ移植して得られるのは「書き慣れ」くらいで、代わりに依存ツリーとビルド設定という、まさに避けたかったものを抱え込みます。
  • ランタイムは1枚のJSに閉じているので、ブラックボックスでも怖くない。最悪、中を読めば全部そこにある。node_modules 数百個を追うより、1ファイルを把握するほうが現実的です。
  • 依存パッケージを抱えていないので、アップデート追従そのものが発生しません。今後この道具を大規模に拡張する予定もないため、ライブラリやフレームワークの破壊的変更を追いかけたり、脆弱性パッチを当て続けたりする手間とは無縁です。サプライチェーン経由の事故が増えている昨今、依存が無いこと自体がひとつの安心材料でもあります。

「AI が生成したものだから本番では使わない」と反射的に避けるより、その生成物が手元の要件と噛み合うかで判断する。今回はたまたま、ランタイムの性質(ビルドレス・依存ゼロ)と自分の方針が一致していたので、そのまま土台にしました。

逆に言えば、ここが噛み合わなければ載せ替えていたと思います。

どこまでが既定で、どこからが自前か

今回とくに意識した切り分けです。観察できる範囲で整理すると、こうなります。

ランタイムが規定する部分(=Claude Design 由来。従う前提)

  • <x-dc>…</x-dc> の中にテンプレートを書く、というカスタム要素の作法
  • テンプレートの {{ 名前 }} ホールと、<sc-for><sc-if> の制御構文(式は書けず、値は名前で渡す)
  • ロジックは class Component extends DCLogic に書き、renderVals() が返したオブジェクトがテンプレートの穴に入る、という契約
  • Component はインラインの <script data-dc-script> に置く必要がある(外部 src に出すと中身が読まれない)
  • data-props 属性で宣言する Tweaks(後述)

自分で決めた部分(=独自実装。ランタイムは関知しない)

  • ロジックの大半を js/*.js に出し、window.PortfolioLogic 経由で Component に合成する構成(先述の「ロジックを mixin で分離する」がこれ)
  • pf- プレフィックスの素の CSS でスタイルを当てる方針
  • 取引台帳CSV → 生成物、という単一ソースのデータ設計
  • GitHub Actions による自動更新・OGP生成・デプロイ

つまり、「画面をどう記述するか」はランタイムに従い、「コードと運用をどう構成するか」は自分で決めた、という分担です。前者を変えるとランタイムが動かなくなりますが、後者はランタイムから見れば領域外なので、自由に設計できます。

先ほどの mixin 分離も「ランタイムが要求する契約面だけインラインに残し、残りは自分の都合で js/ に出す」という、まさにこの境界線上の判断でした。

Tweaks(data-props)は Claude Design 由来の仕組み

Component を書く <script> タグには、data-props という属性が付いています。

<script type="text/x-dc" data-dc-script
  data-props='{"ownerName":{"editor":"text","default":"星影",...},
               "usdRate":{"editor":"float","default":160.83,...},
               "goldPrice":{"editor":"int","default":21920,...}}'>

なお実ファイルでは、この data-props はHTML属性なので &quot; でエンコードされ1行に収まっています。ここでは読みやすさのためデコードして整形しています。

これは Claude Design の「Tweaks」を宣言したものです。Tweaks は、生成したプロトタイプの一部の値を、コードを再生成せずに調整できる Claude Design 側のコントロールで、自分で実装したものではありません。

editor(入力UIの種類)・default(初期値)・型情報を書いておくと、Claude Design 上に値を編集するパネルが出て、コードを触らずに保有者名や為替レートを差し替えられます。

Tweaks(data-props)の編集画面
Claude Design 上の Tweaks 編集パネル

とはいえ、この編集パネルが出るのは Claude Design 上だけです。公開した静的サイトにはパネル自体が存在せず、閲覧者が値を書き換えることもありません。なので本番では、宣言した値は実質的に「既定値・フォールバック」として効いています。

為替や金価格は、ライブ取得が成功すればその値、失敗したら data-propsdefault に落とす、という二段構えのフォールバックに使っています。プロトタイプ時代の「パネルで調整する値」が、本番では「ライブ取得が壊れたときに戻る安全値」として再利用されている格好です。

ここも、Claude Design 由来の仕組み(Tweaks の宣言の枠)はそのまま使い、その値を何に使うか(フォールバック)は自分で決めた、という既定と独自の組み合わせになっています。


CLAUDE.md とルールで前提を共有する

Claude Code との開発で効いたのが CLAUDE.md.claude/rules/ の整備です。プロジェクトの概要・コマンド・編集の住み分けを CLAUDE.md に書いておくと、毎回の会話で説明し直さなくても、前提を共有した状態で作業を始められます。

本プロジェクトの CLAUDE.md は、全体像の把握に必要な最小限だけを残し、詳細は .claude/rules/ 配下のポインタで参照する構成にしています。

# 資産ポートフォリオ ダッシュボード

必ず日本語で回答してください。

## Project
国内株・米国株・投資信託・金(ゴールド)の保有を可視化する公開ダッシュボード。
ビルド工程のない静的サイト(dc-runtime ベース)で、GitHub Pages にホスティング。

## 編集の目安
- 見た目 → styles.css(pf- クラス)
- ロジック → js/
- 画面構造 → dashboard.dc.html の <x-dc> テンプレート

## References
- アーキテクチャ: .claude/rules/architecture.md
- コーディング規約: .claude/rules/conventions.md
- データ保存方式: .claude/rules/data.md
- デザイン トンマナ: .claude/rules/design.md

ドメイン固有のルールは .claude/rules/ に分離しています。

たとえば「dashboard.dc.html に開発経緯やデータ保存方式を直接書かない」「support.js は生成物なので編集しない」「デザイン実値(styles.cssjs/format.js)を変えたら design.md を同期する」といった規約です。

Claude Design で固めたトンマナを design.md に落として、Claude Code がそれを正として参照する、という橋渡しにもなっています。

さらに、これらの規約はコミット前に自動検出するようにしています。pre-commit フック(check-rules.mjs)で、support.js の編集・HTMLコメントへの禁止語・絶対パス参照・デザイン実値変更時の design.md 未同期などを検査します。

やってはいけないことを、人の注意力に頼らず仕組みの側で止める、という考え方です。

git config core.hooksPath .githooks   # クローン後に一度だけ有効化

ルールを明文化して仕組みに組み込んでおくと、AIに作業を任せたときも規約に沿った対応をしてくれるので、ドキュメントと実装の乖離が起きにくくなりました。

この CLAUDE.md.claude/rules/ の運用や、GitHub Pages × GitHub Actions で静的サイトを回す土台は、以前 Claude Code でコミュニティポータルサイトを作ったときの知見をそのまま引き継いでいます。

https://zenn.dev/easy_easy/articles/89318e4d0acb4f


データの持ち方

可視化アプリで一番事故りやすいのが、保有データの二重管理です。画面用のデータと集計用の別データがずれて、表示が嘘をつく。これを設計で潰しました。

保有構成の単一ソースは取引台帳CSV

transactions.csv ─┐
                  ├─ import-holdings.mjs ─→ holdings.json / js/data.js
prices.csv ───────┘                              │
   ↑ update-prices.mjs(株価自動)                 └─ アプリ・snapshot.mjs が参照
  • data/transactions.csv … 1行=1取引(buy/sell・株数・約定単価)。追記のみで運用し、過去行は消しません。import-holdings.mjs が移動平均法で株数と加重平均取得単価を畳み込み、全売却(残0)は自動除外します。保有銘柄・保有量・取得単価はここが唯一の正。
  • data/prices.csv … 時価のスナップショット。国内株・米国株は日次cronが Yahoo Finance から自動更新します。手動更新が要るのは金・為替・投信の行だけです。
  • data/holdings.json … アプリが読む保有データですが、上記2つのCSVから生成される派生物です。js/data.js の既定データも同時生成して二重管理を防ぎます。直接編集は禁止(pre-commit がCSVとの一致を検査)。
  • data/history.json … 評価額の日次スナップショット履歴。GitHub Actions だけが書き込み、毎日 22:00 JST にコミットします(差分があるときだけコミット)。推移グラフと全体の前日比・前月比の実測値に使います。

手で更新が必要になるのは、基本的に銘柄を入れ替えたり売買したりしたときの transactions.csv への追記くらいです。自分はデイトレのような頻繁な売買はせず、中長期で株を持つスタイルなので、取引のたびに数行足すだけで足ります。

今回の「手動は売買時だけ、あとはCIまかせ」という運用は、この投資スタイルにうまくフィットしていると感じています。

ブラウザは一切リポジトリに書き込まない

閲覧者の端末で取れる為替・金スポットはライブ取得し、共有履歴がない場合のフォールバックとしてのみ localStorage に蓄積します。

為替(USD/JPY)のライブ更新表示
ブラウザ側でライブ取得した為替(USD/JPY)

サーバもDBも持たないので、データの真実はGitリポジトリとCIに閉じます。これが静的サイトで動的に見せるための肝で、運用の単純さとプライバシーを同時に確保できました。


株価の自動取得

当初は時価も手で prices.csv に書いていました。でも銘柄ごとの前月比まで出したくなった時点で「そもそも公開株価の推移だから自動で取れるのでは?」と Claude Code に相談しました。

候補は yfinance、でも依存を増やしたくない

最初に候補に挙げたのは Python の yfinance ライブラリです。Yahoo Finance から株価を手軽に取得できる定番で、実績もあり手堅いものでした。

https://github.com/ranaroussi/yfinance

ただ、CIに Python ランタイムと pip 依存を一つ増やすのは、このプロジェクトの「依存ゼロ・ビルドレス」志向と噛み合いません。便利そうなライブラリでも、入れる前に土台の思想と合うかを一度立ち止まって考える。長く使う道具では、この判断が効いてきます。

選んだのは chart エンドポイントの直叩き

そこで、yfinance が内部で叩いているのと同じ Yahoo Finance の chart エンドポイント(query1.finance.yahoo.com/v8/finance/chart/{symbol})を、Node のスクリプトから直接叩く形にしました。ライブラリは使わず、考え方だけ借りた格好です。

うれしかったのは、range=3mo の1リクエストで最新終値・前営業日・約1か月前終値がまとめて取れることです。過去分を別に保存せず、前日比・前月比をステートレスに揃えられます。

非公式APIなので、壊れる前提で備える

なお、この chart エンドポイントは Yahoo 公式のAPIではなく、yfinance などが内部的に使っている非公式なものです。仕様が予告なく変わったり、利用が制限されたりする可能性があります。なので、いつ壊れても困らないように次の手を打ちました。

  • 取得はCIに隔離 … ブラウザから叩くとCORSにも当たるので、取得は update-prices.mjs(CI)に閉じる。
  • 失敗時は据え置き … 取得に失敗したら prices.csv の既存値を維持。壊れても古い値のままで済み、画面が空になりません。
  • 自動対象は国内株・米国株だけ … 金・為替・投信は性質が違うので手動のまま、と割り切りました。

実環境で触りながら仕様を詰める

ここからは、Claude Code との対話でリリースに向けて仕様を詰めていったセッションの記録です。何を考えて手を入れたかを、ひとつずつ振り返ります。

今回は足すより、やめる・整えるに時間を使いました。手を動かす動機の多くも「実機で見たら気になった」という具体的な違和感からでした。

ファーストビューの重要性:スマホで開いた瞬間にドーナツを

振り返ると、序盤の指示の多くがひとつのこだわりから出ていました。スマホで開いた瞬間に、ポートフォリオ全体のドーナツが見えてほしい、という点です。

スマホのファーストビュー(評価額推移+ドーナツ)
スマホで開いたときのファーストビュー。上部に資産評価額の推移、下部に資産構成ドーナツが一画面に収まる

  • 「評価額合計の表示領域をもう少しコンパクトにしたい」
  • 「評価額の推移もコンパクトにして、ドーナツがファーストビューで見えるように」
  • 「評価額合計と推移は情報が重複してるので、統合しちゃっても良さそう」
  • 「モバイルで評価損益・前日比・前月比が縦に積まれて縦幅を食うので、サマリー見出しを圧縮したい」

一目で全体を掴むという、このツールの存在理由を守るための調整でした。後で出てくる損益率ランキングの「モバイルで折りたたみ」も、元をたどればここに行き着きます。何を最初に見せるかは、機能の数より大事だと思っています。

推移グラフの泥臭い作り込み

推移グラフは、実機で見るたびに細かい不満が出て、何度も往復した部分です。

  • 丸ポチが楕円に伸びる
    • SVGを横全幅に引き伸ばすと、各点の丸ポチまで楕円になる
    • preserveAspectRatio=none で横に間延びするのが原因
    • 点だけ SVG をやめ、% 配置のHTMLオーバーレイ(真円)で描いて解決。横長でも円は円のまま
  • 任意地点の値が見たい
    • 月ごとの点にカーソル/タップで、その時点の評価額を表示
    • 透明な操作レイヤーで最寄り点を拾い、強調ドット+ツールチップを出す
  • 点が多すぎて潰れる
    • 過去データを足したら点が増えすぎた
    • 狭い画面では常設ドットを省略してラインだけに
    • ドットが無くてもホバー/タップで値は出し、情報は失わないように
  • 軸ラベルの本数と表記
    • 「全期間で何月か分かりづらい」への対応
    • 横幅に応じて月ラベルの本数を増減(広いほど多く)
    • 年をまたぐときは YYYY/M、同年内は M/D

ちなみに過去データは、自分が実際に記録していた月次の資産額をそのまま投入しました(2021〜2026年分)。期間トグルの 1M/3M/6M という数カ月単位の表示は、もともと Claude Design のプロトタイプ段階で出力されたものをそのまま使っていました。

プロトタイプはサンプルデータ前提で、短期の値動きを見せる粒度になっていたからです。そこへ数年分の実データを入れたことで刻みが合わなくなり、1年/3年/5年/全期間 に作り替えました。

評価額の推移グラフ
評価額の推移グラフ(期間トグルで1年/3年/5年/全期間を切り替え)

資産構成の積み上げ棒グラフのほうも、月次表示では横スクロールで過去分まで一気にたどれるようにしています。細かいところでは、棒にカーソルを当てたときのツールチップが、左右の端では表示順の都合で見切れてしまったので、常に画面内へ収まるよう位置を制御しました。

資産構成の推移を示す積み上げ棒グラフ
資産構成の推移(積み上げ棒グラフ・月次/年次)

グラフは入れる中身が育つと、見せ方の正解も変わるんだな、と感じました。

既存データからインサイトを引き出す

新しいデータを増やさず、今あるデータから意味を引き出す方針で機能を選びました。

  • 評価損益率ランキング
    • 上位3/下位3銘柄をカードで可視化
    • 表を目視でスキャンせずに勝ち負けが掴める
    • スマホでは既定で折りたたみ、ファーストビューのドーナツを守った(前述のこだわり)
  • 銘柄テーブルのソート
    • 並び替えバー新設から「ヘッダのラベル自体をクリック」へ方向転換
    • デスクトップはヘッダクリック+昇降トグル(矢印 ↑/↓、非選択は薄い ↕)
    • モバイルはヘッダが無いのでチップ列で代替
    • データ無(—)の銘柄は方向に関わらず常に末尾にする、というところまで詰めた

ヘッダクリックで並び替わる銘柄テーブル(PC表示)
PCはヘッダのラベル自体をクリックして並び替え(昇降は ↑/↓ で表示)

UIは新しい部品を足すより、既存の部品に機能を持たせるほうが学習コストが低い。この方向転換はその好例でした。

証券サービスらしさを物差しにする

銘柄テーブルのカラム順では、現在値の置き場所を何度か行き来しました。銘柄名の下にティッカー・数量とまとめてみたり、独立カラムに戻したり。最後は「一般的な証券サービスで見る並びと比べて違和感がないか」を物差しに、Claude Code と一緒に最終形を詰めています。

ここは自分の好みだけでなく、「利用者が他で見慣れた型に寄せる」という判断軸です。

余談:作ってからやめた「共有モード」

これはもともと、Claude Design に現状のダッシュボードを精査してもらって「足したり変えたりすると良さそうな候補」を挙げてもらった中のひとつでした。Claude Design はプロトタイプを作って終わりではなく、いまの画面を見たうえで改善案を並べてくれるので、その候補を実際に試してみた、という位置づけです。

公開ダッシュボードなので、金額を伏せて構成と成績だけ見せる共有モード。整形層(format.js)で金額・数量を ¥••• にマスクし、比率・騰落率・銘柄名・現在値だけ残す方式です。マスクを整形層に集約したので、全画面に自動で効きました。

ところが実物を見て、これはそもそも「自分の資産ポートフォリオをオープンに公開したい」という目的から外れていることに気づきました。肝心の金額がマスクされると、結局は割合くらいのふわっとした情報しか見えない。それって、まさに自分が既存のポートフォリオ紹介に物足りなさを感じていた状態そのものです。だったらこれを作る意味がないな、となって撤去しました。

金額を伏せて共有する仕組み自体は、家計簿アプリやSNSのスクショ共有でもよく見かける一般的な機能で、「構成は共有したいけれど金額は出したくない」というニーズがあれば間違いなく効きます。ただ今回は金額まで含めて公開するのが狙いだったので、不要でした。

これは失敗ではなく、実装して初めて要否が判断できる類のものだと思っています。整形層に隔離してあったおかげで撤去も一手。安く作って見てから捨てるほうが速いこともある、という好例でした。

それでも、こうした改善候補をいろんな観点から出してくれて、画面のプレビューですぐ確かめられるのは、Claude Design の強みのひとつかもしれません。言葉で「こういう機能どう?」と議論するより、出てきた画面を見て「あ、これは違うな」と即断できるぶん、試して捨てるサイクルが速く回ります。

詰めてみて感じたこと

「何となくこんな感じで」と伝えればAIがそれっぽい形にしてくれる時代にはなりました。とはいえ、実際に触ってああでもないこうでもないと試行錯誤して、AIとの壁打ちも挟みながら、結局は「自分にとってはこれが使いやすい」というかたちにたどり着く。

今回それに集中できたのは、まず自分だけが使うもの、自分の資産ポートフォリオを公開したいもの、という名目がはっきりしていたからでした。

これが「多くの人にも使えるように」「いろんなニーズを取り込んで」だったら、まったく違う開発スタイルになっていた気がします。

何のために作るのか、誰に向けたものか、何を達成したいのか。AIが多くを肩代わりしてくれる時代になっても、その芯の部分は結局、作り手の中から出てくるのだろうなと感じました。


見た目の仕上げ:いちばん粘った OGP 自動生成

機能が固まったら、最後は見た目の詰めです。なかでも往復を重ねたのが、SNSでの見え方(OGP画像)でした。

自動生成されたOGP画像

SNSでシェアしたときに、その日の資産構成ドーナツと区分別の割合・損益が入ったカード画像を出したい。これが今回のなかでも大きな作業でした。

設計上の制約として、SNSクローラはJSを実行しません。だからOGP画像は静的にコミットされたPNGである必要があり、クライアントでの動的生成は使えません。

そこで次の流れを組みました。

  1. og.htmldata/history.json を読んでドーナツ+凡例を 1200×630 で描く独立ページ
  2. scripts/og.mjs … CIで Playwright が og.html を実ブラウザで開き、その領域をキャプチャして og.png を書き出す
  3. snapshot.yml(日次cron)に組み込み、履歴更新と同時にOGP画像も再生成・コミット
  4. dashboard.dc.htmlog:imagetwitter:image を Pages のサブパスを含む絶対URLで指定(meta値は絶対URLが正)

試行錯誤のポイントはこんな感じでした。

  • フォント
    • キャプチャするとダッシュボードと字形がズレた
    • og.html 側で Google Fonts(Manrope / Noto Sans JP)を読み込む
    • Playwright で document.fonts.ready を待ってから撮影し、同じ字形に揃える
  • ドーナツ中央の損益表示
    • 桁数が増えるとテキストがセグメントと重なって読みにくい
    • text-shadow で金額と損益にだけ白い縁取りを掛ける(小さなラベルには掛けない)。背景のセグメント色に関わらず数字が浮き上がる、最小限の処理
    • 損益額と損益%を2行に分ける構成も、もとはこのOGP出力時に「このほうが見やすい」と気づき、本体側へ取り込んだもの
  • 凡例レイアウトのはみ出し
    • 凡例幅が限られ、損益が右にはみ出てクリップされた
    • バー幅・フォント・ドーナツ径・余白を実測しながら詰めて収める
    • 割合バーが構成名と離れすぎる、本文が上に寄って下に余白が出る、といった細かいズレも実表示と揃うまで調整
  • シェア検証で出たSEO警告
    • opengraph.xyz で「タイトルが短い」「description が短い」「og:site_name が無い」と警告が出た
    • タイトル・説明文・og:site_name を補う
    • 実際にプレビューしてはじめて分かる類の指摘だった

https://www.opengraph.xyz/

CIで実ブラウザを起動してスクショを撮るという一見重いやり方を取ったのは、サイトと寸分違わぬ画像を保証する確実な方法だからです。Canvasで描き直す手もありましたが、字形やレイアウトがサイトと乖離するリスクを避けました。


セキュリティと公開範囲

そもそも今回は、冒頭に書いたとおり「自分の資産構成をシンプルかつオープンに見せる人がもっといてもいい」という思いから、評価額や保有内訳まで含めて公開するのが狙いでした。なので、自身の資産情報の一部が見えること自体は想定どおりで、むしろ大事なのは「見せると決めたもの」と「漏らしてはいけないもの」の線引きです。

その前提で、ここは慎重に設計しました。自身の経験則に加えて、Claude Code に「現状の実装にセキュリティ的な懸念がないか精査して」と棚卸しを頼み、出てきた指摘を一つずつ潰しています。

とはいえ、このプロダクトのリポジトリは現時点では非公開で、どこかへデータを送信したり、外部からデータを書き換えたりするものでもありません。なので大がかりな対策が要るわけではなく、最低限おさえておきたいポイントだけ対応した、というのが実態です。

  • 公開範囲の最小化
    • deploy.yml が公開専用 _site/ を組み立て、必要なファイルだけコピー
    • 取引台帳CSV・スクリプト・.claude/.git/ は Pages に載せない
    • dashboard.dc.htmlindex.html に複製し、<head>(OGPメタタグ含む)をクローラに届ける
  • サプライチェーン対策
    • 外部 GitHub Actions を commit SHA でピン固定(Action乗っ取り対策)
    • Dependabot が週次でSHA更新PRを出し、固定と追従を両立
  • 外部APIレスポンスの検証
    • ブラウザから叩く為替・金スポットの応答を有限数値チェック
    • おかしな値が来たら props の代替値にフォールバック
  • 規約の自動検査 … 前述の pre-commit(check-rules.mjs)で、禁止語の直書き・絶対パス参照・ドキュメント未同期を検出。
  • 公開リスクの明示
    • private でも、GitHub Pages の公開URL自体は誰でも閲覧できる
    • アクセス制御付きの非公開 Pages は GitHub Enterprise Cloud のみ
    • 資産情報がURL経由で公開される前提で使う旨をREADMEに明記
    • 取引台帳・ソースは _site/ に含めないので、サイトからは取得できない

自動更新とデプロイ

自分が手を動かさなくても、サイトに表示される株価や評価額が毎日最新に保たれる。これを支えているのが GitHub Actions によるCI環境です。

日次cron(snapshot.yml)が、株価更新 → 保有データ再生成 → 評価額スナップショット追記 → OGP画像再生成 → コミット、までを自動で回します。

デプロイ(deploy.yml)は、main 更新時と snapshot 完了時(workflow_run の連鎖)に _site/ を組み立てて GitHub Pages へ公開します。

設定で意識したポイントは次の通りです。

  • SHAピン留め: 外部Actionsはすべて commit SHA で固定(理由・Dependabot連携は前述の「セキュリティと公開範囲」を参照)
  • permissions の最小化: コミット&プッシュ用・Pages デプロイ用に絞る
  • 変更なし時のスキップ: 差分がなければコミットせず、不要な空コミットを防止
  • OGP画像の同時再生成: 履歴更新とOGP画像の再生成を同じワークフローで行い、画像とデータの鮮度を揃える

前述のとおりブラウザはリポジトリに書き込まないので、自動化はすべてCI側に閉じます。閲覧者は常に最新のスナップショットを見るだけ、という構造です。


制作のワークフロー

今回とりわけ紹介したかったのが、Claude Design と Claude Code を行き来する、この作り方のループです。

基本のループ

  1. Claude Design で大枠のデザインと動くプロトタイプを作る(案A/B/C を見比べて方向を決める)
  2. 受け取った変更を手元のリポジトリに適用・コミット・push して Git の正にする
  3. Claude Code で実データ・CI・挙動調整を作り込む。実機(PC/スマホ)で見て気になった所を、対話で直しては確認、を繰り返す
  4. 確定したものだけがコミットされ、また次の「見て直す」へ

このやり方の良いところは、実物を見て判断するのと、Gitで正とするのを両立できる点です。判断は常に動く画面に対して行い、確定したものだけが記録に残る。

前述の共有モード(金額を伏せて構成だけ見せる機能。実装して試したうえで、目的に合わないと判断して撤去した)のように、作って見てやめる判断も、このループだから速くできました。

デザインの発散は Claude Design、実装の収束は Claude Code、と道具を使い分けた感覚です。

ローカルリポジトリを直接つなぐ

当初、Claude Design と手元のリポジトリの行き来は手作業でした。渡すときは GitHub からインポート、戻すときは変更ファイルを ZIP で書き出して上書き。往復のたびに「どっちが最新か」を気にするのが地味に面倒で、ここがずっと引っかかっていました。

この往復のうち、まず手元のリポジトリを Claude Design に読み込ませる側は、ディレクトリ接続でぐっと楽になりました。

プロダクトを作る過程で Claude Design のメニューをポチポチ押してみたり、公式ドキュメントを見直してみたりしているうちに、「Link Local code」から手元のリポジトリディレクトリを直接読み込めると分かりました。

Claude Designの「Link Local code」メニュー
「Link Local code」から手元のローカルディレクトリ(リポジトリ)を指定して読み込ませる

この連携を設定しておくと、GitHub を介さず、Claude Code で編集した最新ファイルをそのまま読めます。

余談:ZIP受け渡しで出た mac の「エラー14」

変更ファイルをZIPで受け取った際、macOS標準の Finder で解凍すると「エラー14」が出てつまずきました。原因はZIP内のドットファイル/ドットディレクトリ名で、.github/.claude/ をドット無しの名前に置き換えて出力し直すと解決しました。AIとの開発でも、こうした受け渡しまわりの泥臭い部分は地道に潰す必要があります。

書き戻しは Send 連携で

やっかいだったのは逆向き、つまりキャンバスでの編集をリポジトリへ戻す書き戻しの方です。

最初は ZIP 以外の手段があるのか分からず手探りでしたが、こちらもメニューを探っていくと「Send to...」という共有機能が見つかりました。

Claude Designの「Send to...」宛先メニュー
「Share」ボタンから「Send to...」と辿った先にある

結論から言うと、この Send 連携を使えば ZIP を介さずスムーズに反映できます。

流れはシンプルです。

  1. Claude Design のキャンバスで編集する
  2. 「Share」→「Send to...」→ 宛先「local coding agent」(=Claude Code)を選んで Send
  3. 表示されたプロンプトを Claude Code に貼る(プロジェクトと対象ファイルが指定済み)
  4. Claude Code がプルして git diff を表示。確認して commit

「Send to local coding agent」で生成されたハンドオフ用プロンプト
生成されるプロンプト。プロジェクトURLと対象ファイルが入り、Copy prompt でそのまま Claude Code に貼れる

実際の転送は Claude Code 側からのプルで、「Send to local coding agent」はその指示プロンプトを用意してくれるだけです。なので Send を使わず、Claude Code に直接「あのプロジェクトを取り込んで」と頼んでも結果は同じでした。

この方式の良いところは、取り込みのたびに git diff を挟めることです。Claude Design が勝手にリポジトリを書き換えるのではなく、最終的なコミットは人間+Git で確定します。ZIP の解凍も手上書きも要らず、いつもの開発ループにそのまま乗りました。


さらに踏み込む:デザインシステムで単一ソース化

基本のループが回るようになると、次に気になるのが「デザインとコードの単一ソース化」です。以下は、/design-sync というコマンドを入口に、今の運用からどこまで踏み込めるかを調べ、実際に試した記録です。

/design-sync で単一ソース化はできるか

書き戻しとは別に、/design-sync というコマンド(スキル)も気になっていました。Claude 公式は「Claude Code と Claude Design が sync both ways(双方向)」とアナウンスしていて、デザインシステムをリポジトリへ取り込む方向も、コードからデザインへ戻す方向も使える、とされています。

双方向に行き来できること自体は、公式の機能です。

https://claude.com/blog/claude-design-stays-on-brand-for-daily-work

ただ、ここで同期の主役になるのは、アプリのページ一式ではなく 「デザインシステム」 です。pf- のようなコンポーネントや配色トークンを共通ライブラリとして登録し、それを正として Claude Design と揃える、という仕組みです。

用語メモ:デザインプロジェクトとデザインシステム(Claude Design 上の単位)

ここで言う「デザインプロジェクト」「デザインシステム」は、いずれも Claude Design の中で作る制作単位の呼び名 です。一般的な意味で「デザインシステム」というと、配色・タイポ・コンポーネントの規約をまとめた仕組み全般を指しますが、ここでは Claude Design 上に作る具体的なオブジェクトを指して使っています。

  • デザインプロジェクト … ページやプロトタイプを作る個別の制作単位。今回のダッシュボードもこれにあたります
  • デザインシステム … 色・タイポグラフィ・コンポーネントなどを抽出した、再利用可能な「基準」のセット。アカウントや組織内で作る各プロジェクトの土台になります

業界一般の「デザインシステム」という概念を、Claude Design がセットアップして登録できる機能として持っている、と捉えると分かりやすいです。公式ヘルプは、この機能としてのデザインシステムを「ブランドアセットから Claude が抽出する、再利用可能なコンポーネントとガイドラインの基礎となるセット」(A design system is a foundational set of reusable components and guidelines that Claude extracts from your brand assets)と定義しています。一度セットアップすると、以降そのアカウントで作るプロジェクトがこのシステムを既定として使うようになる、という位置づけです。

つまり /design-sync が橋渡しするのは「デザインシステム」であって、自分がやりたかった「Claude Design でいじったページの差分を、そのままリポジトリへ書き戻す」のとは、少し層が違いました。

試してみると、同期先が無かった

実際に Claude Code から確認したところ、自分の Claude アカウントに紐づく書き込み可能なデザインシステムの一覧は空でした。つまり、今のダッシュボードは通常の「デザインプロジェクト」であって、「デザインシステム」としては登録されていません。

取り込む先の「デザインシステム」がそもそも無いので、今のアプリ単位の往復を /design-sync がそのまま肩代わりしてくれるわけではない、というのが調べてみての結論です。

ではどういうときに効くのか。pf- のコンポーネントと配色トークン(styles.cssjs/format.jsdesign.md の実値)をデザインシステムとして切り出し、ローカルを正として登録すれば、Claude Design が常に自分の実部品で組むようになります。

今回 OGP 画像をサイト本体と寸分違わず揃えるのに苦労したような、配色やコンポーネントの食い違いを、構造的に減らせるはず。これは今の運用の置き換えというより、一段上の「単一ソース化」に踏み込むなら、という次の一手として捉えています。

実際に pf- をデザインシステム化してみた

せっかくなので、この記事を書いているセッションでそのまま試してみました。

Claude Code 側から、先ほどの配色トークン(styles.css などの実値)と代表コンポーネント(カテゴリチップ・トグル)を、新規のデザインシステムへ push します。

向きはドキュメントどおり ローカル(コード)→ Claude Design です。

push すると、Claude Design 側にカードとして並びました。

デザインシステムのColorsカードに配色トークンが描画されている
Colors カード。design.md の実値そのままに配色が並ぶ

ColorsTypeComponents(チップ・トグル)が並び、配色は16進数まで実値どおり。これで Claude Design は、次に何かをデザインするとき、この実コンポーネントを土台に組んでくれる状態になりました。前のセクションで「単一ソース化が効く」と書いた、まさにその状態を実際に作れたわけです。

そしてこの「コード → デザインシステム」の向きは、/design-sync(Claude Code 側)が入口になります。コードを正とする今回の運用とは相性がよく、コードを直すたびに Claude Code から押し上げれば、デザイン側との食い違いを元から減らせそうです。

正直、今回のダッシュボードは画面も部品も限られていて、デザインシステム化をフルに活かすほどの規模ではありませんでした。ただ、業務で扱うような画面数の多いサービスやアプリで、しかも長く運用を続けていくほど、この仕組みは効いてくるのではと感じます。配色やコンポーネントの基準を一箇所に集約し、コードとデザインの食い違いを構造的に防げる価値は、規模が大きく寿命が長いほど大きくなるはずです。


おわりに

設計を貫いた5つの価値観

今回のプロダクトづくりを振り返ってみると、設計判断のほとんどに自身の価値観が反映されていました。

  1. メンテナンスコストを極力抑えること(そもそも頻繁なアップデートをかけない前提で、放っておいても維持できる状態) → ビルドレス、依存ゼロ、キー不要API
  2. データが嘘をつかないこと → 取引台帳という単一ソース、生成物は直接編集しない、pre-commit で一致を強制
  3. 触らず最新であること → CIが株価取得・スナップショット・OGP生成・デプロイを日次で回す
  4. 意味のない色・数字・装飾を足さないこと → 情報密度は上げつつ、ノイズは削る
  5. 安く作って、見てから捨てること → 関心の分離が、機能の撤退も楽にする

道具の使い分け:発散は Claude Design、収束は Claude Code

Claude Design を使うと、プロダクトの方向性を定めるのが速くなると感じました。複数案を動く形で並べてくれるので、文字の仕様で悩むより先に「これだ」を選べる。トンマナと配色の軸が最初に固まると、その後の細部判断がぶれません。

Claude Designが生成したプロトタイプ画面
動くプロトタイプなら、ひと目で良し悪しを判断して方向を選べる

一方の Claude Code は、決めた方向を実機で見ながら詰めるのが強い。今回のように「スマホで見たら縦幅を食う」「中間幅でテキストがはみ出す」といった、実物を触らないと出てこない不満を、対話で直してはすぐ確認できます。

発散と収束で道具を分けると、両方の良さが活きるのではないかと感じました。

それでも、手放してはいけないところ

AIに任せても大丈夫そうな範囲は、確かに増えてきました。それでも、生成されたUIは実際にブラウザやスマホで触ると気になる点が必ず出てきます。

推移グラフの泥臭い作り込みがまさにそうで、自分の目で確認して改善を重ねることが完成度につながりました。大量の変更時には意図しない上書きもあり得るので、git diff での差分確認も欠かせません。

評価額の推移グラフ
推移グラフは実機で見るたびに不満が出て、自分の目で確認しながら何度も往復して詰めた

それこそハーネスやループエンジニアリング的な設計を突き詰めていけば、作業のほとんどはAIに任せられるようになるのかもしれません。それでも、最終的なアウトプットを見るのは自分ですし、何か問題が起きればそれは自分の責任です。

責任や倫理にかかわる部分は、安易に手放さず人間がやるべきところだと思っています。

個人の道具だからこそ

あくまで個人サービスなので「多くの人にとって最適」を目指す必要がなく、「いまの自分にとっての最適解」をすぐ形にできました。あとから「やっぱりイマイチだな」と思う部分が出ても、その改善サイクルを高速に回せること自体が、AIエージェントを軸にした開発の強みだと感じます。

開発ワークフローやCI、ハーネス、セキュリティ、公開の仕方といった土台は、これまでAIで作ってきた個人サービスの知見がそのまま活きています。一方で、思いついたアイデアをすぐ形にして数を打てることは、今までの自分のスキルだけでは届かなかったところです。これらはAIの恩恵を存分に受けた部分だと言えます。

機能を増やすより、既にある価値を画面に出し、要素の役割を整え、運用を自動化する。地味ですが、長く使う個人の道具にはこれが効きます。資産の可視化ツールのつもりで始めましたが、結局のところ力を入れていたのは、放っておいても正しく動き続ける仕組みのほうだった気がします。

今回はこの資産ダッシュボードを事例に紹介しましたが、肝は中身が何であれ同じです。もっと自分用に最適化したいアプリやサービス、「こういうのが欲しいけど世の中にちょうどいいのが無い」というものがあれば、Claude Design で大枠を作って Claude Code で詰める、というこのループでいろいろ作ってみると面白いと思います。

Claude Design は公式のプロダクトページから始められます。気になった方はぜひ触ってみてください。

https://claude.com/product/design

現場からは以上です。

9
2

Discussion

ログインするとコメントできます
9
2