📗

機能はできた。でも画面に個性がない——自作アプリを「机の上の紙の道具」に見立て直した話

に公開

自作アプリの画面を眺めていて、あるとき気づいてしまいました。

清潔で、読みやすくて、どこにでもある画面だな、と。

長い長いノート」というタスク管理アプリを個人開発しています。タスクを完了すると自動的にタイムラインに記録されて、「あれいつやったっけ?」が後から検索できるアプリです。機能は安定し、色も前回の記事でCSS変数に整理してティールに統一し、ダークモードも整えました。それでも既視感が消えない。色は自分のものになったのに、それを載せている骨格が、明るいグレーの背景に白いカード、角丸、細線アイコンという標準的な文法そのままだったからです。

個人開発のアプリにとって、これは見た目だけの問題ではありません。宣伝素材はほぼスクリーンショットしかないので、画面の画像が一目で「あのアプリだ」と分かるかどうかは、そのまま実利に関わります。

この記事は、その画面を3日間で全面的に作り直した記録です。私はライターで、コードを自分で書く力はありません。実装はすべてClaude Code(AIコーディングツール。モデルはClaude Opus 5)にやってもらっています。今回の自分の仕事は、これまでのシリーズと少し違いました。このアプリを何に見立てるかを決めることです。

刷新前と刷新後
刷新前と刷新後

ひとつの比喩に、全部を対応させる

派手な色や変わったレイアウトは「変わった画面」にはなりますが、「このアプリらしい画面」になる保証はありません。とはいえデザインの設計なんてやったことがないので、Claude Cowork(モデルはClaude Fable 5。ローカルのフォルダを読み書きできるClaudeのチャット)に現行のコードベースを丸ごと見せて、進め方から相談しました。返ってきたのは、色や部品を個別にいじるのではなく、画面全体を貫くひとつの比喩、つまりデザイン言語を先に決めるという答えです。

比喩の種は自分の中にありました。ひとつは連用日記。同じ日付のページに数年分の欄が並ぶ、あの日記帳です。完了記録が何年分も積み上がるこのアプリは、要するに、終わったことが日記になるアプリなのです。もうひとつは付箋。まだ終わっていないタスクは、剥がす前提で仮に貼ってある紙であってほしい。この2つを対話で突き合わせて、アプリ全体を「机の上の紙の道具」に見立て直すと決めました。

アプリの概念 見立て
未完了タスク 付箋(剥がす前提の仮の紙)
タイムライン 帳面(残す前提の長い一本の記録)
タスク完了 付箋を剥がして帳面に清書する
過去の同じ日の記録 帳面に挟んだ紙を引き出して読む
タグ 帳面の小口に貼ったインデックス
モーダルの背景 トレーシングペーパー

この対応関係には最初から動きが含まれています。付箋を剥がして帳面に清書する、は静止画では表せないからです。だからプロトタイプの最初の依頼も「連用日記モチーフでプロトタイプ設計できる? タスク管理から自然にトランスフォームしている感じのエフェクトも」という注文でした。これは装飾ではなく構造の比喩で、後の判断の多くがここから導かれることになります。

刷新後の画面。付箋のタスクと帳面のノート
刷新後の画面。タスクは付箋、下のノートが帳面

実装の前に、終わらせる

このアプリを最初に作ったときは、Claude.aiのチャットでプロトタイプを22バージョン改良してから実装に入りました。今回も同じやり方ですが、道具は変えました。動いているアプリの刷新なので、既存のコードという文脈を読んだ上で描いてもらう必要がある。CoworkでHTMLのプロトタイプを9点作り、新しい付箋を上に貼るか下に貼るかは現行実装の挿入順に揃える、といった突き合わせをしながらフォルダに保存していきました。

失敗もこの段階で潰れています。代表がダークモードです。Coworkは紙のメタファーに忠実に、ダークモードまで茶系の暖色で組んできて、画面はセピア色の古文書になりました。考えてみれば当然で、Coworkはコードは読めても、前回17回の調整を重ねてSlate系のダークモードを作った経緯までは知りません。ライトモードが白から紙の色になるのは連続的な変化でも、ダークモードまで茶色にしたら既存ユーザーには別物に見えてしまう。今までのトーンには青が入っていたはずだと伝えて現行の実値を確認させ、今のダークモードに紙の質感が乗った、という形に再設計してもらいました。

