diff --git a/dashboard/static/css/cyber-core.css b/dashboard/static/css/cyber-core.css new file mode 100644 index 0000000..1c85cc4 --- /dev/null +++ b/dashboard/static/css/cyber-core.css @@ -0,0 +1,364 @@ +/** + * AutoGLM - Industrial Cyber Console Theme + * 工业赛博控制台核心样式 + */ + +@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;600;700;900&family=JetBrains+Mono:wght@300;400;500;600&display=swap'); + +/* ==================== 核心变量 ==================== */ +:root { + /* 主色调 - 霓虹绿 */ + --cyber-green: #00ff9f; + --cyber-green-dim: rgba(0, 255, 159, 0.15); + --cyber-green-glow: rgba(0, 255, 159, 0.5); + + /* 状态色 */ + --cyber-amber: #ffb800; + --cyber-amber-dim: rgba(255, 184, 0, 0.15); + --cyber-red: #ff4757; + --cyber-red-dim: rgba(255, 71, 87, 0.15); + --cyber-blue: #00d4ff; + --cyber-blue-dim: rgba(0, 212, 255, 0.15); + + /* 背景色 */ + --cyber-bg-primary: #0a0e27; + --cyber-bg-secondary: #131829; + --cyber-bg-tertiary: #1a2040; + --cyber-bg-elevated: #222b4a; + + /* 文字色 */ + --cyber-text-primary: #e8eaed; + --cyber-text-secondary: #9aa0b8; + --cyber-text-muted: #5a6382; + + /* 边框和分隔 */ + --cyber-border: #2a3455; + --cyber-border-bright: #3a4a7a; + + /* 阴影和发光 */ + --cyber-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); + --cyber-glow-green: 0 0 20px rgba(0, 255, 159, 0.3); + --cyber-glow-blue: 0 0 20px rgba(0, 212, 255, 0.3); + --cyber-glow-red: 0 0 20px rgba(255, 71, 87, 0.3); + + /* 字体 */ + --cyber-font-display: 'Orbitron', sans-serif; + --cyber-font-mono: 'JetBrains Mono', 'Consolas', 'Monaco', monospace; + + /* 间距 */ + --cyber-space-xs: 0.25rem; + --cyber-space-sm: 0.5rem; + --cyber-space-md: 1rem; + --cyber-space-lg: 1.5rem; + --cyber-space-xl: 2rem; + --cyber-space-2xl: 3rem; + + /* 过渡 */ + --cyber-transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1); + --cyber-transition-normal: 250ms cubic-bezier(0.4, 0, 0.2, 1); + --cyber-transition-slow: 400ms cubic-bezier(0.4, 0, 0.2, 1); +} + +/* ==================== 全局重置 ==================== */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: var(--cyber-font-mono); + background-color: var(--cyber-bg-primary); + color: var(--cyber-text-primary); + line-height: 1.6; + min-height: 100vh; + overflow-x: hidden; + position: relative; +} + +/* ==================== 背景网格效果 ==================== */ +body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-image: + linear-gradient(rgba(0, 255, 159, 0.03) 1px, transparent 1px), + linear-gradient(90deg, rgba(0, 255, 159, 0.03) 1px, transparent 1px); + background-size: 50px 50px; + pointer-events: none; + z-index: 0; +} + +/* ==================== CRT 扫描线效果 ==================== */ +body::after { + content: ''; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: repeating-linear-gradient( + 0deg, + rgba(0, 0, 0, 0.1) 0px, + transparent 1px, + transparent 2px, + rgba(0, 0, 0, 0.1) 3px + ); + background-size: 100% 4px; + pointer-events: none; + z-index: 9999; + opacity: 0.3; + animation: scanline 8s linear infinite; +} + +@keyframes scanline { + 0% { transform: translateY(0); } + 100% { transform: translateY(50px); } +} + +/* ==================== 主容器 ==================== */ +#app { + position: relative; + z-index: 1; +} + +/* ==================== 滚动条样式 ==================== */ +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background: var(--cyber-bg-secondary); +} + +::-webkit-scrollbar-thumb { + background: var(--cyber-border); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: var(--cyber-border-bright); +} + +/* ==================== 选择文本样式 ==================== */ +::selection { + background: var(--cyber-green-dim); + color: var(--cyber-green); +} + +/* ==================== 链接样式 ==================== */ +a { + color: var(--cyber-green); + text-decoration: none; + transition: var(--cyber-transition-fast); +} + +a:hover { + color: var(--cyber-blue); + text-shadow: var(--cyber-glow-blue); +} + +/* ==================== 通用工具类 ==================== */ +.cyber-text-glow { + text-shadow: 0 0 10px currentColor; +} + +.cyber-border-glow { + box-shadow: 0 0 15px currentColor, inset 0 0 15px currentColor; +} + +.cyber-flicker { + animation: flicker 3s infinite; +} + +@keyframes flicker { + 0%, 100% { opacity: 1; } + 92% { opacity: 1; } + 93% { opacity: 0.8; } + 94% { opacity: 1; } + 96% { opacity: 0.9; } + 97% { opacity: 1; } +} + +/* ==================== 装饰性角落 ==================== */ +.cyber-corner { + position: relative; +} + +.cyber-corner::before, +.cyber-corner::after { + content: ''; + position: absolute; + width: 20px; + height: 20px; + border-color: var(--cyber-green); + border-style: solid; + opacity: 0.5; + transition: var(--cyber-transition-normal); +} + +.cyber-corner::before { + top: 0; + left: 0; + border-width: 2px 0 0 2px; +} + +.cyber-corner::after { + bottom: 0; + right: 0; + border-width: 0 2px 2px 0; +} + +.cyber-corner:hover::before, +.cyber-corner:hover::after { + opacity: 1; + width: 30px; + height: 30px; +} + +/* ==================== 数据流动画 ==================== */ +@keyframes dataFlow { + 0% { + transform: translateX(-100%); + opacity: 0; + } + 50% { + opacity: 1; + } + 100% { + transform: translateX(100%); + opacity: 0; + } +} + +.cyber-data-flow { + position: relative; + overflow: hidden; +} + +.cyber-data-flow::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, transparent, var(--cyber-green), transparent); + animation: dataFlow 2s linear infinite; +} + +/* ==================== 脉冲动画 ==================== */ +@keyframes pulse { + 0%, 100% { + opacity: 1; + } + 50% { + opacity: 0.5; + } +} + +.cyber-pulse { + animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; +} + +/* ==================== 打字机效果 ==================== */ +@keyframes typing { + from { + width: 0; + } + to { + width: 100%; + } +} + +@keyframes blink { + 50% { + border-color: transparent; + } +} + +.cyber-typing { + overflow: hidden; + white-space: nowrap; + border-right: 2px solid var(--cyber-green); + animation: typing 3s steps(40, end), blink 0.75s step-end infinite; +} + +/* ==================== 故障效果 ==================== */ +@keyframes glitch { + 0% { + transform: translate(0); + } + 20% { + transform: translate(-2px, 2px); + } + 40% { + transform: translate(-2px, -2px); + } + 60% { + transform: translate(2px, 2px); + } + 80% { + transform: translate(2px, -2px); + } + 100% { + transform: translate(0); + } +} + +.cyber-glitch:hover { + animation: glitch 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94) both infinite; + color: var(--cyber-green); +} + +/* ==================== 全息效果 ==================== */ +.cyber-hologram { + position: relative; + background: linear-gradient( + 135deg, + rgba(0, 255, 159, 0.1) 0%, + rgba(0, 212, 255, 0.1) 50%, + rgba(0, 255, 159, 0.1) 100% + ); + backdrop-filter: blur(10px); +} + +.cyber-hologram::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient( + 45deg, + transparent 30%, + rgba(0, 255, 159, 0.1) 50%, + transparent 70% + ); + animation: hologramShift 3s linear infinite; +} + +@keyframes hologramShift { + 0% { + transform: translateX(-100%) translateY(-100%) rotate(45deg); + } + 100% { + transform: translateX(100%) translateY(100%) rotate(45deg); + } +} + +/* ==================== 响应式 ==================== */ +@media (max-width: 768px) { + body::before { + background-size: 30px 30px; + } + + body::after { + background-size: 100% 3px; + } +} diff --git a/dashboard/static/css/dashboard.css b/dashboard/static/css/dashboard.css index 5ef18d8..8a0c3bc 100644 --- a/dashboard/static/css/dashboard.css +++ b/dashboard/static/css/dashboard.css @@ -1,38 +1,23 @@ -/* AutoGLM Dashboard Styles */ +/** + * AutoGLM Dashboard - Industrial Cyber Console + * 主仪表板样式 + */ -:root { - --primary-color: #6366f1; - --primary-hover: #4f46e5; - --success-color: #10b981; - --warning-color: #f59e0b; - --danger-color: #ef4444; - --bg-color: #0f172a; - --card-bg: #1e293b; - --border-color: #334155; - --text-primary: #f1f5f9; - --text-secondary: #94a3b8; - --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3); - --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4); +/* 导入核心样式 */ +@import url('./cyber-core.css'); + +/* ==================== 标题样式 ==================== */ +h1, h2, h3, h4, h5, h6 { + font-family: var(--cyber-font-display); + font-weight: 600; + letter-spacing: 0.05em; + text-transform: uppercase; } -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif; - background-color: var(--bg-color); - color: var(--text-primary); - line-height: 1.6; - min-height: 100vh; -} - -/* Header */ +/* ==================== Header ==================== */ .header { - background-color: var(--card-bg); - border-bottom: 1px solid var(--border-color); + background: linear-gradient(180deg, var(--cyber-bg-secondary) 0%, var(--cyber-bg-primary) 100%); + border-bottom: 1px solid var(--cyber-border); padding: 1rem 2rem; display: flex; justify-content: space-between; @@ -40,7 +25,19 @@ body { position: sticky; top: 0; z-index: 100; - box-shadow: var(--shadow); + box-shadow: 0 4px 30px rgba(0, 255, 159, 0.1); + backdrop-filter: blur(10px); +} + +.header::before { + content: ''; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 1px; + background: linear-gradient(90deg, transparent, var(--cyber-green), transparent); + opacity: 0.5; } .header-content { @@ -51,8 +48,17 @@ body { .header h1 { font-size: 1.5rem; - font-weight: 600; - color: var(--text-primary); + font-weight: 700; + color: var(--cyber-green); + text-shadow: var(--cyber-glow-green); + letter-spacing: 0.1em; + position: relative; +} + +.header h1::before { + content: '>'; + margin-right: 0.5rem; + animation: blink 1s step-end infinite; } .stats { @@ -64,20 +70,39 @@ body { display: flex; align-items: center; gap: 0.5rem; - font-size: 0.875rem; - color: var(--text-secondary); + font-size: 0.8rem; + color: var(--cyber-text-secondary); + font-family: var(--cyber-font-mono); + padding: 0.375rem 0.75rem; + background: var(--cyber-bg-tertiary); + border: 1px solid var(--cyber-border); + border-radius: 4px; + position: relative; + overflow: hidden; +} + +.stat::before { + content: ''; + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 3px; + background: var(--cyber-text-muted); } .stat svg { opacity: 0.7; } -.ws-status { - color: var(--danger-color); +.stat.ws-status.connected::before { + background: var(--cyber-green); + box-shadow: var(--cyber-glow-green); } -.ws-status.connected { - color: var(--success-color); +.stat.ws-status::before { + background: var(--cyber-red); + box-shadow: var(--cyber-glow-red); } .header-actions { @@ -85,46 +110,94 @@ body { gap: 0.75rem; } -/* Main Content */ +/* ==================== Main Content ==================== */ .main-content { padding: 2rem; - max-width: 1600px; + max-width: 1800px; margin: 0 auto; + position: relative; } .main-content h2 { font-size: 1.25rem; - font-weight: 600; - margin-bottom: 1rem; - color: var(--text-primary); + margin-bottom: 1.5rem; + color: var(--cyber-text-primary); + display: flex; + align-items: center; + gap: 0.75rem; + position: relative; + padding-bottom: 0.75rem; } -/* Device Grid */ +.main-content h2::before { + content: ''; + width: 4px; + height: 100%; + background: linear-gradient(180deg, var(--cyber-green), transparent); + position: absolute; + left: -1rem; +} + +.main-content h2::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 1px; + background: linear-gradient(90deg, var(--cyber-green), transparent); +} + +/* ==================== Device Grid ==================== */ .device-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); + grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); gap: 1.5rem; margin-bottom: 3rem; } .device-card { - background-color: var(--card-bg); - border: 1px solid var(--border-color); - border-radius: 12px; - padding: 1.25rem; - transition: box-shadow 0.2s, border-color 0.2s; + background: linear-gradient(135deg, var(--cyber-bg-secondary) 0%, var(--cyber-bg-tertiary) 100%); + border: 1px solid var(--cyber-border); + padding: 1.5rem; + position: relative; + transition: var(--cyber-transition-normal); + overflow: hidden; +} + +.device-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, transparent, var(--cyber-green), transparent); + opacity: 0; + transition: var(--cyber-transition-normal); } .device-card:hover { - box-shadow: var(--shadow-lg); + border-color: var(--cyber-green); + box-shadow: var(--cyber-glow-green); + transform: translateY(-2px); +} + +.device-card:hover::before { + opacity: 1; } .device-card.busy { - border-color: var(--warning-color); + border-color: var(--cyber-amber); +} + +.device-card.busy::before { + background: linear-gradient(90deg, transparent, var(--cyber-amber), transparent); } .device-card.offline { - opacity: 0.6; + opacity: 0.5; + filter: grayscale(0.5); } .device-header { @@ -135,33 +208,41 @@ body { } .device-header h3 { - font-size: 1rem; - font-weight: 600; - color: var(--text-primary); + font-size: 0.95rem; + font-weight: 500; + color: var(--cyber-text-primary); word-break: break-all; + font-family: var(--cyber-font-mono); } .status-badge { padding: 0.25rem 0.75rem; - border-radius: 9999px; - font-size: 0.75rem; + font-size: 0.65rem; font-weight: 600; text-transform: uppercase; + letter-spacing: 0.1em; + font-family: var(--cyber-font-display); + border: 1px solid; + position: relative; } .status-badge.online { - background-color: rgba(16, 185, 129, 0.2); - color: var(--success-color); + background: var(--cyber-green-dim); + color: var(--cyber-green); + border-color: var(--cyber-green); } .status-badge.offline { - background-color: rgba(239, 68, 68, 0.2); - color: var(--danger-color); + background: var(--cyber-red-dim); + color: var(--cyber-red); + border-color: var(--cyber-red); } .status-badge.busy { - background-color: rgba(245, 158, 11, 0.2); - color: var(--warning-color); + background: var(--cyber-amber-dim); + color: var(--cyber-amber); + border-color: var(--cyber-amber); + animation: pulse 2s infinite; } .device-info { @@ -169,9 +250,9 @@ body { } .device-info p { - font-size: 0.875rem; - color: var(--text-secondary); - margin-bottom: 0.25rem; + font-size: 0.8rem; + color: var(--cyber-text-secondary); + margin-bottom: 0.35rem; display: flex; align-items: center; gap: 0.5rem; @@ -179,14 +260,28 @@ body { .device-info p svg { flex-shrink: 0; + color: var(--cyber-green); } .screenshot { margin-bottom: 1rem; - border-radius: 8px; + border: 1px solid var(--cyber-border); overflow: hidden; - background-color: #000; + background: #000; aspect-ratio: 9/16; + position: relative; +} + +.screenshot::before { + content: ''; + position: absolute; + top: 5px; + left: 5px; + right: 5px; + bottom: 5px; + border: 1px solid rgba(0, 255, 159, 0.3); + pointer-events: none; + z-index: 1; } .screenshot img { @@ -203,16 +298,18 @@ body { .device-actions input { flex: 1; padding: 0.625rem 0.875rem; - background-color: var(--bg-color); - border: 1px solid var(--border-color); - border-radius: 8px; - color: var(--text-primary); - font-size: 0.875rem; + background: var(--cyber-bg-primary); + border: 1px solid var(--cyber-border); + color: var(--cyber-text-primary); + font-size: 0.8rem; + font-family: var(--cyber-font-mono); + transition: var(--cyber-transition-fast); } .device-actions input:focus { outline: none; - border-color: var(--primary-color); + border-color: var(--cyber-green); + box-shadow: 0 0 10px var(--cyber-green-dim); } .device-actions input:disabled { @@ -220,7 +317,11 @@ body { cursor: not-allowed; } -/* Task List */ +.device-actions input::placeholder { + color: var(--cyber-text-muted); +} + +/* ==================== Task List ==================== */ .task-list { display: flex; flex-direction: column; @@ -228,20 +329,41 @@ body { } .task-item { - background-color: var(--card-bg); - border: 1px solid var(--border-color); - border-radius: 8px; + background: linear-gradient(135deg, var(--cyber-bg-secondary) 0%, var(--cyber-bg-tertiary) 100%); + border: 1px solid var(--cyber-border); padding: 1rem; display: flex; justify-content: space-between; align-items: start; gap: 1rem; - transition: border-color 0.2s; + transition: var(--cyber-transition-normal); + position: relative; + overflow: hidden; +} + +.task-item::before { + content: ''; + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 3px; + background: var(--cyber-text-muted); + transition: var(--cyber-transition-normal); +} + +.task-item:hover { + border-color: var(--cyber-border-bright); } .task-item.active { - border-color: var(--primary-color); - box-shadow: 0 0 0 1px var(--primary-color); + border-color: var(--cyber-green); + box-shadow: inset 0 0 20px var(--cyber-green-dim); +} + +.task-item.active::before { + background: var(--cyber-green); + box-shadow: var(--cyber-glow-green); } .task-info { @@ -256,93 +378,130 @@ body { } .task-id { - font-size: 0.75rem; - color: var(--text-secondary); - font-family: monospace; + font-size: 0.7rem; + color: var(--cyber-text-muted); + font-family: var(--cyber-font-mono); } .task-status { - padding: 0.125rem 0.5rem; - border-radius: 4px; - font-size: 0.7rem; + padding: 0.2rem 0.6rem; + font-size: 0.65rem; font-weight: 600; text-transform: uppercase; + letter-spacing: 0.05em; + font-family: var(--cyber-font-display); } .task-status.running { - background-color: rgba(99, 102, 241, 0.2); - color: var(--primary-color); + background: var(--cyber-green-dim); + color: var(--cyber-green); + border: 1px solid var(--cyber-green); } .task-status.completed { - background-color: rgba(16, 185, 129, 0.2); - color: var(--success-color); + background: rgba(16, 185, 129, 0.15); + color: #10b981; + border: 1px solid #10b981; } .task-status.failed { - background-color: rgba(239, 68, 68, 0.2); - color: var(--danger-color); + background: var(--cyber-red-dim); + color: var(--cyber-red); + border: 1px solid var(--cyber-red); } .task-status.stopped { - background-color: rgba(148, 163, 184, 0.2); - color: var(--text-secondary); + background: rgba(148, 163, 184, 0.15); + color: var(--cyber-text-secondary); + border: 1px solid var(--cyber-text-muted); } .task-description { - font-size: 0.95rem; - color: var(--text-primary); + font-size: 0.9rem; + color: var(--cyber-text-primary); margin-bottom: 0.5rem; } .task-meta { display: flex; - gap: 1rem; - font-size: 0.8rem; - color: var(--text-secondary); + gap: 1.5rem; + font-size: 0.75rem; + color: var(--cyber-text-muted); + font-family: var(--cyber-font-mono); +} + +.task-meta span { + display: flex; + align-items: center; + gap: 0.35rem; +} + +.task-meta span::before { + content: '◆'; + color: var(--cyber-green); + font-size: 0.5rem; } .task-progress { - height: 4px; - background-color: var(--bg-color); - border-radius: 2px; + height: 3px; + background: var(--cyber-bg-primary); overflow: hidden; - margin-top: 0.5rem; + margin-top: 0.75rem; + position: relative; +} + +.task-progress::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: repeating-linear-gradient( + 90deg, + transparent, + transparent 2px, + rgba(0, 0, 0, 0.3) 2px, + rgba(0, 0, 0, 0.3) 4px + ); } .progress-bar { height: 100%; - background-color: var(--primary-color); + background: linear-gradient(90deg, var(--cyber-green), var(--cyber-blue)); transition: width 0.3s ease; + position: relative; + box-shadow: 0 0 10px var(--cyber-green); } -.task-thinking { +.task-thinking, +.task-action, +.task-message { display: flex; align-items: start; gap: 0.5rem; margin-top: 0.5rem; - padding: 0.5rem; - background-color: var(--bg-color); - border-radius: 6px; - font-size: 0.85rem; - color: var(--text-secondary); + padding: 0.6rem; + font-size: 0.8rem; + line-height: 1.4; + border-left: 2px solid; +} + +.task-thinking { + background: var(--cyber-bg-primary); + color: var(--cyber-text-secondary); + border-left-color: var(--cyber-blue); } .task-thinking svg { flex-shrink: 0; - margin-top: 2px; + color: var(--cyber-blue); } .task-action { - display: flex; - align-items: center; - gap: 0.5rem; - margin-top: 0.5rem; - padding: 0.5rem; - background-color: rgba(99, 102, 241, 0.1); - border-radius: 6px; - font-size: 0.85rem; - color: var(--primary-color); + background: var(--cyber-green-dim); + color: var(--cyber-green); + border-left-color: var(--cyber-green); } .task-action svg { @@ -350,56 +509,71 @@ body { } .task-action strong { - color: var(--text-primary); + color: var(--cyber-text-primary); } .task-message { - display: flex; - align-items: start; - gap: 0.5rem; - margin-top: 0.5rem; - padding: 0.5rem; - border-radius: 6px; - font-size: 0.85rem; - line-height: 1.4; + border-radius: 0 4px 4px 0; +} + +.task-message.completed { + background: rgba(16, 185, 129, 0.1); + color: #10b981; + border-left-color: #10b981; +} + +.task-message.failed { + background: var(--cyber-red-dim); + color: var(--cyber-red); + border-left-color: var(--cyber-red); +} + +.task-message.stopped { + background: rgba(148, 163, 184, 0.1); + color: var(--cyber-text-secondary); + border-left-color: var(--cyber-text-muted); } .task-message svg { flex-shrink: 0; - margin-top: 2px; -} - -.task-message.completed { - background-color: rgba(16, 185, 129, 0.1); - color: var(--success-color); -} - -.task-message.failed { - background-color: rgba(239, 68, 68, 0.1); - color: var(--danger-color); -} - -.task-message.stopped { - background-color: rgba(148, 163, 184, 0.1); - color: var(--text-secondary); } .task-actions { flex-shrink: 0; } -/* Buttons */ +/* ==================== Buttons ==================== */ .btn { padding: 0.625rem 1rem; - border: none; - border-radius: 8px; - font-size: 0.875rem; + border: 1px solid; + font-size: 0.8rem; font-weight: 500; + font-family: var(--cyber-font-display); + text-transform: uppercase; + letter-spacing: 0.05em; cursor: pointer; - transition: all 0.2s; + transition: var(--cyber-transition-fast); display: inline-flex; align-items: center; gap: 0.5rem; + position: relative; + overflow: hidden; + background: transparent; +} + +.btn::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent); + transition: var(--cyber-transition-slow); +} + +.btn:hover::before { + left: 100%; } .btn:disabled { @@ -407,37 +581,49 @@ body { cursor: not-allowed; } +.btn:disabled::before { + display: none; +} + .btn-primary { - background-color: var(--primary-color); - color: white; + background: var(--cyber-green-dim); + color: var(--cyber-green); + border-color: var(--cyber-green); } .btn-primary:hover:not(:disabled) { - background-color: var(--primary-hover); + background: var(--cyber-green); + color: var(--cyber-bg-primary); + box-shadow: var(--cyber-glow-green); } .btn-secondary { - background-color: var(--card-bg); - color: var(--text-primary); - border: 1px solid var(--border-color); + background: var(--cyber-bg-tertiary); + color: var(--cyber-text-primary); + border-color: var(--cyber-border); } .btn-secondary:hover:not(:disabled) { - background-color: var(--border-color); + background: var(--cyber-bg-elevated); + border-color: var(--cyber-border-bright); + box-shadow: 0 0 15px var(--cyber-border-dim); } .btn-danger { - background-color: var(--danger-color); - color: white; + background: var(--cyber-red-dim); + color: var(--cyber-red); + border-color: var(--cyber-red); } .btn-danger:hover:not(:disabled) { - background-color: #dc2626; + background: var(--cyber-red); + color: white; + box-shadow: var(--cyber-glow-red); } .btn-sm { padding: 0.5rem 0.75rem; - font-size: 0.8rem; + font-size: 0.7rem; } .spinning { @@ -449,28 +635,46 @@ body { to { transform: rotate(360deg); } } -/* Empty State */ +/* ==================== Empty State ==================== */ .empty-state { text-align: center; padding: 4rem 2rem; - color: var(--text-secondary); + color: var(--cyber-text-muted); + position: relative; +} + +.empty-state::before { + content: ''; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 200px; + height: 200px; + border: 1px dashed var(--cyber-border); + border-radius: 50%; + animation: pulse 3s infinite; } .empty-state svg { margin-bottom: 1rem; opacity: 0.3; + position: relative; + z-index: 1; } .empty-state p { margin-bottom: 1.5rem; + position: relative; + z-index: 1; } .empty-state .hint { - font-size: 0.875rem; + font-size: 0.8rem; opacity: 0.7; } -/* Toast */ +/* ==================== Toast ==================== */ .toast-container { position: fixed; bottom: 2rem; @@ -483,25 +687,52 @@ body { .toast { padding: 0.75rem 1rem; - border-radius: 8px; - font-size: 0.875rem; - box-shadow: var(--shadow-lg); + font-size: 0.85rem; + font-family: var(--cyber-font-mono); + border: 1px solid; + position: relative; + overflow: hidden; animation: slideIn 0.3s ease; + backdrop-filter: blur(10px); +} + +.toast::before { + content: ''; + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 3px; } .toast.success { - background-color: var(--success-color); - color: white; + background: rgba(16, 185, 129, 0.2); + color: #10b981; + border-color: #10b981; +} + +.toast.success::before { + background: #10b981; } .toast.error { - background-color: var(--danger-color); - color: white; + background: var(--cyber-red-dim); + color: var(--cyber-red); + border-color: var(--cyber-red); +} + +.toast.error::before { + background: var(--cyber-red); } .toast.info { - background-color: var(--primary-color); - color: white; + background: var(--cyber-blue-dim); + color: var(--cyber-blue); + border-color: var(--cyber-blue); +} + +.toast.info::before { + background: var(--cyber-blue); } @keyframes slideIn { @@ -515,7 +746,7 @@ body { } } -/* Responsive */ +/* ==================== Responsive ==================== */ @media (max-width: 768px) { .header { flex-direction: column; @@ -526,7 +757,7 @@ body { .header-content { flex-direction: column; gap: 0.75rem; - align-items: start; + align-items: flex-start; } .device-grid { @@ -536,4 +767,9 @@ body { .main-content { padding: 1rem; } + + .stats { + flex-wrap: wrap; + gap: 0.75rem; + } } diff --git a/dashboard/static/css/sessions.css b/dashboard/static/css/sessions.css index 363423c..dc093ba 100644 --- a/dashboard/static/css/sessions.css +++ b/dashboard/static/css/sessions.css @@ -1,208 +1,423 @@ /** - * Video Learning Sessions Page Styles + * Video Learning Sessions Page - Industrial Cyber Console + * 任务列表页面样式 */ -/* Sessions Grid */ -.sessions-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); - gap: 20px; - padding: 20px; +/* 导入核心样式 */ +@import url('./cyber-core.css'); + +/* ==================== 页面容器 ==================== */ +.sessions-page { + min-height: 100vh; + padding: 2rem; } -/* Session Card */ +/* ==================== 页面标题 ==================== */ +.page-header { + text-align: center; + margin-bottom: 3rem; + position: relative; +} + +.page-header h1 { + font-size: 2rem; + font-weight: 700; + color: var(--cyber-green); + text-transform: uppercase; + letter-spacing: 0.2em; + text-shadow: 0 0 30px var(--cyber-green-dim); + margin-bottom: 0.5rem; +} + +.page-header h1::before { + content: '>'; + margin-right: 0.75rem; + animation: blink 1s step-end infinite; +} + +.page-header p { + color: var(--cyber-text-secondary); + font-family: var(--cyber-font-mono); + font-size: 0.85rem; +} + +.page-header p::before { + content: '// '; + color: var(--cyber-green); +} + +/* ==================== Sessions Grid ==================== */ +.sessions-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); + gap: 1.5rem; + padding: 1rem 0; +} + +/* ==================== Session Card ==================== */ .session-card { - background: white; - border-radius: 8px; - padding: 20px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); - transition: transform 0.2s, box-shadow 0.2s; + background: linear-gradient(135deg, var(--cyber-bg-secondary) 0%, var(--cyber-bg-tertiary) 100%); + border: 1px solid var(--cyber-border); + padding: 1.5rem; + position: relative; + transition: var(--cyber-transition-normal); + overflow: hidden; +} + +.session-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: linear-gradient(90deg, transparent, var(--cyber-green), transparent); + opacity: 0; + transition: var(--cyber-transition-normal); +} + +.session-card::after { + content: ''; + position: absolute; + top: 1rem; + right: 1rem; + width: 8px; + height: 8px; + border-radius: 50%; + background: var(--cyber-text-muted); + box-shadow: 0 0 10px currentColor; + transition: var(--cyber-transition-normal); } .session-card:hover { - transform: translateY(-2px); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + border-color: var(--cyber-green); + box-shadow: 0 0 30px var(--cyber-green-dim); + transform: translateY(-4px); +} + +.session-card:hover::before { + opacity: 1; } .session-card.completed { - opacity: 0.8; + opacity: 0.7; } -/* Session Header */ +.session-card.completed::after { + background: var(--cyber-text-muted); +} + +/* ==================== Session Header ==================== */ .session-header { display: flex; justify-content: space-between; align-items: center; - margin-bottom: 12px; + margin-bottom: 1rem; + position: relative; } .session-platform { + font-size: 0.95rem; font-weight: 600; - font-size: 16px; display: flex; align-items: center; - gap: 8px; + gap: 0.75rem; + font-family: var(--cyber-font-display); + text-transform: uppercase; + letter-spacing: 0.1em; + color: var(--cyber-text-primary); } .session-platform::before { - content: ''; - width: 24px; - height: 24px; - background-size: contain; - background-repeat: no-repeat; + content: '◆'; + color: var(--cyber-green); + font-size: 0.7rem; } -/* Session Status */ +/* ==================== Session Status ==================== */ .session-status { - padding: 4px 12px; - border-radius: 12px; - font-size: 12px; - font-weight: 500; + padding: 0.3rem 0.75rem; + font-size: 0.65rem; + font-weight: 600; text-transform: uppercase; + letter-spacing: 0.1em; + font-family: var(--cyber-font-display); + border: 1px solid; } .session-status.status-active { - background: #10b981; - color: white; + background: var(--cyber-green-dim); + color: var(--cyber-green); + border-color: var(--cyber-green); + animation: pulse 2s infinite; } .session-status.status-paused { - background: #f59e0b; - color: white; + background: var(--cyber-amber-dim); + color: var(--cyber-amber); + border-color: var(--cyber-amber); } .session-status.status-completed { - background: #6b7280; - color: white; + background: rgba(148, 163, 184, 0.15); + color: var(--cyber-text-secondary); + border-color: var(--cyber-text-muted); } -/* Session ID */ +/* ==================== Session ID ==================== */ .session-id { - margin-bottom: 12px; - padding: 8px 12px; - background: #f3f4f6; - border-radius: 4px; + margin-bottom: 1rem; + padding: 0.75rem; + background: var(--cyber-bg-primary); + border: 1px solid var(--cyber-border); + position: relative; +} + +.session-id::before { + content: 'SESSION_ID'; + position: absolute; + top: -0.5rem; + left: 0.5rem; + background: var(--cyber-bg-secondary); + padding: 0 0.5rem; + font-size: 0.55rem; + font-family: var(--cyber-font-display); + color: var(--cyber-text-muted); + letter-spacing: 0.05em; } .session-id small { display: block; - font-size: 11px; - color: #6b7280; - margin-bottom: 4px; + font-size: 0.65rem; + color: var(--cyber-text-muted); + margin-bottom: 0.35rem; + font-family: var(--cyber-font-mono); +} + +.session-id small::before { + content: '// '; + color: var(--cyber-border-bright); } .session-id code { - font-family: 'Monaco', 'Consolas', monospace; - font-size: 12px; - color: #374151; + font-family: var(--cyber-font-mono); + font-size: 0.75rem; + color: var(--cyber-green); + word-break: break-all; + display: block; } -/* Session Progress */ +/* ==================== Session Progress ==================== */ .session-progress { - margin-bottom: 12px; + margin-bottom: 1rem; } .progress-info { display: flex; justify-content: space-between; - font-size: 14px; - color: #374151; - margin-bottom: 6px; + font-size: 0.75rem; + color: var(--cyber-text-secondary); + margin-bottom: 0.5rem; + font-family: var(--cyber-font-mono); +} + +.progress-info span:first-child::before { + content: 'PROGRESS::'; + color: var(--cyber-green); + margin-right: 0.35rem; } .progress-bar { - height: 8px; - background: #e5e7eb; - border-radius: 4px; + height: 6px; + background: var(--cyber-bg-primary); + border: 1px solid var(--cyber-border); overflow: hidden; + position: relative; +} + +.progress-bar::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: repeating-linear-gradient( + 90deg, + transparent, + transparent 2px, + rgba(0, 0, 0, 0.3) 2px, + rgba(0, 0, 0, 0.3) 4px + ); } .progress-fill { height: 100%; - background: linear-gradient(90deg, #3b82f6, #8b5cf6); - transition: width 0.3s ease; + background: linear-gradient(90deg, var(--cyber-green), var(--cyber-blue)); + transition: width 0.5s ease; + box-shadow: 0 0 10px var(--cyber-green-glow); + position: relative; } -/* Session Duration */ +.progress-fill::after { + content: ''; + position: absolute; + right: 0; + top: 0; + bottom: 0; + width: 15px; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3)); + animation: shimmer 2s infinite; +} + +/* ==================== Session Duration ==================== */ .session-duration { display: flex; align-items: center; - gap: 6px; - margin-bottom: 16px; - font-size: 14px; - color: #6b7280; + gap: 0.5rem; + margin-bottom: 1.25rem; + font-size: 0.75rem; + color: var(--cyber-text-muted); + font-family: var(--cyber-font-mono); } -/* Session Actions */ +.session-duration::before { + content: '⏱'; + color: var(--cyber-green); + font-size: 0.85rem; +} + +/* ==================== Session Actions ==================== */ .session-actions { display: flex; - gap: 8px; + gap: 0.5rem; flex-wrap: wrap; } .session-actions .btn { flex: 1; min-width: 80px; + font-size: 0.7rem; + padding: 0.5rem 0.75rem; } -/* Empty State */ +/* ==================== Empty State ==================== */ .empty-state { text-align: center; - padding: 80px 20px; - color: #6b7280; + padding: 6rem 2rem; + color: var(--cyber-text-muted); + position: relative; +} + +.empty-state::before { + content: ''; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 300px; + height: 300px; + border: 1px dashed var(--cyber-border); + border-radius: 50%; + animation: pulse 4s infinite; } .empty-state svg { - margin-bottom: 20px; - color: #d1d5db; + margin-bottom: 2rem; + color: var(--cyber-text-muted); + opacity: 0.3; + position: relative; + z-index: 1; } .empty-state h2 { - font-size: 24px; - margin-bottom: 8px; - color: #374151; + font-size: 1.5rem; + margin-bottom: 0.75rem; + color: var(--cyber-text-secondary); + font-family: var(--cyber-font-display); + text-transform: uppercase; + letter-spacing: 0.1em; + position: relative; + z-index: 1; } .empty-state p { - font-size: 16px; - margin-bottom: 24px; + font-size: 0.9rem; + margin-bottom: 2rem; + position: relative; + z-index: 1; } -/* Button Styles */ +.empty-state .btn { + position: relative; + z-index: 1; +} + +/* ==================== Button Styles ==================== */ .btn-sm { - padding: 6px 12px; - font-size: 13px; + padding: 0.5rem 0.75rem; + font-size: 0.7rem; } -/* Toast Notifications */ +/* ==================== Toast Notifications ==================== */ .toast-container { position: fixed; - bottom: 20px; - right: 20px; + bottom: 2rem; + right: 2rem; z-index: 1000; + display: flex; + flex-direction: column; + gap: 0.5rem; } .toast { - padding: 12px 20px; - border-radius: 6px; - margin-bottom: 10px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + padding: 0.75rem 1rem; + border: 1px solid; + font-size: 0.8rem; + font-family: var(--cyber-font-mono); + position: relative; + overflow: hidden; animation: slideIn 0.3s ease; + backdrop-filter: blur(10px); +} + +.toast::before { + content: ''; + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 3px; } .toast.info { - background: #3b82f6; - color: white; + background: var(--cyber-blue-dim); + color: var(--cyber-blue); + border-color: var(--cyber-blue); +} + +.toast.info::before { + background: var(--cyber-blue); } .toast.success { + background: rgba(16, 185, 129, 0.2); + color: #10b981; + border-color: #10b981; +} + +.toast.success::before { background: #10b981; - color: white; } .toast.error { - background: #ef4444; - color: white; + background: var(--cyber-red-dim); + color: var(--cyber-red); + border-color: var(--cyber-red); +} + +.toast.error::before { + background: var(--cyber-red); } @keyframes slideIn { @@ -216,12 +431,64 @@ } } -/* Responsive Design */ +/* ==================== Loading State ==================== */ +.loading-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 4rem 2rem; + color: var(--cyber-text-muted); +} + +.loading-state svg { + width: 48px; + height: 48px; + margin-bottom: 1rem; + color: var(--cyber-green); + animation: spin 1s linear infinite; +} + +.loading-state p { + font-family: var(--cyber-font-mono); + font-size: 0.85rem; +} + +.loading-state p::before { + content: 'LOADING...'; + color: var(--cyber-green); + animation: blink 1s step-end infinite; +} + +/* ==================== 装饰性元素 ==================== */ +.sessions-grid::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: + radial-gradient(circle at 20% 30%, rgba(0, 255, 159, 0.03) 0%, transparent 50%), + radial-gradient(circle at 80% 70%, rgba(0, 212, 255, 0.03) 0%, transparent 50%); + pointer-events: none; + z-index: -1; +} + +/* ==================== Responsive Design ==================== */ @media (max-width: 768px) { + .sessions-page { + padding: 1rem; + } + .sessions-grid { grid-template-columns: 1fr; } + .page-header h1 { + font-size: 1.5rem; + } + .session-actions { flex-direction: column; } @@ -229,4 +496,93 @@ .session-actions .btn { width: 100%; } + + .toast-container { + left: 1rem; + right: 1rem; + bottom: 1rem; + } +} + +/* ==================== 删除按钮特殊样式 ==================== */ +.btn-delete { + background: var(--cyber-red-dim); + color: var(--cyber-red); + border-color: var(--cyber-red); +} + +.btn-delete:hover:not(:disabled) { + background: var(--cyber-red); + color: white; + box-shadow: var(--cyber-glow-red); +} + +/* ==================== 详情按钮特殊样式 ==================== */ +.btn-details { + background: var(--cyber-blue-dim); + color: var(--cyber-blue); + border-color: var(--cyber-blue); +} + +.btn-details:hover:not(:disabled) { + background: var(--cyber-blue); + color: var(--cyber-bg-primary); + box-shadow: var(--cyber-glow-blue); +} + +/* ==================== 控制按钮 ==================== */ +.btn-control { + background: var(--cyber-green-dim); + color: var(--cyber-green); + border-color: var(--cyber-green); +} + +.btn-control:hover:not(:disabled) { + background: var(--cyber-green); + color: var(--cyber-bg-primary); + box-shadow: var(--cyber-glow-green); +} + +.btn-control.paused { + background: var(--cyber-amber-dim); + color: var(--cyber-amber); + border-color: var(--cyber-amber); +} + +.btn-control.paused:hover:not(:disabled) { + background: var(--cyber-amber); + color: var(--cyber-bg-primary); +} + +/* ==================== 过滤器样式 ==================== */ +.sessions-filter { + display: flex; + gap: 1rem; + margin-bottom: 2rem; + justify-content: center; + flex-wrap: wrap; +} + +.filter-btn { + padding: 0.5rem 1rem; + background: transparent; + border: 1px solid var(--cyber-border); + color: var(--cyber-text-secondary); + font-family: var(--cyber-font-display); + font-size: 0.75rem; + text-transform: uppercase; + letter-spacing: 0.05em; + cursor: pointer; + transition: var(--cyber-transition-fast); +} + +.filter-btn:hover { + border-color: var(--cyber-green); + color: var(--cyber-green); +} + +.filter-btn.active { + background: var(--cyber-green-dim); + border-color: var(--cyber-green); + color: var(--cyber-green); } diff --git a/dashboard/static/css/video-learning.css b/dashboard/static/css/video-learning.css index 8417779..d322723 100644 --- a/dashboard/static/css/video-learning.css +++ b/dashboard/static/css/video-learning.css @@ -1,20 +1,48 @@ -/* Video Learning Module Styles */ +/** + * Video Learning Page - Industrial Cyber Console + * 视频学习页面样式 + */ -/* Header modifications */ +/* 导入核心样式 */ +@import url('./cyber-core.css'); + +/* ==================== Header 特殊样式 ==================== */ .header h1 { display: flex; align-items: center; gap: 0.75rem; } -/* Configuration Section */ +/* ==================== 配置区域 ==================== */ .config-section { - background-color: var(--card-bg); - border: 1px solid var(--border-color); - border-radius: 12px; + background: linear-gradient(135deg, var(--cyber-bg-secondary) 0%, var(--cyber-bg-tertiary) 100%); + border: 1px solid var(--cyber-border); padding: 2rem; max-width: 800px; margin: 0 auto; + position: relative; +} + +.config-section::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, transparent, var(--cyber-green), transparent); +} + +.config-section::after { + content: 'CONFIG_MODE'; + position: absolute; + top: 0.5rem; + right: 1rem; + font-size: 0.6rem; + font-family: var(--cyber-font-display); + color: var(--cyber-green); + opacity: 0.5; + letter-spacing: 0.1em; } .config-form { @@ -27,39 +55,70 @@ display: flex; flex-direction: column; gap: 0.5rem; + position: relative; } .form-group label { - font-size: 0.875rem; + font-size: 0.8rem; font-weight: 500; - color: var(--text-primary); + font-family: var(--cyber-font-display); + color: var(--cyber-text-secondary); + text-transform: uppercase; + letter-spacing: 0.05em; + display: flex; + align-items: center; + gap: 0.5rem; +} + +.form-group label::before { + content: '>'; + color: var(--cyber-green); + font-size: 0.7rem; } .form-group select, -.form-group input { +.form-group input[type="text"], +.form-group input[type="number"] { padding: 0.75rem 1rem; - background-color: var(--bg-color); - border: 1px solid var(--border-color); - border-radius: 8px; - color: var(--text-primary); - font-size: 0.95rem; + background: var(--cyber-bg-primary); + border: 1px solid var(--cyber-border); + color: var(--cyber-text-primary); + font-size: 0.9rem; + font-family: var(--cyber-font-mono); + transition: var(--cyber-transition-fast); + position: relative; } .form-group select:focus, .form-group input:focus { outline: none; - border-color: var(--primary-color); + border-color: var(--cyber-green); + box-shadow: 0 0 15px var(--cyber-green-dim), inset 0 0 10px var(--cyber-green-dim); } .form-group select:disabled, .form-group input:disabled { - opacity: 0.5; + opacity: 0.4; cursor: not-allowed; } +.form-group select option { + background: var(--cyber-bg-secondary); + color: var(--cyber-text-primary); +} + .form-group small { - font-size: 0.75rem; - color: var(--text-secondary); + font-size: 0.7rem; + color: var(--cyber-text-muted); + font-family: var(--cyber-font-mono); + display: flex; + align-items: center; + gap: 0.5rem; +} + +.form-group small::before { + content: '//'; + color: var(--cyber-border-bright); } .form-row { @@ -68,12 +127,73 @@ gap: 1rem; } -/* Session Section */ +/* 复选框组 */ +.checkbox-group { + flex-direction: row; + align-items: center; + gap: 1rem !important; +} + +.checkbox-group label { + flex-direction: row; + cursor: pointer; +} + +.checkbox-group label::before { + display: none; +} + +.checkbox-group input[type="checkbox"] { + appearance: none; + width: 20px; + height: 20px; + border: 2px solid var(--cyber-border); + background: var(--cyber-bg-primary); + cursor: pointer; + position: relative; + transition: var(--cyber-transition-fast); +} + +.checkbox-group input[type="checkbox"]:checked { + background: var(--cyber-green); + border-color: var(--cyber-green); + box-shadow: 0 0 10px var(--cyber-green-glow); +} + +.checkbox-group input[type="checkbox"]:checked::after { + content: '✓'; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + color: var(--cyber-bg-primary); + font-size: 0.8rem; + font-weight: bold; +} + +.checkbox-group span { + font-size: 0.85rem; + color: var(--cyber-text-primary); +} + +/* ==================== 会话区域 ==================== */ .session-section { - background-color: var(--card-bg); - border: 1px solid var(--border-color); - border-radius: 12px; + background: linear-gradient(135deg, var(--cyber-bg-secondary) 0%, var(--cyber-bg-tertiary) 100%); + border: 1px solid var(--cyber-border); padding: 2rem; + position: relative; + overflow: hidden; +} + +.session-section::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, var(--cyber-green), var(--cyber-blue), var(--cyber-green)); + animation: dataFlow 3s linear infinite; } .session-header { @@ -81,12 +201,24 @@ justify-content: space-between; align-items: center; margin-bottom: 1.5rem; + position: relative; } .session-header h2 { - font-size: 1.25rem; + font-size: 1.1rem; font-weight: 600; - color: var(--text-primary); + color: var(--cyber-green); + text-transform: uppercase; + letter-spacing: 0.1em; + display: flex; + align-items: center; + gap: 0.75rem; +} + +.session-header h2::before { + content: '◆'; + font-size: 0.8rem; + animation: pulse 2s infinite; } .session-controls { @@ -94,71 +226,181 @@ gap: 0.5rem; } -/* Progress Section */ +/* ==================== 进度条 ==================== */ .progress-section { - background-color: var(--bg-color); - border-radius: 8px; + background: var(--cyber-bg-primary); + border: 1px solid var(--cyber-border); padding: 1.5rem; margin-bottom: 1.5rem; + position: relative; +} + +.progress-section::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 4px; + height: 100%; + background: linear-gradient(180deg, var(--cyber-green), transparent); } .progress-info { display: flex; justify-content: space-between; - margin-bottom: 0.5rem; - font-size: 0.875rem; - color: var(--text-secondary); + margin-bottom: 0.75rem; + font-size: 0.85rem; + color: var(--cyber-text-secondary); + font-family: var(--cyber-font-mono); +} + +.progress-info span:first-child::before { + content: 'PROGRESS::'; + color: var(--cyber-green); + margin-right: 0.5rem; +} + +.progress-info span:last-child::after { + content: '%'; + color: var(--cyber-green); } .progress-bar-large { - height: 8px; - background-color: rgba(99, 102, 241, 0.2); - border-radius: 4px; + height: 10px; + background: var(--cyber-bg-secondary); + border: 1px solid var(--cyber-border); overflow: hidden; + position: relative; +} + +.progress-bar-large::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: repeating-linear-gradient( + 90deg, + transparent, + transparent 4px, + rgba(0, 0, 0, 0.4) 4px, + rgba(0, 0, 0, 0.4) 8px + ); } .progress-fill { height: 100%; - background-color: var(--primary-color); - transition: width 0.3s ease; + background: linear-gradient(90deg, var(--cyber-green), var(--cyber-blue)); + transition: width 0.5s ease; + position: relative; + box-shadow: 0 0 15px var(--cyber-green-glow); +} + +.progress-fill::after { + content: ''; + position: absolute; + right: 0; + top: 0; + bottom: 0; + width: 20px; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3)); + animation: shimmer 1.5s infinite; +} + +@keyframes shimmer { + 0% { opacity: 0; } + 50% { opacity: 1; } + 100% { opacity: 0; } } .progress-stats { - margin-top: 0.5rem; - font-size: 0.8rem; - color: var(--text-secondary); + margin-top: 0.75rem; + font-size: 0.75rem; + color: var(--cyber-text-muted); + font-family: var(--cyber-font-mono); + display: flex; + align-items: center; + gap: 0.5rem; } -/* Current Video */ +.progress-stats::before { + content: '⏱'; + color: var(--cyber-green); +} + +/* ==================== 当前视频 ==================== */ .current-video { margin-bottom: 2rem; } .current-video h3 { - font-size: 1rem; + font-size: 0.95rem; font-weight: 600; - color: var(--text-primary); + color: var(--cyber-text-primary); margin-bottom: 1rem; + font-family: var(--cyber-font-display); + text-transform: uppercase; + letter-spacing: 0.1em; + display: flex; + align-items: center; + gap: 0.5rem; } -/* Video Cards */ +.current-video h3::before { + content: '▶'; + color: var(--cyber-green); + font-size: 0.7rem; +} + +/* ==================== 视频卡片 ==================== */ .video-card { - background-color: var(--bg-color); - border: 1px solid var(--border-color); - border-radius: 8px; + background: var(--cyber-bg-primary); + border: 1px solid var(--cyber-border); overflow: hidden; - transition: border-color 0.2s; + transition: var(--cyber-transition-normal); + position: relative; +} + +.video-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border: 1px solid transparent; + transition: var(--cyber-transition-normal); + pointer-events: none; } .video-card:hover { - border-color: var(--primary-color); + border-color: var(--cyber-green); + box-shadow: 0 0 20px var(--cyber-green-dim); +} + +.video-card:hover::before { + border-color: var(--cyber-green); + opacity: 0.3; } .video-screenshot { width: 100%; aspect-ratio: 9/16; - background-color: #000; + background: #000; overflow: hidden; + position: relative; +} + +.video-screenshot::after { + content: ''; + position: absolute; + top: 10px; + left: 10px; + right: 10px; + bottom: 10px; + border: 1px solid rgba(0, 255, 159, 0.2); + pointer-events: none; } .video-screenshot img { @@ -170,105 +412,180 @@ .video-placeholder { width: 100%; aspect-ratio: 9/16; - background-color: var(--bg-color); + background: var(--cyber-bg-secondary); display: flex; align-items: center; justify-content: center; - color: var(--text-secondary); + color: var(--cyber-text-muted); + position: relative; +} + +.video-placeholder::before { + content: 'NO_SIGNAL'; + position: absolute; + bottom: 1rem; + font-size: 0.6rem; + font-family: var(--cyber-font-display); + color: var(--cyber-red); + animation: blink 2s infinite; } .video-info { padding: 1rem; + background: var(--cyber-bg-secondary); + border-top: 1px solid var(--cyber-border); } .video-id { - font-size: 0.75rem; + font-size: 0.7rem; font-weight: 600; - color: var(--primary-color); + color: var(--cyber-green); margin-bottom: 0.5rem; + font-family: var(--cyber-font-mono); + display: flex; + align-items: center; + gap: 0.5rem; +} + +.video-id::before { + content: '#'; } .video-description { - font-size: 0.875rem; - color: var(--text-primary); - margin-bottom: 0.5rem; - line-height: 1.4; + font-size: 0.85rem; + color: var(--cyber-text-primary); + margin-bottom: 0.75rem; + line-height: 1.5; } .video-stats { display: flex; - gap: 1rem; + gap: 1.25rem; font-size: 0.75rem; - color: var(--text-secondary); + color: var(--cyber-text-secondary); } .video-stats span { display: flex; align-items: center; - gap: 0.25rem; + gap: 0.35rem; } .video-stats svg { - flex-shrink: 0; + color: var(--cyber-green); } -/* Category Badge */ +/* 分类标签 */ .video-category { - margin-top: 0.5rem; + margin-top: 0.75rem; } .category-badge { - display: inline-block; - padding: 0.2rem 0.5rem; - background-color: rgba(99, 102, 241, 0.2); - color: var(--primary-color); - border-radius: 4px; - font-size: 0.7rem; + display: inline-flex; + align-items: center; + padding: 0.25rem 0.6rem; + background: var(--cyber-green-dim); + color: var(--cyber-green); + border: 1px solid var(--cyber-green); + font-size: 0.65rem; font-weight: 500; + font-family: var(--cyber-font-display); + text-transform: uppercase; + letter-spacing: 0.05em; } -/* Tags */ +.category-badge::before { + content: '◆'; + margin-right: 0.35rem; + font-size: 0.5rem; +} + +/* 标签 */ .video-tags { display: flex; flex-wrap: wrap; - gap: 0.25rem; - margin-top: 0.5rem; + gap: 0.35rem; + margin-top: 0.75rem; } .video-tags .tag { font-size: 0.65rem; - color: var(--text-secondary); - background-color: var(--bg-color); - padding: 0.15rem 0.4rem; - border-radius: 3px; + color: var(--cyber-text-secondary); + background: var(--cyber-bg-primary); + padding: 0.2rem 0.5rem; + border: 1px solid var(--cyber-border); + font-family: var(--cyber-font-mono); } -/* Session Complete */ +.video-tags .tag::before { + content: '#'; + color: var(--cyber-green); +} + +/* ==================== 会话完成 ==================== */ .session-complete { text-align: center; padding: 3rem 2rem; + position: relative; +} + +.session-complete::before { + content: ''; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 250px; + height: 250px; + border: 2px solid var(--cyber-green); + border-radius: 50%; + opacity: 0.1; + animation: pulse 3s infinite; } .complete-icon { display: flex; justify-content: center; - margin-bottom: 1rem; - color: var(--success-color); + margin-bottom: 1.5rem; + position: relative; +} + +.complete-icon svg { + color: var(--cyber-green); + filter: drop-shadow(0 0 15px var(--cyber-green)); + animation: successPulse 2s ease-in-out infinite; +} + +@keyframes successPulse { + 0%, 100% { + transform: scale(1); + filter: drop-shadow(0 0 15px var(--cyber-green)); + } + 50% { + transform: scale(1.05); + filter: drop-shadow(0 0 25px var(--cyber-green)); + } } .session-complete h3 { font-size: 1.5rem; font-weight: 600; - color: var(--text-primary); - margin-bottom: 0.5rem; + color: var(--cyber-green); + margin-bottom: 0.75rem; + font-family: var(--cyber-font-display); + text-transform: uppercase; + letter-spacing: 0.1em; + text-shadow: 0 0 20px var(--cyber-green-dim); } .session-complete p { - color: var(--text-secondary); - margin-bottom: 1.5rem; + color: var(--cyber-text-secondary); + margin-bottom: 2rem; + font-family: var(--cyber-font-mono); + font-size: 0.9rem; } -/* Video Grid */ +/* ==================== 视频网格 ==================== */ .video-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); @@ -284,19 +601,31 @@ aspect-ratio: 9/16; } -/* History Section */ +/* ==================== 历史记录 ==================== */ .history-section { margin-top: 2rem; } .history-section h2 { - font-size: 1.25rem; + font-size: 1.1rem; font-weight: 600; - color: var(--text-primary); + color: var(--cyber-text-primary); margin-bottom: 1rem; + font-family: var(--cyber-font-display); + text-transform: uppercase; + letter-spacing: 0.1em; + display: flex; + align-items: center; + gap: 0.75rem; } -/* Responsive */ +.history-section h2::before { + content: '◆'; + color: var(--cyber-green); + font-size: 0.8rem; +} + +/* ==================== 响应式 ==================== */ @media (max-width: 768px) { .form-row { grid-template-columns: 1fr; @@ -311,4 +640,9 @@ .video-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); } + + .config-section, + .session-section { + padding: 1.5rem; + } }