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

37 KiB
Raw Blame History

DramaLing UI/UX 設計規範

設計理念

DramaLing詞彙學習系統採用清新、直觀、專注學習的設計理念,致力於創造無障礙且引人入勝的學習體驗。設計強調簡潔性、一致性和互動性,讓用戶能夠專注於學習內容本身。


1. 視覺設計系統

1.1 顏色系統

主要顏色調色板

/* 主色調 - 藍色系統 */
--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 字體系統

字體家族

font-family: 'Inter', 'Noto Sans TC', 'system-ui', 'sans-serif';

字體尺寸階層

/* 標題層級 */
.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; }      /* 標籤、說明文字 */

字重規範

.font-bold { font-weight: 700; }      /* 標題、重點強調 */
.font-semibold { font-weight: 600; }  /* 副標題、按鈕文字 */
.font-medium { font-weight: 500; }    /* 導航、標籤 */
.font-normal { font-weight: 400; }    /* 正文內容 */

1.3 間距系統

間距單位

/* 基礎間距單位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 圓角系統

.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)

<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)

<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)

<button className="
  px-4 py-2
  bg-red-600 text-white
  rounded-lg
  hover:bg-red-700
  transition-colors
  font-medium
">
  刪除/危險動作
</button>

模式切換按鈕 (Mode Toggle)

<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 卡片設計系統

主要內容卡片

<div className="
  bg-white
  rounded-xl
  shadow-lg
  p-8
  hover:shadow-xl
  transition-shadow
">
  {/* 卡片內容 */}
</div>

資訊展示卡片

<div className="
  bg-gray-50
  rounded-lg
  p-4
  border border-gray-200
">
  {/* 資訊內容 */}
</div>

狀態回饋卡片

{/* 成功狀態 */}
<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 輸入組件設計

文字輸入框

<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
" />

下拉選單

<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>

複選框/單選框

<input type="checkbox" className="
  w-4 h-4
  text-blue-600
  bg-gray-100
  border-gray-300
  rounded
  focus:ring-blue-500
" />

2.4 標籤和徽章系統

難度等級標籤

{/* 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>

詞性標籤

<span className="
  text-sm
  bg-gray-100 text-gray-600
  px-2 py-1
  rounded
">
  noun
</span>

同義詞標籤

<span className="
  text-xs
  bg-blue-100 text-blue-700
  px-2 py-1
  rounded-full
">
  synonym
</span>

3. 交互設計模式

3.1 學習模式設計

模式切換器設計原則

  • 視覺清晰: 當前選中模式使用主色調高亮
  • 狀態一致: 所有模式按鈕使用相同的設計語言
  • 響應迅速: 切換模式時即時更新UI狀態
  • 分組合理: 相關功能模式在視覺上聚集
{/* 學習模式切換器 */}
<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 進度指示設計

學習進度條

<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 狀態回饋設計

答案回饋模式

{/* 正確回饋 */}
<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>

載入狀態設計

{/* 按鈕載入狀態 */}
<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 互動式元素設計

點擊式詞彙分析

{/* 高價值詞彙 - 綠色邊框 + 星星 */}
<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>

詞彙詳情彈窗

<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 學習卡片設計

翻卡記憶卡片

{/* 卡片容器 */}
<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

.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 測驗模式設計

選擇題設計

<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>

填空題設計

{/* 句子中的填空輸入 */}
<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 例句重組設計

重組區域設計

{/* 答案區域 */}
<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 頁面布局模式

學習頁面布局

<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>

內容頁面布局

<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 響應式設計

斷點系統

/* 小屏幕 (手機) */
sm: '640px'

/* 中等屏幕 (平板) */
md: '768px'

/* 大屏幕 (桌面) */
lg: '1024px'

/* 超大屏幕 */
xl: '1280px'

響應式組件範例

{/* 網格布局響應式 */}
<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 微互動設計

懸停效果

{/* 卡片懸停 */}
<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>

動畫效果

{/* 載入動畫 */}
<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 狀態管理原則

視覺狀態指示

{/* 禁用狀態 */}
<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 回饋設計模式

即時回饋

{/* 成功提示 */}
<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 模態對話框設計

標準模態框

{/* 遮罩層 */}
<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>

圖片預覽模態框

<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 導航設計

學習導航按鈕

<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 錯誤報告組件

{/* 錯誤報告按鈕 */}
<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 間距令牌

/* 基礎間距單位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 陰影令牌

/* 陰影系統 */
--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 過渡動畫令牌

/* 過渡時間 */
--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

按鈕尺寸規範

{/* 大型按鈕 - 主要動作 */}
<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 表單組件使用

輸入框設計

<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
" />

選擇器設計

<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

{/* 使用適當的語義標籤 */}
<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 鍵盤導航

{/* 支援鍵盤操作 */}
<input
  onKeyDown={(e) => {
    if (e.key === 'Enter') {
      handleSubmit();
    }
    if (e.key === 'Escape') {
      handleCancel();
    }
  }}
/>

9.3 焦點管理

{/* 明確的焦點樣式 */}
<button className="
  focus:ring-2 focus:ring-primary focus:ring-offset-2
  focus:outline-none
">
  按鈕
</button>

10. 動畫設計規範

10.1 頁面過渡

/* 頁面淡入 */
@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 互動動畫

/* 懸停上升效果 */
.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 卡片翻轉動畫

.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組織

{/* 使用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'
  }
`;

響應式設計模式

{/* 移動優先的響應式設計 */}
<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 詞彙學習系統全產品線