/* * Drama Ling UI/UX Design System * Complete CSS Library based on Official Guidelines * Version: 1.0 */ /* ===== CSS VARIABLES ===== */ :root { /* Primary Colors - 主要色彩 */ --primary-teal: #00E5CC; --primary-teal-light: #33E8D1; --primary-teal-dark: #00B3A0; /* Secondary Colors - 輔助色 */ --secondary-purple: #8E44AD; --secondary-purple-light: #A569BD; --secondary-purple-dark: #6C3483; /* Accent Colors - 強調色 */ --accent-violet: #9B59B6; --accent-violet-light: #BB8FCE; --accent-violet-dark: #7D3C98; /* Functional Colors - 功能性色彩 */ --error-red: #E74C3C; --warning-yellow: #F39C12; --info-cyan: #3498DB; --success-green: #27AE60; /* Dark Theme Colors - 暗色主題 */ --text-primary: #FFFFFF; --text-secondary: #B8BCC8; --text-tertiary: #95A5A6; --background-primary: #2C3E50; --background-secondary: #34495E; --background-dark: #1A252F; --divider: #4A5568; --card-background: #3A4A5C; /* Gamification Colors - 遊戲化色彩 */ --star-active: #F1C40F; --star-inactive: #7F8C8D; --bronze: #CD7F32; --silver: #C0C0C0; --gold: #FFD700; --diamond: #B9F2FF; --exp-bar: #00E5CC; --level-background: #8E44AD; --achievement-glow: #F39C12; --rank-other: #718096; /* Typography - 字體大小 */ --text-xs: 11px; --text-sm: 13px; --text-base: 16px; --text-lg: 18px; --text-xl: 22px; --text-2xl: 28px; --text-3xl: 34px; --text-4xl: 42px; --text-game-score: 24px; --text-game-level: 14px; --text-game-title: 20px; /* Spacing System - 間距系統 */ --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; /* Border Radius - 圓角系統 */ --radius-sm: 8px; --radius-md: 12px; --radius-lg: 16px; --radius-xl: 24px; --radius-2xl: 32px; --radius-full: 50%; /* Shadow System - 陰影系統 */ --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); /* Animation Timing - 動畫時間 */ --duration-fast: 0.15s; --duration-normal: 0.3s; --duration-slow: 0.5s; --easing-standard: cubic-bezier(0.4, 0, 0.2, 1); } /* ===== RESET & BASE STYLES ===== */ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: linear-gradient(135deg, var(--background-primary) 0%, var(--background-secondary) 100%); color: var(--text-primary); line-height: 1.6; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* ===== BUTTON COMPONENTS ===== */ /* Primary Button */ .btn-primary { background: var(--primary-teal); color: var(--background-dark); padding: 16px 24px; border-radius: 12px; font-weight: 800; font-size: var(--text-base); border: none; border-bottom: 4px solid var(--primary-teal-dark); cursor: pointer; transition: all 0.1s ease; display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); text-decoration: none; font-family: inherit; min-height: 48px; position: relative; top: 0; } .btn-primary:hover { background: var(--primary-teal-light); } .btn-primary:active { top: 3px; border-bottom-width: 1px; } .btn-primary:disabled { background: var(--text-tertiary); border-bottom-color: #7F8C8D; cursor: not-allowed; top: 0; opacity: 0.6; } /* Secondary Button */ .btn-secondary { background: var(--background-secondary); color: var(--text-primary); border: 2px solid var(--text-secondary); border-bottom: 4px solid var(--text-tertiary); padding: 16px 24px; border-radius: 12px; font-weight: 700; font-size: var(--text-base); cursor: pointer; transition: all 0.1s ease; display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); text-decoration: none; font-family: inherit; min-height: 48px; position: relative; top: 0; } .btn-secondary:hover { background: var(--card-background); border-color: var(--text-primary); } .btn-secondary:active { top: 3px; border-bottom-width: 1px; } /* Danger Button */ .btn-danger { background: var(--error-red); color: var(--text-primary); padding: 16px 24px; border-radius: 12px; font-weight: 800; font-size: var(--text-base); border: none; border-bottom: 4px solid #C0392B; cursor: pointer; transition: all 0.1s ease; display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); text-decoration: none; font-family: inherit; min-height: 48px; position: relative; top: 0; } .btn-danger:hover { background: #DC7633; } .btn-danger:active { top: 3px; border-bottom-width: 1px; } /* Outline Button */ .btn-outline { background: transparent; color: var(--text-primary); border: 3px solid var(--text-secondary); border-bottom: 4px solid var(--text-tertiary); padding: 16px 24px; border-radius: 12px; font-weight: 700; font-size: var(--text-base); cursor: pointer; transition: all 0.1s ease; display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); text-decoration: none; font-family: inherit; min-height: 48px; position: relative; top: 0; } .btn-outline:hover { background: rgba(255, 255, 255, 0.1); border-color: var(--text-primary); } .btn-outline:active { top: 2px; border-bottom-width: 2px; } /* Reply Help Button */ .btn-reply-help { background: var(--info-cyan); color: var(--text-primary); padding: 14px 20px; border-radius: 12px; font-weight: 700; font-size: var(--text-sm); border: none; border-bottom: 3px solid #2980B9; cursor: pointer; transition: all 0.1s ease; display: inline-flex; align-items: center; gap: var(--space-2); font-family: inherit; position: relative; top: 0; } .btn-reply-help::before { content: '?'; font-size: 1em; font-weight: 800; background: rgba(255, 255, 255, 0.2); border-radius: 50%; width: 18px; height: 18px; display: flex; align-items: center; justify-content: center; } .btn-reply-help:hover { background: #5DADE2; } .btn-reply-help:active { top: 2px; border-bottom-width: 1px; } .btn-reply-help:disabled { background: var(--text-tertiary); border-bottom-color: #7F8C8D; cursor: not-allowed; top: 0; opacity: 0.6; } /* Button Sizes */ .btn-lg { padding: 20px 32px; font-size: var(--text-lg); min-height: 56px; border-bottom-width: 5px; } .btn-sm { padding: 12px 18px; font-size: var(--text-sm); min-height: 36px; border-bottom-width: 3px; } .btn-xs { padding: 8px 12px; font-size: var(--text-xs); min-height: 28px; border-bottom-width: 2px; } .btn-lg:active { top: 4px; border-bottom-width: 1px; } .btn-sm:active { top: 2px; border-bottom-width: 1px; } .btn-xs:active { top: 1px; border-bottom-width: 1px; } /* Icon Button */ .btn-icon { width: 48px; height: 48px; padding: 0; border-radius: 12px; border-bottom: 4px solid rgba(0, 0, 0, 0.3); display: inline-flex; align-items: center; justify-content: center; font-size: var(--text-xl); position: relative; top: 0; transition: all 0.1s ease; } .btn-icon-sm { width: 36px; height: 36px; font-size: var(--text-lg); border-bottom-width: 3px; } .btn-icon:active { top: 3px; border-bottom-width: 1px; } .btn-icon-sm:active { top: 2px; border-bottom-width: 1px; } /* Icon Button Variants */ .btn-icon.btn-secondary { background: var(--background-secondary); color: var(--text-primary); border: 2px solid var(--text-secondary); border-bottom: 4px solid var(--text-tertiary); width: 48px; height: 48px; padding: 0; gap: 0; min-height: auto; } .btn-icon.btn-secondary:hover { background: var(--card-background); border-color: var(--text-primary); } .btn-icon.btn-primary { background: var(--primary-teal); color: var(--background-dark); border: none; border-bottom: 4px solid var(--primary-teal-dark); width: 48px; height: 48px; padding: 0; gap: 0; min-height: auto; } .btn-icon.btn-primary:hover { background: var(--primary-teal-light); } .btn-icon.btn-danger { background: var(--error-red); color: var(--text-primary); border: none; border-bottom: 4px solid #C0392B; width: 48px; height: 48px; padding: 0; gap: 0; min-height: auto; } .btn-icon.btn-danger:hover { background: #DC7633; } /* ===== CARD COMPONENTS ===== */ /* Base Card */ .card { background: var(--card-background); border-radius: var(--radius-xl); padding: var(--space-6); box-shadow: var(--shadow-lg); border: 1px solid rgba(255, 255, 255, 0.1); transition: all var(--duration-normal) var(--easing-standard); } .card:hover { border-color: rgba(255, 255, 255, 0.3); background: var(--card-background); } /* Game Card */ .card-game { background: var(--card-background); border-radius: var(--radius-xl); padding: var(--space-6); box-shadow: var(--shadow-lg); border: 2px solid var(--secondary-purple); transition: all var(--duration-normal) var(--easing-standard); } .card-game:hover { border-color: var(--secondary-purple-light); background: var(--card-background); } /* Achievement Card */ .card-achievement { background: var(--card-background); border-radius: var(--radius-xl); padding: var(--space-6); box-shadow: var(--shadow-lg); border: 2px solid var(--gold); transition: all var(--duration-normal) var(--easing-standard); color: var(--text-primary); } .card-achievement:hover { border-color: #FFE55C; background: var(--card-background); } /* Progress Card */ .card-progress { background: var(--card-background); border-radius: var(--radius-xl); padding: var(--space-6); box-shadow: var(--shadow-lg); border: 2px solid var(--primary-teal); transition: all var(--duration-normal) var(--easing-standard); } .card-progress:hover { border-color: var(--primary-teal-light); background: var(--card-background); } /* Card Header */ .card-header { margin-bottom: var(--space-4); padding-bottom: var(--space-3); border-bottom: 1px solid rgba(255, 255, 255, 0.1); } .card-title { font-size: var(--text-xl); font-weight: 700; color: var(--text-primary); margin-bottom: var(--space-1); } .card-subtitle { font-size: var(--text-sm); color: var(--text-secondary); } /* Card Actions */ .card-actions { margin-top: var(--space-5); display: flex; gap: var(--space-3); justify-content: flex-end; } /* ===== INPUT COMPONENTS ===== */ /* Text Input */ .input-field { width: 100%; padding: 16px 20px; 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 var(--duration-normal) var(--easing-standard); font-family: inherit; } .input-field:focus { outline: none; background: var(--card-background); border-color: var(--primary-teal); box-shadow: 0 0 0 4px rgba(0, 229, 204, 0.15); } .input-field::placeholder { color: var(--text-secondary); } /* Input States */ .input-error { border-color: var(--error-red); box-shadow: 0 0 0 4px rgba(231, 76, 60, 0.15); } .input-success { border-color: var(--success-green); box-shadow: 0 0 0 4px rgba(39, 174, 96, 0.15); } /* Input Group */ .input-group { margin-bottom: var(--space-4); } .input-label { display: block; margin-bottom: var(--space-2); font-size: var(--text-base); font-weight: 600; color: var(--text-primary); } .input-help { margin-top: var(--space-2); font-size: var(--text-sm); color: var(--text-secondary); } /* ===== BADGE COMPONENTS ===== */ /* Base Badge */ .badge { display: inline-flex; align-items: center; padding: 6px 12px; border-radius: 12px; font-size: var(--text-sm); font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; border: 1px solid transparent; } .badge-primary { background: var(--primary-teal); color: var(--background-dark); border-color: var(--primary-teal-dark); } .badge-secondary { background: var(--secondary-purple); color: var(--text-primary); border-color: var(--secondary-purple-dark); } .badge-success { background: var(--success-green); color: var(--text-primary); border-color: #1E8449; } .badge-warning { background: var(--warning-yellow); color: var(--background-dark); border-color: #D68910; } .badge-danger { background: var(--error-red); color: var(--text-primary); border-color: #C0392B; } /* Level Badge */ .badge-level { background: var(--secondary-purple); color: var(--text-primary); padding: 8px 16px; font-size: var(--text-base); font-weight: 800; border-radius: 12px; border: 2px solid var(--secondary-purple-dark); } /* ===== PROGRESS COMPONENTS ===== */ /* Progress Bar */ .progress { width: 100%; height: 12px; background: var(--background-secondary); border-radius: 50px; overflow: hidden; border: 1px solid var(--text-tertiary); } .progress-bar { height: 100%; background: var(--primary-teal); border-radius: 50px; transition: width var(--duration-slow) var(--easing-standard); position: relative; } /* XP Progress */ .progress-xp { background: var(--primary-teal); } /* Level Progress */ .progress-level { background: var(--secondary-purple); } /* ===== AVATAR COMPONENTS ===== */ /* Base Avatar */ .avatar { display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; font-weight: 700; overflow: hidden; position: relative; background: var(--background-secondary); border: 2px solid var(--text-secondary); color: var(--text-primary); flex-shrink: 0; } .avatar-sm { display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; font-weight: 700; overflow: hidden; position: relative; background: var(--background-secondary); border: 2px solid var(--text-secondary); color: var(--text-primary); flex-shrink: 0; width: 32px; height: 32px; font-size: var(--text-sm); } .avatar-md { display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; font-weight: 700; overflow: hidden; position: relative; background: var(--background-secondary); border: 2px solid var(--text-secondary); color: var(--text-primary); flex-shrink: 0; width: 48px; height: 48px; font-size: var(--text-lg); } .avatar-lg { display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; font-weight: 700; overflow: hidden; position: relative; background: var(--background-secondary); border: 2px solid var(--text-secondary); color: var(--text-primary); flex-shrink: 0; width: 64px; height: 64px; font-size: var(--text-xl); } .avatar-xl { display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; font-weight: 700; overflow: hidden; position: relative; background: var(--background-secondary); border: 2px solid var(--text-secondary); color: var(--text-primary); flex-shrink: 0; width: 96px; height: 96px; font-size: var(--text-3xl); } /* Avatar Variants */ .avatar-user { background: var(--primary-teal); color: var(--background-dark); border-color: var(--primary-teal); } .avatar-ai { background: var(--secondary-purple); color: var(--text-primary); border-color: var(--secondary-purple); } .avatar-achievement { background: var(--gold); color: var(--background-dark); border-color: #DAA520; } /* ===== STAR RATING ===== */ .star-rating { display: inline-flex; gap: 2px; } .star { font-size: var(--text-lg); color: var(--star-inactive); cursor: pointer; transition: all var(--duration-fast) var(--easing-standard); } .star.active { color: var(--star-active); } .star:hover { transform: scale(1.2); } /* ===== NOTIFICATION/TOAST ===== */ .toast { position: fixed; top: 20px; right: 20px; padding: var(--space-4) var(--space-5); border-radius: var(--radius-lg); color: var(--text-primary); font-weight: 600; box-shadow: var(--shadow-xl); transform: translateX(400px); transition: transform var(--duration-normal) var(--easing-standard); z-index: 1000; max-width: 400px; } .toast.show { transform: translateX(0); } .toast-success { background: linear-gradient(135deg, var(--success-green), #27AE60); } .toast-error { background: linear-gradient(135deg, var(--error-red), #C0392B); } .toast-warning { background: linear-gradient(135deg, var(--warning-yellow), #E67E22); } .toast-info { background: linear-gradient(135deg, var(--info-cyan), #2980B9); } /* ===== MODAL ===== */ .modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.8); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; z-index: 1000; opacity: 0; visibility: hidden; transition: all var(--duration-normal) var(--easing-standard); } .modal-overlay.show { opacity: 1; visibility: visible; } .modal { background: var(--card-background); border-radius: var(--radius-2xl); padding: var(--space-8); max-width: 500px; width: 90%; max-height: 90vh; overflow-y: auto; transform: scale(0.9); transition: transform var(--duration-normal) var(--easing-standard); box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); border: 1px solid rgba(255, 255, 255, 0.1); } .modal-overlay.show .modal { transform: scale(1); } .modal-header { margin-bottom: var(--space-6); text-align: center; } .modal-title { font-size: var(--text-2xl); font-weight: 700; color: var(--text-primary); margin-bottom: var(--space-2); } .modal-subtitle { font-size: var(--text-base); color: var(--text-secondary); } /* ===== UTILITY CLASSES ===== */ /* Text Utilities */ .text-center { text-align: center; } .text-left { text-align: left; } .text-right { text-align: right; } .text-xs { font-size: var(--text-xs); } .text-sm { font-size: var(--text-sm); } .text-base { font-size: var(--text-base); } .text-lg { font-size: var(--text-lg); } .text-xl { font-size: var(--text-xl); } .text-2xl { font-size: var(--text-2xl); } .text-3xl { font-size: var(--text-3xl); } .text-4xl { font-size: var(--text-4xl); } .font-normal { font-weight: 400; } .font-medium { font-weight: 500; } .font-semibold { font-weight: 600; } .font-bold { font-weight: 700; } .font-extrabold { font-weight: 800; } /* Color Utilities */ .text-primary { color: var(--text-primary); } .text-secondary { color: var(--text-secondary); } .text-tertiary { color: var(--text-tertiary); } .text-teal { color: var(--primary-teal); } .text-purple { color: var(--secondary-purple); } .text-success { color: var(--success-green); } .text-warning { color: var(--warning-yellow); } .text-error { color: var(--error-red); } /* Spacing Utilities */ .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-5 { margin: var(--space-5); } .m-6 { margin: var(--space-6); } .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-5 { padding: var(--space-5); } .p-6 { padding: var(--space-6); } .mb-2 { margin-bottom: var(--space-2); } .mb-4 { margin-bottom: var(--space-4); } .mb-6 { margin-bottom: var(--space-6); } .mt-2 { margin-top: var(--space-2); } .mt-4 { margin-top: var(--space-4); } .mt-6 { margin-top: var(--space-6); } /* Layout Utilities */ .flex { display: flex; } .flex-col { flex-direction: column; } .items-center { align-items: center; } .justify-center { justify-content: center; } .justify-between { justify-content: space-between; } .gap-2 { gap: var(--space-2); } .gap-4 { gap: var(--space-4); } .gap-6 { gap: var(--space-6); } .hidden { display: none; } .block { display: block; } .inline-block { display: inline-block; } /* Border Radius Utilities */ .rounded-sm { border-radius: var(--radius-sm); } .rounded-md { border-radius: var(--radius-md); } .rounded-lg { border-radius: var(--radius-lg); } .rounded-xl { border-radius: var(--radius-xl); } .rounded-2xl { border-radius: var(--radius-2xl); } .rounded-full { border-radius: var(--radius-full); } /* Animation Utilities */ .animate-pulse { animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } .animate-bounce { animation: bounce 1s infinite; } @keyframes bounce { 0%, 100% { transform: translateY(-25%); animation-timing-function: cubic-bezier(0.8, 0, 1, 1); } 50% { transform: none; animation-timing-function: cubic-bezier(0, 0, 0.2, 1); } } /* Hover Effects */ .hover-lift { transition: transform var(--duration-normal) var(--easing-standard); } .hover-lift:hover { opacity: 0.9; } /* Glass Morphism Effect */ .glass { background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.2); } /* Glow Effects */ .glow-teal { box-shadow: 0 0 20px rgba(0, 229, 204, 0.4); } .glow-purple { box-shadow: 0 0 20px rgba(142, 68, 173, 0.4); } .glow-gold { box-shadow: 0 0 20px rgba(255, 215, 0, 0.4); } /* ===== RESPONSIVE DESIGN ===== */ @media (max-width: 768px) { .btn-primary, .btn-secondary, .btn-danger { width: 100%; justify-content: center; } .card { padding: var(--space-4); } .modal { padding: var(--space-6); margin: var(--space-4); } .toast { right: 10px; left: 10px; transform: translateY(-100px); } .toast.show { transform: translateY(0); } } /* ===== ACCESSIBILITY ===== */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } } /* Focus Styles for Keyboard Navigation */ button:focus-visible, .btn-primary:focus-visible, .btn-secondary:focus-visible, .btn-danger:focus-visible { outline: 2px solid var(--primary-teal); outline-offset: 2px; } .input-field:focus-visible { outline: 2px solid var(--primary-teal); outline-offset: 2px; } /* Color Preview Classes */ .color-preview-teal { background: var(--primary-teal); color: var(--background-dark); } .color-preview-purple { background: var(--secondary-purple); color: var(--text-primary); } .color-preview-violet { background: var(--accent-violet); color: var(--text-primary); } .color-preview-success { background: var(--success-green); color: var(--text-primary); } .color-preview-warning { background: var(--warning-yellow); color: var(--background-dark); } .color-preview-error { background: var(--error-red); color: var(--text-primary); } .color-preview-gold { background: var(--gold); color: var(--background-dark); } .color-preview-star { background: var(--star-active); color: var(--background-dark); } .color-preview-glow { background: var(--achievement-glow); color: var(--background-dark); } /* Progress Width Classes */ .w-45 { width: 45%; } .w-75 { width: 75%; } .w-80 { width: 80%; } .w-86 { width: 86%; } /* Demo Effect Classes */ .demo-hover-effect { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(0, 229, 204, 0.3); } /* Utility Classes */ .hidden { display: none; } /* High Contrast Mode Support */ @media (prefers-contrast: high) { :root { --text-secondary: #FFFFFF; --divider: #FFFFFF; } .card { border: 2px solid var(--text-primary); } .btn-secondary { border-width: 3px; } }