dramaling-vocab-learning/DramaLing_UI_UX設計規範.md

1540 lines
37 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# DramaLing UI/UX 設計規範
## 設計理念
DramaLing詞彙學習系統採用**清新、直觀、專注學習**的設計理念,致力於創造無障礙且引人入勝的學習體驗。設計強調**簡潔性、一致性和互動性**,讓用戶能夠專注於學習內容本身。
---
## 1. 視覺設計系統
### 1.1 顏色系統
#### 主要顏色調色板
```css
/* 主色調 - 藍色系統 */
--primary-default: #3B82F6; /* 主要按鈕、鏈接 */
--primary-hover: #2563EB; /* 懸停狀態 */
--primary-light: #EFF6FF; /* 淺色背景 */
/* 語義顏色 */
--success: #10B981; /* 正確答案、成功狀態 */
--warning: #F59E0B; /* 警告、提示 */
--error: #EF4444; /* 錯誤、失敗狀態 */
--info: #8B5CF6; /* 資訊提示 */
/* 中性色系 */
--gray-50: #F9FAFB; /* 最淺背景 */
--gray-100: #F3F4F6; /* 卡片背景 */
--gray-200: #E5E7EB; /* 邊框、分隔線 */
--gray-300: #D1D5DB; /* 次要邊框 */
--gray-500: #6B7280; /* 次要文字 */
--gray-600: #4B5563; /* 主要文字 */
--gray-700: #374151; /* 標題文字 */
--gray-900: #111827; /* 強調文字 */
```
#### 顏色使用規範
- **主色調藍色**: 用於主要動作按鈕、導航高亮、進度指示
- **成功綠色**: 正確答案回饋、完成狀態、積極反饋
- **錯誤紅色**: 錯誤答案回饋、警告信息、負面反饋
- **警告黃色**: 提示信息、注意事項、中性反饋
- **中性灰色**: 文字內容、背景、邊框等
### 1.2 字體系統
#### 字體家族
```css
font-family: 'Inter', 'Noto Sans TC', 'system-ui', 'sans-serif';
```
#### 字體尺寸階層
```css
/* 標題層級 */
.text-3xl { font-size: 1.875rem; } /* 主頁面標題 */
.text-2xl { font-size: 1.5rem; } /* 區塊標題 */
.text-xl { font-size: 1.25rem; } /* 子標題 */
.text-lg { font-size: 1.125rem; } /* 大號正文 */
/* 正文層級 */
.text-base { font-size: 1rem; } /* 標準正文 */
.text-sm { font-size: 0.875rem; } /* 小號文字 */
.text-xs { font-size: 0.75rem; } /* 標籤、說明文字 */
```
#### 字重規範
```css
.font-bold { font-weight: 700; } /* 標題、重點強調 */
.font-semibold { font-weight: 600; } /* 副標題、按鈕文字 */
.font-medium { font-weight: 500; } /* 導航、標籤 */
.font-normal { font-weight: 400; } /* 正文內容 */
```
### 1.3 間距系統
#### 間距單位
```css
/* 基礎間距單位4px */
.space-y-1 { margin: 4px 0; } /* 緊密間距 */
.space-y-2 { margin: 8px 0; } /* 小間距 */
.space-y-3 { margin: 12px 0; } /* 標準間距 */
.space-y-4 { margin: 16px 0; } /* 中等間距 */
.space-y-6 { margin: 24px 0; } /* 大間距 */
.space-y-8 { margin: 32px 0; } /* 區塊間距 */
/* 內邊距 */
.p-2 { padding: 8px; } /* 小內距 */
.p-3 { padding: 12px; } /* 標準內距 */
.p-4 { padding: 16px; } /* 中等內距 */
.p-6 { padding: 24px; } /* 大內距 */
.p-8 { padding: 32px; } /* 大型容器內距 */
```
### 1.4 圓角系統
```css
.rounded-md { border-radius: 6px; } /* 小元素:按鈕、輸入框 */
.rounded-lg { border-radius: 8px; } /* 標準元素:卡片、容器 */
.rounded-xl { border-radius: 12px; } /* 大元素:主要卡片 */
.rounded-full { border-radius: 50%; } /* 圓形:頭像、標籤 */
```
---
## 2. 組件設計規範
### 2.1 按鈕設計系統
#### 主要按鈕 (Primary Button)
```tsx
<button className="
px-6 py-3
bg-primary text-white
rounded-lg
hover:bg-primary-hover
transition-colors
font-medium
disabled:opacity-50
disabled:cursor-not-allowed
">
主要動作
</button>
```
#### 次要按鈕 (Secondary Button)
```tsx
<button className="
px-6 py-3
bg-gray-200 text-gray-700
rounded-lg
hover:bg-gray-300
transition-colors
font-medium
">
次要動作
</button>
```
#### 危險按鈕 (Danger Button)
```tsx
<button className="
px-4 py-2
bg-red-600 text-white
rounded-lg
hover:bg-red-700
transition-colors
font-medium
">
刪除/危險動作
</button>
```
#### 模式切換按鈕 (Mode Toggle)
```tsx
<button className={`
px-3 py-2
rounded-md
transition-colors
${isActive
? 'bg-primary text-white'
: 'text-gray-600 hover:text-gray-900'
}
`}>
模式名稱
</button>
```
### 2.2 卡片設計系統
#### 主要內容卡片
```tsx
<div className="
bg-white
rounded-xl
shadow-lg
p-8
hover:shadow-xl
transition-shadow
">
{/* 卡片內容 */}
</div>
```
#### 資訊展示卡片
```tsx
<div className="
bg-gray-50
rounded-lg
p-4
border border-gray-200
">
{/* 資訊內容 */}
</div>
```
#### 狀態回饋卡片
```tsx
{/* 成功狀態 */}
<div className="
bg-green-50
border border-green-200
rounded-lg
p-6
">
{/* 成功內容 */}
</div>
{/* 錯誤狀態 */}
<div className="
bg-red-50
border border-red-200
rounded-lg
p-6
">
{/* 錯誤內容 */}
</div>
{/* 警告狀態 */}
<div className="
bg-yellow-50
border border-yellow-200
rounded-lg
p-6
">
{/* 警告內容 */}
</div>
```
### 2.3 輸入組件設計
#### 文字輸入框
```tsx
<input className="
w-full
px-4 py-3
border border-gray-300
rounded-lg
focus:ring-2 focus:ring-primary focus:border-transparent
outline-none
placeholder-gray-400
" />
```
#### 下拉選單
```tsx
<select className="
w-full
p-2
border border-gray-300
rounded-md
focus:ring-blue-500 focus:border-blue-500
bg-white
">
<option>選項</option>
</select>
```
#### 複選框/單選框
```tsx
<input type="checkbox" className="
w-4 h-4
text-blue-600
bg-gray-100
border-gray-300
rounded
focus:ring-blue-500
" />
```
### 2.4 標籤和徽章系統
#### 難度等級標籤
```tsx
{/* A1-A2 基礎等級 */}
<span className="
text-xs px-2 py-1
rounded-full
bg-green-100 text-green-700
">
CEFR A2
</span>
{/* B1-B2 中級等級 */}
<span className="
text-xs px-2 py-1
rounded-full
bg-yellow-100 text-yellow-700
">
CEFR B1
</span>
{/* C1-C2 高級等級 */}
<span className="
text-xs px-2 py-1
rounded-full
bg-red-100 text-red-700
">
CEFR C1
</span>
```
#### 詞性標籤
```tsx
<span className="
text-sm
bg-gray-100 text-gray-600
px-2 py-1
rounded
">
noun
</span>
```
#### 同義詞標籤
```tsx
<span className="
text-xs
bg-blue-100 text-blue-700
px-2 py-1
rounded-full
">
synonym
</span>
```
---
## 3. 交互設計模式
### 3.1 學習模式設計
#### 模式切換器設計原則
- **視覺清晰**: 當前選中模式使用主色調高亮
- **狀態一致**: 所有模式按鈕使用相同的設計語言
- **響應迅速**: 切換模式時即時更新UI狀態
- **分組合理**: 相關功能模式在視覺上聚集
```tsx
{/* 學習模式切換器 */}
<div className="bg-white rounded-lg shadow-sm p-1 inline-flex flex-wrap">
{modes.map(mode => (
<button
key={mode.id}
onClick={() => setMode(mode.id)}
className={`
px-3 py-2 rounded-md transition-colors
${currentMode === mode.id
? 'bg-primary text-white'
: 'text-gray-600 hover:text-gray-900'
}
`}
>
{mode.label}
</button>
))}
</div>
```
### 3.2 進度指示設計
#### 學習進度條
```tsx
<div className="mb-8">
{/* 進度資訊 */}
<div className="flex justify-between items-center mb-2">
<span className="text-sm text-gray-600">進度</span>
<div className="flex items-center gap-4">
<span className="text-sm text-gray-600">
{currentIndex + 1} / {total}
</span>
<div className="text-sm">
<span className="text-green-600 font-semibold">{correct}</span>
<span className="text-gray-500">/</span>
<span className="text-gray-600">{total}</span>
{total > 0 && (
<span className="text-blue-600 ml-2">
({Math.round((correct / total) * 100)}%)
</span>
)}
</div>
</div>
</div>
{/* 進度條 */}
<div className="w-full bg-gray-200 rounded-full h-2">
<div
className="bg-primary h-2 rounded-full transition-all"
style={{ width: `${((currentIndex + 1) / total) * 100}%` }}
/>
</div>
</div>
```
### 3.3 狀態回饋設計
#### 答案回饋模式
```tsx
{/* 正確回饋 */}
<div className="
p-6 rounded-lg
bg-green-50 border border-green-200
">
<p className="font-semibold text-left text-xl mb-4 text-green-700">
正確!
</p>
{/* 回饋內容 */}
</div>
{/* 錯誤回饋 */}
<div className="
p-6 rounded-lg
bg-red-50 border border-red-200
">
<p className="font-semibold text-left text-xl mb-4 text-red-700">
錯誤!
</p>
<div className="mb-4">
<p className="text-gray-700 text-left">
正確答案是:<strong className="text-lg">{correctAnswer}</strong>
</p>
</div>
</div>
```
#### 載入狀態設計
```tsx
{/* 按鈕載入狀態 */}
<button disabled className="
flex items-center justify-center gap-2
bg-primary text-white
px-4 py-2 rounded-lg
opacity-50 cursor-not-allowed
">
<div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" />
<span>載入中...</span>
</button>
{/* 頁面載入狀態 */}
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 flex items-center justify-center">
<div className="text-gray-500 text-lg">載入中...</div>
</div>
```
### 3.4 互動式元素設計
#### 點擊式詞彙分析
```tsx
{/* 高價值詞彙 - 綠色邊框 + 星星 */}
<span className="
cursor-pointer transition-all duration-200 rounded relative
mx-0.5 px-1 py-0.5
bg-green-100 border-2 border-green-400
hover:bg-green-200 hover:shadow-sm
transform hover:-translate-y-0.5
">
{word}
<span className="absolute -top-1 -right-1 text-xs"></span>
</span>
{/* 高價值片語 - 黃色邊框 + 星星 */}
<span className="
cursor-pointer transition-all duration-200 rounded relative
mx-0.5 px-1 py-0.5
bg-yellow-100 border-2 border-yellow-400
hover:bg-yellow-200 hover:shadow-sm
transform hover:-translate-y-0.5
">
{phrase}
<span className="absolute -top-1 -right-1 text-xs"></span>
</span>
{/* 普通詞彙 - 藍色邊框 */}
<span className="
cursor-pointer transition-all duration-200 rounded
mx-0.5 px-1 py-0.5
bg-blue-100 border-2 border-blue-300
hover:bg-blue-200 hover:shadow-sm
">
{word}
</span>
```
#### 詞彙詳情彈窗
```tsx
<div className="
fixed z-20
bg-white border border-gray-300
rounded-lg shadow-lg
p-4 w-80 max-w-sm
" style={{
left: `${position.x}px`,
top: `${position.y}px`,
transform: 'translate(-50%, -100%)'
}}>
{/* 標題區 */}
<div className="flex items-center justify-between mb-3">
<h3 className="text-lg font-bold text-gray-900">{word}</h3>
<button className="text-gray-400 hover:text-gray-600"></button>
</div>
{/* 高價值標記 */}
{isHighValue && (
<div className="bg-green-50 border border-green-200 rounded-lg p-3 mb-3">
<div className="flex items-center gap-2">
<div className="text-green-600 text-lg">🎯</div>
<div className="text-sm font-medium text-green-800">重點學習詞彙</div>
</div>
</div>
)}
{/* 詞彙資訊 */}
<div className="space-y-3">
{/* 詞性和發音 */}
<div className="flex items-center gap-4">
<span className="text-sm bg-gray-100 px-2 py-1 rounded">
{partOfSpeech}
</span>
<span className="text-sm text-gray-600">{pronunciation}</span>
<AudioPlayer text={word} />
</div>
{/* 翻譯 */}
<div>
<div className="text-sm font-medium text-gray-700">翻譯</div>
<div className="text-base text-gray-900">{translation}</div>
</div>
{/* 定義 */}
<div>
<div className="text-sm font-medium text-gray-700">定義</div>
<div className="text-sm text-gray-600">{definition}</div>
</div>
{/* 保存按鈕 */}
<div className="pt-3 border-t border-gray-200">
<button className="
w-full
bg-blue-600 text-white
py-2 px-4
rounded-lg
text-sm font-medium
hover:bg-blue-700
transition-colors
flex items-center justify-center gap-2
">
<span>💾</span>
<span>保存到詞卡</span>
</button>
</div>
</div>
</div>
```
### 2.2 學習卡片設計
#### 翻卡記憶卡片
```tsx
{/* 卡片容器 */}
<div className="card-container" style={{ height: `${cardHeight}px` }}>
<div className={`card ${isFlipped ? 'flipped' : ''}`}>
{/* 正面 */}
<div className="card-front">
<div className="
bg-white rounded-xl shadow-lg
cursor-pointer hover:shadow-xl transition-shadow
p-8
">
{/* 標題區 */}
<div className="flex justify-between items-start mb-6">
<h2 className="text-2xl font-bold text-gray-900">翻卡記憶</h2>
<span className="bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded-full">
{difficulty}
</span>
</div>
{/* 單字展示 */}
<div className="flex-1 flex items-center justify-center mt-6">
<div className="bg-gray-50 rounded-lg p-8 w-full text-center">
<h3 className="text-4xl font-bold text-gray-900 mb-6">{word}</h3>
<div className="flex items-center justify-center gap-3">
<span className="text-lg text-gray-500">{pronunciation}</span>
<AudioPlayer text={word} />
</div>
</div>
</div>
</div>
</div>
{/* 背面 */}
<div className="card-back">
<div className="bg-white rounded-xl shadow-lg p-6">
<div className="space-y-4">
{/* 定義區塊 */}
<div className="bg-gray-50 rounded-lg p-4">
<h3 className="font-semibold text-gray-900 mb-2 text-left">定義</h3>
<p className="text-gray-700 text-left">{definition}</p>
</div>
{/* 例句區塊 */}
<div className="bg-gray-50 rounded-lg p-4">
<h3 className="font-semibold text-gray-900 mb-2 text-left">例句</h3>
<div className="relative">
<p className="text-gray-700 italic mb-2 text-left pr-12">"{example}"</p>
<div className="absolute bottom-0 right-0">
<AudioPlayer text={example} />
</div>
</div>
<p className="text-gray-600 text-sm text-left">"{exampleTranslation}"</p>
</div>
{/* 同義詞區塊 */}
<div className="bg-gray-50 rounded-lg p-4">
<h3 className="font-semibold text-gray-900 mb-2 text-left">同義詞</h3>
<div className="flex flex-wrap gap-2">
{synonyms.map((synonym, index) => (
<span key={index} className="
bg-white text-gray-700
px-3 py-1
rounded-full text-sm
border border-gray-200
">
{synonym}
</span>
))}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
```
#### 3D翻卡動畫CSS
```css
.card-container {
perspective: 1000px;
transition: height 0.3s ease;
overflow: visible;
position: relative;
}
.card {
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 0.6s ease;
transform-style: preserve-3d;
}
.card.flipped {
transform: rotateY(180deg);
}
.card-front, .card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
display: flex;
align-items: stretch;
justify-content: center;
top: 0;
left: 0;
}
.card-back {
transform: rotateY(180deg);
}
```
### 3.3 測驗模式設計
#### 選擇題設計
```tsx
<div className="space-y-3 mb-6">
{options.map((option, idx) => (
<button
key={idx}
onClick={() => handleAnswer(option)}
disabled={showResult}
className={`
w-full p-4 text-left
rounded-lg border-2 transition-all
${showResult
? option === correctAnswer
? 'border-green-500 bg-green-50 text-green-700'
: option === selectedAnswer
? 'border-red-500 bg-red-50 text-red-700'
: 'border-gray-200 bg-gray-50 text-gray-500'
: 'border-gray-200 hover:border-blue-300 hover:bg-blue-50'
}
`}
>
{option}
</button>
))}
</div>
```
#### 填空題設計
```tsx
{/* 句子中的填空輸入 */}
<input
type="text"
value={answer}
onChange={(e) => setAnswer(e.target.value)}
disabled={showResult}
className={`
inline-block px-2 py-1 text-center
bg-transparent focus:outline-none
disabled:bg-gray-100
${answer
? 'border-b-2 border-blue-500'
: 'border-b-2 border-dashed border-gray-400 focus:border-blue-400 focus:border-solid'
}
`}
style={{
width: `${Math.max(100, Math.max(targetWord.length * 12, answer.length * 12 + 20))}px`
}}
/>
```
### 3.4 例句重組設計
#### 重組區域設計
```tsx
{/* 答案區域 */}
<div className="
relative min-h-[120px]
bg-gray-50 rounded-lg p-4
border-2 border-dashed border-gray-300
">
{arrangedWords.length === 0 ? (
<div className="absolute inset-0 flex items-center justify-center text-gray-400 text-lg">
答案區
</div>
) : (
<div className="flex flex-wrap gap-2">
{arrangedWords.map((word, index) => (
<div
key={index}
className="
inline-flex items-center
bg-blue-100 text-blue-800
px-3 py-2 rounded-full
text-lg font-medium
cursor-pointer hover:bg-blue-200
transition-colors
"
onClick={() => removeWord(word)}
>
{word}
<span className="ml-2 text-blue-600 hover:text-blue-800">×</span>
</div>
))}
</div>
)}
</div>
{/* 可用單字區域 */}
<div className="bg-white border border-gray-200 rounded-lg p-4 min-h-[80px]">
{shuffledWords.length === 0 ? (
<div className="text-center text-gray-400">所有單字都已使用</div>
) : (
<div className="flex flex-wrap gap-2">
{shuffledWords.map((word, index) => (
<button
key={index}
onClick={() => selectWord(word)}
className="
bg-gray-100 text-gray-800
px-3 py-2 rounded-full
text-lg font-medium
cursor-pointer hover:bg-gray-200
active:bg-gray-300
transition-colors select-none
"
>
{word}
</button>
))}
</div>
)}
</div>
```
---
## 4. 布局設計規範
### 4.1 頁面布局模式
#### 學習頁面布局
```tsx
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100">
{/* 導航欄 */}
<Navigation showExitLearning={true} onExitLearning={handleExit} />
{/* 主要內容區 */}
<div className="max-w-4xl mx-auto px-4 py-8">
{/* 進度條 */}
<ProgressBar />
{/* 模式切換器 */}
<ModeSelector />
{/* 學習內容 */}
<LearningContent />
{/* 導航按鈕 */}
<NavigationButtons />
</div>
</div>
```
#### 內容頁面布局
```tsx
<div className="min-h-screen bg-gray-50">
<Navigation />
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
{/* 頁面標題 */}
<h1 className="text-3xl font-bold mb-8">頁面標題</h1>
{/* 內容區塊 */}
<div className="max-w-4xl mx-auto space-y-6">
{/* 內容卡片 */}
</div>
</div>
</div>
```
### 4.2 響應式設計
#### 斷點系統
```css
/* 小屏幕 (手機) */
sm: '640px'
/* 中等屏幕 (平板) */
md: '768px'
/* 大屏幕 (桌面) */
lg: '1024px'
/* 超大屏幕 */
xl: '1280px'
```
#### 響應式組件範例
```tsx
{/* 網格布局響應式 */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{/* 項目 */}
</div>
{/* 導航響應式 */}
<div className="hidden md:flex space-x-6">
{/* 桌面版導航 */}
</div>
<div className="md:hidden">
{/* 手機版導航 */}
</div>
{/* 文字大小響應式 */}
<h1 className="text-2xl md:text-3xl font-bold">標題</h1>
```
---
## 5. 互動設計原則
### 5.1 微互動設計
#### 懸停效果
```tsx
{/* 卡片懸停 */}
<div className="
bg-white rounded-xl shadow-lg
hover:shadow-xl
transition-shadow duration-300
">
{/* 內容 */}
</div>
{/* 按鈕懸停 */}
<button className="
bg-primary text-white
hover:bg-primary-hover
transform hover:scale-105
transition-all duration-200
">
按鈕
</button>
{/* 詞彙懸停 */}
<span className="
cursor-pointer
hover:bg-blue-200 hover:shadow-sm
transform hover:-translate-y-0.5
transition-all duration-200
">
詞彙
</span>
```
#### 動畫效果
```tsx
{/* 載入動畫 */}
<div className="animate-spin w-4 h-4 border-2 border-white border-t-transparent rounded-full" />
{/* 淡入動畫 */}
<div className="animate-fadeIn opacity-0 animate-fade-in">
{/* 內容 */}
</div>
{/* 滑入動畫 */}
<div className="transform translate-x-full animate-slide-in">
{/* 內容 */}
</div>
```
### 5.2 狀態管理原則
#### 視覺狀態指示
```tsx
{/* 禁用狀態 */}
<button className="
opacity-50 cursor-not-allowed
bg-gray-300 text-gray-500
">
禁用按鈕
</button>
{/* 選中狀態 */}
<div className="
border-2
${isSelected
? 'border-blue-500 bg-blue-50'
: 'border-gray-200'
}
">
{/* 內容 */}
</div>
{/* 錯誤狀態 */}
<div className="
border-red-400 bg-red-50
text-red-700
">
{/* 錯誤內容 */}
</div>
```
### 5.3 回饋設計模式
#### 即時回饋
```tsx
{/* 成功提示 */}
<div className="
fixed bottom-4 right-4
bg-green-600 text-white
px-4 py-3 rounded-lg shadow-lg
animate-slide-up
">
操作成功
</div>
{/* 錯誤提示 */}
<div className="
fixed bottom-4 right-4
bg-red-600 text-white
px-4 py-3 rounded-lg shadow-lg
animate-slide-up
">
操作失敗
</div>
```
---
## 6. 特殊組件設計
### 6.1 模態對話框設計
#### 標準模態框
```tsx
{/* 遮罩層 */}
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
{/* 模態內容 */}
<div className="bg-white rounded-lg p-6 max-w-md w-full mx-4">
{/* 標題 */}
<h3 className="text-lg font-semibold mb-4">對話框標題</h3>
{/* 內容 */}
<div className="mb-4">
{/* 對話框內容 */}
</div>
{/* 按鈕區 */}
<div className="flex gap-2">
<button className="flex-1 px-4 py-2 border border-gray-300 text-gray-700 rounded-md hover:bg-gray-50">
取消
</button>
<button className="flex-1 px-4 py-2 bg-primary text-white rounded-md hover:bg-primary-hover">
確認
</button>
</div>
</div>
</div>
```
#### 圖片預覽模態框
```tsx
<div
className="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50"
onClick={closeModal}
>
<div className="relative max-w-4xl max-h-[90vh] mx-4">
<img
src={imageUrl}
alt="放大圖片"
className="max-w-full max-h-full rounded-lg"
/>
<button
onClick={closeModal}
className="
absolute top-4 right-4
bg-black bg-opacity-50 text-white
p-2 rounded-full
hover:bg-opacity-75
"
>
</button>
</div>
</div>
```
### 6.2 導航設計
#### 學習導航按鈕
```tsx
<div className="flex gap-4 mt-6">
{/* 上一張按鈕 */}
<button
onClick={handlePrevious}
disabled={isFirst}
className="
flex-1 py-3
bg-gray-500 text-white
rounded-lg
disabled:opacity-50 disabled:cursor-not-allowed
hover:bg-gray-600
transition-colors font-medium
"
>
上一張
</button>
{/* 下一張按鈕 */}
<button
onClick={handleNext}
className="
flex-1 py-3
bg-primary text-white
rounded-lg
hover:bg-primary-dark
transition-colors font-medium
"
>
{isLast ? '完成' : '下一張'}
</button>
</div>
```
### 6.3 錯誤報告組件
```tsx
{/* 錯誤報告按鈕 */}
<div className="flex justify-end mb-2">
<button
onClick={openReportModal}
className="px-3 py-2 rounded-md transition-colors text-gray-600 hover:text-gray-900"
>
🚩 回報錯誤
</button>
</div>
{/* 錯誤報告模態框 */}
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg p-6 max-w-md w-full mx-4">
<h3 className="text-lg font-semibold mb-4">回報錯誤</h3>
<div className="mb-4">
<p className="text-sm text-gray-600 mb-2">單字:{word}</p>
</div>
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700 mb-2">
錯誤類型
</label>
<select className="
w-full p-2
border border-gray-300 rounded-md
focus:ring-blue-500 focus:border-blue-500
">
<option value="">請選擇錯誤類型</option>
<option value="translation">翻譯錯誤</option>
<option value="definition">定義錯誤</option>
<option value="pronunciation">發音錯誤</option>
<option value="example">例句錯誤</option>
</select>
</div>
<div className="flex gap-2">
<button className="flex-1 px-4 py-2 border border-gray-300 text-gray-700 rounded-md hover:bg-gray-50">
取消
</button>
<button className="flex-1 px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700">
送出回報
</button>
</div>
</div>
</div>
```
---
## 7. 設計令牌 (Design Tokens)
### 7.1 間距令牌
```css
/* 基礎間距單位4px */
--spacing-1: 4px; /* gap-1, p-1, m-1 */
--spacing-2: 8px; /* gap-2, p-2, m-2 */
--spacing-3: 12px; /* gap-3, p-3, m-3 */
--spacing-4: 16px; /* gap-4, p-4, m-4 */
--spacing-6: 24px; /* gap-6, p-6, m-6 */
--spacing-8: 32px; /* gap-8, p-8, m-8 */
/* 布局間距 */
--layout-xs: 16px; /* 小型組件間距 */
--layout-sm: 24px; /* 中型組件間距 */
--layout-md: 32px; /* 標準組件間距 */
--layout-lg: 48px; /* 大型區塊間距 */
--layout-xl: 64px; /* 頁面區塊間距 */
```
### 7.2 陰影令牌
```css
/* 陰影系統 */
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05); /* 輕微陰影 */
--shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1); /* 標準陰影 */
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1); /* 中等陰影 */
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1); /* 大陰影(卡片) */
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1); /* 超大陰影(懸停) */
```
### 7.3 過渡動畫令牌
```css
/* 過渡時間 */
--transition-fast: 150ms; /* 快速回饋 */
--transition-normal: 300ms; /* 標準過渡 */
--transition-slow: 500ms; /* 慢速動畫 */
/* 過渡函數 */
--ease-out: cubic-bezier(0, 0, 0.2, 1);
--ease-in: cubic-bezier(0.4, 0, 1, 1);
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
```
---
## 8. 組件使用指南
### 8.1 按鈕組件使用
#### 使用場景對照表
| 按鈕類型 | 使用場景 | CSS類別 |
|---------|----------|---------|
| Primary | 主要動作(保存、確認、下一步) | `bg-primary text-white hover:bg-primary-hover` |
| Secondary | 次要動作(取消、重置) | `bg-gray-200 text-gray-700 hover:bg-gray-300` |
| Danger | 危險動作(刪除、清除) | `bg-red-600 text-white hover:bg-red-700` |
| Success | 成功動作(完成、提交) | `bg-success text-white hover:bg-green-600` |
#### 按鈕尺寸規範
```tsx
{/* 大型按鈕 - 主要動作 */}
<button className="px-6 py-3 text-base">大按鈕</button>
{/* 標準按鈕 - 一般動作 */}
<button className="px-4 py-2 text-sm">標準按鈕</button>
{/* 小型按鈕 - 次要動作 */}
<button className="px-3 py-1 text-xs">小按鈕</button>
```
### 8.2 卡片組件使用
#### 主要內容卡片
- **用途**: 主要學習內容、重要信息展示
- **特點**: 大陰影、圓角、懸停效果
- **樣式**: `bg-white rounded-xl shadow-lg hover:shadow-xl`
#### 資訊展示卡片
- **用途**: 次要信息、詳細說明
- **特點**: 淺色背景、邊框、適中內距
- **樣式**: `bg-gray-50 rounded-lg p-4 border border-gray-200`
#### 狀態回饋卡片
- **用途**: 答案回饋、操作結果
- **特點**: 狀態色彩、邊框強調
- **樣式**: `bg-green-50 border border-green-200` (成功)
### 8.3 表單組件使用
#### 輸入框設計
```tsx
<input className="
w-full px-4 py-3
border border-gray-300 rounded-lg
focus:ring-2 focus:ring-primary focus:border-transparent
outline-none
placeholder-gray-400
" />
```
#### 選擇器設計
```tsx
<select className="
w-full p-2
border border-gray-300 rounded-md
focus:ring-blue-500 focus:border-blue-500
bg-white
">
<option>選項</option>
</select>
```
---
## 9. 可訪問性設計
### 9.1 語義化HTML
```tsx
{/* 使用適當的語義標籤 */}
<main role="main">
<section aria-labelledby="learning-section">
<h2 id="learning-section">學習區塊</h2>
{/* 內容 */}
</section>
</main>
{/* 按鈕語義 */}
<button
type="button"
aria-label="播放音頻"
aria-pressed={isPlaying}
>
{isPlaying ? <Pause /> : <Play />}
</button>
```
### 9.2 鍵盤導航
```tsx
{/* 支援鍵盤操作 */}
<input
onKeyDown={(e) => {
if (e.key === 'Enter') {
handleSubmit();
}
if (e.key === 'Escape') {
handleCancel();
}
}}
/>
```
### 9.3 焦點管理
```tsx
{/* 明確的焦點樣式 */}
<button className="
focus:ring-2 focus:ring-primary focus:ring-offset-2
focus:outline-none
">
按鈕
</button>
```
---
## 10. 動畫設計規範
### 10.1 頁面過渡
```css
/* 頁面淡入 */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
/* 滑動進入 */
@keyframes slideIn {
from { transform: translateX(100%); }
to { transform: translateX(0); }
}
/* 放大進入 */
@keyframes scaleIn {
from { transform: scale(0.9); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
```
### 10.2 互動動畫
```css
/* 懸停上升效果 */
.hover-lift {
transition: transform 0.2s ease;
}
.hover-lift:hover {
transform: translateY(-2px);
}
/* 點擊回饋 */
.click-feedback {
transition: transform 0.1s ease;
}
.click-feedback:active {
transform: scale(0.98);
}
```
### 10.3 卡片翻轉動畫
```css
.card-flip-container {
perspective: 1000px;
}
.card-flip {
transition: transform 0.6s ease;
transform-style: preserve-3d;
}
.card-flip.flipped {
transform: rotateY(180deg);
}
.card-flip-front,
.card-flip-back {
backface-visibility: hidden;
position: absolute;
width: 100%;
height: 100%;
}
.card-flip-back {
transform: rotateY(180deg);
}
```
---
## 11. 設計一致性檢查清單
### 11.1 視覺一致性
- [ ] 所有按鈕使用統一的顏色和尺寸系統
- [ ] 卡片陰影和圓角保持一致
- [ ] 文字層級和間距符合設計系統
- [ ] 狀態顏色使用語義化且一致
### 11.2 交互一致性
- [ ] 相同功能的組件使用相同的交互模式
- [ ] 懸停和點擊效果在所有組件中保持一致
- [ ] 載入狀態使用統一的視覺表現
- [ ] 錯誤處理採用一致的回饋方式
### 11.3 內容一致性
- [ ] 標題層級結構合理且一致
- [ ] 說明文字使用統一的語調和格式
- [ ] 圖標使用保持一致的視覺風格
- [ ] 操作流程邏輯清晰且可預測
---
## 12. 實現指南
### 12.1 新組件開發流程
1. **設計審查**: 確認設計符合系統規範
2. **組件拆分**: 識別可重用的設計模式
3. **樣式實現**: 使用設計令牌和預定義類別
4. **互動測試**: 驗證各種狀態和過渡效果
5. **響應式測試**: 確保在不同設備上的表現
6. **可訪問性測試**: 驗證鍵盤導航和屏幕閱讀器支援
### 12.2 設計系統維護
#### 新增設計元素流程
1. **需求評估**: 確認是否需要新的設計模式
2. **一致性檢查**: 與現有系統的兼容性
3. **文檔更新**: 更新設計規範文檔
4. **團隊同步**: 與開發團隊同步新的設計規範
#### 設計令牌更新
1. **修改tailwind.config.ts**: 更新顏色、間距等令牌
2. **組件更新**: 更新受影響的組件實現
3. **測試驗證**: 確保變更不會破壞現有設計
4. **文檔同步**: 更新設計規範文檔
---
## 13. 最佳實踐
### 13.1 用戶體驗原則
#### 學習流程設計
- **循序漸進**: 從簡單到複雜的學習模式安排
- **即時回饋**: 每個操作都有明確的視覺回饋
- **進度可視**: 清晰的進度指示和成就感
- **錯誤友好**: 錯誤狀態提供建設性的指導
#### 認知負荷管理
- **視覺層次**: 使用大小、顏色、間距建立清晰的信息層次
- **內容聚焦**: 每個頁面專注於單一主要任務
- **減少選擇**: 避免過多的同時選項,使用漸進式披露
### 13.2 技術實現最佳實踐
#### CSS組織
```tsx
{/* 使用Tailwind的組合類別 */}
const buttonClass = `
px-6 py-3
bg-primary text-white
rounded-lg
hover:bg-primary-hover
transition-colors
font-medium
disabled:opacity-50
disabled:cursor-not-allowed
`;
{/* 條件式樣式 */}
const cardClass = `
border rounded-lg p-4 transition-all duration-200
${isSelected
? 'border-blue-500 bg-blue-50 shadow-sm'
: 'border-gray-200 bg-white hover:border-gray-300'
}
`;
```
#### 響應式設計模式
```tsx
{/* 移動優先的響應式設計 */}
<div className="
grid grid-cols-1 gap-4
md:grid-cols-2 md:gap-6
lg:grid-cols-3 lg:gap-8
">
{/* 內容 */}
</div>
{/* 條件式顯示 */}
<div className="hidden md:flex space-x-6">
{/* 桌面版內容 */}
</div>
<div className="md:hidden">
{/* 手機版內容 */}
</div>
```
---
## 14. 組件庫結構
### 14.1 基礎組件
```
/components
├── ui/
│ ├── Button.tsx # 基礎按鈕組件
│ ├── Card.tsx # 基礎卡片組件
│ ├── Modal.tsx # 模態對話框
│ ├── Input.tsx # 輸入組件
│ ├── Badge.tsx # 徽章標籤
│ └── Progress.tsx # 進度條
├── layout/
│ ├── Navigation.tsx # 導航組件
│ ├── PageHeader.tsx # 頁面標題
│ └── Container.tsx # 容器組件
└── learning/
├── FlipCard.tsx # 翻卡組件
├── QuizCard.tsx # 測驗卡片
├── AudioPlayer.tsx # 音頻播放器
└── VoiceRecorder.tsx # 語音錄製
```
### 14.2 設計系統文件結構
```
/design-system
├── tokens/
│ ├── colors.ts # 顏色令牌
│ ├── spacing.ts # 間距令牌
│ ├── typography.ts # 字體令牌
│ └── shadows.ts # 陰影令牌
├── components/
│ ├── Button.stories.tsx # 按鈕故事書
│ ├── Card.stories.tsx # 卡片故事書
│ └── ...
└── guidelines/
├── accessibility.md # 可訪問性指南
├── responsive.md # 響應式設計指南
└── animation.md # 動畫設計指南
```
---
## 15. 設計演進記錄
### 15.1 當前版本特色
- **清新漸層背景**: 營造舒適的學習氛圍
- **3D翻卡效果**: 增強學習的互動體驗
- **智能狀態回饋**: 即時的學習成果反饋
- **多模式學習**: 適應不同學習偏好的設計
### 15.2 設計改進方向
- **暗色主題支援**: 提供夜間學習模式
- **個人化界面**: 根據用戶偏好調整界面
- **更豐富的動畫**: 增加學習過程的趣味性
- **無障礙優化**: 進一步提升可訪問性
---
**文件版本**: 1.0
**建立日期**: 2025-09-20
**維護者**: DramaLing 設計團隊
**適用範圍**: DramaLing 詞彙學習系統全產品線