前回の記事の続きです。
Vibe Coding に最適な Next.js と Claude Code に向けて、UX デザイン設計ガイドを整理します。
dApps 開発の実知見を基に、 「仮説検証期における MVP 開発」 を想定したデザインシステムです。
デザイナーのアサインを省略しながら、エンジニアと PdM だけで及第点の UX デザインを可能にする ことを企図しています。
対象読者
本記事は以下の方々を想定しています。
- Web3 のエンジニア・PM: dApps 開発の効率化や技術選定に悩んでいる方
- ハッカソンのビルダー: 短期間で機能する dApps を構築したい方
- Vibe Coding の最適な構成について模索している方: AI ツールを活用した開発フローを構築したい方
特に、複雑な機能よりもスピードを重視し、ブロックチェーンネイティブな機能に集中したい開発者に有用な内容となっています。
また、FB や Tips をシェアは大歓迎なので、ぜひお気軽にコメントしてください。「ここはバッドプラクティスでは?」などのツッコミもぜひ。
デザインガイド全文
docs/design-guide.md
のように配置して使用します。
実際に使用する際は、英語に翻訳することを推奨します。
また、Web3 向けになっている箇所があるので、Web2 用途で使用する場合は適宜修正してください。
# Web3 dApps カラー設計ガイド
## 基本原則
dApps では NFT やトークンが主役。UI の色は**最小限かつ意味駆動**であるべき。
- UI は情報設計、色は構造・意味・状態の伝達手段
- 装飾ではなく、役割ある色のみ使用
- 95% はニュートラルカラーで構成
## カラーシステム
### 1. ニュートラルカラー
UI の構造・階層・テキストを表現
```css
背景: white, gray-50
テキスト: black, gray-900 (主) / gray-500, gray-600 (副)
ボーダー: gray-200, gray-300
```
### 2. セマンティックカラー
意味・状態・フィードバック専用
```css
成功: green-600 /* Wallet接続済、TX成功 */
警告: yellow-400 /* 高ガス、注意事項 */
エラー: red-500 /* 失敗、高リスク */
情報: blue-500 /* Tips、補足 */
```
### 3. インタラクションステート
ボタンや UI の状態表現
```css
通常: bg-black text-white
hover: bg-gray-900 shadow-sm
disabled: bg-gray-300 text-gray-500 opacity-50
loading: opacity-50 + spinner
```
## 実装パターン
### Header & Navigation
```tsx
<header className="sticky top-0 z-40 border-b border-gray-200 bg-white/95 backdrop-blur">
<div className="container mx-auto px-4">
<div className="flex h-16 items-center justify-between">
<Logo />
<Navigation />
<WalletButton />
</div>
</div>
</header>
```
**ナビゲーション状態**:
- アクティブ: `bg-black text-white`
- ホバー: `hover:bg-gray-100`
- フォーカス: `focus:ring-2 focus:ring-gray-400`
### Wallet Button
```tsx
<Button
className={`
${
isConnected ? 'bg-green-600 hover:bg-green-700' : 'bg-black hover:bg-gray-800'
} text-white transition-all duration-200
`}
>
{isConnecting ? (
<>
<Zap className="mr-2 h-4 w-4 animate-spin" />
Connecting...
</>
) : isConnected ? (
<>
<CheckCircle className="mr-2 h-4 w-4" />
{formatAddress(address)}
</>
) : (
<>
<Wallet className="mr-2 h-4 w-4" />
Connect Wallet
</>
)}
</Button>
```
### Mint Button
```tsx
<Button
onClick={handleMint}
disabled={!isValid || isMinting}
className="w-full bg-black hover:bg-gray-800 text-white"
size="lg"
>
{isMinting ? (
<>
<Zap className="mr-2 h-5 w-5 animate-spin" />
Minting NFT...
</>
) : (
'Mint NFT'
)}
</Button>
```
### Loading States
```tsx
// プロセス中
<div className="text-center p-3 bg-gray-50 border border-gray-200 rounded-lg">
<div className="text-sm text-black">🔄 Processing transaction...</div>
<div className="text-xs text-gray-600 mt-1">Gas: {gasEstimate}</div>
</div>
// エラー状態
<div className="text-center p-4 bg-red-50 border border-red-200 rounded-lg">
<div className="text-sm text-red-600 font-medium mb-2">
Minting Failed (Attempt {retryCount}/{maxRetries})
</div>
<div className="text-sm text-red-500 mb-3">{errorMessage}</div>
<Button className="text-yellow-700 border-yellow-300 hover:bg-yellow-50">
<Zap className="mr-1 h-3 w-3" />
Retry
</Button>
</div>
// 成功状態
<div className="w-24 h-24 bg-gradient-to-br from-green-100 to-green-200 rounded-full flex items-center justify-center mx-auto mb-6 shadow-lg">
<CheckCircle className="h-14 w-14 text-green-600" />
</div>
<h1 className="text-3xl font-bold text-black mb-4">
🎉 Agent Successfully Deployed!
</h1>
```
### Risk Level Display
```tsx
const getRiskColor = (level: string) => {
const colors = {
High: 'text-red-600 bg-red-100',
'Medium-High': 'text-orange-600 bg-orange-100',
Medium: 'text-yellow-600 bg-yellow-100',
Low: 'text-green-600 bg-green-100',
};
return colors[level] || 'text-gray-600 bg-gray-100';
};
```
## Tailwind Theme 設定
```ts
theme: {
colors: {
neutral: {
background: "#ffffff",
surface: "#f4f4f4",
border: "#e5e7eb",
text: "#000000",
subtext: "#6b7280"
},
semantic: {
success: "#16A34A",
warning: "#FACC15",
danger: "#EF4444",
info: "#3B82F6"
},
state: {
primary: "#000000",
onPrimary: "#ffffff",
disabled: "#d1d5db"
}
}
}
```
## 実装指針
### 技術スタック
- **Next.js + Tailwind CSS + shadcn/ui**
- **zustand** でグローバルステート管理
- **react-hook-form** でフォームバリデーション
- **TypeScript** 強制
### 設計ルール
- Light Mode 専用(Dark Mode なし)
- 画像は NFT・トークンアイコン・ロゴのみ許可
- アニメーションは 200ms 以下
- アイコン + テキストでアクセシビリティ確保
### レスポンシブ対応
```tsx
// モバイルファーストアプローチ
<div className="hidden md:flex items-center space-x-6">
<Navigation />
</div>
<div className="md:hidden flex items-center space-x-2">
<MobileButton />
</div>
```
## 効果
- **高いユーザビリティ**: 直感的な Wallet 接続フロー
- **一貫した UX**: 全画面サイズでの統一感
- **保守性**: shadcn/ui + Tailwind の組み合わせ
- **拡張性**: コンポーネント分割と zustand 活用
この設計システムは Web3 特有の UX 課題(長いトランザクション時間、ガス見積もり、エラー処理)を解決する実証済みのパターンです。
解説
基本原則
このデザインガイドの核心は**「UI は情報設計であり、色は構造・意味・状態の伝達手段」**という考え方です。
Web3 dApps では以下の理由から、色彩設計に特別な配慮が必要です。
NFT・トークンが主役
- ユーザーの関心は NFT アート、トークンの価値、取引結果に集中
- UI の色が強すぎると、本来の主役であるコンテンツから注意を逸らしてしまう
- 控えめな色使いによって、NFT 画像やトークン情報を際立たせる
複雑な状態管理
- Wallet 接続状態、トランザクション進行状況、エラー発生など多数の状態が存在
- 各状態を直感的に理解できる色彩設計が必要
- 装飾的な色ではなく、役割ある色のみ使用することで混乱を防ぐ
情報階層の明確化
- 重要度の高い情報(残高、ガス料金、リスクレベル)を適切に強調
- 95%をニュートラルカラーで構成し、重要な情報にのみアクセントカラーを使用
- 視認性の高い情報設計を実現
Claude Code など AI による Next.js 実装にフレンドリーな技術スタックとデザイン要件
このガイドはClaude Codeをはじめとする AI によるコード生成に最適化されています。
技術スタックの選定理由
// 推奨スタック
Next.js + Tailwind CSS + shadcn/ui + zustand + react-hook-form + TypeScript
AI フレンドリーな設計要件:
-
明確な命名規則
-
semantic
(意味的)、neutral
(中立的)、state
(状態)など、AI が理解しやすいカテゴリ名 -
bg-black hover:bg-gray-800
のような予測可能なクラス名パターン
-
-
標準化されたコンポーネント
- shadcn/ui の
<Button>
,<Card>
,<Badge>
を基本コンポーネントとして使用 - AI が既存のパターンを学習しやすい一貫した構造
- shadcn/ui の
-
実装例の豊富さ
// AIが参照しやすい実装パターン <Button className={` ${isConnected ? "bg-green-600 hover:bg-green-700" : "bg-black hover:bg-gray-800" } text-white transition-all duration-200 `} >
-
TypeScript 強制
- 型定義により、AI が正確なコード生成を行える
- プロパティの予測と補完が容易
MVP 開発における利点:
- パターン化された実装により、AI が素早く機能を生成
- 一貫したデザインシステムで品質の安定化
- 最小限の色彩設計により、デザイン判断の負荷を軽減
色は白黒グレーを基調にして、アクセントカラーのみ使用
ニュートラルカラー中心のアプローチ
/* 基本パレット(UI全体の95%) */
背景: white, gray-50
テキスト: black, gray-900 (主要) / gray-500, gray-600 (副次的)
ボーダー: gray-200, gray-300
この設計思想には以下の利点があります。
1. 視認性の向上
- 高いコントラスト比により、テキストの可読性が向上
- NFT 画像やトークンアイコンとの色彩衝突を回避
- 長時間の使用でも目の疲労を軽減
2. ブランドニュートラル
- 特定のブランドカラーに依存しない汎用的な設計
- 複数のプロジェクトで再利用可能
- NFT やトークンの多様な色彩に対応
3. アクセントカラーの効果的活用
// セマンティックカラー(意味を持つ色彩のみ)
const semanticColors = {
success: 'green-600', // Wallet接続成功、トランザクション完了
warning: 'yellow-400', // 高ガス料金、注意事項
danger: 'red-500', // エラー発生、高リスク表示
info: 'blue-500', // 補足情報、ヒント
};
実装における効果:
- エラーは赤、成功は緑という直感的な色彩設計
- 状態変化が明確に伝わる
- 装飾的な色を排除し、機能的な色のみを使用
画像やリッチなデザインはなるべく使用しない。CSS と絵文字で表現
ミニマルデザインのアプローチ
このガイドでは**「画像は NFT・トークンアイコン・ロゴのみ許可」**という厳格なルールを設けています。
CSS ベースの表現手法:
// 絵文字とCSSを活用した状態表現
{
mintingState === 'minting' && (
<div className="text-center p-3 bg-gray-50 border border-gray-200 rounded-lg">
<div className="text-sm text-black">🔄 Processing transaction...</div>
<div className="text-xs text-gray-600 mt-1">Gas: {gasEstimate}</div>
</div>
);
}
// 成功状態の豪華な表現(画像不使用)
<div className="w-24 h-24 bg-gradient-to-br from-green-100 to-green-200 rounded-full flex items-center justify-center mx-auto mb-6 shadow-lg">
<CheckCircle className="h-14 w-14 text-green-600" />
</div>;
この手法の利点:
-
パフォーマンス向上
- 画像読み込みの遅延なし
- バンドルサイズの削減
- レスポンシブ対応の簡素化
-
保守性の向上
- CSS のみで完結する視覚表現
- 色変更やサイズ調整が容易
- バージョン管理が簡単
-
アクセシビリティの向上
- 絵文字による直感的な状態表現
- スクリーンリーダー対応
- 多言語対応時の翻訳不要
実装パターンの例:
// リスクレベル表示(画像不使用)
const getRiskColor = (level: string) => {
const styles = {
High: 'text-red-600 bg-red-100',
Medium: 'text-yellow-600 bg-yellow-100',
Low: 'text-green-600 bg-green-100',
};
return styles[level] || 'text-gray-600 bg-gray-100';
};
// 絵文字を活用した状態表現
<div className="text-center">
<div className="text-4xl mb-2">🎉</div>
<h1 className="text-3xl font-bold text-black">Agent Successfully Deployed!</h1>
</div>;
この設計により、視覚的な豊かさを保ちながら、技術的な複雑さを最小限に抑えることが可能になります。特に Claude Code などの AI ツールを使用する場合、画像処理やリッチなデザイン要素の実装よりも、CSS ベースの表現の方が確実で高速な開発が期待できます。