公開版のダークモード
公開版のダークモード。青いトーンを保ったまま、紙の質感だけが乗った

数字の裏付けも入りました。プロトタイプが出そろってきた深夜、並行してClaude Codeに「このデザインで現行コードを刷新する場合の課題と、UI的に適しているのか」を検討させたところ、判定は「条件付きで適する」。条件のひとつが文字の読みやすさで、紙らしい淡さを狙った文字色は、文字と背景の明るさの差(コントラスト比)が実測3.2:1しかなく、Webアクセシビリティの指針が本文に求める4.5:1を割っていました。言われるまで、そういう基準があることすら知りませんでした。以降のすべての色は実測値付きで決まっています。

この検討では、設計とコードの食い違いも実装前に7件見つかりました。たとえば、タスクを完了した瞬間の記録です。完了日時はサーバー側で確定する作りになっていて、確定が返ってくるまでのコンマ数秒、記録は日時を持ちません。日時のないデータは1970年1月1日として扱われるため、その一瞬だけ、できたての記録はタイムラインの最下部、何年も前の記録のさらに下に置かれていました。すぐ正しい位置に移るので今まで誰も気づかなかったのですが、これから作る完了エフェクトは、付箋の文字が今日の欄へ飛んで着地する演出です。着地するべき記録が、その瞬間だけ画面のはるか下にいる。これでは成立しません。修正は d.data({ serverTimestamps: 'estimate' }) の1行でした。作り始めてから踏めば手戻りになるものばかりです。

HTMLプロトタイプのライトとダーク
HTMLプロトタイプ。左がライト、右は再設計後のダークで作った画面の見本集

基準で決めて、行き過ぎは止める

比喩を決めて一番助かったのは、判断に基準ができたことです。私にはデザインの素養がなく、「なんとなくこっちがいい」では決められません。でも「紙ならどうなっているか」なら考えられます。

済スタンプは完了の瞬間だけ表示して約2秒で消すことにしました。帳面に載っている時点で完了は自明なので、全行に付けたら意味のない模様になるからです。

付箋の色は、Coworkの最初の案が黄色とティールを交互に差し込む賑やかしだったのをやめて、タグの色からだけ導くことにしました。意味のない色の違いは、見る人に偽の謎を与えるだけです。それに、このアプリには記事に書きそびれたままのタグ機能があって、その成果を使わない手はない。

テーマ色のティールはチェックや保存ボタンなどシステム専用に固定し、紫はAI、くすんだ朱は危険、と色の役割も決めました。どれも審美眼ではなく、紙ならどうか、現行の使い方と衝突しないか、という物差しに当てただけです。

比喩を詰めていくと、デザインの範囲を超えて作るものまで決まりました。過去年の同じ月日に記録がある日だけ、日付見出しの下から紙の端が覗いて、押すと挟み紙が引き出される「この日の記録」。連用日記の楽しさを、記録のない日には何も出さない形で取り込んだ新機能です。ログイン画面は「机に置かれた閉じた帳面」になり、その表紙を考える過程でタグライン「終わったことが、日記になる。」も決まりました。

この日の記録
「この日の記録」。過去年の同じ月日の記録が、挟み紙として引き出される

一方で、行き過ぎを止めるのは人間の仕事でした。やり過ぎるのは、だいたいClaudeの側です。デザイン担当のFable 5が書いたプロトタイプはCSS変数の名前からして机(desk)・紙(paper)・インク(ink)。実装担当のOpus 5は作業日誌に「検索を帳面から剥がして一枚の紙にする」と見出しを付ける始末で、比喩に浸かりきっているから画面は一貫するのですが、その言葉はユーザーに見える場所へも漏れ出します。調べると、UIの文言に見立ての言葉が7箇所混ざっていました。そこで名詞は機能名、動詞と状態は見立てというルールに揃えています。比喩は見た目で伝えるものであって、言葉で「これは付箋のつもりです」と説明したらそれは注釈です。刷新のお知らせ文も、Claudeの初案は見立てを前面に出したものでしたが、紙の道具に変わりました、はキザすぎる。「デザインと操作を新しくしました」に直しました。

