Portfolio Skill
採用担当者、リクルーター、またはクライアントがタブを閉じた後も記憶に残るポートフォリオを構築します。それは、ひとつの確固たるビジュアルアイデア、具体的なコピー、意味のあるモーション、そしてDevToolsを開いたときに評価されるエンジニアリングによって実現されます。
テーマは各人に合わせて選択されます。このファイル内の固定値は、色、フォント、レイアウトスタイルを固定するものではありません。すべての具体的な値は、コピーすべきデフォルトではなく、パターンの例です。
1. 品質基準(完了前にすべて確認すること)
- 一貫して実行された、ひとつのアートディレクション。 名前の付けられたコンセプトが、タイプ、色、レイアウト、モーション、コピーのトーンを決定づけます。無関係なスタイル(ガラス+ネオン+ブルータリズム+グラデーション)を1つのサイトで混在させないでください。
- 実際の、具体的なコンテンツ。 すべての主張はユーザーの履歴書、リポジトリ、プロフィール、またはメッセージに基づいています。具体的な数値、スタック名、役割、日付を使用します。Lorem ipsum、架空の指標、「コードを愛する情熱的な開発者」のようなものは禁止です。
- 作品を主役に。 トップ2~4のプロジェクトに最も多くのスペースを与え、理想的にはそれぞれにインタラクティブな要素を持つ専用のケーススタディページを設けます。それ以外の作品は、スキャン可能でフィルタリング可能なインデックスにまとめます。
- タイポグラフィがデザインを牽引する。 表現力豊かなディスプレイフェイス + 読みやすいテキストフェイス + オプションのモノ/ユーティリティフェイスを使用します。流動的な
clamp()サイズを使用します。Inter、Roboto、Arial、またはシステムスタックをディスプレイボイスとして使用しないでください。 - モーションは振り付けられており、散りばめられていない。 イントロ、スクロールリビール、および1~2の特徴的な瞬間。すべてが
prefers-reduced-motionを尊重し、クリーンに劣化します。 - どこでも機能する。 360pxからウルトラワイドまで、キーボード操作可能、WCAG AAコントラスト、高速なファーストペイント、WebGLやJSアニメーションなしで完全に読み取り可能。
- 出荷する。 型エラーゼロ、プロダクションビルドが通過、ルートごとのメタ/OGタグ、履歴書リンク、配信される連絡先パス、デプロイ設定。
2. ワークフロー
- 資料を収集する。 提供されたすべてのもの(履歴書PDF/DOCX、既存サイト、README、GitHubデータ、メモ)を読み込みます。不足している必須項目(名前、役割、ターゲットオーディエンス、主力プロジェクト2~4、リンク、ビジュアルの好み)のみを尋ねます。好みが指定されていない場合は、自分で方向性を選び、その方向性とその理由を伝えます。
- アーキタイプと野心レベル(セクション6A.2)をユーザーとスケジュールに合わせて選択し、UIコードの前にデザインブリーフ(セクション3)を作成します。
- 基盤を構築する(セクション5):コンテンツモジュール、トークン、タイポグラフィ、ルーター、スムーススクロール。
- ページを表示順に構成する: コンテンツ -> トークン/タイポ -> ナビ/フッター -> ヒーロー -> 主力作品 -> 作品インデックス -> アバウト/ケイパビリティ/タイムライン -> コンタクト -> ケーススタディページ -> 404。次にモーション(セクション6)。WebGLとシグネチャーエフェクトは最後に追加します。
- 実際のブラウザで約1440pxと約390pxで検証(セクション9)を行います。コードだけを読んで完了と宣言しないでください。
リポジトリですでにスタック(Next.js、Astro、SvelteKit、プレーンHTML)が使用されている場合は、それを維持します。以下のすべてのパターンは翻訳可能です。
3. アートディレクション
3.1 個人からテーマを導き出す
誰がこれを見るのか、5秒で何を感じるべきか、この人の作品はどのように見えるのかを自問します。それをコンセプトにマッピングします。ユーザー指定のブランドカラー、フォント、テーマは常に優先されます。
| 個人 / シグナル | 方向性の例(ひとつを選ぶか、考案する) |
|---|---|
| バックエンド / システム / インフラ | エディトリアルな紙+インク;設計図/テクニカルドローイング;ターミナルブルータリズム;データビジュアライゼーションアクセントを加えたスイスグリッド |
| フロントエンド / クリエイティブデベロッパー | 大胆なキネティックタイプ;WebGL主導の没入型;遊び心のあるステッカー/ジン;ハイコントラストなモノクロに一点のネオン |
| プロダクト / UXデザイナー | 落ち着いたギャラリーのような余白;暖かみのあるスタジオ(クリーム、テラコッタ、ソフトなセリフ);ケーススタディマガジン |
| ML / 研究 / データ | ラボノート(方眼紙、モノの注釈);科学ジャーナル;プロット線のあるダークな天文台 |
| モバイルデベロッパー | デバイスを前面に押し出したショーケース;柔らかな触感のある表面;ライブの電話モックアップを備えたアプリストア的な洗練 |
| 写真家 / アーティスト | イメージファーストのフルブリード;ミニマルなクローム;ダークシネマ;コンタクトシートグリッド |
| ファウンダー / ジェネラリスト | 自信に満ちたエディトリアル;マニフェストタイポグラフィ;指標に基づく信頼性 |
| 学生 / 初期キャリア | クリーンでエネルギッシュ、誠実;肩書きよりもプロジェクトと学習経路を強調 |
AIが生成したと読まれるデフォルトを避ける:白地に紫から青へのグラデーション、一般的なグラスモーフィズムカード、「こんにちは、私はXです」+ウェーブ絵文字が中央にあるヒーロー、3つの等しいフィーチャーカード、ありきたりな3Dブロブ。
3.2 デザインブリーフのテンプレート(これを最初に作成する)
コンセプト: <名前+意図の一文>
オーディエンス: <誰か、何を持ち帰ってもらうか>
パレット: bg, bg-2, fg, fg-2, muted, line, accent(+プロジェクトごとのアクセント、使用する場合)
タイポグラフィ: ディスプレイ / テキスト / モノ(フォールバック付き)、スケール比
レイアウト文法: グリッド、ガター、セクションのリズム、罫線/ボーダーとカードの使い分け
モーション: 性格(キビキビ/弾力性/ゆっくり/メカニカル)、主なイーズ、所要時間
シグネチャー: 人々が覚えているであろう1~2の瞬間
テクスチャー: グレイン / グリッド線 / なし / シェーダー
3.3 トークン(構造は固定、値はテーマごと)
:root {
/* パレット:テーマに合わせて値を置き換え */
--bg: #eeeae2; --bg-2: #e5e0d5;
--fg: #121210; --fg-2: #2a2925;
--muted: #6d695f;
--line: rgba(18,18,16,.14);
--accent: #ff4d1c;
/* タイプボイス */
--display: 'Instrument Serif', 'Times New Roman', serif;
--text: 'Geist', 'Helvetica Neue', sans-serif;
--mono: 'Geist Mono', ui-monospace, monospace;
/* リズム */
--gutter: clamp(1.1rem, 3.2vw, 2.75rem);
--ease: cubic-bezier(.16, 1, .3, 1);
/* ページレベルのエイリアス。ケーススタディページがこれらを上書きして再テーマ化できるようにする */
--page-bg: var(--bg); --page-fg: var(--fg); --page-muted: var(--muted);
--page-line: var(--line); --page-accent: var(--accent);
}
コンポーネントは--page-*のみを参照します。ケーススタディページはその<main>に新しい--page-*値を設定し、UI全体(ボタン、罫線、カーソル、選択)が自動的に再テーマ化されます。
3.4 タイポグラフィのルール
- コントラストのある組み合わせ:セリフ体ディスプレイ+グロテスク体テキスト、またはヘビーグロテスク体ディスプレイ+モノ体、またはコンデンスドディスプレイ+ヒューマニスト体テキスト。
display=swapとpreconnectを指定して、Google Fonts経由またはセルフホストwoff2で読み込みます。 - clampを使用した流動的なスケール、例:
h-xl: clamp(3.6rem, 14.5vw, 15rem)、h-lg: clamp(2.8rem, 8vw, 8.5rem)、h-md: clamp(2.1rem, 5vw, 4.6rem)、lede: clamp(1.05rem, 1.45vw, 1.3rem)。 - ディスプレイ:タイトライン(0.85-0.95)、ネガティブトラッキング(-0.02~-0.04em)。ボディ:1.5-1.65のライン、
max-width38-62ch。 - メタデータは、小さな大文字のモノ体に若干のトラッキングを加えて表示("(02) Selected work"、"2024 - Present")。
- 見出し内の1単語にイタリックまたは太さの変化を使用してアクセントを付ける("The ones I'd demo first.")。
- カウンターや統計には
font-variant-numeric: tabular-numsを使用。
3.5 レイアウト文法
- フルブリードヒーロー(
min-height: 100svh)、コンテンツは左下またはグリッド全体にアンカー、中央揃えは避ける。 - セクションヘッダーは細い罫線と左側に番号付きモノラルラベル、右側にコンテキストを配置。
- ドロップシャドウ付きカードよりも、ヘアライン罫線とグリッドを優先(コンセプトが tactile/soft でない限り)。
- セクションのリズムに変化をつける:大きなステートメント、密度の高いインデックス、水平リール、2カラム分割。6つの同一セクションを連続させない。
- 一貫した
--gutterを全体で使用。セクションのパディングはclamp(5rem, 13vw, 11rem)。
3.6 テクスチャのオプション
フィルムグレイン(body::after上のSVG feTurbulenceデータURI、不透明度0.04-0.08、pointer-events:none)、設計図グリッド線、控えめなラジアルグラデーション、またはWebGLフィールド。1つ選び、スタックしない。
4. コンテンツ戦略
4.1 情報アーキテクチャ
ホーム(シングルスクロール):
- ヒーロー: 名前、ワンライナーのポジショニング、1~2文のリード、プライマリCTA(作品を見る)+セカンダリ(履歴書 / 連絡先)、小さなメタ行(役割、専門分野、場所、稼働状況)。
- ステートメント / アバウト: 本人の言葉による2~4文の自己紹介と、真実の統計3~4つ(出荷したプロジェクト数、年数、ユーザー数、スター数、学生の場合はCGPAなど)。
- 主力作品: 2~4のヒーロープロジェクト、大きなカード、それぞれがケーススタディページにリンク。
- 作品インデックス: 他のすべてのプロジェクトを行で表示(番号、名前、一言の説明、スタック、年/リンク)、種類でフィルタリング可能。
- ケイパビリティ: グループ化されたスキル(例:バックエンド、モバイル、AI、ツール)、面接で説明できるもののみ。
- パス / タイムライン: 学歴、役割、注目すべき業績。
- コンタクト: 大きなCTA見出し、メール、フォーム、ソーシャルリンク、履歴書ダウンロード。
主力プロジェクトごとのケーススタディページ:テーマ設定されたヒーロー(名前、タグライン、役割、スタック、リンク)、問題、構築したもの、インタラクティブなデモ(シミュレーター、プレイグラウンド、ライブモックアップ、ホバーできるアーキテクチャ図)、主要な決定/トレードオフ、指標/成果、そして「次のプロジェクト」への誘導と連絡先。
404ページも同じトーンで。
4.2 コピーのルール
- 一人称、平易、具体的。何を構築したか、なぜそれが重要なのかを最初に述べ、次にどのように構築したかを述べる。
- 良い例:「独自のAWS、GCP、Azureアカウントを接続すると、それらの無料枠が1つのディスクとして機能します。」悪い例:「最先端のテクノロジーを活用した革新的なクラウドソリューション。」
- 禁止されたフィラー:情熱的な、最先端の、活用する、シームレスな、堅牢な、革新的な、旅、深く掘り下げる(delve)、「私はコードを書くのが大好きです」。
- すべての指標は出典があるか、省略します。絶対に捏造しない。
- マイクロコピーには個性を持たせるが、明確さは保つ(404では「Lost in the reel.」、「Scroll to pan」のヒント)。
4.3 単一のコンテンツモジュール
すべてのコピーとデータはsrc/content.tsに配置します。コンポーネントが伝記テキストをハードコードすることはありません。
export const PROFILE = { name, role, location, email, github, linkedin, resume: '/resume.pdf', statement };
export type Metric = { value: string; label: string };
export type Flagship = {
slug: string; path: string; index: string; name: string; kicker: string; tagline: string;
summary: string; role: string; stack: string[]; metrics: Metric[]; repo: string;
accent: string; bg: string; fg: string; // プロジェクトごとのテーマ
};
export const FLAGSHIPS: Flagship[] = [ /* 2-4 */ ];
export type WorkKind = 'Systems' | 'AI' | 'Mobile' | 'Web'; // 個人に合わせて調整
export const WORKS: { name: string; blurb: string; stack: string[]; kind: WorkKind; year: string; href: string; route?: string }[] = [];
export const CAPABILITIES: { title: string; items: string[] }[] = [];
export const PATH: { when: string; what: string; detail: string }[] = [];
export const STATS: Metric[] = [];
5. アーキテクチャ
5.1 デフォルトのスタック
Vite + React + TypeScript;カスタムプロパティを使用したプレーンCSS(チームが好めばTailwindも可);gsap + @gsap/react (ScrollTrigger);スムーススクロール用のlenis;WebGLを使用する場合のみthree;連絡先用のnodemailer;Vercel/Netlifyにデプロイ。
5.2 構造
index.html フォント、ベースメタ/OG、noscriptフォールバックテキスト
public/ favicon.svg, resume.pdf, og-image
src/content.ts すべてのコピーとデータ
src/index.css トークン、タイポグラフィ、レイアウト、コンポーネント、レスポンシブ、reduced-motion
src/lib/smooth.ts Lenis + GSAPティッカー、reduced-motionフラグ、スクロール速度
src/lib/motion.tsx useReveals, useHeroIntro, <Split>, useMeta
src/lib/router.tsx 履歴ルーター + カーテントランジション + <Link>
src/components/Chrome.tsx ナビ、モバイルメニュー、カーソル、プリローダー、フッター/コンタクト
src/components/Field.tsx オプションのWebGLヒーローバックグラウンド
src/components/CaseShell.tsx 共有のケーススタディシェル
src/pages/*.tsx ホーム、主力プロジェクトごとに1ページ、NotFound
api/contact.ts サーバーレスメールハンドラー
vercel.json SPAリライト
5.3 ルーティング
ポートフォリオには小さな履歴ルーターで十分であり、トランジションを自由に制御できます:
normalizePath(末尾のスラッシュを削除、小文字化)。navigate(to):同じパス+ハッシュ -> スムーススクロールでアンカーへ;異なるパス -> カーテンを再生、カバーされている間にページを入れ替え、トップにスクロールしてから表示。popstateをリッスン;ルート変更のたびにScrollTrigger.refresh()を呼び出す;スワップ後、保留中の#hashを処理。<Link>:外部(http、mailto)はtarget="_blank" rel="noopener noreferrer"付きのプレーンアンカーをレンダリング;内部はmetaKey/ctrlKey/shiftKeyまたは左ボタン以外の場合を除きクリックをインターセプトし、新しいタブが機能するようにします。- Next.js/Astro:それらのルーターを使用し、レイアウト/トランジションフックでカーテンを実装します。
5.4 ルートごとのSEO
useMeta(title, description, themeColor)は、ルートが変わるたびにdocument.title、description、og:*、twitter:*、theme-color、canonicalを更新します。index.htmlには完全なデフォルトと<noscript>テキストサマリーが含まれています。可能であればsummary_large_image TwitterカードとOG画像を追加します。JSON-LD Personスキーマを検討します。
5.5 連絡先API(サーバーレス、api/contact.ts)
要件:
- POSTのみ(それ以外は405)、
Cache-Control: no-store。 - ハニーポットフィールド(例:隠しフィールド
website):入力された場合、200を返して破棄。 - すべてのフィールドをトリミングし、長さ制限を設ける;単純な正規表現でメールを検証;最小メッセージ長。
- ヘッダー/件名で使用されるものから
\r\nを削除(ヘッダーインジェクション対策);HTML本文内のすべてをHTMLエスケープ。 replyTo= 送信者;from= SMTPユーザー。- IPごとのベストエフォートのレート制限(例:10分あたり3回、インメモリMapで、IPは
x-forwarded-forから取得)。 - SMTP環境変数がない場合、503と「直接メールしてください」というフレンドリなメッセージを返す;UIはフォールバックとしてメールアドレスを表示する必要があります。
- 環境変数:
SMTP_HOST、SMTP_PORT、SMTP_USER、SMTP_PASS、CONTACT_TO。.env.exampleを提供する。秘密情報を絶対にコミットしない。 - フロントエンドフォーム:アイドル/送信中/送信済み/エラーの状態、
aria-live="polite"のステータス表示、送信中は送信ボタンを無効化、すべての入力にラベル。
5.6 デプロイ
Vercel vercel.json:
{ "cleanUrls": true,
"rewrites": [{ "source": "/((?!api/|assets/|.*\..*).*)", "destination": "/" }] }
Netlify:_redirectsに/* /index.html 200。履歴書はpublic/resume.pdfに配置;すべての履歴書ボタンはdownload属性付きでそこにリンク。
6. モーションシステム
6.1 原則
- 1つのハウスイーズ(例:
expo.out/cubic-bezier(.16,1,.3,1))、リビールは0.6~1.4秒、ホバーは0.3~0.6秒。 transform、opacity、clip-pathのみアニメーションさせる。レイアウトプロパティをアニメーションさせない。- マスクされたリビール(テキストが
overflow:hiddenのボックスから浮かび上がる)は高級感がある;単なるフェードは安っぽく見える。 - 振り付け:ヒーローイントロは、プリローダー/カーテンがクリアされるのを待つ(共有
intro.delay)。 - すべてのエフェクトは
prefersReducでゲートされる。
…
[翻訳のため省略]