目次
はじめに
2025年9月に、Kiro と Cursor を使った仕様駆動開発の記事を書きました。その中のひとつが色彩学習アプリ Colorism です。当時は「6色を選ぶと世界が変わる」体験はできたものの、中身は薄く、学習カリキュラムとしては未完成でした。
半年ほど経ち、Colorism は v2 として作り直し、2026年6月に本番公開しました。今回の記事では、なぜ作り直したのか、どう進めたか、どこで苦労したか、そして v1 の記事より踏み込んだ所感をまとめます。
v1でうまくいったことと、限界
v1(Kiro + Cursor で仕上げた版)で資産になったのは、主に「体験」と「技術の土台」です。6色を選ぶとヒーロー画像やフォトギャラリーが変わるブランド体験、色相環や色彩心理学のインタラクティブ UI、Next.js App Router + Tailwind + Zustand という構成は、v2 でもそのまま活かしています。
- 6色グローバルテーマ
unified-colors.ts で全画面の色体験を統一 - ヒーロースライダー
選択色 × Unsplash。切替時のクロスフェードも v2 で改良 - インタラクティブ図解
色相環・色温度・色彩心理。ただし v1 ではホーム常設で説明が追いつかない - ドキュメント文化
docs/ と specs/ の蓄積。v2 では docs を正本に一本化
一方で、v1 を触っていて「学習アプリ」として物足りなかった点もはっきりしていました。
- コンテンツが UI の付属物になっており、カリキュラムとして設計されていない
- リッチな TypeScript DB と UI 内ハードコードの二重管理で、改善が線形に進まない
- 学習・作成・ツール・ギャラリーが並列メニューで、前提知識や到達目標が見えない
- 練習モードは問題数が少なく、難易度切替時の「次の問題」バグも残っていた
- 色彩検定対策の深度が足りない(色覚シミュレーション程度)
- color-practice-mode.tsx が約2,200行と巨大化し、改修コストが高い
見た目は豊かでも中身が薄い学習サイトではなく、初学者から検定・実務まで段階的に深まる「色彩の学習プラットフォーム」をつくる──これが v2 の目標です。
Colorism v2で目指したもの
v2 は、CursorのエージェントモードでAI駆動開発を行い、公開しました。v1 から意図的に継承したのは6色選択とヒーロー だけです。それ以外はアーキテクチャとコンテンツモデルを先に定義し直しています。
| 領域 | v2 の到達点(記事執筆時点) |
|---|---|
| 学習 | 6コース・25レッスン(MDX)。各レッスンにミニクイズ |
| 図解 | 色相環・Kelvin スケール・感情マップ等をレッスン内 Interactive に配置 |
| 練習 | 統一クイズエンジン・183問(4択・正誤・並べ替え等) |
| 検定対策 | /cert 新設。用語51語・ドリル6種・模擬テスト |
| 作成 | /create パレット(5色生成・保存・CSS/HEX エクスポート) |
| ツール | 変換・コントラスト・色覚シミュレーション |
| 品質 | WCAG 2.1 AA 目標・Lighthouse 85+・v1 URL 308 リダイレクト |
原則として Learn first(ツールやギャラリーは学習の補助)、Single source of truth(表示テキストは MDX/JSON のみ)、Show, then tell(説明の直後に図解やインタラクション)を方針としました。未実装や β 機能はラベルで正直に示す方針も v2 では明文化しています。
開発の進め方
v1 のときと同様、仕様駆動の考え方は継続しています。ただし v2 では docs/ を唯一の正本 にし、Phase 0(基盤)→ Phase 1(学習コア)→ Phase 2(コンテンツ)→ Phase 2.5(図解)→ Phase 3(練習・検定)→ Phase 4(SEO・a11y・リダイレクト)と、フェーズごとに出口条件を決めて進めました。
- プロジェクト憲章・要件・機能仕様・UI 設計・アーキテクチャを先に書く
- 実装計画書で Phase とタスクを分解し、完了ごとにドキュメントを更新
- 意思決定は decisions.mdに ADR 形式で残す
- 不具合は v2-issue-resolution-log.md に IR-001 以降で時系列記録
- 実装は Cursor Agent が主担当。人間はレビュー・方針決定・コンテンツ監修
v1 では Kiro で仕様を起こし Cursor に引き継ぐ流れでしたが、v2 では最初から Cursor 単独で docs を読み込ませながら進めました。Kiro の Specs/Vibe 消費や UI 一貫性の問題は v1 記事で触れた通りで、v2 では ルール(.cursor/rules)と docs の更新 で一貫性を保つ方針に寄せています。
アーキテクチャ上の設計判断
v2 で効いたのは、機能追加より先に データとルーティングの形 を固定したことです。代表例をいくつか挙げます。
コンテンツは MDX 単一ソース
v1 の `color-theory-database.ts` のような巨大 TS ファイルと、UI 内ハードコードの二重管理をやめ、`content/lessons/**/*.mdx` と `courses.ts` に集約しました。レッスン本文・Callout・MiniQuiz・Interactive は MDX 内で宣言し、`next-mdx-remote` + `remark-gfm` で GFM 表もそのまま使えます。
// レッスン MDX のイメージ(抜粋)
## HSL とは
<Callout type="info">色相・彩度・明度の3属性で色を説明します。</Callout>
| 属性 | 英語 | 意味 |
| --- | --- | --- |
| 色相 | Hue | 赤・青などの種類 |
<Interactive id="color-wheel" />
<MiniQuiz id="hsl-basics-01" />図解はレッスン内に閉じる
v1 ではホームに大型色相環を常設し、ヘッダーの6色と双方向同期させていました。見た目は派手ですが、「環の色とサイトテーマが一致しない」混乱も起きていました。v2 では ホームは入口に徹し、色相環・Kelvin スケール・感情マップは該当レッスン内の `<Interactive />` に移動。1レッスン1主役 Interactive、静止 Figure は補助1枚まで、というルール(D15〜D22)で読了フローを守っています。
クイズエンジン1本化
練習・検定ドリル・模擬テストは、すべて `content/quiz/*.json` と共通エンジンから出題します。v1 の「次の問題」が初級プール固定になるバグは、難易度に関係なく `getNextQuestion` を通す設計で再発防止しました。問題形式も4択だけでなく正誤・並べ替え・配色識別などを Phase 3.6 で拡張し、合計183問まで増やしています。
つまずいた点(紆余曲折)
いやー、スムーズではありませんでした。v1 よりドキュメントは厚いのに、AI 実装特有の「局所は直るが全体の整合が崩れる」問題は v2 でも繰り返し発生します。特に印象に残ったのは次のとおりです。
- 開発環境の Node 増殖
useSyncExternalStore の getSnapshot が毎回新オブジェクトを返し、無限再レンダー → Turbopack が暴走。親ディレクトリの lockfile 誤検出も重なった。対策: useState + イベント同期へ戻す、turbopack.root 明示、ブランチ切替後は npm run reinstall 必須 - ヘッダー2行化とモバイルナビ欠如
中幅でナビが消え、本文がヘッダーに被る。v1 同様の1行固定 + ハンバーガーメニューに戻した - Unsplash まわり
「画像を更新」が1時間キャッシュで同じ結果。紫の検索語 Royal Purple が城・バイク写真を返す。Purple に変更し API は no-store + ランダム page - MDX の GFM 表が素のテキスト表示
remark-gfm 未設定。比較表だらけのレッスン執筆前に気づけてよかった - Figure SVG の重なり・クリップ
viewBox 不足で注釈が切れる、色相環で橙と黄が同時選択になる。markerKey 単一選択・build-lesson-figures-ja.mjs で量産規約化 - 検証ハーネスのメモリ枯渇
Playwright 一括実行で PC がハング。日常は test:unit:light + validate:lessons、E2E は CI 手動のみ(D13) - /create パレットの URL ロック
?color= 付きで6色が固定されヘッダー連動不能。初回マウントのみ適用・customSnapshot で6色⇔任意色を往復
これらはすべて issue-resolution-log に ID 付きで残してあり、再発防止チェックリストも添えています。v1 の記事では「UI とロジックの一貫性が難しい」と書いただけでしたが、v2 では どの層で起きたか(React フック、Turbopack、MDX パイプライン、SVG レイアウト、外部 API)まで分解して記録した分、次に同種の問題が来ても当たり所が早くなりました。
v1からv2への機能整理
| v1 | v2 の扱い | 理由 |
|---|---|---|
| /learn/theory?section=* | 6コース25レッスン MDX | クエリ1画面 → カリキュラム型 |
| ホーム常設色相環 | harmony レッスン内 Interactive | Show, then tell |
| /gallery 専用 | ホーム下部ギャラリー | インスピレーションは入口に集約 |
| /create/design テンプレ | 未移植(308 → /create) | MVP はパレットに集中 |
| ゲーミフィケーション | 見送り | 学習深度を優先 |
| ユーザーアカウント | 未実装 | localStorage 進捗のみ |
| /test/* 開発ページ | 廃止 | Vitest + 手動チェックへ |
v1 ユーザーのブックマーク救済のため、主要 URL は `buildV1Redirects()` で 308 リダイレクトしています。外部 URL へのオープンリダイレクトは禁止し、テストで固定パスのみを検証するルールも決めました。
デプロイとパフォーマンス
本番は Vercel 上の既存ドメインを v2 リポジトリに付け替え、 https://color.app.bau-haus.com/ で公開しました。v1 のときと同様、ローカル dev は重く感じることがありますが、本番ビルドはサクサク動く印象です。Next.js 16 + React 19 + Tailwind CSS 4 という比較的新しいスタックですが、静的生成と MDX コンパイルの組み合わせは Vercel との相性が良かったです。

所感──v1の記事から変わったこと
v1 記事で書いた「仕様を固めても Vibe コーディングの途中でブラッシュアップが必要」「ルールを増やすと複雑化する」という話は、v2 でもその通りでした。ただし v2 では **仕様書そのものを成果物の一部** として扱い、実装と同じ粒度で更新し続けた点が大きく違います。
- 機能一覧の表(v1-v2-feature-matrix)で「なぜ捨てたか」を先に決めると、AI への指示がブレにくい
- 決定ログ(D番号)があると、同じ議論の繰り返しを防げる
- 不具合ログ(IR番号)があると、エージェント切替時も文脈を引き継げる
- Phase 出口条件があると、「とりあえず動く」で次に進まず済む
- コンテンツ品質監査(audit:cq)でレッスン深度を数値化できた
AI によるコーディングで初速は確実に上がります。一方で、人によるレビュー時間も増える──このバランスは v1 のときより実感として強くなりました。特に MDX 執筆・SVG 図解・クイズ JSON の コンテンツ整合 は、コードレビューとは別の目が必要です。個人的には、エージェントに「実装して」と言う前に「docs のどの節を更新するか」まで指定すると、手戻りが減ると感じています。
均質化の鍵は、生成物そのものより「正本ドキュメントと Phase 境界」にある──v2 を通してそう思いました。
得たもの
- 学習プラットフォームとしての骨格
25レッスン・183問・検定ハブまで一気通貫。v1 では到達できなかった「中身の厚さ」 - 再現可能な開発運用
docs 正本・決定ログ・不具合ログ・Phase 計画。別チャット・別エージェントでも再開しやすい - v1 資産の選別基準
「 delight は残す・負債は捨てる」を feature matrix で可視化 - 公開可能なプロダクト
本番 URL・308 リダイレクト・Lighthouse/a11y ゲート。ポートフォリオとして語れる完成度
まとめ
Colorism v2 は、v1 の「色を選ぶと世界が変わる」体験を残しつつ、中身を学習プラットフォームとして作り直したプロジェクトです。Kiro から Cursor へ、v1 から v2 へとツールとコードベースは変わりましたが、仕様駆動の考え方自体はより強くなっています。
これから AI エディタで個人アプリを育てる方にとって、v1 だけでは見えなかった「ドキュメントを正本にする」「Phase で出口を決める」「不具合を ID 管理する」あたりが、長期戦では効くのではないかと思います。Colorism はこれからもコンテンツ深度の充実や settings 画面など、バックログに載せた機能を少しずつ足していく予定です。もし、ご興味があれば https://color.app.bau-haus.com/ を触ってみてください。
フィードバックも頂けると嬉しいです!










No responses yet