コードは読まない。画面を触る

実装は7フェーズに分け、フェーズごとに全テストを通しながら専用ブランチに積みました。この間、正直に言うと、私はコードを読んでいません。Claude CodeはAutoモード(変更のたびに承認を求めない設定)で走らせたので、読む時間がそもそもない。流れていく差分を眺めて、ずいぶん複雑な書き方をするなと思うことはあっても、その動きをコードの側から確かめてはいない。エンジニアの作法としてどうなのか、と自分でも思います。

実装中の画面の変遷
実装中の画面の変遷。チェックボックスの行が付箋になり、公開版ではタグの色が差す

代わりにやったのが、区切りごとに実機のスマホで触って、感じたことを言うことです。ダークモードの付箋を見て「付箋っぽく見えないな」。検索画面が幅からはみ出していたら、スクリーンショットに「入りきってないよ」と添えて送る。その程度の雑な報告でも、向こうが原因を特定して直してきます。判断が要る場面では選択肢が比較と推奨付きで提示されるので、返事はたいてい数語でした。「おすすめで」「進めて」「それでいい。ノートにするか」。

刷新の目玉である清書の演出も、この往復で仕上がりました。チェックを入れると付箋が剥がれ、文字だけが帳面の今日の欄へ飛び、着地すると本文が左から右へ綴られ、最後に済の判が押される。面白かったのは、最初の実装では一番下の行に着地してから一番上に出てきたことです。付箋が消えるとリストが上にずれ、記録が挿入されると行が下にずれる。飛んでいる間に着地点のほうが動くので、毎フレーム測り直す方式になりました。

清書の演出
清書の演出。付箋が剥がれ、文字が今日の欄へ飛んで綴られ、済の判が押される

// src/contexts/FlightLayerContext.jsx(抜粋・一部略)
const step = (now) => {
  if (startTime === null) startTime = now;
  const progress = Math.min((now - startTime) / duration, 1);
  const eased = 1 - Math.pow(1 - progress, 3);

  const to = anchor.getBoundingClientRect(); // 着地点は毎フレーム測り直す
  /* …座標と幅の補間… */
  // 飛びながら徐々に薄くなり、着地の瞬間には完全に透明になる
  node.style.opacity = String(1 - progress);

  if (progress < 1) {
    rafId = requestAnimationFrame(step);
  }
};

文字が綴られる速さも、固定時間では「綴られてない」と感じたので、1文字あたり110ミリ秒の比例式になりました。手で書く速度は文字数で決まるからです。

export const getWriteDuration = (title) =>
  Math.min(Math.max((title?.length ?? 0) * 110, 600), 2000);

一方で、実機でしか出ない問題にも次々当たりました。象徴的だったのが付箋の束です。このアプリには、タスクが増えたときに先頭の数枚だけ見せて残りを畳んでおける機能があり、刷新後は、隠れている付箋の縁が数ミリずつ覗く「束」の見た目にしました。タップで全部開き、つまんで上下にドラッグすると表示する枚数を調整できる。束には「あと8枚 — つまんで引き出す」というラベルが付きます。この束が、実機だとタップで開かない。報告するとClaudeが直してくるのに、触るとまだおかしい。3回直してもらっても駄目で、4回目にようやく私が気づきました。「つまんで引き出すの文字を長押ししてた」。つまめるのは付箋の縁だけで、「つまんで引き出す」と書いてあるラベル自体はつまめない実装だったのです。Claudeは3回とも、書いてある言葉の通りに触れるかという一番手前の観点が抜けたまま、細部だけを直し続けていました。

実機での確認
確認はコードではなく実機で

