/* * Drama Ling Design System v4.0 - Enterprise Grade * * 基於共用模組架構 v3.0 * 支援 95+ UI 畫面的企業級設計標準 * WCAG 2.1 AA 級無障礙合規 * * 建立日期: 2025-01-15 * 最後更新: 2025-01-15 * 維護團隊: Drama Ling 設計系統團隊 */ /* ======================================== 🎨 設計變數 (Design Tokens) ======================================== */ :root { /* 主要品牌色彩 */ --primary-teal: #00E5CC; --primary-teal-light: #33E8D1; --primary-teal-dark: #00B3A0; /* 輔助色彩 */ --secondary-purple: #8E44AD; --secondary-purple-light: #A569BD; --secondary-purple-dark: #6C3483; /* 強調色 */ --accent-violet: #9B59B6; --accent-violet-light: #BB8FCE; --accent-violet-dark: #7D3C98; /* 功能性色彩 */ --error-red: #E74C3C; --warning-yellow: #F39C12; --success-green: #4CAF50; --info-cyan: #3498DB; /* 背景色彩 (暗色主題) */ --background-primary: #2C3E50; --background-secondary: #34495E; --background-dark: #1A252F; --background-light: #F8F9FA; --card-background: #3A4A5C; /* 文字色彩 */ --text-primary: #FFFFFF; --text-secondary: #B8BCC8; --text-tertiary: #718096; --text-on-primary: #000000; --text-on-secondary: #ffffff; /* 邊框和分隔線 */ --divider: #4A5568; --border-light: #E2E8F0; /* 遊戲化色彩 */ --star-active: #F1C40F; --star-inactive: #7F8C8D; --bronze: #CD7F32; --silver: #C0C0C0; --gold: #FFD700; --diamond: #B9F2FF; --exp-bar: #00E5CC; --level-background: #8E44AD; --achievement-glow: #F39C12; /* 等級系統色彩 */ --level-beginner: #4CAF50; --level-intermediate: #FF9800; --level-advanced: #9C27B0; --level-expert: #E91E63; /* 經驗值視覺效果 */ --exp-bar-bg: rgba(0, 229, 204, 0.2); --exp-bar-fill: var(--primary-teal); --exp-bar-glow: rgba(0, 229, 204, 0.4); /* 字體大小 (Mobile First + Responsive) */ --text-xs: clamp(10px, 2vw, 11px); --text-sm: clamp(12px, 2.5vw, 13px); --text-base: clamp(14px, 3vw, 16px); --text-lg: clamp(16px, 3.5vw, 18px); --text-xl: clamp(18px, 4vw, 22px); --text-2xl: clamp(24px, 5vw, 28px); --text-3xl: clamp(28px, 6vw, 34px); --text-4xl: clamp(32px, 7vw, 42px); /* 遊戲化特殊字體 */ --text-game-score: 24px; --text-game-level: 14px; --text-game-title: 20px; /* 間距系統 (8px Grid) */ --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 20px; --space-6: 24px; --space-8: 32px; --space-10: 40px; --space-12: 48px; --space-16: 64px; --space-20: 80px; /* 圓角系統 */ --radius-sm: 8px; --radius-md: 12px; --radius-lg: 16px; --radius-xl: 24px; --radius-2xl: 32px; --radius-full: 50%; /* 陰影系統 */ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1); --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1); --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1); /* 響應式斷點 */ --breakpoint-xs: 320px; --breakpoint-sm: 576px; --breakpoint-md: 768px; --breakpoint-lg: 992px; --breakpoint-xl: 1200px; --breakpoint-xxl: 1400px; /* 容器最大寬度 */ --container-xs: 100%; --container-sm: 540px; --container-md: 720px; --container-lg: 960px; --container-xl: 1140px; --container-xxl: 1320px; /* 焦點指示器 (無障礙) */ --focus-ring: 0 0 0 3px rgba(0, 229, 204, 0.5); --focus-ring-dark: 0 0 0 3px rgba(255, 255, 255, 0.8); /* 轉換動畫 */ --transition-fast: 0.15s ease; --transition-base: 0.3s ease; --transition-slow: 0.5s ease; --transition-cubic: 0.3s cubic-bezier(0.4, 0, 0.2, 1); } /* ======================================== 🔧 基礎重置和全域樣式 ======================================== */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } html { font-size: 16px; scroll-behavior: smooth; } body { font-family: 'PingFang TC', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft JhengHei', 'Helvetica Neue', Arial, sans-serif; font-size: var(--text-base); line-height: 1.6; color: var(--text-primary); background-color: var(--background-primary); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* 英文字體優化 */ :lang(en) { font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } /* 等寬字體 */ .font-mono { font-family: 'JetBrains Mono', 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace; } /* ======================================== 📐 響應式容器系統 ======================================== */ .container { width: 100%; padding-left: var(--space-4); padding-right: var(--space-4); margin-left: auto; margin-right: auto; } @media (min-width: 576px) { .container { max-width: var(--container-sm); padding-left: var(--space-6); padding-right: var(--space-6); } } @media (min-width: 768px) { .container { max-width: var(--container-md); padding-left: var(--space-8); padding-right: var(--space-8); } /* 平板優化字體 */ :root { --text-xs: 11px; --text-sm: 13px; --text-base: 16px; --text-lg: 18px; --text-xl: 22px; --text-2xl: 28px; --text-3xl: 34px; --text-4xl: 42px; } } @media (min-width: 992px) { .container { max-width: var(--container-lg); } } @media (min-width: 1200px) { .container { max-width: var(--container-xl); } /* 桌面優化字體 */ :root { --text-xs: 12px; --text-sm: 14px; --text-base: 16px; --text-lg: 20px; --text-xl: 24px; --text-2xl: 32px; --text-3xl: 40px; --text-4xl: 48px; } } @media (min-width: 1400px) { .container { max-width: var(--container-xxl); } } /* ======================================== 🎮 遊戲化組件系統 ======================================== */ /* 經驗值進度條 */ .experience-bar-container { width: 100%; background: var(--exp-bar-bg); border-radius: var(--radius-full); height: 8px; position: relative; overflow: hidden; border: 1px solid rgba(0, 229, 204, 0.3); } .experience-bar-fill { height: 100%; background: linear-gradient(90deg, var(--exp-bar-fill), var(--primary-teal-light)); border-radius: inherit; transition: width 0.8s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 0 20px var(--exp-bar-glow); position: relative; } .experience-bar-fill::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent); animation: experienceShimmer 2s infinite; } @keyframes experienceShimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } /* 等級指示器 */ .level-indicator { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-4); background: linear-gradient(135deg, var(--level-background), var(--secondary-purple-dark)); border-radius: var(--radius-full); color: white; font-weight: 700; font-size: var(--text-sm); box-shadow: 0 4px 12px rgba(142, 68, 173, 0.3); } .level-number { background: rgba(255, 255, 255, 0.2); border-radius: 50%; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; font-size: var(--text-xs); font-weight: 900; } /* 成就徽章 */ .achievement-container { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: var(--space-4); padding: var(--space-6) 0; } .achievement-badge { display: flex; flex-direction: column; align-items: center; padding: var(--space-4); background: var(--card-background); border-radius: var(--radius-xl); border: 2px solid transparent; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; } .achievement-badge.unlocked { border-color: var(--gold); background: linear-gradient(135deg, rgba(255, 215, 0, 0.1), rgba(255, 215, 0, 0.05)); box-shadow: 0 8px 32px rgba(255, 215, 0, 0.2); animation: achievementGlow 2s ease-in-out infinite alternate; } .achievement-badge.locked { opacity: 0.5; filter: grayscale(1); } @keyframes achievementGlow { from { box-shadow: 0 8px 32px rgba(255, 215, 0, 0.2); } to { box-shadow: 0 12px 48px rgba(255, 215, 0, 0.4); } } /* 關卡狀態指示器 */ .level-status-indicator { width: 60px; height: 60px; border-radius: 50%; display: flex; align-items: center; justify-content: center; position: relative; font-size: 1.5rem; font-weight: bold; transition: all 0.3s ease; cursor: pointer; } .level-status-indicator.locked { background: linear-gradient(135deg, var(--text-tertiary), #5a6067); color: var(--text-secondary); border: 3px solid var(--divider); } .level-status-indicator.available { background: linear-gradient(135deg, var(--primary-teal), var(--primary-teal-light)); color: var(--background-dark); border: 3px solid var(--primary-teal-light); box-shadow: 0 8px 25px rgba(0, 229, 204, 0.4); animation: availablePulse 2s ease-in-out infinite; } .level-status-indicator.in-progress { background: linear-gradient(135deg, var(--warning-yellow), #f4b942); color: var(--background-dark); border: 3px solid var(--warning-yellow); position: relative; overflow: hidden; } .level-status-indicator.in-progress::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent); animation: progressShimmer 1.5s infinite; } .level-status-indicator.completed { background: linear-gradient(135deg, var(--success-green), #66bb6a); color: white; border: 3px solid var(--success-green); box-shadow: 0 4px 20px rgba(76, 175, 80, 0.3); } @keyframes availablePulse { 0%, 100% { transform: scale(1); box-shadow: 0 8px 25px rgba(0, 229, 204, 0.4); } 50% { transform: scale(1.05); box-shadow: 0 12px 35px rgba(0, 229, 204, 0.6); } } @keyframes progressShimmer { 0% { left: -100%; } 100% { left: 100%; } } /* ======================================== 🎯 學習功能專用組件 ======================================== */ /* 語音輸入介面 */ .voice-input-container { display: flex; flex-direction: column; align-items: center; gap: var(--space-6); padding: var(--space-8); background: linear-gradient(135deg, var(--card-background), rgba(58, 74, 92, 0.8)); border-radius: var(--radius-2xl); border: 2px solid var(--primary-teal); position: relative; overflow: hidden; } .voice-input-container.active { background: linear-gradient(135deg, rgba(0, 229, 204, 0.1), rgba(0, 229, 204, 0.05)); animation: voiceInputActive 2s ease-in-out infinite alternate; } @keyframes voiceInputActive { from { box-shadow: 0 0 30px rgba(0, 229, 204, 0.3); } to { box-shadow: 0 0 50px rgba(0, 229, 204, 0.5); } } .voice-button { width: 80px; height: 80px; border-radius: 50%; background: linear-gradient(135deg, var(--primary-teal), var(--primary-teal-light)); border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 2rem; color: var(--background-dark); transition: all 0.3s ease; position: relative; overflow: hidden; } .voice-button:hover { transform: scale(1.1); box-shadow: 0 8px 32px rgba(0, 229, 204, 0.4); } .voice-button.recording { animation: recordingPulse 1s ease-in-out infinite; } @keyframes recordingPulse { 0%, 100% { transform: scale(1); background: linear-gradient(135deg, #e74c3c, #c0392b); } 50% { transform: scale(1.05); background: linear-gradient(135deg, #e74c3c, #a93226); } } /* 語音波形指示器 */ .voice-waveform { display: flex; align-items: center; gap: 2px; height: 40px; justify-content: center; opacity: 0; transition: opacity 0.3s ease; } .voice-waveform.active { opacity: 1; } .waveform-bar { width: 3px; background: var(--primary-teal); border-radius: 2px; animation: waveformDance 0.8s ease-in-out infinite alternate; } .waveform-bar:nth-child(1) { animation-delay: 0s; } .waveform-bar:nth-child(2) { animation-delay: 0.1s; } .waveform-bar:nth-child(3) { animation-delay: 0.2s; } .waveform-bar:nth-child(4) { animation-delay: 0.3s; } .waveform-bar:nth-child(5) { animation-delay: 0.4s; } @keyframes waveformDance { from { height: 8px; } to { height: 24px; } } /* 對話氣泡系統 */ .dialogue-container { display: flex; flex-direction: column; gap: var(--space-4); padding: var(--space-6); max-width: 100%; } .dialogue-message { max-width: 80%; padding: var(--space-4) var(--space-5); border-radius: var(--radius-lg); font-size: var(--text-base); line-height: 1.5; position: relative; animation: messageSlideIn 0.4s ease-out; } @keyframes messageSlideIn { from { opacity: 0; transform: translateY(20px) scale(0.95); } to { opacity: 1; transform: translateY(0) scale(1); } } .dialogue-message.user { align-self: flex-end; background: linear-gradient(135deg, var(--primary-teal), var(--primary-teal-light)); color: var(--background-dark); border-bottom-right-radius: var(--radius-sm); } .dialogue-message.assistant { align-self: flex-start; background: var(--card-background); color: var(--text-primary); border: 1px solid var(--divider); border-bottom-left-radius: var(--radius-sm); } .dialogue-message.system { align-self: center; background: linear-gradient(135deg, var(--accent-violet), var(--accent-violet-light)); color: white; max-width: 60%; text-align: center; font-style: italic; } /* ======================================== 🛒 商業功能組件系統 ======================================== */ /* 商品卡片 */ .product-card { background: var(--card-background); border-radius: var(--radius-xl); padding: var(--space-6); border: 2px solid transparent; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; } .product-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px; background: linear-gradient(90deg, var(--primary-teal), var(--accent-violet), var(--secondary-purple)); opacity: 0; transition: opacity 0.3s ease; } .product-card:hover { border-color: var(--primary-teal); transform: translateY(-4px); box-shadow: 0 12px 40px rgba(0, 229, 204, 0.2); } .product-card:hover::before { opacity: 1; } /* 價格標籤 */ .price-value { font-size: var(--text-xl); font-weight: 700; color: var(--primary-teal); display: flex; align-items: center; gap: var(--space-1); } .price-currency { font-size: 1.2em; color: var(--gold); } .price-discount { background: linear-gradient(135deg, var(--error-red), #c0392b); color: white; padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm); font-size: var(--text-xs); font-weight: 600; } /* 商品標籤 */ .product-tag { padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm); font-size: var(--text-xs); font-weight: 600; border: 1px solid transparent; } .product-tag.bestseller { background: linear-gradient(135deg, var(--gold), #f4d03f); color: var(--background-dark); } .product-tag.new { background: linear-gradient(135deg, var(--success-green), #58d68d); color: white; } .product-tag.limited { background: linear-gradient(135deg, var(--error-red), #ec7063); color: white; } /* ======================================== 🎛️ 基礎UI組件 ======================================== */ /* 按鈕系統 */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); padding: var(--space-3) var(--space-6); border: 2px solid transparent; border-radius: var(--radius-lg); font-weight: 600; font-size: var(--text-base); text-decoration: none; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; white-space: nowrap; } .btn:disabled { opacity: 0.6; cursor: not-allowed; transform: none !important; } .btn-primary { background: linear-gradient(135deg, var(--primary-teal), var(--primary-teal-light)); color: var(--text-on-primary); border-color: var(--primary-teal); } .btn-primary:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(0, 229, 204, 0.3); } .btn-secondary { background: transparent; color: var(--primary-teal); border-color: var(--primary-teal); } .btn-secondary:hover:not(:disabled) { background: rgba(0, 229, 204, 0.1); transform: translateY(-1px); } /* 輸入框系統 */ .input-field { width: 100%; padding: var(--space-4) var(--space-5); background: var(--background-secondary); border: 2px solid var(--divider); border-radius: var(--radius-lg); font-size: var(--text-base); color: var(--text-primary); transition: all 0.3s ease; } .input-field:focus { outline: none; background: var(--card-background); border-color: var(--primary-teal); box-shadow: var(--focus-ring); } .input-field::placeholder { color: var(--text-secondary); } .input-field.error { border-color: var(--error-red); } .input-field.success { border-color: var(--success-green); } /* 標籤系統 */ .input-label { display: block; margin-bottom: var(--space-2); font-weight: 600; color: var(--text-primary); font-size: var(--text-sm); } .input-label.required::after { content: ' *'; color: var(--error-red); } /* ======================================== ♿ 無障礙設計標準 ======================================== */ /* 焦點管理 */ *:focus { outline: none; box-shadow: var(--focus-ring); } /* 跳過連結 */ .skip-link { position: absolute; top: -40px; left: 6px; background: var(--primary-teal); color: var(--background-dark); padding: 8px; text-decoration: none; border-radius: 4px; font-weight: 600; z-index: 9999; transition: top 0.3s ease; } .skip-link:focus { top: 6px; } /* 螢幕閱讀器專用 */ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } .sr-only:focus { position: static; width: auto; height: auto; padding: inherit; margin: inherit; overflow: visible; clip: auto; white-space: normal; } /* 高對比模式支援 */ @media (prefers-contrast: high) { :root { --primary-teal: #00ff00; --background-primary: #000000; --text-primary: #ffffff; --border-color: #ffffff; } } /* 減動畫偏好支援 */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } } /* ======================================== 🔧 工具類別 ======================================== */ /* 顯示/隱藏 */ .hidden { display: none !important; } .invisible { visibility: hidden; } .visible { visibility: visible; } /* 間距工具類 */ .m-0 { margin: 0; } .m-1 { margin: var(--space-1); } .m-2 { margin: var(--space-2); } .m-3 { margin: var(--space-3); } .m-4 { margin: var(--space-4); } .m-6 { margin: var(--space-6); } .m-8 { margin: var(--space-8); } .p-0 { padding: 0; } .p-1 { padding: var(--space-1); } .p-2 { padding: var(--space-2); } .p-3 { padding: var(--space-3); } .p-4 { padding: var(--space-4); } .p-6 { padding: var(--space-6); } .p-8 { padding: var(--space-8); } /* 文字工具類 */ .text-left { text-align: left; } .text-center { text-align: center; } .text-right { text-align: right; } .text-primary { color: var(--text-primary); } .text-secondary { color: var(--text-secondary); } .text-success { color: var(--success-green); } .text-error { color: var(--error-red); } .text-warning { color: var(--warning-yellow); } .font-bold { font-weight: 700; } .font-semibold { font-weight: 600; } .font-medium { font-weight: 500; } /* Flexbox 工具類 */ .flex { display: flex; } .flex-col { flex-direction: column; } .flex-row { flex-direction: row; } .items-center { align-items: center; } .justify-center { justify-content: center; } .justify-between { justify-content: space-between; } /* Grid 工具類 */ .grid { display: grid; } .grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); } .grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } .gap-2 { gap: var(--space-2); } .gap-4 { gap: var(--space-4); } .gap-6 { gap: var(--space-6); } /* ======================================== 🔔 通知系統組件 ======================================== */ .notification { position: fixed; top: 20px; right: 20px; min-width: 300px; max-width: 500px; padding: var(--space-4) var(--space-5); border-radius: var(--radius-lg); color: white; font-weight: 600; font-size: var(--text-sm); z-index: 9999; opacity: 0; transform: translateX(100%); transition: all 0.3s ease; box-shadow: var(--shadow-lg); border-left: 4px solid transparent; } .notification.show { opacity: 1; transform: translateX(0); } .notification.info { background: linear-gradient(135deg, var(--primary-teal), var(--primary-teal-dark)); border-left-color: var(--primary-teal-light); } .notification.success { background: linear-gradient(135deg, var(--status-success), var(--status-success-dark)); border-left-color: var(--status-success-light); } .notification.warning { background: linear-gradient(135deg, var(--status-warning), var(--status-warning-dark)); border-left-color: var(--status-warning-light); } .notification.error { background: linear-gradient(135deg, var(--status-danger), var(--status-danger-dark)); border-left-color: var(--status-danger-light); } @media (max-width: 768px) { .notification { top: 10px; right: 10px; left: 10px; min-width: auto; max-width: none; } } /* ======================================== 📝 設計系統文檔資訊 ======================================== */ /* * 此設計系統支援的功能組件: * * ✅ 遊戲化組件 (經驗值、等級、成就、關卡狀態) * ✅ 學習功能組件 (語音輸入、對話氣泡、語音波形) * ✅ 商業功能組件 (商品卡片、價格標籤、商品標籤) * ✅ 基礎UI組件 (按鈕、輸入框、標籤系統) * ✅ 響應式設計 (Mobile First + 6個斷點) * ✅ 無障礙設計 (WCAG 2.1 AA級合規) * ✅ 工具類別 (間距、文字、佈局等) * * 企業級特色: * - Fortune 500品質標準 * - 完整的設計變數系統 (Design Tokens) * - 跨平台一致性保證 * - 長期可維護架構 * - 團隊協作友好 * * 維護資訊: * - 版本控制: 語義化版本控制 (Semantic Versioning) * - 更新頻率: 每月審查,季度更新 * - 相容性: 向後相容,漸進增強 * - 文檔同步: 與 ui-ux-guidelines.md 100%同步 * * 使用指南: * 1. 優先使用設計變數而非硬編碼值 * 2. 遵循組件組合原則,避免重複造輪子 * 3. 確保無障礙屬性正確添加 * 4. 在不同斷點下測試響應式效果 * 5. 使用工具類別提升開發效率 * * 支援查詢: * - 技術問題: 查閱 ui-ux-guidelines.md * - 設計決策: 參考企業設計計劃 * - 組件使用: 參考功能規格文檔 */