SOUZOHSPECS

業務システム ・ Souzoh Portal

社内ポータル

会社の「いま」が、ひと目で分かるダッシュボード型ポータル

  1. 要件定義書を保存する

    パソコンに portal-app のようなフォルダを作り、その中に保存します。

    要件定義書.md として保存

  2. ChatGPT で画面イメージを作る デザインにこだわりたい人

    ChatGPT に要件定義書を添付して、下の文を送ります。雰囲気のところは、好きな言葉に書きかえてください。

    ChatGPT に送る
    添付の要件定義書は、これから作るアプリ「社内ポータル」のものです。
    このアプリのいちばん大事な画面を、デザイン画像にしてください。
    実際のアプリのように、文字やボタンまで入れてください。
    雰囲気:(例:やさしい/高級感/ポップ/シンプル など、好きな言葉で)

    気に入るまで「もっと明るく」「ボタンを大きく」のように直してもらい、できた画像を保存します。ほかの画面も欲しければ、同じように作ってもらえます。

  3. Claude Code に渡して「作って」と頼む

    Claude のデスクトップアプリで「Code」タブを開き、「Select folder」から portal-app を選びます。画面イメージがある人は、入力欄に画像をドラッグして貼りつけてから、下の文を送ります。詳しく

    Claude Code に送る(画像あり)
    @要件定義書.md をもとに、このアプリを作ってください。
    デザインは添付の画像に合わせてください。
    「母艦」など手元に無いものは、一から作ってください。
    Claude Code に送る(画像なし)
    @要件定義書.md をもとに、このアプリを作ってください。
    「母艦」など手元に無いものは、一から作ってください。

    作り終わるまで、しばらくかかります。途中で「許可しますか」と聞かれたら、内容を見て許可してください。

  4. 動かして確かめる・直す

    できたら、実際に画面を開いて触ります。直してほしいところは、スクリーンショットを貼りつけて、言葉で伝えれば大丈夫です。

    Claude Code に送る
    アプリを起動して、ブラウザで開けるようにしてください。
    Claude Code に送る
    (画面名)で(操作)をすると(今の動き)になります。
    (こうなってほしい動き)にしてください。
    Claude Code に送る
    このエラーを直してください。
    
    (ここにエラーの文をそのまま貼る)
  5. 途中で止まったら 必要なときだけ

    要件定義書が長いので、一度で作りきれないことがあります。そのときは新しい会話で、こう送ります。

    Claude Code に送る
    @要件定義書.md の続きを作ってください。
    まず、どこまでできているかを確かめてから進めてください。

    それでも進まないときは、30分無料相談でお手伝いします。公式LINEからのご相談もどうぞ。

    1段階ずつ頼みたいとき(全6段階)

    要件定義書には、作る順番が Session 0〜5 で書かれています。止まりやすいときは、1つずつ頼むと確実です。

    Session 0母艦を複製 → theme.css app.config.js data/ 差し替え。画面は触らずビルドを通す
    Claude Code に送る
    @要件定義書.md の「実装手順」にある Session 0 を作ってください。
    Session 1scripts/fetch-images.mjs + SmartImage + Tile + motion.js。画像18枚の取得までを完了させる
    Claude Code に送る
    @要件定義書.md の「実装手順」にある Session 1 を作ってください。
    Session 2P1ホーム(ベントーグリッド+KPI+演出シーケンス)
    Claude Code に送る
    @要件定義書.md の「実装手順」にある Session 2 を作ってください。
    Session 3P7 ⌘Kパレット + 画面遷移(View Transitions) + 共有要素モーフ
    Claude Code に送る
    @要件定義書.md の「実装手順」にある Session 3 を作ってください。
    Session 4P2フィード + P3お知らせ + P6投稿作成
    Claude Code に送る
    @要件定義書.md の「実装手順」にある Session 4 を作ってください。
    Session 5P4名鑑・組織図 + P5メンバー詳細 + 仕上げ(reduced-motion全確認)
    Claude Code に送る
    @要件定義書.md の「実装手順」にある Session 5 を作ってください。
  6. 自分用に変える・公開する 必要な人だけ

    Claude Code に送る
    この要件定義書は、記事に埋め込むデモ用に書かれています。
    自分の会社で実際に使えるように変えたいです。外したほうがいいところと、残したほうがいいところを教えてください。
    Claude Code に送る
    このアプリをインターネットに公開したいです。
    無料でできる方法を、1手順ずつ案内してください。

準備や、うまくいかないときの対処は 作り方ガイド にまとめています。分からないときは 30分無料相談 へどうぞ。

社内SNS・社内ポータル テンプレート 要件定義書

プロダクト名:Souzoh Portal

シリーズ4本目。「デザインで殴る1本」として位置づけます。 前3本が題材の説明に軸足を置いていたのに対し、本アプリは開いた瞬間の印象を最優先の要件に置きます。 記事のサムネイル・OGP・営業資料に使う画像は、すべてこのアプリから撮る想定です。


1. 目的とゴール

項目 内容
コンセプト 全社のお知らせ・社内の動き・組織の情報が1画面に集まる、ダッシュボード型の社内ポータル
一次目的 一目で「おっ」と思わせる。 URLを開いて2秒で判断される勝負
二次目的 前3本のC2Cと違いB2B(受注につながる題材)。読者=事業者が「自社にこれが欲しい」と直結する
成功条件 記事のサムネイルにこの画面を使い、クリック率が他3本を上回る
非ゴール 実運用可能な社内システム。権限管理・監査ログ・SSO

