マッチングアプリ テンプレート 要件定義書
プロダクト名:Souzoh Match
「Claude Codeでマッチングアプリを開発する方法と費用|そのまま使えるテンプレート配布【2026年】」記事のデモアプリ。 母艦テンプレート(Souzoh SNS)からの2本目。共通基盤を流用し、固有画面のみ新規実装します。
1. 目的とゴール
| 項目 | 内容 |
|---|---|
| コンセプト | 「できること」と「力を借りたいこと」で人をつなぐ、共創マッチング。恋愛・出会い系ではない |
| なぜこの題材か | ①スワイプUIという"マッチングアプリらしさ"を保ったまま恋愛色を外せる ②読者(事業者)が自社に置き換えて発注イメージを持てる ③デモデータそのものが「マッチする仕組み」の説明になる |
| 成功条件 | カードを3枚めくった時点で「これ自社の◯◯に使えるな」と読者が思う |
| 非ゴール | 実在ユーザーの本番マッチング。推薦アルゴリズムの精度 |
想定シーン:デザイナーが「フロント実装を手伝ってほしい」、エンジニアが「UIを見てほしい」。この2人が噛み合う。求人でも恋愛でもない、対等な交換のマッチングです。
2. スコープ
2.1 作るもの
| # | 画面 | 優先度 | 母艦との関係 |
|---|---|---|---|
| M1 | 探す(スワイプカードスタック) | A | 新規(母艦S1タイムラインを置換) |
| M2 | プロフィール詳細 | A | 母艦S2を改修 |
| M3 | 一覧・絞り込み | A | 母艦S3を改修 |
| M4 | マッチ/届いた興味 | A | 母艦S4を改修 |
| M5 | マイプロフィール | B | 母艦S5を改修 |
| M6 | 興味を送るモーダル | A | 母艦S6の枠をほぼ流用 |
| M7 | チャット | B | 母艦S7をそのまま流用 |
2.2 作らないもの
- ❌ バックエンド・DB・認証・データ永続化(母艦と同じ)
- ❌ 本物の推薦アルゴリズム(タグの重なり数で算出。むしろ仕組みが見えるほうがデモとして良い)
- ❌ 通報・ブロック・本人確認・課金
- ❌ ダークモード切替、多言語、テストコード
- ❌ スワイプの物理演算(慣性・回転は CSS transform で十分)
3. 技術構成
母艦と完全に同一。Vite + React 18(JSX)/Tailwind CSS v4/lucide-react/Cloudflare Pages。
1つだけ追加:スワイプのドラッグ判定に Pointer Events を素で使います(ライブラリ不要、約60行)。
4. デザイン仕様
4.1 方向性
母艦SNSが「明るい背景に浮かぶカード」だったのに対し、こちらは深いプラム地の"ステージ"に白いカードが1枚だけ立つ構成。視線をカード1枚に集中させます。
配色は当初案のコーラル×ピンクから変更しました。あの組み合わせは恋愛マッチングの記号そのもので、今回の非恋愛コンセプトと真っ向からぶつかるためです。代わりにアンバー+エメラルドを採用し、「取引・交換」の温度感に寄せています。
シグネチャー要素:重なりリング カード右上の円弧。自分の「力を借りたいこと」と相手の「できること」が何個重なっているかを弧の長さで表示し、タップすると一致したタグだけが発光します。マッチ率を数字で出すより、なぜ勧められたのかが一目でわかる。ここだけに演出を集中させ、他は静かに保ちます。
4.2 デザイントークン(src/theme.css)
@theme {
/* ---- Color ---- */
--color-bg: #201C2E; /* ディーププラム:カードが立つ舞台 */
--color-surface: #FFFFFF; /* カード面 */
--color-surface-2: #2E2842; /* 背景上のパネル・入力欄 */
--color-ink: #17161F; /* カード内テキスト */
--color-ink-sub: #6E6B7E;
--color-ink-inv: #F3F1F8; /* 暗背景上のテキスト */
--color-line: #E6E4EC;
--color-accent: #FFB020; /* アンバー:気になる・CTA */
--color-accent-sub:#2ED3A0; /* エメラルド:マッチ成立・一致タグ */
--color-skip: #8B85A3; /* 見送る(赤にしない。拒絶の記号を避ける) */
/* ---- Type ---- */
--font-display: "Bricolage Grotesque", "Zen Kaku Gothic New", sans-serif; /* 700 */
--font-body: "Noto Sans JP", sans-serif; /* 400/500 */
--font-num: "Space Grotesk", monospace; /* 一致数・稼働時間 */
/* ---- Scale ---- */
--text-display: 30px/1.25;
--text-title: 19px/1.45;
--text-body: 15px/1.75;
--text-meta: 12px/1.4;
/* ---- Space ---- */
--space-1: 4px; --space-2: 8px; --space-3: 12px;
--space-4: 16px; --space-6: 24px; --space-8: 32px;
/* ---- Shape ---- */
--radius-card: 24px; /* 母艦の20pxより大きく:カードが主役なので */
--radius-input: 14px;
--radius-pill: 999px;
--shadow-card: 0 24px 60px rgba(0,0,0,.35); /* 暗背景なので影は強め */
--shadow-pop: 0 12px 40px rgba(0,0,0,.45);
}
--color-skipを赤にしないのは意図的です。恋愛アプリの「×」は拒絶ですが、ここでは「今回は縁がなかった」だけ。ニュートラルグレーで温度を下げます。
4.3 レイアウト
| 仕様 | |
|---|---|
| モバイル(〜768px) | カード幅 = 画面幅 - 32px、高さ = 表示領域の68%。下部にアクションボタン3つ |
| PC(769px〜) | カード 400×560px を中央に固定。左に幅240pxの縦ナビ |
| カードスタック | 3枚重ね。2枚目 scale(.95) translateY(12px)、3枚目 scale(.90) translateY(24px)、透明度も段階的に |
prefers-reduced-motion |
ドラッグ追従は残し、弾け演出とスタックの動きだけ無効化 |
4.4 画像
母艦と同一。アバターはIDから決定的に生成したグラデーション円+頭1文字。public/images/{id}.jpg を置けば実写に差し替わります。
5. 画面仕様
M1. 探す(スワイプカードスタック)★固有画面
カードの中身(上から)
- アバター(72px)+ 氏名 + 肩書き + エリア
- 重なりリング(右上・48px):一致数を弧で表示。中央に
--font-numで数字 - 一言(1〜2行)
できることチップ群 — 一致したものは--color-accent-subの地に白文字力を借りたいことチップ群 — 同上- 稼働:
週2〜3時間 / 平日夜など
操作
| 操作 | 結果 |
|---|---|
| 右へドラッグ or ♡ボタン | 気になる。カードが右上へ回転しながら退場(rotate(12deg)) |
| 左へドラッグ or ×ボタン | 見送る。左下へ退場 |
| 上へドラッグ or ✉ボタン | M6「興味を送る」モーダルを開く |
| カードをタップ | M2 プロフィール詳細へ |
| ↩ボタン | 直前の1枚だけ戻せる(連続不可) |
| キーボード ← → ↑ | 上記に対応(アクセシビリティ必須) |
ドラッグ中のフィードバック:移動量80pxを超えたら、進行方向にラベル(気になる / 見送る)がフェードイン。カードは移動量に応じて最大12度傾く。
マッチ成立演出:u01 / u05 / u09 を右スワイプすると必ず発火。暗転オーバーレイ+2つのアバターが中央で寄り、マッチしました + 一致タグを表示。メッセージを送る / 続けて探す の2択。
カードが尽きたら:空状態「今日はここまでです」+条件を変えて探す(M3へ)。
M2. プロフィール詳細
- カード内容の全量表示。スクロール
これまでの共創:3件を箇条書き(例:「ECサイト構築 × 商品撮影」)- 一致タグを画面上部にサマリー表示
- 下部固定:
見送る/興味を送る
★評価スコアやレビューは入れません。実体のない星は信頼を作らず、デモの誠実さを落とします。
M3. 一覧・絞り込み
- 上部フィルタバー:
分野(開発/デザイン/映像/士業/その他)・エリア(オンライン可を含む)・稼働時間帯 - 2列カードグリッド(PCは3列)。カードは縮小版
- 並び替え:
一致数が多い順/新着順 - 空状態:「条件に合う人が見つかりません」+フィルタを1つ外す提案ボタン
M4. マッチ/届いた興味
- タブ:
マッチ/届いた興味 - マッチ:横スクロールのアバター列(新着)+ 下に会話一覧
- 届いた興味:相手のカード+添えられた一言。
ありがとう、話したい/今回は見送るの2択。承諾するとマッチ成立演出を再利用 - 未対応は左端に3pxのアンバーバー
M5. マイプロフィール
- 自分の
できること/力を借りたいことをチップで編集(追加・削除は動く) - 編集すると M1 の重なりリングの数字がリアルタイムで変わる ← 仕組みが伝わる仕掛け。ここは必ず動かしてください
- 稼働時間帯のセレクト
M6. 興味を送るモーダル
- ボトムシート(PCは中央モーダル)
- 相手カードの縮小版を上部に固定
- 一言(120字カウンター)。プレースホルダは「一緒にやりたいことを一言で」
- 定型文チップ3つ(
話を聞いてみたいです/お互いに補い合えそうです/具体的な相談があります)→ タップで本文に挿入 - 送信 → シート下降 + トースト「興味を送りました」
M7. チャット
母艦S7をそのまま流用。自分=右・アンバー地に濃紺文字、相手=左・白地。送信1.2秒後に autoReply から定型返信。
6. データモデル
// person
{ id:"u01", name:"及川 涼", role:"プロダクトデザイナー",
area:"東京・中央区", online:true,
intro:"...",
canDo:["UIデザイン","Figma","プロトタイピング"],
wantTo:["フロントエンド実装","個人開発の壁打ち"],
field:"デザイン",
availability:"週2〜3時間 / 平日夜",
works:["ECサイトのUI × 商品撮影","予約システムのUI設計"] }
// me(u00)
{ ...person, canDo:["ノーコード開発","業務自動化","Claude Code"],
wantTo:["UIデザイン","LPコピー","商品撮影"] }
// 一致数の算出(これだけ。ブラックボックスにしない)
overlap = me.wantTo ∩ person.canDo → リングに表示
mutual = person.wantTo ∩ me.canDo → 「相互に補える」バッジ
// match
{ personId:"u01", matchedAt:"...", unread:2,
messages:[{ from:"me"|"them", body:"...", at:"14:02" }],
autoReply:["ありがとうございます!","来週あたりどうですか?"] }
// incomingInterest
{ personId:"u07", message:"...", receivedAt:"...", status:"pending" }
7. デモデータ
7.1 人物(14名)
できること と 力を借りたいこと が噛み合うペアを意図的に仕込んでいます(及川↔早瀬、桜庭↔富永、宮下↔千葉)。カードをめくるうちに「あ、この2人つながるな」と読者が気づく設計です。
| id | 氏名 | 肩書き | エリア | できること | 力を借りたいこと | 稼働 |
|---|---|---|---|---|---|---|
| u00 | あなた | ノーコード開発 | 東京・中央区 | ノーコード開発 / 業務自動化 / Claude Code | UIデザイン / LPコピー / 商品撮影 | 週3〜5時間 |
| u01 | 及川 涼 | プロダクトデザイナー | 東京・渋谷 | UIデザイン / Figma / プロトタイピング | フロントエンド実装 / 個人開発の壁打ち | 週2〜3時間 / 平日夜 |
| u02 | 楢崎 健吾 | 管理栄養士 | 大阪 | 献立設計 / 栄養計算 / 監修 | 動画編集 / SNS運用 | 週1〜2時間 / 土日 |
| u03 | 三雲 あさひ | バックエンドエンジニア | オンライン | API設計 / Python / インフラ | ロゴ制作 / LPコピー | 週4〜6時間 |
| u04 | 白鳥 恵理 | 中小企業診断士 | 名古屋 | 事業計画 / 補助金申請 / 資金繰り | 業務自動化 / 自社サイト制作 | 週2時間 / 平日昼 |
| u05 | 桜庭 拓真 | 映像ディレクター | 福岡 | 撮影 / 動画編集 / カラーグレーディング | 音楽制作 / 見積りの相談 | 週3〜4時間 |
| u06 | 泉 みちる | 社会保険労務士 | 札幌 | 就業規則 / 労務相談 / 助成金 | 業務自動化 / 資料デザイン | 週1〜2時間 / 平日夜 |
| u07 | 神谷 拓海 | データアナリスト | 横浜 | SQL / ダッシュボード構築 / 分析設計 | 英語の壁打ち / プレゼン構成 | 週2〜3時間 |
| u08 | 宮下 かなえ | 陶芸家 | 岐阜 | 器の制作 / ワークショップ企画 | ECサイト構築 / 商品撮影 | 週2時間 / 不定 |
| u09 | 早瀬 蓮 | フロントエンドエンジニア | オンライン | React / アニメーション実装 / 保守 | UIデザイン / 企画のネタ出し | 週5〜8時間 |
| u10 | 一之瀬 由紀 | コピーライター | 京都 | LPコピー / ネーミング / 取材記事 | SEO設計 / 表計算の自動化 | 週3時間 / 平日昼 |
| u11 | 富永 廉 | 音楽プロデューサー | 東京・世田谷 | 作編曲 / MA / 音源制作 | 動画編集 / 権利まわりの相談 | 週2〜4時間 / 夜 |
| u12 | 黒木 沙羅 | パーソナルトレーナー | 神戸 | 運動指導 / オンライン指導設計 | 予約システム / 動画撮影 | 週2時間 / 早朝 |
| u13 | 千葉 智也 | 農家(6次産業化) | 長野 | 農作物 / 加工品開発 / 産地の知見 | ブランディング / 商品撮影 / 販路開拓 | 週1〜2時間 |
| u14 | 舞原 詩織 | 通訳・翻訳(英日) | オンライン | 同時通訳 / 技術翻訳 / 字幕 | 音声編集 / 名刺デザイン | 週3〜4時間 |
一言(intro)
| id | 一言 |
|---|---|
| u01 | 作ったものが動いているところが見たいだけの人です |
| u02 | 「体にいい」で終わらせず、続けられる形にするのが仕事です |
| u03 | 裏側は得意ですが、表側が壊滅的なので助けてください |
| u04 | 数字の話をやわらかい言葉に翻訳します |
| u05 | 撮る・切る・整えるまで一人で完結できます |
| u06 | 制度は使えるものを使ったほうがいい、という立場です |
| u07 | データを見て終わりにせず、次の一手まで一緒に考えます |
| u08 | 土日は窯の前にいます。器を全国に届けたい |
| u09 | 動くものを最短で作るのが好きです。設計は苦手 |
| u10 | 一行で説明できないものは、たぶんまだ整理されていません |
| u11 | 映像に音が付くと世界が変わるので、その瞬間が好きです |
| u12 | 続かない運動に意味はないと思っています |
| u13 | 畑はあるのに売り方がわからない、を7年やっています |
| u14 | 訳すというより、伝わる形に置き換える仕事です |
7.2 スワイプデッキ初期順
u09 → u01 → u10 → u05 → u13 → u03 → u08 → u11 → u07 → u04 → u12 → u14
1枚目の
u09(早瀬)は自分のwantTo:UIデザインと重ならず一致数1、2枚目のu01(及川)が一致数2。最初の2枚で「リングの数字が変わる」ことを体感させる意図的な並びです。
7.3 既存マッチ(4件)
| 相手 | 最新メッセージ | 未読 | autoReply |
|---|---|---|---|
| u10 一之瀬 由紀 | LPの構成案、ざっくり作ってみました | 2 | 「見出しだけ先に決めちゃいましょう」/「今週中なら動けます」 |
| u08 宮下 かなえ | 撮影、来週の火曜はいかがですか? | 1 | 「岐阜まで来ていただく形でも大丈夫ですか?」/「器は15点ほど用意します」 |
| u03 三雲 あさひ | APIの叩き方、こちらで用意しておきます | 0 | 「認証まわりだけ先に共有しますね」/「詰まったらいつでも」 |
| u13 千葉 智也 | 加工品のラベル、意見もらえますか | 0 | 「写真だけ先に送ります」/「トマトの加工品です。名前がまだ決まっていません」 |
7.4 届いた興味(3件・未対応)
| 相手 | 添えられた一言 |
|---|---|
| u06 泉 みちる | 顧問先の労務手続きを自動化したくて、相談だけでもできませんか |
| u12 黒木 沙羅 | オンライン指導の予約まわりを整えたいです。お互いに補い合えそうです |
| u04 白鳥 恵理 | 補助金の申請支援と交換で、業務まわりのご相談ができればと思っています |
8. ディレクトリ構成
母艦と同一。新規は features/swipe/ のみです。
souzoh-match/
├── public/images/
├── src/
│ ├── theme.css ★差し替え済み(§4.2)
│ ├── app.config.js ★差し替え(下記)
│ ├── data/
│ │ ├── people.js matches.js interests.js me.js
│ ├── components/ui/ ← 母艦からそのままコピー。触らない
│ │ └── OverlapRing.jsx ← ★このアプリで追加
│ ├── components/shell/ ← 母艦からそのままコピー
│ ├── features/
│ │ ├── swipe/ ★新規:CardStack.jsx / SwipeCard.jsx / MatchOverlay.jsx
│ │ ├── person-detail/ browse/ matches/ my-profile/
│ │ ├── interest/ ← 母艦 composer/ を改名
│ │ └── chat/ ← 母艦 dm/ をそのまま
│ ├── store.js
│ └── main.jsx
└── README.md
// app.config.js
export default {
appName: "Souzoh Match",
tagline: "「できる」と「借りたい」で、人はつながる",
nav: [
{ key:"swipe", label:"探す", icon:"Layers" },
{ key:"browse", label:"一覧", icon:"LayoutGrid" },
{ key:"matches", label:"マッチ", icon:"Handshake" },
{ key:"chat", label:"メッセージ", icon:"Mail" },
{ key:"me", label:"プロフィール", icon:"User" },
],
labels: {
listTitle: "あなたと補い合える人",
itemNoun: "人",
createCta: "興味を送る",
primaryAction: "気になる",
},
};
9. 実装手順(Claude Codeへの投げ方)
母艦があるので3セッションで足ります。
| Session | やること | 冒頭で読ませるもの |
|---|---|---|
| 0 | 母艦リポジトリを複製 → theme.css app.config.js data/ を差し替え。画面は一切触らない。この時点で一度ビルドを通す |
§4.2・§7・§8 |
| 1 | M1 スワイプ(CardStack / SwipeCard / OverlapRing / MatchOverlay) | §4.1・§4.3・§5(M1) |
| 2 | M2 詳細 + M3 一覧 + M4 マッチ | §5(M2〜M4) + 既存 ui/ |
| 3 | M5 マイプロフィール + M6 モーダル + 仕上げ | §5(M5,M6)・§10 |
Session 0 を必ず独立させてください。 ここでビルドが通ることを確認してから画面に入ると、後段のエラーが「新規実装のせい」だと確定でき、原因切り分けの往復が消えます。母艦方式で一番効くのがこの一手です。
Session 1 の指示文テンプレ:
添付の要件定義書 §4.1・§4.3・§5(M1) を実装してください。
src/components/ui/ と src/store.js は完成済みです。新規作成せず import して使ってください。
スワイプは Pointer Events のみで実装し、ライブラリを追加しないでください。
色・余白・角丸は src/theme.css の変数のみを使ってください。
実装前に、作成・変更するファイルの一覧だけ先に提示してください。
10. 受け入れ基準
- ドラッグ・ボタン・キーボードの3経路でスワイプできる
- ドラッグ量に応じてカードが傾き、方向ラベルが出る
- 重なりリングの数字が、M5でタグを編集すると即座に変わる
-
u01 / u05 / u09の右スワイプでマッチ演出が出る - ↩で直前の1枚だけ戻せる(2連続は不可)
- デッキが尽きると空状態が出て、M3への導線がある
- 届いた興味を承諾するとマッチに移り、チャットが開ける
- 375px幅と1440px幅で崩れない
- 生の色コードがJSX内に1つも無い
-
prefers-reduced-motion: reduceで弾け演出が止まる -
npm run buildが警告なく通り、Cloudflare Pagesで表示される
11. 母艦テンプレからの再利用率
| 領域 | 扱い |
|---|---|
components/ui/ 8点 |
そのまま(OverlapRing のみ追加) |
components/shell/ |
そのまま(app.config.js のnavが変わるだけ) |
store.js |
骨格そのまま。アクション名のみ変更(like/skip/sendInterest) |
| チャット(M7) | そのまま |
| モーダル(M6) | 枠そのまま。中身のフォームだけ差し替え |
| 一覧・詳細・通知 | 構造流用、中身差し替え |
| スワイプ(M1) | 完全新規(このアプリ唯一の固有実装) |
実質的な新規実装は1画面+1コンポーネントです。§9のSession 0を守れば、ここまで圧縮できます。
12. 補足:コスト感
母艦がある分、SNS初回より軽くなります。ただしスワイプのドラッグ挙動だけは調整の往復が発生しやすい箇所です。「もう少し軽く」「戻りが速すぎる」といった感覚的な指示は費用がかさむので、閾値を数値で指定してください(判定80px / 傾き最大12度 / 復帰アニメ180ms / 退場220ms)。§4.3と§5(M1)にすでに数値で書いてあるので、そのまま渡せば1〜2回で決まります。