diff --git a/web/src/App.vue b/web/src/App.vue index 70903f3..b734f5b 100644 --- a/web/src/App.vue +++ b/web/src/App.vue @@ -290,13 +290,16 @@ const handleApplyServerUpdate = () => { min-height: 100vh; display: flex; flex-direction: column; - background: var(--color-bg-primary); + background: var(--gradient-bg); + position: relative; } -/* Header */ +/* Header - 毛玻璃效果 */ .app-header { - height: 56px; - background: var(--color-bg-secondary); + height: 64px; + background: var(--glass-bg); + backdrop-filter: var(--glass-blur); + -webkit-backdrop-filter: var(--glass-blur); border-bottom: 1px solid var(--color-border); display: flex; align-items: center; @@ -305,41 +308,62 @@ const handleApplyServerUpdate = () => { position: sticky; top: 0; z-index: 100; + box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1); +} + +/* 头部顶部高光线 */ +.app-header::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 1px; + background: linear-gradient(90deg, + transparent 0%, + rgba(255, 255, 255, 0.1) 50%, + transparent 100%); } .logo { - font-size: 18px; - font-weight: 600; - color: var(--color-text-primary); + font-size: 20px; + font-weight: 700; + background: var(--gradient-accent); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; letter-spacing: -0.5px; } /* Navigation */ .header-nav { display: flex; - gap: 4px; + gap: 6px; } .nav-item { display: flex; align-items: center; - gap: 6px; - padding: 8px 16px; + gap: 8px; + padding: 10px 18px; color: var(--color-text-secondary); text-decoration: none; - border-radius: 6px; + border-radius: 10px; font-size: 14px; - transition: all 0.15s; + font-weight: 500; + transition: all 0.2s ease; + position: relative; } .nav-item:hover { color: var(--color-text-primary); - background: rgba(255, 255, 255, 0.06); + background: var(--glass-bg-light); } .nav-item.active { - color: var(--color-text-primary); - background: var(--color-accent); + color: white; + background: var(--gradient-accent); + box-shadow: 0 4px 15px var(--color-accent-glow); } .nav-icon { @@ -354,21 +378,24 @@ const handleApplyServerUpdate = () => { } .user-icon { - width: 28px; - height: 28px; + width: 32px; + height: 32px; color: var(--color-text-secondary); - transition: color 0.15s; + transition: all 0.2s ease; + padding: 4px; + border-radius: 8px; } .user-icon:hover { color: var(--color-text-primary); + background: var(--glass-bg-light); } /* Theme Menu */ .header-right { display: flex; align-items: center; - gap: 12px; + gap: 8px; } .theme-menu { @@ -377,14 +404,17 @@ const handleApplyServerUpdate = () => { } .theme-icon { - width: 24px; - height: 24px; + width: 28px; + height: 28px; + padding: 4px; color: var(--color-text-secondary); - transition: color 0.15s; + transition: all 0.2s ease; + border-radius: 8px; } .theme-icon:hover { color: var(--color-text-primary); + background: var(--glass-bg-light); } .theme-dropdown { @@ -392,21 +422,24 @@ const handleApplyServerUpdate = () => { top: 100%; right: 0; margin-top: 8px; - background: var(--color-bg-tertiary); + background: var(--glass-bg); + backdrop-filter: var(--glass-blur); + -webkit-backdrop-filter: var(--glass-blur); border: 1px solid var(--color-border); - border-radius: 8px; - padding: 4px; - min-width: 120px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); + border-radius: 12px; + padding: 6px; + min-width: 130px; + box-shadow: var(--shadow-lg); } .dropdown-item.active { - background: var(--color-accent); + background: var(--gradient-accent); color: white; + box-shadow: 0 2px 8px var(--color-accent-glow); } .dropdown-item.active:hover { - background: var(--color-accent-hover); + filter: brightness(1.1); } .user-dropdown { @@ -414,31 +447,33 @@ const handleApplyServerUpdate = () => { top: 100%; right: 0; margin-top: 8px; - background: var(--color-bg-tertiary); + background: var(--glass-bg); + backdrop-filter: var(--glass-blur); + -webkit-backdrop-filter: var(--glass-blur); border: 1px solid var(--color-border); - border-radius: 8px; - padding: 4px; - min-width: 140px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); + border-radius: 12px; + padding: 6px; + min-width: 150px; + box-shadow: var(--shadow-lg); } .dropdown-item { display: flex; align-items: center; - gap: 8px; + gap: 10px; width: 100%; - padding: 10px 12px; + padding: 10px 14px; background: none; border: none; color: var(--color-text-primary); font-size: 14px; cursor: pointer; - border-radius: 6px; - transition: all 0.15s; + border-radius: 8px; + transition: all 0.2s ease; } .dropdown-item:hover { - background: var(--color-bg-elevated); + background: var(--glass-bg-hover); } .dropdown-icon { @@ -451,10 +486,12 @@ const handleApplyServerUpdate = () => { overflow-y: auto; } -/* Footer */ +/* Footer - 毛玻璃效果 */ .app-footer { - height: 48px; - background: var(--color-bg-secondary); + height: 52px; + background: var(--glass-bg); + backdrop-filter: var(--glass-blur); + -webkit-backdrop-filter: var(--glass-blur); border-top: 1px solid var(--color-border); display: flex; align-items: center; @@ -466,20 +503,24 @@ const handleApplyServerUpdate = () => { .footer-left { display: flex; align-items: center; - gap: 12px; + gap: 16px; } .brand { font-weight: 600; - color: var(--color-text-primary); + background: var(--gradient-accent); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; } .version { - padding: 2px 8px; - background: var(--color-bg-elevated); + padding: 4px 10px; + background: var(--glass-bg-light); color: var(--color-text-secondary); - border-radius: 4px; + border-radius: 6px; font-size: 12px; + border: 1px solid var(--color-border); } .version-info { @@ -499,24 +540,33 @@ const handleApplyServerUpdate = () => { align-items: center; gap: 4px; font-size: 12px; - padding: 2px 8px; - border-radius: 4px; + padding: 4px 10px; + border-radius: 6px; cursor: pointer; - transition: all 0.15s; + transition: all 0.2s ease; + border: 1px solid transparent; } .update-status:hover { - opacity: 0.8; + transform: translateY(-1px); } .update-status.latest { - color: #00ba7c; - background: rgba(0, 186, 124, 0.1); + color: var(--color-success); + background: rgba(16, 185, 129, 0.1); + border-color: rgba(16, 185, 129, 0.2); } .update-status.has-update { - color: #f7931a; - background: rgba(247, 147, 26, 0.1); + color: var(--color-warning); + background: rgba(245, 158, 11, 0.1); + border-color: rgba(245, 158, 11, 0.2); + animation: pulse-glow 2s ease-in-out infinite; +} + +@keyframes pulse-glow { + 0%, 100% { box-shadow: 0 0 0 0 var(--color-warning-glow); } + 50% { box-shadow: 0 0 8px 2px var(--color-warning-glow); } } .status-icon { @@ -562,11 +612,12 @@ const handleApplyServerUpdate = () => { } } -/* Update Modal */ +/* Update Modal - 毛玻璃效果 */ .modal-overlay { position: fixed; inset: 0; - background: rgba(0, 0, 0, 0.7); + background: rgba(0, 0, 0, 0.6); + backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; @@ -574,16 +625,18 @@ const handleApplyServerUpdate = () => { } .update-modal { - background: var(--color-bg-tertiary); + background: var(--glass-bg); + backdrop-filter: var(--glass-blur); + -webkit-backdrop-filter: var(--glass-blur); border: 1px solid var(--color-border); - border-radius: 12px; + border-radius: 16px; width: 90%; max-width: 480px; max-height: 80vh; overflow: hidden; display: flex; flex-direction: column; - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5); + box-shadow: var(--shadow-lg), var(--shadow-glow); } .modal-header { @@ -681,29 +734,32 @@ const handleApplyServerUpdate = () => { } .modal-btn { - padding: 8px 16px; - border-radius: 6px; + padding: 10px 18px; + border-radius: 10px; font-size: 14px; font-weight: 500; cursor: pointer; - transition: all 0.15s; - background: var(--color-bg-elevated); + transition: all 0.2s ease; + background: var(--glass-bg); border: 1px solid var(--color-border); color: var(--color-text-primary); } .modal-btn:hover:not(:disabled) { - background: var(--color-border); + background: var(--glass-bg-hover); + transform: translateY(-1px); } .modal-btn.primary { - background: var(--color-accent); + background: var(--gradient-accent); border: none; color: white; + box-shadow: 0 4px 15px var(--color-accent-glow); } .modal-btn.primary:hover:not(:disabled) { - background: var(--color-accent-hover); + box-shadow: 0 6px 20px var(--color-accent-glow); + filter: brightness(1.1); } .modal-btn:disabled { diff --git a/web/src/components/GlassModal.vue b/web/src/components/GlassModal.vue index e26420c..491a823 100644 --- a/web/src/components/GlassModal.vue +++ b/web/src/components/GlassModal.vue @@ -37,7 +37,8 @@ const emit = defineEmits<{ .modal-overlay { position: fixed; inset: 0; - background: rgba(0, 0, 0, 0.7); + background: rgba(0, 0, 0, 0.6); + backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; @@ -47,10 +48,28 @@ const emit = defineEmits<{ .modal-container { width: 100%; - background: var(--color-bg-tertiary); - border-radius: 12px; + background: var(--glass-bg); + backdrop-filter: var(--glass-blur); + -webkit-backdrop-filter: var(--glass-blur); + border-radius: 16px; border: 1px solid var(--color-border); overflow: hidden; + box-shadow: var(--shadow-lg), var(--shadow-glow); + position: relative; +} + +/* 顶部高光 */ +.modal-container::before { + content: ''; + position: absolute; + top: 0; + left: 15%; + right: 15%; + height: 1px; + background: linear-gradient(90deg, + transparent 0%, + rgba(255, 255, 255, 0.15) 50%, + transparent 100%); } .modal-header { @@ -69,20 +88,20 @@ const emit = defineEmits<{ } .close-btn { - background: var(--color-bg-elevated); + background: var(--glass-bg-light); border: none; - border-radius: 6px; + border-radius: 8px; padding: 6px; color: var(--color-text-secondary); cursor: pointer; - transition: all 0.15s; + transition: all 0.2s ease; display: flex; align-items: center; justify-content: center; } .close-btn:hover { - background: rgba(244, 33, 46, 0.15); + background: rgba(239, 68, 68, 0.15); color: var(--color-error); } diff --git a/web/src/style.css b/web/src/style.css index f28afd6..f99aa83 100644 --- a/web/src/style.css +++ b/web/src/style.css @@ -1,42 +1,121 @@ @import "tailwindcss"; -/* 深色主题(默认) */ +/* ======================================== + GoTunnel 毛玻璃设计系统 + Glassmorphism Design System + ======================================== */ + +/* 深色主题(默认) - 深邃渐变背景 */ :root, [data-theme="dark"] { - --color-bg-primary: #0f1419; - --color-bg-secondary: #15202b; - --color-bg-tertiary: #1e2732; - --color-bg-elevated: #253341; - --color-border: #38444d; - --color-border-light: #2f3336; - --color-text-primary: #e7e9ea; - --color-text-secondary: #8b98a5; - --color-text-muted: #6e767d; - --color-accent: #1d9bf0; - --color-accent-hover: #1a8cd8; - --color-success: #00ba7c; - --color-warning: #f7931a; - --color-error: #f4212e; - --color-info: #1d9bf0; + /* 背景色 - 深色渐变基底 */ + --color-bg-primary: #0a0e17; + --color-bg-secondary: #0d1220; + --color-bg-tertiary: #111827; + --color-bg-elevated: #1a2332; + + /* 玻璃态背景 - 半透明 */ + --glass-bg: rgba(17, 24, 39, 0.6); + --glass-bg-hover: rgba(26, 35, 50, 0.7); + --glass-bg-light: rgba(255, 255, 255, 0.03); + --glass-bg-card: rgba(17, 24, 39, 0.5); + + /* 边框 - 高光描边 */ + --color-border: rgba(255, 255, 255, 0.08); + --color-border-light: rgba(255, 255, 255, 0.05); + --color-border-glow: rgba(99, 179, 237, 0.3); + --glass-border: 1px solid rgba(255, 255, 255, 0.1); + --glass-border-hover: 1px solid rgba(255, 255, 255, 0.15); + + /* 文字颜色 */ + --color-text-primary: #f0f4f8; + --color-text-secondary: rgba(240, 244, 248, 0.7); + --color-text-muted: rgba(240, 244, 248, 0.45); + + /* 强调色 - 霓虹高光 */ + --color-accent: #3b82f6; + --color-accent-hover: #60a5fa; + --color-accent-glow: rgba(59, 130, 246, 0.4); + --color-success: #10b981; + --color-success-glow: rgba(16, 185, 129, 0.4); + --color-warning: #f59e0b; + --color-warning-glow: rgba(245, 158, 11, 0.4); + --color-error: #ef4444; + --color-error-glow: rgba(239, 68, 68, 0.4); + --color-info: #06b6d4; + --color-info-glow: rgba(6, 182, 212, 0.4); + + /* 渐变背景 */ + --gradient-bg: linear-gradient(135deg, #0a0e17 0%, #1a1f35 50%, #0d1220 100%); + --gradient-accent: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%); + --gradient-card: linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%); + + /* 模糊效果 */ + --glass-blur: blur(20px); + --glass-blur-light: blur(12px); + + /* 阴影 - 悬浮感 */ + --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3); + --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.4); + --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.5); + --shadow-glow: 0 0 20px rgba(59, 130, 246, 0.15); + --shadow-card: 0 8px 32px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.05); } -/* 浅色主题 */ +/* 浅色主题 - 柔和渐变背景 */ [data-theme="light"] { - --color-bg-primary: #ffffff; - --color-bg-secondary: #f7f9fa; - --color-bg-tertiary: #eff3f4; - --color-bg-elevated: #e7e9ea; - --color-border: #cfd9de; - --color-border-light: #eff3f4; - --color-text-primary: #0f1419; - --color-text-secondary: #536471; - --color-text-muted: #8b98a5; - --color-accent: #1d9bf0; - --color-accent-hover: #1a8cd8; - --color-success: #00ba7c; - --color-warning: #f7931a; - --color-error: #f4212e; - --color-info: #1d9bf0; + /* 背景色 - 浅色渐变基底 */ + --color-bg-primary: #f0f4f8; + --color-bg-secondary: #e8eef4; + --color-bg-tertiary: #ffffff; + --color-bg-elevated: #ffffff; + + /* 玻璃态背景 - 半透明白 */ + --glass-bg: rgba(255, 255, 255, 0.7); + --glass-bg-hover: rgba(255, 255, 255, 0.85); + --glass-bg-light: rgba(255, 255, 255, 0.5); + --glass-bg-card: rgba(255, 255, 255, 0.6); + + /* 边框 - 柔和描边 */ + --color-border: rgba(0, 0, 0, 0.08); + --color-border-light: rgba(0, 0, 0, 0.05); + --color-border-glow: rgba(59, 130, 246, 0.3); + --glass-border: 1px solid rgba(255, 255, 255, 0.8); + --glass-border-hover: 1px solid rgba(255, 255, 255, 0.95); + + /* 文字颜色 */ + --color-text-primary: #1a202c; + --color-text-secondary: rgba(26, 32, 44, 0.7); + --color-text-muted: rgba(26, 32, 44, 0.5); + + /* 强调色 */ + --color-accent: #3b82f6; + --color-accent-hover: #2563eb; + --color-accent-glow: rgba(59, 130, 246, 0.3); + --color-success: #10b981; + --color-success-glow: rgba(16, 185, 129, 0.3); + --color-warning: #f59e0b; + --color-warning-glow: rgba(245, 158, 11, 0.3); + --color-error: #ef4444; + --color-error-glow: rgba(239, 68, 68, 0.3); + --color-info: #06b6d4; + --color-info-glow: rgba(6, 182, 212, 0.3); + + /* 渐变背景 */ + --gradient-bg: linear-gradient(135deg, #e8eef4 0%, #f0f4f8 50%, #e0e8f0 100%); + --gradient-accent: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%); + --gradient-card: linear-gradient(135deg, rgba(255,255,255,0.9) 0%, rgba(255,255,255,0.7) 100%); + + /* 模糊效果 */ + --glass-blur: blur(20px); + --glass-blur-light: blur(12px); + + /* 阴影 */ + --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.08); + --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.1); + --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.12); + --shadow-glow: 0 0 20px rgba(59, 130, 246, 0.1); + --shadow-card: 0 8px 32px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.8); } * { @@ -49,21 +128,205 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - background: var(--color-bg-primary); + background: var(--gradient-bg); color: var(--color-text-primary); + min-height: 100vh; } #app { min-height: 100vh; + position: relative; } -/* Card utilities */ +/* ======================================== + 玻璃态卡片组件 + ======================================== */ + .glass-card { - background: var(--color-bg-tertiary); - border-radius: 12px; + background: var(--glass-bg); + backdrop-filter: var(--glass-blur); + -webkit-backdrop-filter: var(--glass-blur); + border-radius: 16px; border: 1px solid var(--color-border); + box-shadow: var(--shadow-card); + position: relative; + overflow: hidden; + transition: all 0.2s ease; +} + +/* 卡片顶部高光 */ +.glass-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 1px; + background: linear-gradient(90deg, + transparent 0%, + rgba(255, 255, 255, 0.1) 50%, + transparent 100%); + pointer-events: none; } .glass-card-hover:hover { - background: var(--color-bg-elevated); + background: var(--glass-bg-hover); + border-color: rgba(255, 255, 255, 0.12); + box-shadow: var(--shadow-lg), var(--shadow-glow); + transform: translateY(-2px); +} + +/* ======================================== + 玻璃态按钮 + ======================================== */ + +.glass-btn { + background: var(--glass-bg); + backdrop-filter: var(--glass-blur-light); + -webkit-backdrop-filter: var(--glass-blur-light); + border: 1px solid var(--color-border); + border-radius: 10px; + padding: 10px 18px; + color: var(--color-text-primary); + font-size: 14px; + font-weight: 500; + cursor: pointer; + transition: all 0.2s ease; + position: relative; + overflow: hidden; +} + +.glass-btn:hover { + background: var(--glass-bg-hover); + border-color: rgba(255, 255, 255, 0.15); + box-shadow: var(--shadow-sm); +} + +.glass-btn:active { + transform: scale(0.98); +} + +.glass-btn.primary { + background: var(--gradient-accent); + border: none; + color: white; + box-shadow: 0 4px 15px var(--color-accent-glow); +} + +.glass-btn.primary:hover { + box-shadow: 0 6px 20px var(--color-accent-glow); + filter: brightness(1.1); +} + +.glass-btn.small { + padding: 6px 12px; + font-size: 12px; + border-radius: 8px; +} + +/* ======================================== + 玻璃态输入框 + ======================================== */ + +.glass-input { + background: var(--glass-bg-light); + backdrop-filter: var(--glass-blur-light); + -webkit-backdrop-filter: var(--glass-blur-light); + border: 1px solid var(--color-border); + border-radius: 10px; + padding: 12px 16px; + color: var(--color-text-primary); + font-size: 15px; + width: 100%; + transition: all 0.2s ease; + outline: none; +} + +.glass-input:focus { + border-color: var(--color-accent); + box-shadow: 0 0 0 3px var(--color-accent-glow); +} + +.glass-input::placeholder { + color: var(--color-text-muted); +} + +/* ======================================== + 动画背景粒子 + ======================================== */ + +.particles { + position: absolute; + inset: 0; + overflow: hidden; + pointer-events: none; + z-index: 0; +} + +.particle { + position: absolute; + border-radius: 50%; + opacity: 0.15; + filter: blur(60px); + animation: float 20s ease-in-out infinite; +} + +.particle-1 { + width: 400px; + height: 400px; + background: var(--color-accent); + top: -100px; + right: -100px; + animation-delay: 0s; +} + +.particle-2 { + width: 300px; + height: 300px; + background: #8b5cf6; + bottom: -50px; + left: -50px; + animation-delay: -5s; +} + +.particle-3 { + width: 250px; + height: 250px; + background: var(--color-info); + top: 50%; + left: 50%; + animation-delay: -10s; +} + +.particle-4 { + width: 200px; + height: 200px; + background: var(--color-success); + bottom: 20%; + right: 20%; + animation-delay: -15s; +} + +.particle-5 { + width: 350px; + height: 350px; + background: #ec4899; + top: 30%; + left: 10%; + animation-delay: -7s; +} + +@keyframes float { + 0%, 100% { + transform: translate(0, 0) scale(1); + } + 25% { + transform: translate(30px, -30px) scale(1.05); + } + 50% { + transform: translate(-20px, 20px) scale(0.95); + } + 75% { + transform: translate(-30px, -20px) scale(1.02); + } } diff --git a/web/src/views/ClientsView.vue b/web/src/views/ClientsView.vue index b2e32e0..9f1cbc9 100644 --- a/web/src/views/ClientsView.vue +++ b/web/src/views/ClientsView.vue @@ -106,16 +106,60 @@ onMounted(loadClients) diff --git a/web/src/views/LoginView.vue b/web/src/views/LoginView.vue index 325cd9c..5d3fa10 100644 --- a/web/src/views/LoginView.vue +++ b/web/src/views/LoginView.vue @@ -101,57 +101,131 @@ const handleLogin = async () => { display: flex; align-items: center; justify-content: center; - background: var(--color-bg-primary); + background: var(--gradient-bg); padding: 16px; position: relative; overflow: hidden; } -/* 移除浮动粒子动画 */ +/* 动画背景粒子 */ .particles { - display: none; + position: absolute; + inset: 0; + overflow: hidden; + pointer-events: none; + z-index: 0; } -/* Login card */ +.particle { + position: absolute; + border-radius: 50%; + opacity: 0.2; + filter: blur(60px); + animation: float 20s ease-in-out infinite; +} + +.particle-1 { + width: 400px; + height: 400px; + background: var(--color-accent); + top: -100px; + right: -100px; +} + +.particle-2 { + width: 300px; + height: 300px; + background: #8b5cf6; + bottom: -50px; + left: -50px; + animation-delay: -5s; +} + +.particle-3 { + width: 250px; + height: 250px; + background: var(--color-info); + top: 50%; + left: 20%; + animation-delay: -10s; +} + +.particle-4 { + width: 200px; + height: 200px; + background: #ec4899; + bottom: 30%; + right: 10%; + animation-delay: -15s; +} + +@keyframes float { + 0%, 100% { transform: translate(0, 0) scale(1); } + 25% { transform: translate(30px, -30px) scale(1.05); } + 50% { transform: translate(-20px, 20px) scale(0.95); } + 75% { transform: translate(-30px, -20px) scale(1.02); } +} + +/* Login card - 毛玻璃效果 */ .login-card { width: 100%; - max-width: 380px; - background: var(--color-bg-tertiary); - border-radius: 16px; + max-width: 400px; + background: var(--glass-bg); + backdrop-filter: var(--glass-blur); + -webkit-backdrop-filter: var(--glass-blur); + border-radius: 20px; border: 1px solid var(--color-border); - box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4); - padding: 40px 32px; + box-shadow: var(--shadow-card); + padding: 48px 36px; position: relative; z-index: 10; } +/* 卡片顶部高光 */ +.login-card::before { + content: ''; + position: absolute; + top: 0; + left: 20%; + right: 20%; + height: 1px; + background: linear-gradient(90deg, + transparent 0%, + rgba(255, 255, 255, 0.15) 50%, + transparent 100%); +} + /* Header */ .login-header { text-align: center; - margin-bottom: 32px; + margin-bottom: 36px; } .logo-icon { - width: 56px; - height: 56px; - margin: 0 auto 16px; - background: var(--color-accent); - border-radius: 12px; + width: 64px; + height: 64px; + margin: 0 auto 20px; + background: var(--gradient-accent); + border-radius: 16px; display: flex; align-items: center; justify-content: center; + box-shadow: 0 8px 24px var(--color-accent-glow); } .logo-icon svg { color: white; - width: 28px; - height: 28px; + width: 32px; + height: 32px; } .logo-text { - font-size: 24px; - font-weight: 600; - color: var(--color-text-primary); + font-size: 28px; + font-weight: 700; + background: var(--gradient-accent); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; margin: 0 0 8px 0; } @@ -181,19 +255,22 @@ const handleLogin = async () => { } .glass-input { - background: var(--color-bg-elevated); + background: var(--glass-bg-light); + backdrop-filter: var(--glass-blur-light); + -webkit-backdrop-filter: var(--glass-blur-light); border: 1px solid var(--color-border); - border-radius: 8px; - padding: 12px 14px; + border-radius: 12px; + padding: 14px 16px; color: var(--color-text-primary); font-size: 15px; width: 100%; - transition: all 0.15s; + transition: all 0.2s ease; outline: none; } .glass-input:focus { border-color: var(--color-accent); + box-shadow: 0 0 0 3px var(--color-accent-glow); } .glass-input::placeholder { @@ -211,9 +288,9 @@ const handleLogin = async () => { align-items: center; gap: 8px; padding: 12px 14px; - background: rgba(244, 33, 46, 0.1); - border: 1px solid rgba(244, 33, 46, 0.3); - border-radius: 8px; + background: rgba(239, 68, 68, 0.1); + border: 1px solid rgba(239, 68, 68, 0.3); + border-radius: 10px; color: var(--color-error); font-size: 14px; } @@ -224,23 +301,30 @@ const handleLogin = async () => { /* Button */ .glass-button { - background: var(--color-accent); + background: var(--gradient-accent); border: none; - border-radius: 8px; - padding: 12px 24px; + border-radius: 12px; + padding: 14px 24px; color: white; font-size: 15px; font-weight: 600; cursor: pointer; - transition: all 0.15s; + transition: all 0.2s ease; display: flex; align-items: center; justify-content: center; gap: 8px; + box-shadow: 0 4px 15px var(--color-accent-glow); } .glass-button:hover:not(:disabled) { - background: var(--color-accent-hover); + box-shadow: 0 6px 20px var(--color-accent-glow); + transform: translateY(-2px); + filter: brightness(1.1); +} + +.glass-button:active:not(:disabled) { + transform: translateY(0) scale(0.98); } .glass-button:disabled { @@ -265,7 +349,7 @@ const handleLogin = async () => { /* Footer */ .login-footer { text-align: center; - margin-top: 24px; + margin-top: 28px; padding-top: 24px; border-top: 1px solid var(--color-border); color: var(--color-text-muted);