なぜこの題材が"すごく見える"のか:ポータルは数字・グラフ・人・お知らせ・写真が同時に載る唯一の題材です。前3本は一覧とカードしか出せませんでしたが、ここはKPI・組織図・カレンダー・ランキングを1画面に同居させられる。密度と多様性が、そのまま「作り込まれている感」になります。


2. 追加要件(今回の4条件)

本書では以下を独立した必達要件として扱い、それぞれ専用の章を設けています。

条件 対応章 実現方法の要旨
① デザインにとにかくこだわる §5 ベントーグリッド + ダークインク基調 + 可変フォント。§5.6にNGリストを明記
② ネットから自動で画像を取得しデモに組み込む §6 ビルド時に取得するNode製スクリプトnpm run fetch:images)+ 3層フォールバック
③ 動きをつける §7 View Transitions API + スクロール連動 + 段差入場。14種類を定義
④ 一目ですごいと思わせる §8 「最初の2秒」を専用に設計。ファーストビュー演出シーケンスを秒単位で規定

3. スコープ

3.1 作るもの

# 画面 優先度 母艦との関係
P1 ホーム(ベントーダッシュボード) S 完全新規。このアプリの本体
P2 社内フィード(タイムライン) A 母艦S1を改修
P3 お知らせ一覧・詳細 A 母艦S1/S2を改修
P4 メンバー名鑑・組織図 A 新規
P5 メンバー詳細 A 母艦S5を改修
P6 投稿作成(分報・称賛) B 母艦S6を改修
P7 全社検索(⌘K パレット) A 新規。§8の"すごい"を担う要素
P8 メッセージ C 母艦S7をそのまま流用

3.2 作らないもの

  • ❌ バックエンド・DB・認証・SSO・権限管理
  • ❌ データ永続化(リロードで初期化)
  • ❌ ファイルの実アップロード・実ダウンロード
  • ❌ 実際のカレンダー連携・勤怠打刻の実処理
  • ❌ ダークモード切替(ダーク固定。§5.2で理由を記述)
  • ❌ 多言語、テストコード、CI

4. 技術構成

母艦を踏襲しつつ、このアプリのみ3点追加します。

Vite + React 18(JSX)
Tailwind CSS v4
lucide-react
────────── 以下このアプリのみ ──────────
motion(motion.dev)… レイアウトアニメーションのみに使用。§7.4に使用範囲を限定
recharts …………… KPIのスパークライン・面グラフ
cmdk ………………… ⌘Kコマンドパレット(P7)

方針転換の理由:前3本ではアニメーションライブラリを外しました。試行錯誤の往復が費用を食うためです。本アプリは要件③④が最優先なので判断を変えますが、代わりに§7で動きを14種類・数値付きで確定させています。ライブラリを入れても、仕様が確定していれば往復は増えません。増えるのは「もう少し滑らかに」を口頭で往復するときだけです。

recharts を入れる理由:KPIグラフを自前SVGで書くと、軸・目盛り・ツールチップの調整で必ず往復が出ます。ここは既製品が安いです。


5. デザイン仕様 ★要件①

5.1 方向性

シリーズ4本の視覚的な住み分けは次の通りです。

アプリ 基調 密度 主役
SNS 明るいウォームグレー 文章
Match ディーププラム 極低 カード1枚
Market 価格
Portal ディープインク 高+階層あり 情報の集合そのもの

Portalが狙うのは**「管制室」**の質感です。暗い地に、わずかに浮いたガラス質のパネルが不揃いなサイズで並び、そこにだけ光が入る。KPIの数字とライムの差し色が暗闇で映え、写真がパネルの中で発色する。

中心にあるのはベントーグリッドです。均一なカードの反復ではなく、大小・縦横比の違うタイルを組み合わせて1画面を構成します。これが「最新のアプリっぽさ」の正体で、なおかつスクリーンショット1枚に情報が凝縮されるので、記事の画像として最も強い。

5.2 ダーク固定にする判断

社内ポータルの実運用はライトが主流です。それでもダーク固定にします。

  • 要件④(一目ですごい)に対して、暗背景 + 発光する差し色が最短距離であること
  • 前3本がすべて明るい基調なので、4本並べたときの差が最大化されること
  • 写真がダーク地では確実に映えること(要件②の効果が最大化される)

**ただしライト版はtheme.cssの値を差し替えるだけで出せる構造にします。**記事内で「トークンを差し替えるとこうなります」と両方見せられれば、テンプレートの価値の説明そのものになります。ライト版の値も§5.3に併記します。

