ハコヅミを作る #11:「森」の配色で、画面を作り直す
前回(#10)でMVPを振り返り、次にやることの1つに「UIの見直し」を挙げました。 今回は、その最初の一歩として、画面の土台を作り直しました。
これまでの画面は、機能を確かめるための最低限の見た目で、ページごとに bg-emerald-700 のような色を直接書いていました。これを、サービス全体で決めた方針に沿って置き換えます。
先に、共通の方針を決めた
いきなりハコヅミの画面を直し始めるのではなく、先に「どのサービスでも、色とCSSをどう管理するか」を決めました。 デザイントークン・UI部品・最小限の共通クラスの3段構えで、サービスごとに変えるのはトークンの値だけ、というものです。
中身は、別の記事にまとめました。
この方針は、リポジトリの CLAUDE.md と、Notionの「サービス開発の共通方針」にも書きました。Issueも「方針を書く(#42)」と「ハコヅミの画面を置き換える(#44)」の2つに分けています。
今回の記事は、後者の、ハコヅミでの実践編です。
配色は「森」
トークンの値、つまりハコヅミらしい色を決めました。 Claude Codeに、キャンプアプリに合いそうな配色をいくつか出してもらい、その中から「森」を選びました。
| トークン | 色 | 使うところ |
|---|---|---|
primary |
深い緑 #2f5d4a |
ヘッダー、見出し、ボタン、チェックボックス |
primary-soft |
淡い緑 #dce8df |
進み具合のバッジなど |
accent |
焚き火のオレンジ #c0622b |
差し色(まだ使っていない) |
surface |
生成り #f6f3ea |
ページの背景 |
surface-raised |
白 | カード |
ink / ink-muted |
墨色 / 灰色がかった茶 | 文字 / 補足の文字 |
深い緑はテントやタープ、生成りは帆布、オレンジは焚き火のイメージです。
オレンジの accent は、定義だけして、まだどこにも使っていません。「チェックが全部終わったとき」などの使いどころを、あとで決めるつもりです。
フォントは、当面は端末に入っているもの(システムフォント)のままにしました。
見た目:前と後
チェックリストの画面です。

前:白い背景に黒い文字。チェックボックスはブラウザ標準の青

後:上部にヘッダー、生成りの背景に白いカード。見出し・線・チェックボックスが緑になった
画面は、それぞれの時点のコードを手元で動かして撮ったものです。データは#7でNotionから取り込んだ、実際のギアを入れています。
ギアの登録画面です。

前:入力欄は黒い枠、保存ボタンは Tailwind の emerald

後:カードの中に入力欄をまとめ、キャンセルもボタンの形にした
大きく変わったのは次の点です。
- 画面の上部に、共通のヘッダーを置いた。アプリ名と、チェックリスト・ギア・コンテナ・プランへのリンクが並び、どの画面からでも移れる
- 背景を生成りにして、中身を白いカードに載せた
- 見出しを緑にして、コンテナなどのまとまりの見出しには緑の線を引いた
- チェックボックスは、ブラウザ標準の形のまま、色だけ緑に合わせた(CSSの
accent-color)
画面のコードは、こう変わった
ギアの登録画面のボタンの部分です。前は、色も形もその場に書いていました。
<button type="submit" class="rounded bg-emerald-700 px-4 py-2 text-white">保存</button>
<a href={resolve('/gears')} class="px-4 py-2">キャンセル</a>
後は、UI部品を使うだけです。
<Button type="submit">保存</Button>
<LinkButton href={resolve('/gears')} variant="secondary">キャンセル</LinkButton>
色や角丸は Button の中にしかないので、画面のほうは「何のボタンか」だけが読み取れます。
トップ、ギア、コンテナ、プラン、チェックリストの全画面(13画面)を、この形に置き換えました。
動きは変えない:E2Eをそのまま通す
今回のIssueで一番気をつけたのは、「見た目以外(動き・URL・データ)は変えない」ことです。ACにも、次の1行を入れました。
これまでの E2E テストが、すべてそのまま通る(動きが変わっていない)
ほぼ全画面のファイルを書き換える大きな変更なので、動きが変わっていないことを、人の目だけで確かめるのは無理があります。そこで、これまでに書いてきたE2Eテスト(51件)を、テストのほうは1行も変えずに全部通すことを条件にしました。
これが効いたのが、ヘッダーの作り方です。 E2Eテストは、「見出し(h2)が『カーゴ 30L-1』の section」や「リストの項目」のように、画面の構造を手がかりに要素を探しています。ヘッダーのリンクを見出しやリストの項目で作ると、テストが別の要素を拾ってしまうおそれがありました。 そのため、ヘッダーは見出しもリストも使わず、リンクを並べるだけの作りにしています。
「色が1か所で変わる」ことも、テストで確かめた
もう1つ、今回ならではのACがありました。
app.css の primary の値を変えると、ボタン・見出し・チェックボックスなどの色がまとめて変わる
画面を触っても確かめにくいので、「(自動テストで確認)」としたACです。E2Eテストで、ページに --color-primary だけを差し替えるスタイルを足し、ボタンの背景、見出しの文字、ヘッダーの背景、チェックボックスの色が、4つとも新しい色に変わることを確かめています。
// app.css のトークン(--color-primary)だけを差し替える
await page.addStyleTag({ content: ':root { --color-primary: rgb(200, 30, 60); }' });
どこかの画面に bg-emerald-700 が残っていたり、部品が色を直接持っていたりすると、このテストで見つかります。
パレットの色を書くと、CIが止める
共通方針の記事で書いたとおり、ページに bg-emerald-700 や text-gray-600 のようなパレットの色を直接書くと、CIが失敗するようにしました。
見直しの前は、15ほどのファイルにパレットの色が書かれていました。置き換えたあとは0件です。
実際に、ある画面の text-ink-muted を text-gray-600 に書き換えて、チェックが失敗することも確かめてから、元に戻しました。
Issueからの変更
実装してみて、Issueから2点を変えました。どちらもPRとIssueの「変更履歴」に理由を残しています。
- 文字と線のトークン名:Issueでは
text・borderとしていましたが、クラス名がtext-text・border-borderになって読みにくいので、ink・lineにした - UI部品を2つ追加:Issueに挙げた8つに、メモ用の複数行の入力欄(
TextArea)と、白い面(Card)を足した
おわりに
- 先にサービス共通の方針を決めてから、ハコヅミの画面に当てはめた
- 配色は「森」。深い緑・生成り・焚き火のオレンジ
- 動きを変えていないことは、既存のE2Eを変えずに全部通すことで確かめた
- 色が1か所で変わること、パレットの色を書くと止まることも、テストとCIで確かめた
これで、見た目を直したいときは、トークンかUI部品の1か所を直せば済むようになりました。 ただ、今回は「土台」までです。スマホで片手で操作しやすい大きなボタンなど、積み込みの現場での使いやすさは、まだこれからです。