対案まで自分で出した件もあります。タイムラインの行の操作ボタン(タスクに戻す・削除)は、マウスならホバーで先に見えますが、指にはその段階がなく、触った瞬間に編集画面とボタンが同時に現れる。実機で触って「モバイルだと何もないところからいきなりでてきて怖い」と伝えました。Claude側はボタンを常時薄く表示しておく案を検討したのですが、計算すると視認性の基準を満たす薄さの余地がほとんどない。そこで「一回タップするとフォーカスが当たって、2回目で操作できるようにしたら?」と提案して、これが採用されました。ボタンの出現が自分のタップへの応答になるので、驚きが消えます。

コードを読まない代わりに、確かめさせることは惜しみませんでした。そもそも工程が3段階になっています。CoworkのFable 5がデザインを作り、実装に入る前にClaude Code側のFable 5が計画書を書いて設計と現行コードを突き合わせ(先ほどの「条件付きで適する」の判定です)、約12時間のメイン実装はClaude CodeのOpus 5が完走させる。モデルが同じでも、計画書を書く側はデザインの会話の経緯を知らないので、遠慮なく粗を挙げてきます。前の段の成果物を、次の段が疑ってから進む構図です。

書かれたコードには、公式のコードレビュースキルと、以前から使っている先輩2人の会話形式レビューの2種類をかけました。公開前の一括レビューでは43コミットに15件の指摘が出て、抜き取りで検証した4件がすべて実在したので、信用して全件対応しています。

自動テストは608件から816件に増えました。サーバー側の改修はデプロイ前に本物のAPIを一度叩いて確かめ、フォールバックの裏に隠れて気づけないはずだったバグを捕まえています。読んで確かめる代わりに、別の目に何度も判断させていたわけです。

それでも、すり抜けるものはあります。キーボードの件で、コードを読んでいなかったのはClaudeの方でした。このアプリには矢印キーで画面中を移動できる独自の操作体系があり、専用のフックとテスト資産を持つ一等地の作りです。それ自体が「このアプリの使い手はこう動く」という記録なのに、モーダルを紙に載せ替えたとき、ClaudeはそれをWeb標準のTabとEscで置き換え、独自ナビを約90行消せたと日誌に書いていました。コードを字面として読めても、そこに書かれた操作の文法の価値は読めていなかったわけです。毎日矢印キーで動かしている私には、触れば一瞬で分かります。公開前の確認で「キー操作が効かない」と4件続けて報告しました。使い込んだ指は矢印を覚えている。Tabキーは、Webの標準ではあってもこのアプリの中では方言だったのです。

この多段の工程もレビューも通り抜けた問題を捕まえたのは、毎日使っている指でした。

結果

検討開始が8月15日、本番公開が8月18日。ブランチには64コミット、変更は121ファイルでした。操作の構造はほぼ現行踏襲なので既存ユーザーの習慣は壊れていないはずですが、スクリーンショットは別物になりました。少なくとも、もう「どこにでもある画面」ではないと思います。公開したばかりなので、既存ユーザーの反応はこれからです。

これから真似る人向けに、かかったものも書いておきます。デザイン検討がCoworkで一晩と半日、メイン実装がClaude Codeで約12時間、翌日の仕上げと公開までを含めて実働3日強でした。Autoモードは差分の承認を省くぶん速い代わりに、専用ブランチと自動テスト、フェーズごとの実機確認が前提になります。ブランチを切らずに走らせるのはおすすめしません。

なお、AIの利用はClaude Maxの20xプラン(定額)です。開発以外の仕事にも使っているので、この刷新単体のコストは切り出せません。

ログイン不要の体験版で、付箋も帳面も清書の演出も触れます。よかったら見てみてください。

https://longlongnote.aroka.net/?demo=1

関連記事

非エンジニアがClaude Codeでこのアプリをゼロから作った経緯、ダークモード対応、体験版を作った話はこちらです。

https://zenn.dev/tiaroka/articles/f6a0187b721607

https://zenn.dev/tiaroka/articles/3084ac6d4ff555

https://zenn.dev/tiaroka/articles/1fe6169a4bf7d7

Discussion