5.3 デザイントークン(src/theme.css

@theme {
  /* ---- Base(ダーク) ---- */
  --color-bg:        #0B0D12;  /* ほぼ黒。わずかに青 */
  --color-surface:   #131721;  /* パネル面 */
  --color-surface-2: #1B2130;  /* パネル内の入れ子・入力欄 */
  --color-surface-3: #232B3D;  /* ホバー時 */
  --color-ink:       #EEF1F7;  /* 主要テキスト */
  --color-ink-sub:   #8B93A7;  /* メタ・ラベル */
  --color-ink-dim:   #5A6175;  /* さらに弱い情報 */
  --color-line:      #262E3F;  /* 1pxの区切り */
  --color-line-lit:  #38425C;  /* パネル上端のハイライト線 */

  /* ---- Accent ---- */
  --color-accent:    #C6F24E;  /* ライム:CTA・現在地・強調 */
  --color-accent-2:  #4CC9F0;  /* シアン:リンク・進行中 */
  --color-accent-3:  #F5A623;  /* アンバー:期限・注意 */
  --color-danger:    #FF5C6C;
  --color-ok:        #3DDC97;

  /* ---- Glass ---- */
  --glass-bg:     rgba(255,255,255,.035);
  --glass-border: rgba(255,255,255,.075);
  --glass-blur:   18px;

  /* ---- Type ---- */
  --font-display: "Space Grotesk", "Zen Kaku Gothic New", sans-serif;  /* 600/700 */
  --font-body:    "Noto Sans JP", sans-serif;                          /* 400/500 */
  --font-num:     "JetBrains Mono", monospace;                         /* KPI・日付・時刻 */

  --text-hero:   clamp(32px, 4.2vw, 56px)/1.05;  /* ★可変。PCで大きく効く */
  --text-kpi:    clamp(28px, 3.2vw, 44px)/1.0;
  --text-title:  20px/1.35;
  --text-body:   14px/1.8;
  --text-label:  11px/1.3;   /* 大文字+letter-spacing .12em で使う */

  /* ---- Space ---- */
  --space-1: 4px;  --space-2: 8px;  --space-3: 12px;
  --space-4: 16px; --space-6: 24px; --space-8: 32px; --space-12: 48px;

  /* ---- Shape ---- */
  --radius-tile:  18px;
  --radius-inner: 12px;
  --radius-pill:  999px;
  --shadow-tile:  0 1px 0 rgba(255,255,255,.05) inset,
                  0 20px 50px rgba(0,0,0,.45);
  --shadow-lift:  0 30px 70px rgba(0,0,0,.6);

  /* ---- Motion(§7で全て参照) ---- */
  --ease-out:   cubic-bezier(.16,1,.3,1);
  --ease-inout: cubic-bezier(.65,0,.35,1);
  --dur-fast:   140ms;
  --dur-base:   240ms;
  --dur-slow:   520ms;
}

ライト版の差し替え値(記事用。この6行だけで切り替わる)

--color-bg:#F5F6F8; --color-surface:#FFFFFF; --color-surface-2:#EFF1F5;
--color-ink:#0E1219; --color-ink-sub:#5C6478; --color-line:#E3E6EC;
--color-accent:#5B39F5;  /* ライムは白地で沈むのでインディゴに差し替え */

5.4 タイポグラフィの決め事

  • 数字は必ず --font-numfont-variant-numeric: tabular-nums KPIが並ぶ画面で桁がずれると一気に安っぽくなります
  • ラベル(今週の動き など)は --text-label + 大文字/カタカナ + letter-spacing: .12em--color-ink-sub
  • 見出しは --font-display の600以上、letter-spacing: -0.02em
  • 日本語本文の行間は1.8。ダーク地では明るい地より行間を広く取らないと詰まって見えます

5.5 パネル(Tile)の作り

全タイル共通の質感を1コンポーネントに閉じ込めます。

背景:--glass-bg + backdrop-filter: blur(var(--glass-blur))
枠 :1px solid --glass-border
上端:1pxの内側ハイライト(--shadow-tile のinset部分)
角 :--radius-tile
ホバー:translateY(-2px) + --shadow-lift + 枠が --color-line-lit へ(--dur-base)

backdrop-filter は必ず使ってください。 背景に極薄のグラデーション(後述)を敷いた上でガラスを重ねることで、平面的なダークUIとの差が出ます。ここが「最新っぽさ」の実体の半分です。

背景の下地--color-bg の上に、右上から --color-accentopacity .06 で、左下から --color-accent-2opacity .05 で、巨大な楕円グラデーションとして敷きます(filter: blur(120px))。スクロールしても動きません。これがガラスの下に薄く透ける。

5.6 やらないこと(デザイン品質のためのNGリスト)

  • ❌ 紫→ピンクのグラデーションボタン(2020年代前半の記号。古く見えます)
  • ❌ 全タイルへの均一な影(§5.5のホバー時のみ)
  • ❌ 絵文字をUIアイコンとして使う(lucide-reactに統一)
  • ❌ 角丸の混在(--radius-tile / --radius-inner / --radius-pill の3種のみ)
  • ❌ 中央揃えの長文(日本語の左揃えを崩さない)
  • ❌ 3種を超えるフォント
  • ❌ ネオン発光の多用(--color-accentbox-shadow 発光はKPIタイル1枚とライブ表示のみ

6. 画像の自動取得 ★要件②

6.1 方針:ランタイム取得ではなく「ビルド時取得」

「ネットから自動で画像を持ってくる」の実装には2通りありますが、ビルド時に取得してローカルに置く方式を採ります。

ランタイム取得(<img src="https://外部..."> ビルド時取得(採用)
実装量 少ない スクリプト1本(約80行)
表示速度 毎回外部リクエスト。遅い・ちらつく 自ドメイン配信。速い
サービス停止時 デモが全部壊れる 影響なし
レート制限 記事がバズると詰まる 影響なし
再現性 開くたびに絵が変わる seedで固定

配布テンプレートで外部サービスに毎回問い合わせる作りにすると、そのサービスが止まった日に全記事のデモが同時に壊れます。実際、長年使われてきた via.placeholder.com数か月にわたって断続的にダウンし、告知も移行先の案内もないまま404や接続リセット、DNSタイムアウトを繰り返すようになりました。同様に source.unsplash.com も廃止され、公式APIで同じことをする手段は用意されませんでした。この構造的リスクを、記事5本分背負う必要はありません。

6.2 取得元

picsum.photos を使います。実在の写真を指定サイズで返す定番のプレースホルダサービスで、seedを指定すれば同じ画像を安定して取得できます。ただし本番の実行時依存にするのではなく、公開前にキャッシュか自前ホストへ移すのが前提の使い方ですpicsum.photos と placehold.co は2026年時点で稼働・保守されていますが、それでも外部依存であることに変わりはないので、§6.1の方針で吸収します。

https://picsum.photos/seed/{seed}/{w}/{h}

seedを固定しているので、何度実行しても同じ絵が返ります。これが再現性の担保になります。

顔写真は取得しません。 社内SNSにはメンバーの顔が要りますが、実在の人物の写真を架空の社員として配布テンプレートに載せるのは肖像の扱いとして避けるべきです。メンバーのアバターは母艦のID由来グラデーション+頭文字方式を使います(§6.5)。ダーク地では、この幾何学的なアバターのほうがむしろ洗練されて見えます。

6.3 スクリプト仕様(scripts/fetch-images.mjs

npm run fetch:images
  1. src/data/imageManifest.js を読む(seed・幅・高さ・用途の一覧)
  2. 各エントリを https://picsum.photos/seed/{seed}/{w}/{h} から取得
  3. public/images/{seed}.jpg に保存
  4. 既に存在するファイルはスキップ(--force で上書き)
  5. 取得失敗は握りつぶし、ログに1行出して次へ進む(1枚の失敗でビルドを止めない
  6. 完了後にサマリを出力:取得 18 / スキップ 4 / 失敗 0

同時実行は4本までに絞ってください(Promise を4本ずつ処理)。無制限に並列化すると相手側に負荷をかけますし、レート制限にも当たります。

public/images/.gitignore に入れます。 取得した写真をリポジトリにコミットして再配布すると、ライセンスの筋が曖昧になります。配るのはスクリプトとマニフェストだけ。利用者が自分で npm run fetch:images を叩く形にすれば、権利関係はその人と取得元の間で完結します。README冒頭にこの手順を書いてください。

6.4 マニフェスト(src/data/imageManifest.js

export default [
  // ヒーロー・特集
  { seed:"portal-hero",      w:1600, h:900, use:"P1ヒーロー" },
  { seed:"news-offsite",     w:1200, h:800, use:"お知らせ:全社合宿" },
  { seed:"news-office",      w:1200, h:800, use:"お知らせ:新オフィス" },
  { seed:"news-award",       w:1200, h:800, use:"お知らせ:表彰" },
  // フィード投稿
  { seed:"feed-desk",        w:1000, h:750, use:"分報:作業風景" },
  { seed:"feed-whiteboard",  w:1000, h:750, use:"分報:議論" },
  { seed:"feed-lunch",       w:1000, h:1000,use:"分報:ランチ" },
  { seed:"feed-launch",      w:1000, h:562, use:"分報:リリース" },
  { seed:"feed-training",    w:1000, h:750, use:"分報:研修" },
  { seed:"feed-site",        w:1000, h:562, use:"分報:現場" },
  // 部署カバー
  { seed:"team-dev",  w:800, h:400, use:"開発部" },
  { seed:"team-sales",w:800, h:400, use:"営業部" },
  { seed:"team-cs",   w:800, h:400, use:"CS部" },
  { seed:"team-corp", w:800, h:400, use:"管理部" },
  // イベント
  { seed:"event-allhands", w:900, h:600, use:"全社会議" },
  { seed:"event-study",    w:900, h:600, use:"勉強会" },
  { seed:"event-welcome",  w:900, h:600, use:"歓迎会" },
  { seed:"event-1on1",     w:900, h:600, use:"1on1週間" },
];

18枚です。この規模なら取得は数秒で終わります。

6.5 表示側:3層フォールバック(ui/SmartImage.jsx

絶対に壊れた画像アイコンを出さないための構造です。

第1層:/images/{seed}.jpg              ← ビルド時に取得済み。通常はここ
  ↓ onError
第2層:https://picsum.photos/seed/{seed}/{w}/{h}   ← 取得し忘れた場合の保険
  ↓ onError
第3層:seed由来の決定的グラデーション(母艦 GradientImage)  ← 必ず何かは映る

さらに全層共通で:

  • 読み込み完了までseed由来の2色グラデーションを敷き、完了時に opacity 0→1--dur-slow)でクロスフェード。白い箱がパッと出る現象を消します
  • width / height 属性を必ず指定してレイアウトシフトを防ぐ
  • ファーストビュー外は loading="lazy"decoding="async"

このコンポーネントは前3本にも後付けできます。母艦へ還元してください。


7. 動き ★要件③

7.1 原則

  • 意味のない動きは入れない。 出現・状態変化・因果の3つだけを表現する
  • 主要な動きは --dur-base(240ms)、退場は入場の6割の速さ、大きな移動のみ --dur-slow(520ms)
  • イージングは --ease-out を基本とし、往復する動きだけ --ease-inout
  • prefers-reduced-motion: reduce で下表の「停止」列がすべて止まること(受け入れ基準)

7.2 動きの一覧(14種)

# 名称 対象 仕様 reduced時
1 段差入場 P1の全タイル 下から16px+opacity 0→1、--dur-slow60msずつ遅延(最大12枚) 停止(即表示)
2 KPIカウントアップ KPI4枚の数字 0→目標値、900ms、--ease-out。桁はtabular-numsで固定 停止(即表示)
3 スパークライン描画 KPIタイル SVGパスをstroke-dasharrayで左から1.1秒描画 停止(完成形)
4 スクロール連動リビール P1下部・P2 画面下20%に入ったら 下から24px+fade、--dur-slow 停止
5 タイルのホバー浮上 全タイル translateY(-2px)+影強化+枠色、--dur-base 影のみ
6 画面遷移 全ページ View Transitions APIでクロスフェード+4px上移動、--dur-base 即時切替
7 共有要素モーフ メンバー→詳細 view-transition-nameでアバターと氏名が連続移動 停止
8 ⌘Kパレット P7 背景 blur(0→10px)+パネルがscale .96→1--dur-base フェードのみ
9 検索結果の入れ替え P7 各行20ms差でスライドイン。入力中はデバウンス120ms 停止
10 称賛(拍手)演出 フィード ボタン押下でライムの粒が8個放射、600msで消滅+数字がスライド 数字のみ変化
11 ライブ在席パルス 在席中バッジ 緑ドットが2.4秒周期でゆっくり明滅 停止
12 組織図の展開 P4 部署をクリックでメンバーが高さアニメ+段差入場(40ms差) 即展開
13 進捗リング P1「今週の目標」 円弧をstroke-dashoffsetで0→達成率、1.2秒 完成形
14 トースト 全体 右下から16px上+fade、3秒後に自動退場 フェードのみ

7.3 ファーストビューの演出シーケンス ★最重要

開いてから2.0秒で完結させます。長いローディング演出は逆効果です。

0ms     背景グラデーションのみ表示(ほぼ黒)
120ms   ヘッダーとサイドナビが fade-in
200ms   ヒーロータイル(大)が下から入場
260ms   KPIタイル4枚が 60ms差で順に入場   ← #1
400ms   KPIの数字が一斉にカウントアップ開始 ← #2
        同時にスパークラインが左から描画   ← #3
900ms   残りのタイルが 60ms差で入場
1400ms  全タイル着地
2000ms  完了(以降は静止。パルス#11のみ継続)

カウントアップとスパークラインを同時に走らせるのが要点です。数字と線が同時に動く0.9秒が、このアプリで最も"すごい"瞬間になります。ここは実装で必ず確認してください。

7.4 motion ライブラリの使用範囲(限定)

無制限に使うと往復が増えます。以下4つ以外はCSSで実装してください。

  • ✅ #7 共有要素モーフ(layoutId
  • ✅ #12 組織図の高さアニメーション
  • ✅ #8 パレットの出入り
  • ✅ #10 拍手の粒
  • ❌ 上記以外(#1〜#6, #9, #11, #13, #14 はCSS / WAAPI / View Transitions で書く)

8. 「一目ですごい」の設計 ★要件④

8.1 最初の2秒で伝えるもの

読者はスクロールしません。ファーストビュー1枚で判断します。そこに以下が同時に載っている状態を作ります。

  1. 大きな数字(KPI)が動いている
  2. 写真が発色している(暗い地に写真が浮く)
  3. 情報の種類が多い(数字・グラフ・人・写真・お知らせ・カレンダー)
  4. タイルの大きさが不揃い(=テンプレ感の否定)
  5. 右上にライブ表示在席 12名 の緑パルス)

8.2 ベントーグリッドの構成(P1・PC 1440px時)

12カラムグリッド。行の高さは140px単位。

┌─────────────────────────┬───────────┬───────────┐
│ ヒーロー:今週のハイライト      │ KPI①      │ KPI②      │
│ (写真+見出し)  6col × 2row    │ 3col×1row │ 3col×1row │
│                                 ├───────────┼───────────┤
│                                 │ KPI③      │ KPI④      │
├─────────────┬───────────────────┴───────────┴───────────┤
│ 今週の目標      │ 社内フィード(直近5件・縦スクロール)        │
│ 進捗リング      │ 8col × 3row                              │
│ 4col × 3row    │                                           │
├─────────────┼─────────────────┬─────────────────────────┤
│ 在席メンバー    │ 今週の予定       │ 称賛ランキング             │
│ 4col × 2row    │ 4col × 2row     │ 4col × 2row              │
└─────────────┴─────────────────┴─────────────────────────┘
  • タブレット(769〜1279px):6カラムに再構成。ヒーローは6col、KPIは3col×2段
  • モバイル(〜768px):1カラム縦積み。KPIのみ2列。下部固定タブバー

★KPIを2×2の塊にしてヒーローの右に置くのが要点です。均等な4枚横並びは「ダッシュボードのテンプレ」に見えますが、塊にすると意図のあるレイアウトに見えます

8.3 ⌘K コマンドパレット(P7)

要件④への貢献度が最も高い機能です。実装量に対して印象が跳ね上がります。

  • ⌘K / Ctrl+K で起動。ヘッダーにも ⌘K の表示を出す
  • 横断検索:メンバー・お知らせ・投稿・部署・申請メニュー
  • 結果はカテゴリごとにグルーピングし、種別アイコン付き
  • ↑↓ で移動、Enter で遷移、Esc で閉じる(キーボードだけで完結すること
  • 入力が空のときは「最近見たもの」5件と「クイックアクション」3件を表示
  • 検索語が0件のときは「"◯◯" は見つかりませんでした」+近い候補を提示

8.4 記事用スクリーンショットの撮り方(運用メモ)

  • 撮影は 1440×900 のPC幅、ファーストビュー着地後(2.0秒経過後)
  • ⌘Kを開いた状態のカットを必ず1枚押さえる(記事中盤の画像に最適)
  • モバイル幅は390pxで2枚(ホーム・フィード)
  • 前3本と並べるOGP用に、ライト版に切り替えたカットも1枚撮っておく

9. 画面仕様

P1. ホーム(ベントーダッシュボード)★本体

ヒーロータイルportal-hero の写真を背景に、下から --color-bg へのグラデーションを重ね、その上に今週のハイライト見出し+日付+詳しく見る

KPIタイル4枚

タイル 数字 補助
今月の受注 ¥ 8,420,000 前月比 +12.4%--color-ok)+ スパークライン
稼働プロジェクト 17 3 件が納期3日以内(--color-accent-3
新規問い合わせ 48 今週 +9(スパークライン)
平均残業 11.2 h 前月比 −2.8h--color-ok

数字は --font-num--text-kpi「今月の受注」タイルのみ --color-accent の淡い発光を許可(§5.6の例外)。

今週の目標:進捗リング(#13)で 68%。中央に大きく数字、下に 目標 25件 / 実績 17件

社内フィード:直近5件をコンパクト表示。タイル内で縦スクロール。すべて見る でP2へ。

在席メンバー:アバターを敷き詰め、在席中は緑パルス(#11)、離席は opacity .4512 / 28名 の表示。

今週の予定:日付ごとに3件。今日の行は --color-accent の縦線でマーク。

称賛ランキング:今月の称賛獲得数トップ5。1位のみ数字を大きく。

P2. 社内フィード

  • タブ:全社 / 自部署 / フォロー中
  • 投稿種別を色付きラベルで区別:分報(シアン)/ 称賛(ライム)/ お知らせ(アンバー)/ 質問(グレー)
  • 称賛投稿は宛先メンバーのアバターを本文上に表示
  • 拍手ボタン(#10)。リアクション絵文字は使わず、拍手1種に統一(§5.6のNGに沿う)
  • スクロール連動リビール(#4)

P3. お知らせ一覧・詳細

  • 一覧:重要度で3段階(必読 は左端にライムのバー + 未読バッジ)
  • カテゴリ:人事 総務 システム イベント 全社
  • 詳細:カバー写真 + 本文 + 添付ファイル風のリスト(クリックでトースト)+ 既読にする
  • 既読にすると一覧のバッジが消え、P1の未読カウントも連動

P4. メンバー名鑑・組織図

  • 切替タブ:名鑑 / 組織図
  • 名鑑:部署フィルタ + 検索。カードグリッド(アバター・氏名・部署・役職・在席状態・スキルタグ)
  • 組織図:部署をクリックで展開(#12)。部署カバー写真を薄く背景に敷く
  • カードクリック → P5(共有要素モーフ #7)

P5. メンバー詳細

  • ヘッダー:部署カバー写真 + アバター(モーフ着地点)
  • 基本情報:部署・役職・入社年月・内線・在席状態
  • できること スキルタグ
  • 直近の投稿3件・獲得した称賛3件
  • メッセージを送る(P8へ)

P6. 投稿作成

  • ボトムシート。種別を先に選ぶ:分報 / 称賛 / 質問
  • 称賛を選ぶと宛先メンバーの選択UIが出る(名鑑から複数選択可)
  • 本文500字+画像ピッカー(マニフェストの画像から選択)
  • 投稿 → P2先頭に挿入 + P1のフィードにも反映 + トースト

P7. ⌘Kコマンドパレット

§8.3の通り。

P8. メッセージ

母艦S7をそのまま流用。送信1.2秒後に定型返信。


10. データモデル

// member
{ id:"m01", name:"西澤 志門", kana:"にしざわ しもん",
  dept:"経営", role:"代表", joinedAt:"2019-04",
  ext:"101", present:true,
  skills:["事業開発","ノーコード","AI活用"],
  avatarSeed:"m01" }        // ★写真ではなくグラデ生成(§6.2)

// post
{ id:"f01", type:"log"|"praise"|"question"|"notice",
  memberId:"m04", body:"...", createdAt:"...",
  toMemberIds:["m07"],       // praise のみ
  image:{ seed:"feed-desk", w:1000, h:750 } | null,
  claps:14, clapped:false, comments:[...] }

// notice
{ id:"n01", category:"人事"|"総務"|"システム"|"イベント"|"全社",
  priority:"must"|"normal", title:"...", body:"...",
  image:{ seed:"news-offsite", w:1200, h:800 },
  publishedAt:"...", read:false, attachments:["就業規則_2026版.pdf"] }

// kpi
{ key:"revenue", label:"今月の受注", value:8420000, unit:"円",
  delta:+12.4, series:[6.1,6.8,7.2,7.0,7.9,8.4] }

// event
{ id:"e01", date:"2026-07-24", time:"10:00",
  title:"全社定例", place:"大会議室 / オンライン" }

11. デモデータ

11.1 メンバー(28名/主要12名を明記)

id 氏名 部署 役職 在席 スキル
m00 あなた 開発 メンバー
m01 西澤 志門 経営 代表 事業開発 / ノーコード / AI活用
m02 菊池 星哉 開発 テックリード アーキテクチャ / React / 要件定義
m03 海野 遥 開発 エンジニア 実装 / API連携 / 自動化
m04 高木 芽衣 営業 マネージャー 提案 / 折衝 / 与件整理
m05 相馬 隼人 営業 メンバー 新規開拓 / 商談
m06 三宅 千秋 CS リーダー 導入支援 / 研修設計
m07 大野 湊斗 CS メンバー 問い合わせ対応 / FAQ整備
m08 若林 詩織 管理 人事 採用 / 労務 / 制度設計
m09 堀内 樹 管理 経理 経理 / 資金繰り
m10 綾部 実咲 開発 デザイナー UI設計 / 情報設計
m11 郡司 蓮 営業 メンバー インサイドセールス

残り16名は氏名・部署・役職のみで生成(在席は約4割をtrue)。在席は12名に調整してください(P1の 12 / 28名 と一致させる)。

11.2 KPI

key ラベル 前月比 series
revenue 今月の受注 8,420,000 +12.4% 6.1 / 6.8 / 7.2 / 7.0 / 7.9 / 8.4
projects 稼働プロジェクト 17 +2 12 / 13 / 15 / 14 / 16 / 17
inquiries 新規問い合わせ 48 +9 31 / 35 / 33 / 40 / 39 / 48
overtime 平均残業 11.2h −2.8h 18.4 / 17.1 / 15.9 / 14.2 / 14.0 / 11.2

11.3 お知らせ(7件)

重要度 カテゴリ タイトル 画像
必読 人事 2026年度下期の目標設定について(8月8日締切)
必読 システム 経費精算システムの切り替えに伴う操作説明
通常 イベント 全社合宿を10月17〜18日に開催します news-offsite
通常 総務 新オフィス(蔵前)への移転が完了しました news-office
通常 全社 上期MVPを表彰しました news-award
通常 総務 夏季休暇の取得ルールについて
通常 システム 社内Wikiの構成を見直しました

11.4 フィード投稿(12件)

種別 投稿者 本文 画像 拍手
称賛 m04 高田工業所の追加要件、m02さんが休日に整理してくれたおかげで月曜の打ち合わせが3分で終わりました 47
分報 m02 朝から詰まっていた同期処理、原因はこちらの設定漏れでした。手順書に追記しておきます feed-desk 12
分報 m10 新しいポータルの配色、暗い地に振ってみました。写真がちゃんと発色するのが良い feed-whiteboard 31
称賛 m06 導入研修の資料、m07さんが受講者の質問を全部拾って改訂してくれました 38
分報 m05 新規のお問い合わせが今週9件。年明け以来のペースです 24
質問 m03 Cloudflare Workersの環境変数、本番と検証で分ける運用ってどうしてますか 6
分報 m08 来月の入社が2名決まりました。受け入れ準備を進めます feed-training 55
分報 m09 上期の締めが見えてきました。経費精算は今週中にお願いします 9
分報 m01 新オフィス、思ったより静かで集中できます。窓際の席が人気 feed-lunch 41
分報 m02 リリース完了しました。今回は差し戻しゼロ feed-launch 62
称賛 m01 現場対応でm03さんが即日で駆けつけてくれました。助かりました feed-site 33
質問 m11 商談メモのテンプレート、みなさん何を使っていますか 4

11.5 今週の予定(8件)

日付 時刻 予定 場所
7/23(木) 10:00 全社定例 大会議室 / オンライン
7/23(木) 15:00 高田工業所 定例 オンライン
7/24(金) 11:00 新規商談(製造業) 先方オフィス
7/24(金) 17:30 開発ふりかえり 開発エリア
7/27(月) 09:30 週次キックオフ 大会議室
7/28(火) 14:00 社内勉強会「AI活用の現在地」 セミナールーム
7/29(水) 13:00 1on1 週間(〜7/31) 各所
7/30(木) 18:30 歓迎会 蔵前

11.6 称賛ランキング(今月)

順位 メンバー 獲得数
1 m02 菊池 星哉 34
2 m06 三宅 千秋 28
3 m03 海野 遥 21
4 m08 若林 詩織 19
5 m04 高木 芽衣 16

12. ディレクトリ構成

souzoh-portal/
├── scripts/
│   └── fetch-images.mjs        ★新規:§6.3
├── public/images/              ← .gitignore対象。取得先
├── src/
│   ├── theme.css               ★差し替え(§5.3)
│   ├── app.config.js           ★差し替え(下記)
│   ├── data/
│   │   ├── members.js  posts.js  notices.js  kpis.js
│   │   ├── events.js   imageManifest.js
│   ├── components/ui/          ← 母艦からコピー
│   │   ├── SmartImage.jsx      ★新規:3層フォールバック(§6.5)→ 母艦へ還元
│   │   ├── Tile.jsx            ★新規:ガラスパネル(§5.5)
│   │   ├── CountUp.jsx         ← 母艦から流用
│   │   ├── ProgressRing.jsx    ★新規
│   │   └── Sparkline.jsx       ★新規(recharts薄ラッパ)
│   ├── components/shell/       ← 母艦からコピー(layout.maxWidth 対応済み)
│   ├── features/
│   │   ├── home/               ★新規:ベントーグリッド
│   │   ├── feed/  notices/  directory/  member/  composer/
│   │   ├── palette/            ★新規:⌘K
│   │   └── chat/               ← 母艦 dm/ をそのまま
│   ├── motion.js               ★新規:#1〜#14の定数を1箇所に
│   ├── store.js
│   └── main.jsx
└── README.md
// app.config.js
export default {
  appName: "Souzoh Portal",
  tagline: "会社の「いま」が、ひと目で",
  layout: { maxWidth: 1440, bento: true },
  nav: [
    { key:"home",      label:"ホーム",     icon:"LayoutDashboard" },
    { key:"feed",      label:"フィード",   icon:"MessageSquare" },
    { key:"notices",   label:"お知らせ",   icon:"Megaphone" },
    { key:"directory", label:"メンバー",   icon:"Users" },
    { key:"me",        label:"マイページ", icon:"User" },
  ],
  labels: {
    listTitle: "社内の動き",
    itemNoun: "投稿",
    createCta: "投稿する",
    primaryAction: "拍手",
  },
};

13. 実装手順(Claude Codeへの投げ方)

5分割。 Market同様に重い1本ですが、重さの理由が違います(固有画面数ではなく、演出の作り込み)。

Session やること 冒頭で読ませるもの
0 母艦を複製 → theme.css app.config.js data/ 差し替え。画面は触らずビルドを通す §5.3・§11・§12
1 scripts/fetch-images.mjsSmartImageTilemotion.js画像18枚の取得までを完了させる §6全体・§5.5・§7.1
2 P1ホーム(ベントーグリッド+KPI+演出シーケンス) §5・§7.2(#1〜5,13)・§7.3・§8.2・§9(P1)
3 P7 ⌘Kパレット + 画面遷移(View Transitions) + 共有要素モーフ §7.2(#6,7,8,9)・§8.3
4 P2フィード + P3お知らせ + P6投稿作成 §9(P2,P3,P6)・§7.2(#4,10)
5 P4名鑑・組織図 + P5メンバー詳細 + 仕上げ(reduced-motion全確認) §9(P4,P5)・§7.2(#11,12)・§14

Session 1を必ず独立させてください。 画像が18枚ローカルに揃った状態でP1に入ると、レイアウト確認が1発で済みます。画像なしでグリッドを組むと、写真が入った瞬間に余白バランスの作り直しが発生します。要件②を先に片付けることが、要件①のコストを下げます。

Session 2 の指示文テンプレ

添付の要件定義書 §5・§7.3・§8.2・§9(P1) を実装してください。
src/components/ui/ の Tile / SmartImage / CountUp と src/motion.js は完成済みです。
新規作成せず import して使ってください。
ベントーグリッドは CSS Grid の grid-template-areas で組み、
§8.2 の配置図をそのまま再現してください。
アニメーションの遅延・時間は src/motion.js の定数のみを参照し、
JSX に数値を直接書かないでください。
色・余白・角丸は src/theme.css の変数のみを使ってください。
実装前に、作成・変更するファイルの一覧だけ先に提示してください。

14. 受け入れ基準

要件①(デザイン)

  • 生の色コード・生のpx値がJSXに1つも無い(全てトークン経由)
  • 角丸が3種類のみ、フォントが3種類のみ
  • タイルに backdrop-filter が効き、背景の淡いグラデーションが透けている
  • KPIの数字が tabular-nums で桁揃えされている
  • §5.6のNGリストに1つも該当しない

要件②(画像)

  • npm run fetch:images で18枚が public/images/ に取得される
  • 2回目の実行でスキップされ、--force で再取得される
  • public/images/ を空にしても壊れた画像アイコンが1つも出ない(第2層・第3層が働く)
  • 画像読み込み時にレイアウトシフトが起きない
  • public/images/.gitignore に入っている
  • メンバーのアバターに実在人物の写真が使われていない

要件③(動き)

  • §7.2の14種すべてが動作する
  • prefers-reduced-motion: reduce で§7.2の「停止」列がすべて止まる
  • ⌘K がキーボードのみで完結する(起動・移動・決定・閉じる)
  • View Transitions 非対応ブラウザでも遷移が壊れない(即時切替にフォールバック)

要件④(第一印象)

  • 初回表示が§7.3のシーケンス通りに進み、2.0秒で着地する
  • カウントアップとスパークライン描画が同時に走る
  • ファーストビューに「数字・グラフ・人・写真・お知らせ・カレンダー」が同時に見える
  • タイルの大きさが不揃いで、均一グリッドに見えない

共通

  • 390px / 1024px / 1440px の3幅で崩れない
  • npm run build が警告なく通り、Cloudflare Pagesで表示される
  • ライト版トークンに差し替えても破綻しない(記事用カット撮影のため)

15. 母艦テンプレへの還元

このアプリで作った以下は、前3本にも後付けする価値があります

成果物 還元先
SmartImage.jsx(3層フォールバック) 全アプリ。特にMarketの商品写真が実写になる
scripts/fetch-images.mjs 全アプリ。Marketの「実写推奨」がスクリプト一発で解決する
motion.js(動きの定数化) 全アプリ
View Transitions による画面遷移 全アプリ。既存のフェード実装と置き換え可能

特に fetch-images.mjs は Market の課題を直接解決します。 あちらの§4.4で「実写推奨」と書きながら手作業を前提にしていましたが、マニフェストを書いてスクリプトを叩くだけになります。Portalを先に作り、Marketに戻って適用するのが最も効率的です。


16. 補足:コスト感

シリーズ中でMarketと並んで重い1本ですが、重さの質が違います。Marketは状態遷移の複雑さ、Portalは演出の作り込みです。

演出は「もう少し滑らかに」「もう少し速く」の口頭往復が最も費用を食う領域なので、本書では§7.2で14種すべてに数値を与え、§7.3でシーケンスをミリ秒単位で確定させています。motion.js に定数を集約させる指示も同じ目的です。感覚的な指示を一切挟まずに済む状態を作ってあるので、そのまま渡してください。

調整が必要になった場合も、motion.js の数値を1箇所書き換えるだけで全体に反映されます。再生成ではなく定数の編集で済む構造にしてあることが、このアプリで最大のコスト対策です。

FREE CONSULTATION

分からないときは、お気軽に30分無料相談へ

途中で止まった、エラーが消えない、自社向けに作り変えたい。どんなことでも大丈夫です。

日程を決めて話す

代表の西澤と直接お話しできます。空いている日時を選ぶだけで予約できます。

代表 西澤と話す日程を選ぶ

まずは問い合わせる

要件定義書がほしい方・ご相談は公式LINEから。メールでのお問い合わせはフォームから。