diff --git a/static/index.html b/static/index.html index c44aa84..c8b759f 100644 --- a/static/index.html +++ b/static/index.html @@ -5,15 +5,14 @@ Gemold - 模具制造管理系统 - - -
-
-
- 加载中... +
+
+
+

加载中...

+
diff --git a/static/style.css b/static/style.css index 25890a0..a549e00 100644 --- a/static/style.css +++ b/static/style.css @@ -1,82 +1,65 @@ /** - * STP模具几何分析中心 - 现代简约设计系统 - * 版本: 5.0.0 - Modern Minimal UI - * 设计灵感: Linear, Notion, Vercel, Stripe + * MoldInsight - 白色简约现代设计系统 + * 版本: 6.0.0 - Clean White Modern UI + * 设计理念: 极简、纯净、专业 */ /* ================================ - 设计系统变量 - 现代简约风格 + 设计系统变量 - 白色简约风格 ================================ */ :root { - /* 主色调 - 现代蓝紫渐变系 */ - --primary-50: #f0f5ff; - --primary-100: #e0eaff; - --primary-200: #c7d7fe; - --primary-300: #a4bcfd; - --primary-400: #7c96fb; - --primary-500: #5a6ff5; - --primary-600: #4a4ee0; - --primary-700: #3d3dc7; - --primary-800: #3535a5; - --primary-900: #2e2e87; + /* 主色调 - 深蓝专业色 */ + --primary-50: #eff6ff; + --primary-100: #dbeafe; + --primary-200: #bfdbfe; + --primary-300: #93c5fd; + --primary-400: #60a5fa; + --primary-500: #3b82f6; + --primary-600: #2563eb; + --primary-700: #1d4ed8; + --primary-800: #1e40af; + --primary-900: #1e3a8a; - /* 中性灰色系 - 现代冷灰 */ + /* 中性灰色系 */ --gray-50: #fafafa; - --gray-100: #f4f4f5; - --gray-200: #e4e4e7; - --gray-300: #d4d4d8; - --gray-400: #a1a1aa; - --gray-500: #71717a; - --gray-600: #52525b; - --gray-700: #3f3f46; - --gray-800: #27272a; - --gray-900: #18181b; - - /* 强调色 - 翡翠绿 */ - --accent-50: #ecfdf5; - --accent-100: #d1fae5; - --accent-200: #a7f3d0; - --accent-300: #6ee7b7; - --accent-400: #34d399; - --accent-500: #10b981; - --accent-600: #059669; - --accent-700: #047857; + --gray-100: #f5f5f5; + --gray-200: #e5e5e5; + --gray-300: #d4d4d4; + --gray-400: #a3a3a3; + --gray-500: #737373; + --gray-600: #525252; + --gray-700: #404040; + --gray-800: #262626; + --gray-900: #171717; /* 状态色 */ - --success: #10b981; - --success-bg: #ecfdf5; - --warning: #f59e0b; - --warning-bg: #fffbeb; + --success: #22c55e; + --success-bg: #f0fdf4; + --warning: #eab308; + --warning-bg: #fefce8; --error: #ef4444; --error-bg: #fef2f2; --info: #3b82f6; --info-bg: #eff6ff; /* 文字颜色 */ - --text-primary: #18181b; - --text-secondary: #3f3f46; - --text-tertiary: #71717a; - --text-muted: #a1a1aa; - --text-inverse: #fafafa; + --text-primary: #171717; + --text-secondary: #404040; + --text-tertiary: #737373; + --text-muted: #a3a3a3; + --text-inverse: #ffffff; /* 背景色 */ --bg-primary: #ffffff; --bg-secondary: #fafafa; - --bg-tertiary: #f4f4f5; + --bg-tertiary: #f5f5f5; --bg-elevated: #ffffff; - --bg-overlay: rgba(0, 0, 0, 0.5); + --bg-overlay: rgba(0, 0, 0, 0.4); /* 边框 */ - --border-light: #e4e4e7; - --border-default: #d4d4d8; - --border-strong: #a1a1aa; - - /* 渐变 */ - --gradient-primary: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - --gradient-accent: linear-gradient(135deg, #10b981 0%, #059669 100%); - --gradient-hero: linear-gradient(135deg, #f5f7fa 0%, #e4e8f0 100%); - --gradient-card: linear-gradient(180deg, #ffffff 0%, #fafafa 100%); - --gradient-shine: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent); + --border-light: #f0f0f0; + --border-default: #e5e5e5; + --border-strong: #d4d4d4; /* 间距系统 */ --space-1: 0.25rem; @@ -91,8 +74,8 @@ --space-16: 4rem; /* 字体 */ - --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; - --font-mono: 'JetBrains Mono', 'Fira Code', Consolas, monospace; + --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; + --font-mono: 'SF Mono', Monaco, Consolas, monospace; /* 字号 */ --text-xs: 0.75rem; @@ -103,7 +86,6 @@ --text-2xl: 1.5rem; --text-3xl: 1.875rem; --text-4xl: 2.25rem; - --text-5xl: 3rem; /* 字重 */ --font-normal: 400; @@ -111,20 +93,12 @@ --font-semibold: 600; --font-bold: 700; - /* 行高 */ - --leading-tight: 1.25; - --leading-normal: 1.5; - --leading-relaxed: 1.625; - - /* 阴影 - 现代柔和阴影 */ - --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.05); - --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06); - --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); - --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); - --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); - --shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25); - --shadow-inner: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); - --shadow-glow: 0 0 40px rgba(99, 102, 241, 0.15); + /* 阴影 - 极简阴影 */ + --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.04); + --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.06); + --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.06); + --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.08); + --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1); /* 圆角 */ --radius-sm: 0.375rem; @@ -132,15 +106,10 @@ --radius-lg: 0.75rem; --radius-xl: 1rem; --radius-2xl: 1.25rem; - --radius-3xl: 1.5rem; --radius-full: 9999px; /* 动画 */ --ease-default: cubic-bezier(0.4, 0, 0.2, 1); - --ease-in: cubic-bezier(0.4, 0, 1, 1); - --ease-out: cubic-bezier(0, 0, 0.2, 1); - --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); - --ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55); --duration-fast: 150ms; --duration-normal: 200ms; --duration-slow: 300ms; @@ -157,7 +126,6 @@ html { font-size: 16px; - scroll-behavior: smooth; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } @@ -172,63 +140,20 @@ body { } /* ================================ - 排版 - ================================ */ -h1, h2, h3, h4, h5, h6 { - font-weight: var(--font-semibold); - line-height: var(--leading-tight); - color: var(--text-primary); -} - -h1 { font-size: var(--text-4xl); } -h2 { font-size: var(--text-3xl); } -h3 { font-size: var(--text-2xl); } -h4 { font-size: var(--text-xl); } -h5 { font-size: var(--text-lg); } -h6 { font-size: var(--text-base); } - -p { - color: var(--text-secondary); - line-height: var(--leading-relaxed); -} - -a { - color: var(--primary-600); - text-decoration: none; - transition: color var(--duration-fast) var(--ease-default); -} - -a:hover { - color: var(--primary-700); -} - -/* ================================ - 主布局容器 + 应用容器 ================================ */ .app-container { min-height: 100vh; + display: flex; + flex-direction: column; background: var(--bg-secondary); } -.main-content { - max-width: 1400px; - margin: 0 auto; - padding: var(--space-6); -} - -@media (min-width: 768px) { - .main-content { - padding: var(--space-8); - } -} - /* ================================ - 头部导航 + 顶部导航栏 ================================ */ .app-header { - background: rgba(255, 255, 255, 0.8); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); + background: var(--bg-primary); border-bottom: 1px solid var(--border-light); position: sticky; top: 0; @@ -238,7 +163,8 @@ a:hover { .header-content { max-width: 1400px; margin: 0 auto; - padding: var(--space-4) var(--space-6); + padding: 0 var(--space-6); + height: 64px; display: flex; align-items: center; justify-content: space-between; @@ -248,58 +174,51 @@ a:hover { display: flex; align-items: center; gap: var(--space-3); + cursor: pointer; } .logo-icon { - width: 40px; - height: 40px; - background: var(--gradient-primary); + width: 36px; + height: 36px; + background: var(--primary-500); border-radius: var(--radius-lg); display: flex; align-items: center; justify-content: center; - font-size: 1.25rem; color: white; - box-shadow: var(--shadow-md); + font-size: var(--text-lg); + font-weight: var(--font-bold); } .logo-text { font-size: var(--text-xl); - font-weight: var(--font-bold); - background: var(--gradient-primary); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; + font-weight: var(--font-semibold); + color: var(--text-primary); } .logo-subtitle { font-size: var(--text-xs); color: var(--text-tertiary); - text-transform: uppercase; - letter-spacing: 0.1em; - margin-top: 2px; } -/* 导航菜单 */ .nav-menu { display: flex; - gap: var(--space-2); + align-items: center; + gap: var(--space-1); } .nav-item { padding: var(--space-2) var(--space-4); border-radius: var(--radius-md); + color: var(--text-secondary); + text-decoration: none; font-size: var(--text-sm); font-weight: var(--font-medium); - color: var(--text-secondary); - cursor: pointer; transition: all var(--duration-fast) var(--ease-default); - border: none; - background: transparent; } .nav-item:hover { - background: var(--gray-100); + background: var(--bg-tertiary); color: var(--text-primary); } @@ -308,148 +227,65 @@ a:hover { color: var(--primary-600); } -/* 用户信息 */ .user-section { display: flex; align-items: center; gap: var(--space-4); } -.status-badge { +.user-info { display: flex; align-items: center; - gap: var(--space-2); - padding: var(--space-2) var(--space-3); - background: var(--accent-50); + gap: var(--space-3); +} + +.user-avatar { + width: 32px; + height: 32px; + background: var(--primary-100); + color: var(--primary-600); border-radius: var(--radius-full); - font-size: var(--text-sm); - color: var(--accent-700); -} - -.status-dot { - width: 8px; - height: 8px; - background: var(--accent-500); - border-radius: 50%; - animation: pulse-dot 2s infinite; -} - -@keyframes pulse-dot { - 0%, 100% { opacity: 1; transform: scale(1); } - 50% { opacity: 0.7; transform: scale(1.2); } -} - -/* ================================ - 统计卡片区域 - ================================ */ -.stats-grid { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: var(--space-4); - margin-bottom: var(--space-8); -} - -@media (max-width: 1024px) { - .stats-grid { - grid-template-columns: repeat(2, 1fr); - } -} - -@media (max-width: 640px) { - .stats-grid { - grid-template-columns: 1fr; - } -} - -.stat-card { - background: var(--bg-primary); - border-radius: var(--radius-xl); - padding: var(--space-5); - border: 1px solid var(--border-light); - transition: all var(--duration-normal) var(--ease-default); - position: relative; - overflow: hidden; -} - -.stat-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 3px; - background: var(--gradient-primary); - opacity: 0; - transition: opacity var(--duration-normal) var(--ease-default); -} - -.stat-card:hover { - border-color: var(--primary-200); - box-shadow: var(--shadow-lg); - transform: translateY(-2px); -} - -.stat-card:hover::before { - opacity: 1; -} - -.stat-icon { - width: 44px; - height: 44px; - border-radius: var(--radius-lg); display: flex; align-items: center; justify-content: center; - font-size: 1.25rem; - margin-bottom: var(--space-3); -} - -.stat-card:nth-child(1) .stat-icon { - background: var(--primary-50); - color: var(--primary-600); -} - -.stat-card:nth-child(2) .stat-icon { - background: var(--accent-50); - color: var(--accent-600); -} - -.stat-card:nth-child(3) .stat-icon { - background: var(--warning-bg); - color: var(--warning); -} - -.stat-card:nth-child(4) .stat-icon { - background: var(--info-bg); - color: var(--info); -} - -.stat-value { - font-size: var(--text-3xl); - font-weight: var(--font-bold); - color: var(--text-primary); - line-height: 1; - margin-bottom: var(--space-1); -} - -.stat-label { font-size: var(--text-sm); - color: var(--text-tertiary); + font-weight: var(--font-medium); +} + +.user-name { + font-size: var(--text-sm); + font-weight: var(--font-medium); + color: var(--text-primary); } /* ================================ - 主内容区域布局 + 主内容区 ================================ */ -.content-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: var(--space-6); +.main-content { + flex: 1; + max-width: 1400px; + width: 100%; + margin: 0 auto; + padding: var(--space-8) var(--space-6); } -@media (max-width: 1024px) { - .content-grid { - grid-template-columns: 1fr; - } +/* ================================ + 页面标题 + ================================ */ +.page-header { + margin-bottom: var(--space-8); +} + +.page-title { + font-size: var(--text-3xl); + font-weight: var(--font-bold); + color: var(--text-primary); + margin-bottom: var(--space-2); +} + +.page-subtitle { + font-size: var(--text-base); + color: var(--text-tertiary); } /* ================================ @@ -457,191 +293,75 @@ a:hover { ================================ */ .card { background: var(--bg-primary); - border-radius: var(--radius-xl); border: 1px solid var(--border-light); - overflow: hidden; - transition: all var(--duration-normal) var(--ease-default); -} - -.card:hover { - box-shadow: var(--shadow-lg); + border-radius: var(--radius-xl); + padding: var(--space-6); + margin-bottom: var(--space-6); } .card-header { - padding: var(--space-5) var(--space-6); - border-bottom: 1px solid var(--border-light); display: flex; align-items: center; justify-content: space-between; + margin-bottom: var(--space-4); + padding-bottom: var(--space-4); + border-bottom: 1px solid var(--border-light); } .card-title { - display: flex; - align-items: center; - gap: var(--space-3); font-size: var(--text-lg); font-weight: var(--font-semibold); color: var(--text-primary); } -.card-title-icon { - width: 32px; - height: 32px; - background: var(--gray-100); - border-radius: var(--radius-md); - display: flex; - align-items: center; - justify-content: center; - font-size: 1rem; -} - .card-body { - padding: var(--space-6); + padding: var(--space-2) 0; } /* ================================ - 上传区域 - ================================ */ -.upload-zone { - display: block; - border: 2px dashed var(--border-default); - border-radius: var(--radius-xl); - padding: var(--space-10); - text-align: center; - transition: all var(--duration-normal) var(--ease-default); - cursor: pointer; - background: var(--bg-secondary); - position: relative; - overflow: hidden; -} - -.upload-zone::before { - content: ''; - position: absolute; - inset: 0; - background: var(--primary-50); - opacity: 0; - transition: opacity var(--duration-normal) var(--ease-default); - pointer-events: none; -} - -.upload-zone:hover { - border-color: var(--primary-400); -} - -.upload-zone:hover::before { - opacity: 1; -} - -.upload-zone.drag-over { - border-color: var(--primary-400); - transform: scale(1.01); -} - -.upload-zone.drag-over::before { - opacity: 1; -} - -.upload-zone > * { - position: relative; - z-index: 1; -} - -.upload-icon { - width: 64px; - height: 64px; - margin: 0 auto var(--space-4); - background: var(--gradient-primary); - border-radius: var(--radius-xl); - display: flex; - align-items: center; - justify-content: center; - font-size: 2rem; - color: white; - box-shadow: var(--shadow-lg); -} - -.upload-title { - font-size: var(--text-lg); - font-weight: var(--font-semibold); - color: var(--text-primary); - margin-bottom: var(--space-2); -} - -.upload-hint { - font-size: var(--text-sm); - color: var(--text-tertiary); - margin-bottom: var(--space-4); -} - -.upload-formats { - display: flex; - justify-content: center; - gap: var(--space-2); - flex-wrap: wrap; -} - -.format-tag { - padding: var(--space-1) var(--space-3); - background: var(--gray-100); - border-radius: var(--radius-full); - font-size: var(--text-xs); - font-weight: var(--font-medium); - color: var(--text-secondary); -} - -/* ================================ - 按钮样式 + 按钮组件 ================================ */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); - padding: var(--space-4) var(--space-6); - font-size: var(--text-base); + padding: var(--space-3) var(--space-5); + font-size: var(--text-sm); font-weight: var(--font-medium); - border-radius: var(--radius-lg); + border-radius: var(--radius-md); border: none; cursor: pointer; transition: all var(--duration-fast) var(--ease-default); - white-space: nowrap; + text-decoration: none; } .btn-primary { - background: var(--gradient-primary); + background: var(--primary-500); color: white; - box-shadow: var(--shadow-md); } .btn-primary:hover { - transform: translateY(-1px); - box-shadow: var(--shadow-lg); -} - -.btn-primary:active { - transform: translateY(0); + background: var(--primary-600); } .btn-secondary { - background: var(--bg-primary); + background: var(--bg-tertiary); color: var(--text-primary); border: 1px solid var(--border-default); } .btn-secondary:hover { - background: var(--gray-50); - border-color: var(--border-strong); + background: var(--gray-200); } -.btn-ghost { - background: transparent; - color: var(--text-secondary); +.btn-danger { + background: var(--error); + color: white; } -.btn-ghost:hover { - background: var(--gray-100); - color: var(--text-primary); +.btn-danger:hover { + background: #dc2626; } .btn-lg { @@ -649,296 +369,120 @@ a:hover { font-size: var(--text-base); } -.btn-full { - width: 100%; +.btn-sm { + padding: var(--space-2) var(--space-3); + font-size: var(--text-xs); } .btn:disabled { opacity: 0.5; cursor: not-allowed; - transform: none !important; } /* ================================ - 文件列表 + 表单组件 ================================ */ -.file-list { - display: flex; - flex-direction: column; - gap: var(--space-3); +.form-group { + margin-bottom: var(--space-5); } -.file-item { - display: flex; - align-items: center; - gap: var(--space-4); - padding: var(--space-4); - background: var(--bg-secondary); - border-radius: var(--radius-lg); - border: 1px solid transparent; - cursor: pointer; +.form-label { + display: block; + font-size: var(--text-sm); + font-weight: var(--font-medium); + color: var(--text-primary); + margin-bottom: var(--space-2); +} + +.form-input { + width: 100%; + padding: var(--space-3) var(--space-4); + font-size: var(--text-base); + color: var(--text-primary); + background: var(--bg-primary); + border: 1px solid var(--border-default); + border-radius: var(--radius-md); transition: all var(--duration-fast) var(--ease-default); } -.file-item:hover { - background: var(--bg-primary); - border-color: var(--primary-200); - box-shadow: var(--shadow-sm); +.form-input:focus { + outline: none; + border-color: var(--primary-500); + box-shadow: 0 0 0 3px var(--primary-100); } -.file-icon { - width: 44px; - height: 44px; - background: var(--primary-50); - border-radius: var(--radius-lg); - display: flex; - align-items: center; - justify-content: center; - font-size: 1.25rem; - color: var(--primary-600); - flex-shrink: 0; +.form-input::placeholder { + color: var(--text-muted); } -.file-info { - flex: 1; - min-width: 0; -} - -.file-name { - font-weight: var(--font-medium); - color: var(--text-primary); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.file-meta { - display: flex; - gap: var(--space-4); +.form-error { font-size: var(--text-sm); - color: var(--text-tertiary); + color: var(--error); margin-top: var(--space-1); } -.file-actions { - display: flex; - gap: var(--space-2); -} - /* ================================ - 分析结果区域 + 上传区域 ================================ */ -.result-section { - margin-top: var(--space-8); -} - -.result-header { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: var(--space-6); -} - -.result-title { - display: flex; - align-items: center; - gap: var(--space-3); - font-size: var(--text-2xl); - font-weight: var(--font-bold); -} - -.result-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); - gap: var(--space-4); -} - -.result-card.full-width { - grid-column: 1 / -1; -} - -.result-card { - background: var(--bg-primary); +.upload-zone { + border: 2px dashed var(--border-strong); border-radius: var(--radius-xl); - padding: var(--space-5); - border: 1px solid var(--border-light); - transition: all var(--duration-normal) var(--ease-default); -} - -.result-card:hover { - box-shadow: var(--shadow-md); - border-color: var(--primary-200); -} - -.result-card-header { - display: flex; - align-items: center; - gap: var(--space-3); - margin-bottom: var(--space-4); -} - -.result-card-icon { - width: 40px; - height: 40px; - border-radius: var(--radius-lg); - display: flex; - align-items: center; - justify-content: center; - font-size: 1.125rem; -} - -.result-card-title { - font-size: var(--text-sm); - font-weight: var(--font-medium); - color: var(--text-secondary); -} - -.result-card-value { - font-size: var(--text-2xl); - font-weight: var(--font-bold); - color: var(--text-primary); -} - -/* ================================ - 设计建议列表 - ================================ */ -.recommendations-section { - margin-top: var(--space-6); - padding-top: var(--space-6); - border-top: 1px solid var(--border-light); -} - -.recommendations-section h5 { - font-size: var(--text-base); - font-weight: var(--font-semibold); - color: var(--text-primary); - margin-bottom: var(--space-4); -} - -.recommendations-list { - display: flex; - flex-direction: column; - gap: var(--space-3); -} - -.recommendation-item { - display: flex; - align-items: flex-start; - gap: var(--space-3); - padding: var(--space-3); - background: var(--bg-secondary); - border-radius: var(--radius-lg); - border-left: 4px solid var(--gray-300); + padding: var(--space-12); + text-align: center; + cursor: pointer; transition: all var(--duration-fast) var(--ease-default); + background: var(--bg-primary); + position: relative; } -.recommendation-item:hover { - background: var(--gray-50); - transform: translateX(2px); +.upload-zone:hover { + border-color: var(--primary-400); + background: var(--primary-50); } -.recommendation-item.critical { - border-left-color: var(--red-500); - background: linear-gradient(90deg, var(--red-50), transparent); +.upload-zone.dragover { + border-color: var(--primary-500); + background: var(--primary-100); } -.recommendation-item.high { - border-left-color: var(--orange-500); - background: linear-gradient(90deg, var(--orange-50), transparent); +.upload-icon { + width: 48px; + height: 48px; + margin: 0 auto var(--space-4); + color: var(--text-muted); } -.recommendation-item.medium { - border-left-color: var(--blue-500); - background: linear-gradient(90deg, var(--blue-50), transparent); -} - -.recommendation-item.low { - border-left-color: var(--green-500); - background: linear-gradient(90deg, var(--green-50), transparent); -} - -.priority-badge { - display: inline-flex; - align-items: center; - padding: var(--space-1) var(--space-2); - font-size: var(--text-xs); - font-weight: var(--font-semibold); - border-radius: var(--radius-full); - white-space: nowrap; - flex-shrink: 0; -} - -.priority-badge.critical { - background: var(--red-500); - color: white; -} - -.priority-badge.high { - background: var(--orange-500); - color: white; -} - -.priority-badge.medium { - background: var(--blue-500); - color: white; -} - -.priority-badge.low { - background: var(--green-500); - color: white; -} - -.recommendation-text { - flex: 1; - font-size: var(--text-sm); - color: var(--text-primary); - line-height: 1.5; -} - -.recommendation-reason { - font-size: var(--text-xs); - color: var(--text-tertiary); - font-style: italic; -} - -/* ================================ - 分析摘要 - ================================ */ -.analysis-summary { - background: linear-gradient(135deg, var(--blue-50), var(--purple-50)); - border: 1px solid var(--border-light); - border-radius: var(--radius-xl); - padding: var(--space-6); - margin-bottom: var(--space-6); - box-shadow: var(--shadow-sm); -} - -.summary-header { - display: flex; - align-items: center; - gap: var(--space-3); - margin-bottom: var(--space-3); -} - -.summary-header h4 { - font-size: var(--text-lg); - font-weight: var(--font-semibold); - color: var(--text-primary); - margin: 0; -} - -.summary-icon { - font-size: var(--text-xl); -} - -.summary-content { +.upload-text { font-size: var(--text-base); color: var(--text-secondary); - line-height: 1.6; + margin-bottom: var(--space-2); +} + +.upload-hint { + font-size: var(--text-sm); + color: var(--text-muted); } /* ================================ - 数据表格 + 进度条 + ================================ */ +.progress-bar { + width: 100%; + height: 8px; + background: var(--bg-tertiary); + border-radius: var(--radius-full); + overflow: hidden; +} + +.progress-fill { + height: 100%; + background: var(--primary-500); + border-radius: var(--radius-full); + transition: width var(--duration-normal) var(--ease-default); +} + +/* ================================ + 表格 ================================ */ .data-table { width: 100%; @@ -957,8 +501,6 @@ a:hover { font-weight: var(--font-medium); color: var(--text-tertiary); background: var(--bg-secondary); - text-transform: uppercase; - letter-spacing: 0.05em; } .data-table td { @@ -966,22 +508,17 @@ a:hover { color: var(--text-primary); } -.data-table tbody tr { - transition: background var(--duration-fast) var(--ease-default); -} - .data-table tbody tr:hover { - background: var(--gray-50); + background: var(--bg-secondary); } /* ================================ - 标签和徽章 + 徽章 ================================ */ .badge { display: inline-flex; align-items: center; - gap: var(--space-1); - padding: var(--space-1) var(--space-3); + padding: var(--space-1) var(--space-2); font-size: var(--text-xs); font-weight: var(--font-medium); border-radius: var(--radius-full); @@ -1007,182 +544,8 @@ a:hover { color: var(--info); } -.badge-neutral { - background: var(--gray-100); - color: var(--text-secondary); -} - /* ================================ - 模态框 - ================================ */ -.modal-overlay { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.5); - display: flex; - align-items: center; - justify-content: center; - z-index: 1000; - animation: fadeIn 0.2s ease; -} - -.modal-content { - background: var(--bg-primary); - border-radius: var(--radius-lg); - width: 90%; - max-width: 500px; - max-height: 90vh; - overflow: auto; - animation: slideUp 0.3s ease; -} - -.modal-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: var(--space-6); - border-bottom: 1px solid var(--border-light); -} - -.modal-header h2 { - font-size: var(--text-xl); - font-weight: 600; -} - -.modal-close { - width: 32px; - height: 32px; - display: flex; - align-items: center; - justify-content: center; - border: none; - background: transparent; - color: var(--text-secondary); - font-size: 24px; - cursor: pointer; - border-radius: var(--radius-md); - transition: all 0.2s; -} - -.modal-close:hover { - background: var(--gray-100); - color: var(--text-primary); -} - -.modal-body { - padding: var(--space-6); -} - -.modal-footer { - display: flex; - gap: var(--space-3); - justify-content: flex-end; - padding: var(--space-6); - border-top: 1px solid var(--border-light); -} - -/* ================================ - 复选框组 - ================================ */ -.checkbox-group { - display: flex; - flex-wrap: wrap; - gap: var(--space-3); -} - -.checkbox-label { - display: flex; - align-items: center; - gap: var(--space-2); - padding: var(--space-2) var(--space-3); - background: var(--gray-100); - border-radius: var(--radius-md); - cursor: pointer; - transition: all 0.2s; -} - -.checkbox-label:hover { - background: var(--gray-200); -} - -.checkbox-label input[type="checkbox"] { - width: 16px; - height: 16px; - cursor: pointer; -} - -/* ================================ - 按钮变体 - ================================ */ -.btn-error { - background: var(--error); - color: white; - border: none; - padding: var(--space-2) var(--space-4); - border-radius: var(--radius-md); - font-size: var(--text-sm); - cursor: pointer; - transition: all 0.2s; -} - -.btn-error:hover { - background: #dc2626; -} - -.btn-secondary { - background: var(--gray-200); - color: var(--text-primary); - border: none; - padding: var(--space-2) var(--space-4); - border-radius: var(--radius-md); - font-size: var(--text-sm); - cursor: pointer; - transition: all 0.2s; -} - -.btn-secondary:hover { - background: var(--gray-300); -} - -/* ================================ - 进度条 - ================================ */ -.progress-bar { - height: 8px; - background: var(--gray-200); - border-radius: var(--radius-full); - overflow: hidden; -} - -.progress-fill { - height: 100%; - background: var(--gradient-primary); - border-radius: var(--radius-full); - transition: width var(--duration-slow) var(--ease-default); - position: relative; -} - -.progress-fill::after { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: var(--gradient-shine); - animation: shimmer 2s infinite; -} - -@keyframes shimmer { - 0% { transform: translateX(-100%); } - 100% { transform: translateX(100%); } -} - -/* ================================ - 通知消息 + 通知提示 ================================ */ .notification-container { position: fixed; @@ -1192,7 +555,6 @@ a:hover { display: flex; flex-direction: column; gap: var(--space-3); - pointer-events: none; } .notification { @@ -1201,89 +563,371 @@ a:hover { gap: var(--space-3); padding: var(--space-4); background: var(--bg-primary); - border-radius: var(--radius-lg); - box-shadow: var(--shadow-xl); border: 1px solid var(--border-light); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-lg); min-width: 320px; - max-width: 420px; - pointer-events: auto; - animation: slideIn var(--duration-normal) var(--ease-out); -} - -@keyframes slideIn { - from { - opacity: 0; - transform: translateX(100%); - } - to { - opacity: 1; - transform: translateX(0); - } + max-width: 400px; } .notification-icon { - width: 24px; - height: 24px; - border-radius: var(--radius-full); - display: flex; - align-items: center; - justify-content: center; - font-size: 0.875rem; + width: 20px; + height: 20px; flex-shrink: 0; } -.notification-success .notification-icon { - background: var(--success-bg); - color: var(--success); -} - -.notification-error .notification-icon { - background: var(--error-bg); - color: var(--error); -} - -.notification-warning .notification-icon { - background: var(--warning-bg); - color: var(--warning); -} - -.notification-info .notification-icon { - background: var(--info-bg); - color: var(--info); -} - .notification-content { flex: 1; } -.notification-title { - font-weight: var(--font-medium); - color: var(--text-primary); - margin-bottom: var(--space-1); -} - .notification-message { font-size: var(--text-sm); - color: var(--text-secondary); + color: var(--text-primary); } .notification-close { - width: 24px; - height: 24px; - border-radius: var(--radius-md); + width: 20px; + height: 20px; border: none; background: transparent; color: var(--text-muted); cursor: pointer; + padding: 0; +} + +.notification-success { + border-left: 3px solid var(--success); +} + +.notification-error { + border-left: 3px solid var(--error); +} + +.notification-warning { + border-left: 3px solid var(--warning); +} + +/* ================================ + 结果展示区 + ================================ */ +.viewer-section { + background: var(--bg-primary); + border: 1px solid var(--border-light); + border-radius: var(--radius-xl); + padding: var(--space-6); + margin-bottom: var(--space-6); +} + +.viewer-section h3 { + font-size: var(--text-lg); + font-weight: var(--font-semibold); + color: var(--text-primary); + margin-bottom: var(--space-4); +} + +.viewer-section h4 { + font-size: var(--text-base); + font-weight: var(--font-semibold); + color: var(--text-primary); + margin-bottom: var(--space-3); +} + +.viewer-frame { + width: 100%; + height: 500px; + border: 1px solid var(--border-light); + border-radius: var(--radius-lg); +} + +/* ================================ + 结果网格 + ================================ */ +.result-grid { + display: grid; + grid-template-columns: repeat(1, 1fr); + gap: var(--space-6); +} + +@media (min-width: 768px) { + .result-grid { + grid-template-columns: repeat(2, 1fr); + } +} + +.result-card { + background: var(--bg-secondary); + border-radius: var(--radius-lg); + padding: var(--space-5); +} + +.result-card.full-width { + grid-column: 1 / -1; +} + +/* ================================ + 信息列表 + ================================ */ +.info-list { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: var(--space-3); +} + +@media (max-width: 640px) { + .info-list { + grid-template-columns: 1fr; + } +} + +.info-item { + display: flex; + flex-direction: column; + gap: var(--space-1); +} + +.info-label { + font-size: var(--text-xs); + color: var(--text-tertiary); + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.info-value { + font-size: var(--text-sm); + color: var(--text-primary); + font-weight: var(--font-medium); +} + +/* ================================ + 分析摘要 + ================================ */ +.analysis-summary { + background: var(--primary-50); + border: 1px solid var(--primary-100); + border-radius: var(--radius-lg); + padding: var(--space-5); + margin-bottom: var(--space-6); +} + +.summary-header { + display: flex; + align-items: center; + gap: var(--space-3); + margin-bottom: var(--space-3); +} + +.summary-header h4 { + margin: 0; +} + +.summary-icon { + font-size: var(--text-xl); +} + +.summary-content { + font-size: var(--text-sm); + color: var(--text-secondary); + line-height: 1.6; +} + +/* ================================ + 设计建议列表 + ================================ */ +.recommendations-section { + margin-top: var(--space-6); + padding-top: var(--space-6); + border-top: 1px solid var(--border-light); +} + +.recommendations-section h5 { + font-size: var(--text-sm); + font-weight: var(--font-semibold); + color: var(--text-primary); + margin-bottom: var(--space-4); +} + +.recommendations-list { + display: flex; + flex-direction: column; + gap: var(--space-2); +} + +.recommendation-item { + display: flex; + align-items: flex-start; + gap: var(--space-3); + padding: var(--space-3); + background: var(--bg-primary); + border-radius: var(--radius-md); + border-left: 3px solid var(--gray-300); +} + +.recommendation-item.high { + border-left-color: var(--warning); + background: var(--warning-bg); +} + +.recommendation-item.medium { + border-left-color: var(--info); + background: var(--info-bg); +} + +.recommendation-item.low { + border-left-color: var(--success); + background: var(--success-bg); +} + +.priority-badge { + display: inline-flex; + align-items: center; + padding: var(--space-1) var(--space-2); + font-size: var(--text-xs); + font-weight: var(--font-semibold); + border-radius: var(--radius-full); + white-space: nowrap; + flex-shrink: 0; +} + +.priority-badge.high { + background: var(--warning); + color: white; +} + +.priority-badge.medium { + background: var(--info); + color: white; +} + +.priority-badge.low { + background: var(--success); + color: white; +} + +.recommendation-text { + flex: 1; + font-size: var(--text-sm); + color: var(--text-primary); +} + +.recommendation-reason { + font-size: var(--text-xs); + color: var(--text-tertiary); + font-style: italic; +} + +/* ================================ + 登录页面 + ================================ */ +.login-container { + min-height: 100vh; display: flex; align-items: center; justify-content: center; - transition: all var(--duration-fast) var(--ease-default); + background: var(--bg-secondary); + padding: var(--space-6); } -.notification-close:hover { - background: var(--gray-100); +.login-card { + width: 100%; + max-width: 400px; + background: var(--bg-primary); + border: 1px solid var(--border-light); + border-radius: var(--radius-xl); + padding: var(--space-8); +} + +.login-header { + text-align: center; + margin-bottom: var(--space-8); +} + +.login-logo { + width: 48px; + height: 48px; + background: var(--primary-500); + border-radius: var(--radius-lg); + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: var(--text-xl); + font-weight: var(--font-bold); + margin: 0 auto var(--space-4); +} + +.login-title { + font-size: var(--text-2xl); + font-weight: var(--font-bold); color: var(--text-primary); + margin-bottom: var(--space-2); +} + +.login-subtitle { + font-size: var(--text-sm); + color: var(--text-tertiary); +} + +/* ================================ + 首页 + ================================ */ +.hero-section { + text-align: center; + padding: var(--space-16) 0; +} + +.hero-title { + font-size: var(--text-4xl); + font-weight: var(--font-bold); + color: var(--text-primary); + margin-bottom: var(--space-4); +} + +.hero-subtitle { + font-size: var(--text-lg); + color: var(--text-tertiary); + max-width: 600px; + margin: 0 auto var(--space-8); +} + +.features-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: var(--space-6); + margin-top: var(--space-12); +} + +.feature-card { + background: var(--bg-primary); + border: 1px solid var(--border-light); + border-radius: var(--radius-xl); + padding: var(--space-6); + text-align: left; +} + +.feature-icon { + width: 40px; + height: 40px; + background: var(--primary-50); + border-radius: var(--radius-lg); + display: flex; + align-items: center; + justify-content: center; + color: var(--primary-500); + font-size: var(--text-lg); + margin-bottom: var(--space-4); +} + +.feature-title { + font-size: var(--text-base); + font-weight: var(--font-semibold); + color: var(--text-primary); + margin-bottom: var(--space-2); +} + +.feature-desc { + font-size: var(--text-sm); + color: var(--text-tertiary); + line-height: 1.6; } /* ================================ @@ -1292,26 +936,33 @@ a:hover { .loading-spinner { width: 24px; height: 24px; - border: 2px solid var(--gray-200); + border: 2px solid var(--border-default); border-top-color: var(--primary-500); - border-radius: 50%; + border-radius: var(--radius-full); animation: spin 0.8s linear infinite; } @keyframes spin { - to { transform: rotate(360deg); } + to { + transform: rotate(360deg); + } } -.skeleton { - background: linear-gradient(90deg, var(--gray-100) 25%, var(--gray-50) 50%, var(--gray-100) 75%); - background-size: 200% 100%; - animation: skeleton-loading 1.5s infinite; - border-radius: var(--radius-md); +.loading-overlay { + position: fixed; + inset: 0; + background: var(--bg-overlay); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; } -@keyframes skeleton-loading { - 0% { background-position: 200% 0; } - 100% { background-position: -200% 0; } +.loading-content { + background: var(--bg-primary); + padding: var(--space-8); + border-radius: var(--radius-xl); + text-align: center; } /* ================================ @@ -1319,64 +970,305 @@ a:hover { ================================ */ .empty-state { text-align: center; - padding: var(--space-12); + padding: var(--space-12) 0; } .empty-icon { - width: 80px; - height: 80px; + width: 64px; + height: 64px; margin: 0 auto var(--space-4); - background: var(--gray-100); - border-radius: var(--radius-2xl); - display: flex; - align-items: center; - justify-content: center; - font-size: 2rem; color: var(--text-muted); } .empty-title { font-size: var(--text-lg); - font-weight: var(--font-semibold); + font-weight: var(--font-medium); color: var(--text-primary); margin-bottom: var(--space-2); } -.empty-description { +.empty-desc { font-size: var(--text-sm); color: var(--text-tertiary); - max-width: 320px; - margin: 0 auto; } /* ================================ - 页脚 + 响应式设计 ================================ */ -.app-footer { - margin-top: var(--space-12); - padding: var(--space-6); - border-top: 1px solid var(--border-light); +@media (max-width: 768px) { + .header-content { + padding: 0 var(--space-4); + height: 56px; + } + + .logo-subtitle { + display: none; + } + + .nav-menu { + gap: 0; + } + + .nav-item { + padding: var(--space-2) var(--space-3); + font-size: var(--text-xs); + } + + .user-name { + display: none; + } + + .main-content { + padding: var(--space-4); + } + + .page-title { + font-size: var(--text-2xl); + } + + .card { + padding: var(--space-4); + } + + .upload-zone { + padding: var(--space-8); + } + + .hero-section { + padding: var(--space-8) 0; + } + + .hero-title { + font-size: var(--text-2xl); + } +} + +/* ================================ + 动画 + ================================ */ +.notification-enter-active, +.notification-leave-active { + transition: all var(--duration-normal) var(--ease-default); +} + +.notification-enter-from { + opacity: 0; + transform: translateX(100%); +} + +.notification-leave-to { + opacity: 0; + transform: translateX(100%); +} + +/* ================================ + 滚动条 + ================================ */ +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background: var(--bg-tertiary); +} + +::-webkit-scrollbar-thumb { + background: var(--gray-300); + border-radius: var(--radius-full); +} + +::-webkit-scrollbar-thumb:hover { + background: var(--gray-400); +} + +/* ================================ + 选择框 + ================================ */ +select.form-input { + appearance: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23737373' d='M6 8L1 3h10z'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right var(--space-3) center; + padding-right: var(--space-8); +} + +/* ================================ + 复选框 + ================================ */ +.checkbox-group { + display: flex; + align-items: center; + gap: var(--space-2); +} + +.checkbox-input { + width: 16px; + height: 16px; + accent-color: var(--primary-500); +} + +.checkbox-label { + font-size: var(--text-sm); + color: var(--text-primary); + cursor: pointer; +} + +/* ================================ + 标签页 + ================================ */ +.tabs { + display: flex; + gap: var(--space-1); + border-bottom: 1px solid var(--border-light); + margin-bottom: var(--space-6); +} + +.tab-item { + padding: var(--space-3) var(--space-4); + font-size: var(--text-sm); + font-weight: var(--font-medium); + color: var(--text-tertiary); + border-bottom: 2px solid transparent; + cursor: pointer; + transition: all var(--duration-fast) var(--ease-default); +} + +.tab-item:hover { + color: var(--text-primary); +} + +.tab-item.active { + color: var(--primary-600); + border-bottom-color: var(--primary-500); +} + +/* ================================ + 工具类 + ================================ */ +.text-center { text-align: center; } +.text-left { text-align: left; } +.text-right { text-align: right; } + +.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); } + +.mt-2 { margin-top: var(--space-2); } +.mt-4 { margin-top: var(--space-4); } +.mt-6 { margin-top: var(--space-6); } +.mb-2 { margin-bottom: var(--space-2); } +.mb-4 { margin-bottom: var(--space-4); } +.mb-6 { margin-bottom: var(--space-6); } + +.w-full { width: 100%; } +.h-full { height: 100%; } + +.hidden { display: none; } + +/* ================================ + 统计卡片 + ================================ */ +.stats-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: var(--space-4); + margin-bottom: var(--space-6); +} + +.stat-card { + background: var(--bg-primary); + border: 1px solid var(--border-light); + border-radius: var(--radius-xl); + padding: var(--space-5); + cursor: pointer; + transition: all var(--duration-fast) var(--ease-default); +} + +.stat-card:hover { + border-color: var(--primary-300); + box-shadow: var(--shadow-md); +} + +.stat-content { text-align: center; } -.footer-content { - display: flex; - align-items: center; - justify-content: center; - gap: var(--space-6); +.stat-value { + font-size: var(--text-3xl); + font-weight: var(--font-bold); + color: var(--text-primary); + margin-bottom: var(--space-1); +} + +.stat-label { font-size: var(--text-sm); color: var(--text-tertiary); } -.footer-divider { - width: 4px; - height: 4px; - background: var(--gray-300); - border-radius: 50%; +/* ================================ + 用户区域 + ================================ */ +.user-section { + display: flex; + align-items: center; + gap: var(--space-4); +} + +.user-info { + display: flex; + align-items: center; + gap: var(--space-3); +} + +.user-avatar { + width: 32px; + height: 32px; + background: var(--primary-100); + color: var(--primary-600); + border-radius: var(--radius-full); + display: flex; + align-items: center; + justify-content: center; + font-size: var(--text-sm); + font-weight: var(--font-semibold); +} + +.user-name { + font-size: var(--text-sm); + font-weight: var(--font-medium); + color: var(--text-primary); } /* ================================ - Vue 过渡动画 + 加载动画 + ================================ */ +.loading-spinner { + width: 32px; + height: 32px; + border: 3px solid var(--border-default); + border-top-color: var(--primary-500); + border-radius: var(--radius-full); + animation: spin 0.8s linear infinite; +} + +.loading-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: var(--space-12); + gap: var(--space-4); + color: var(--text-tertiary); +} + +/* ================================ + 过渡动画 ================================ */ .fade-enter-active, .fade-leave-active { @@ -1388,671 +1280,300 @@ a:hover { opacity: 0; } -.slide-up-enter-active, -.slide-up-leave-active { - transition: all var(--duration-normal) var(--ease-out); -} - -.slide-up-enter-from { - opacity: 0; - transform: translateY(20px); -} - -.slide-up-leave-to { - opacity: 0; - transform: translateY(-10px); -} - -.scale-enter-active, -.scale-leave-active { - transition: all var(--duration-normal) var(--ease-bounce); -} - -.scale-enter-from, -.scale-leave-to { - opacity: 0; - transform: scale(0.95); -} - -.list-enter-active, -.list-leave-active { - transition: all var(--duration-slow) var(--ease-out); -} - -.list-enter-from { - opacity: 0; - transform: translateX(-20px); -} - -.list-leave-to { - opacity: 0; - transform: translateX(20px); -} - -.list-move { - transition: transform var(--duration-slow) var(--ease-default); -} - /* ================================ - 响应式调整 + 数据表格 ================================ */ -@media (max-width: 768px) { - .main-content { - padding: var(--space-4); - } - - .header-content { - padding: var(--space-3) var(--space-4); - } - - .logo-text { - font-size: var(--text-lg); - } - - .nav-menu { - display: none; - } - - .card-body { - padding: var(--space-4); - } - - .upload-zone { - padding: var(--space-6); - } - - .notification-container { - top: var(--space-4); - right: var(--space-4); - left: var(--space-4); - } - - .notification { - min-width: auto; - max-width: none; - } -} - -/* ================================ - 深色模式支持 - ================================ */ -@media (prefers-color-scheme: dark) { - :root { - --bg-primary: #18181b; - --bg-secondary: #0f0f12; - --bg-tertiary: #27272a; - --bg-elevated: #27272a; - - --border-light: #27272a; - --border-default: #3f3f46; - - --text-primary: #fafafa; - --text-secondary: #d4d4d8; - --text-tertiary: #a1a1aa; - --text-muted: #71717a; - } - - .stat-card, - .card, - .result-card, - .notification { - background: var(--bg-elevated); - } - - .upload-zone { - background: var(--bg-tertiary); - } - - .upload-zone:hover, - .upload-zone.drag-over { - background: rgba(99, 102, 241, 0.1); - } -} - -/* ================================ - 打印样式 - ================================ */ -@media print { - .app-header, - .nav-menu, - .notification-container, - .btn { - display: none !important; - } - - .app-container { - background: white; - } - - .card, - .stat-card, - .result-card { - box-shadow: none; - border: 1px solid #ddd; - } -} - -/* ================================ - 工具类 - ================================ */ -.text-center { text-align: center; } -.text-left { text-align: left; } -.text-right { text-align: right; } - -.font-mono { font-family: var(--font-mono); } -.font-bold { font-weight: var(--font-bold); } -.font-medium { font-weight: var(--font-medium); } - -.text-primary { color: var(--text-primary); } -.text-secondary { color: var(--text-secondary); } -.text-muted { color: var(--text-muted); } - -.mt-2 { margin-top: var(--space-2); } -.mt-4 { margin-top: var(--space-4); } -.mt-6 { margin-top: var(--space-6); } -.mb-2 { margin-bottom: var(--space-2); } -.mb-4 { margin-bottom: var(--space-4); } -.mb-6 { margin-bottom: var(--space-6); } - -.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; } -.visible { visibility: visible; } -.invisible { visibility: hidden; } - -.truncate { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - white-space: nowrap; - border: 0; -} - -.badge-primary { - background: var(--primary-100); - color: var(--primary-700); -} - -.text-warning { - color: var(--warning); -} - -.user-section { - display: flex; - align-items: center; - gap: var(--space-4); -} - -.user-info { - display: flex; - align-items: center; - gap: var(--space-2); -} - -.user-name { - font-size: var(--text-sm); - font-weight: var(--font-medium); - color: var(--text-primary); -} - -.admin-badge { - font-size: var(--text-xs); - padding: var(--space-1) var(--space-2); - background: var(--primary-100); - color: var(--primary-700); - border-radius: var(--radius-sm); -} - -.btn-logout { - padding: var(--space-3) var(--space-5); - font-size: var(--text-base); - font-weight: var(--font-medium); - color: #1a1a1a; - background: #e5e5e5; - border: 1px solid #d4d4d4; - border-radius: var(--radius-md); - cursor: pointer; - transition: all var(--duration-fast) var(--ease-default); -} - -.btn-logout:hover { - background: #d4d4d4; -} - -.btn-login { - padding: var(--space-2) var(--space-4); - font-size: var(--text-sm); - font-weight: var(--font-medium); - color: white; - background: var(--gradient-primary); - border-radius: var(--radius-md); - cursor: pointer; - transition: all var(--duration-fast) var(--ease-default); -} - -.btn-login:hover { - opacity: 0.9; -} - -.auth-page { - min-height: calc(100vh - 200px); - display: flex; - align-items: center; - justify-content: center; - padding: var(--space-8); -} - -.auth-card { +.data-table { width: 100%; - max-width: 400px; - background: var(--bg-primary); - border-radius: var(--radius-xl); - box-shadow: var(--shadow-xl); - padding: var(--space-8); + border-collapse: collapse; } -.auth-header { - text-align: center; - margin-bottom: var(--space-8); +.data-table th, +.data-table td { + padding: var(--space-3) var(--space-4); + text-align: left; + border-bottom: 1px solid var(--border-light); } -.auth-logo { - width: 60px; - height: 60px; - background: var(--gradient-primary); - border-radius: var(--radius-xl); +.data-table th { + font-size: var(--text-xs); + font-weight: var(--font-medium); + color: var(--text-tertiary); + text-transform: uppercase; + letter-spacing: 0.05em; + background: var(--bg-secondary); +} + +.data-table td { + font-size: var(--text-sm); + color: var(--text-primary); +} + +.data-table tbody tr:hover { + background: var(--bg-secondary); +} + +/* ================================ + 分析页面 + ================================ */ +.analysis-header { display: flex; align-items: center; - justify-content: center; - font-size: 1.5rem; - color: white; - margin: 0 auto var(--space-4); - box-shadow: var(--shadow-lg); + justify-content: space-between; + margin-bottom: var(--space-6); } -.auth-header h1 { +.analysis-title { font-size: var(--text-2xl); - margin-bottom: var(--space-2); -} - -.auth-header p { - font-size: var(--text-sm); - color: var(--text-tertiary); -} - -.auth-form { - display: flex; - flex-direction: column; - gap: var(--space-4); -} - -.form-group { - display: flex; - flex-direction: column; - gap: var(--space-2); -} - -.form-group label { - font-size: var(--text-sm); - font-weight: var(--font-medium); - color: var(--text-secondary); -} - -.form-group input { - padding: var(--space-3) var(--space-4); - font-size: var(--text-base); - border: 1px solid var(--border-default); - border-radius: var(--radius-md); - background: var(--bg-primary); + font-weight: var(--font-bold); color: var(--text-primary); +} + +.analysis-actions { + display: flex; + gap: var(--space-3); +} + +/* ================================ + 文件上传区域 + ================================ */ +.upload-area { + border: 2px dashed var(--border-strong); + border-radius: var(--radius-xl); + padding: var(--space-12); + text-align: center; + cursor: pointer; transition: all var(--duration-fast) var(--ease-default); + background: var(--bg-primary); } -.form-group input:focus { - outline: none; +.upload-area:hover { + border-color: var(--primary-400); + background: var(--primary-50); +} + +.upload-area.dragover { border-color: var(--primary-500); - box-shadow: 0 0 0 3px var(--primary-100); + background: var(--primary-100); } -.form-group input::placeholder { +.upload-icon { + width: 48px; + height: 48px; + margin: 0 auto var(--space-4); color: var(--text-muted); } -.error-message { - padding: var(--space-3); - background: var(--error-bg); - color: var(--error); - font-size: var(--text-sm); - border-radius: var(--radius-md); - text-align: center; -} - -.btn-full { - width: 100%; -} - -.auth-footer { - margin-top: var(--space-6); - text-align: center; - font-size: var(--text-sm); - color: var(--text-tertiary); -} - -.auth-footer a { - color: var(--primary-600); +.upload-title { + font-size: var(--text-lg); font-weight: var(--font-medium); - cursor: pointer; -} - -.auth-footer a:hover { - color: var(--primary-700); -} - -.auth-tip { - color: var(--text-tertiary); - font-size: var(--text-sm); -} - -.page-container { - max-width: 1200px; - margin: 0 auto; -} - -.page-header { - margin-bottom: var(--space-6); -} - -.page-header h1 { - font-size: var(--text-3xl); + color: var(--text-primary); margin-bottom: var(--space-2); } -.page-header p { - font-size: var(--text-base); - color: var(--text-tertiary); -} - -.section { - margin-top: var(--space-8); -} - -.section-title { - font-size: var(--text-xl); - margin-bottom: var(--space-4); -} - -.loading-state { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - padding: var(--space-12); - gap: var(--space-4); -} - -.spinner { - width: 40px; - height: 40px; - border: 3px solid var(--gray-200); - border-top-color: var(--primary-500); - border-radius: 50%; - animation: spin 0.8s linear infinite; -} - -.error-state { - text-align: center; - padding: var(--space-12); - color: var(--error); -} - -.tabs { - display: flex; - gap: var(--space-2); - margin-bottom: var(--space-6); - border-bottom: 1px solid var(--border-light); - padding-bottom: var(--space-2); - overflow-x: auto; -} - -.tab { - padding: var(--space-2) var(--space-4); +.upload-desc { font-size: var(--text-sm); - font-weight: var(--font-medium); color: var(--text-tertiary); - background: transparent; - border: none; - border-bottom: 2px solid transparent; - cursor: pointer; - transition: all var(--duration-fast) var(--ease-default); - white-space: nowrap; } -.tab:hover { - color: var(--text-primary); -} - -.tab.active { - color: var(--primary-600); - border-bottom-color: var(--primary-600); -} - -.table-container { +/* ================================ + 分析进度 + ================================ */ +.progress-section { background: var(--bg-primary); - border-radius: var(--radius-lg); - box-shadow: var(--shadow-sm); - overflow: hidden; + border: 1px solid var(--border-light); + border-radius: var(--radius-xl); + padding: var(--space-6); + margin-bottom: var(--space-6); } -.action-buttons { +.progress-header { display: flex; - gap: var(--space-2); -} - -.btn-sm { - padding: var(--space-1) var(--space-3); - font-size: var(--text-xs); - font-weight: var(--font-medium); - border-radius: var(--radius-sm); - border: none; - cursor: pointer; - transition: all var(--duration-fast) var(--ease-default); -} - -.btn-success { - background: var(--success); - color: white; -} - -.btn-success:hover { - background: var(--accent-600); -} - -.btn-warning { - background: var(--warning-bg); - color: var(--warning); -} - -.btn-warning:hover { - background: var(--warning); - color: white; -} - -.btn-back { - padding: var(--space-2) var(--space-4); - font-size: var(--text-sm); - font-weight: var(--font-medium); - color: var(--text-secondary); - background: transparent; - border: none; - cursor: pointer; + align-items: center; + justify-content: space-between; margin-bottom: var(--space-4); } -.btn-back:hover { +.progress-title { + font-size: var(--text-base); + font-weight: var(--font-semibold); color: var(--text-primary); } -.result-container { - display: flex; - flex-direction: column; - gap: var(--space-6); +.progress-status { + font-size: var(--text-sm); + color: var(--primary-600); +} + +.progress-bar { + width: 100%; + height: 8px; + background: var(--bg-tertiary); + border-radius: var(--radius-full); + overflow: hidden; + margin-bottom: var(--space-3); +} + +.progress-fill { + height: 100%; + background: var(--primary-500); + border-radius: var(--radius-full); + transition: width var(--duration-normal) var(--ease-default); +} + +.progress-message { + font-size: var(--text-sm); + color: var(--text-tertiary); +} + +/* ================================ + 分析结果 + ================================ */ +.result-section { + margin-top: var(--space-6); } .result-header { display: flex; align-items: center; - gap: var(--space-4); + justify-content: space-between; + margin-bottom: var(--space-4); } -.result-header h2 { - font-size: var(--text-2xl); +.result-title { + font-size: var(--text-lg); + font-weight: var(--font-semibold); + color: var(--text-primary); } .result-grid { display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: var(--space-6); + grid-template-columns: repeat(2, 1fr); + gap: var(--space-4); } -.result-card { - background: var(--bg-primary); - border-radius: var(--radius-lg); - padding: var(--space-6); - box-shadow: var(--shadow-sm); +@media (max-width: 768px) { + .result-grid { + grid-template-columns: 1fr; + } } -.result-card h3 { - font-size: var(--text-lg); - margin-bottom: var(--space-4); - padding-bottom: var(--space-3); - border-bottom: 1px solid var(--border-light); -} - -.info-list { +.result-item { display: flex; flex-direction: column; - gap: var(--space-3); + gap: var(--space-1); + padding: var(--space-3); + background: var(--bg-secondary); + border-radius: var(--radius-md); } -.info-item { - display: flex; - justify-content: space-between; - align-items: center; -} - -.info-label { - font-size: var(--text-sm); +.result-label { + font-size: var(--text-xs); color: var(--text-tertiary); + text-transform: uppercase; + letter-spacing: 0.05em; } -.info-value { +.result-value { font-size: var(--text-sm); font-weight: var(--font-medium); color: var(--text-primary); } -.viewer-section { - background: var(--bg-primary); - border-radius: var(--radius-lg); - padding: var(--space-6); - box-shadow: var(--shadow-sm); +/* ================================ + 历史记录 + ================================ */ +.history-section { + margin-top: var(--space-8); } -.viewer-section h3 { - font-size: var(--text-lg); +.history-header { + display: flex; + align-items: center; + justify-content: space-between; margin-bottom: var(--space-4); } +.history-title { + font-size: var(--text-lg); + font-weight: var(--font-semibold); + color: var(--text-primary); +} + +.history-table { + background: var(--bg-primary); + border: 1px solid var(--border-light); + border-radius: var(--radius-xl); + overflow: hidden; +} + +/* ================================ + 标签页导航 + ================================ */ +.tabs-nav { + display: flex; + gap: var(--space-1); + border-bottom: 1px solid var(--border-light); + margin-bottom: var(--space-6); +} + +.tab-link { + padding: var(--space-3) var(--space-4); + font-size: var(--text-sm); + font-weight: var(--font-medium); + color: var(--text-tertiary); + text-decoration: none; + border-bottom: 2px solid transparent; + transition: all var(--duration-fast) var(--ease-default); +} + +.tab-link:hover { + color: var(--text-primary); +} + +.tab-link.active { + color: var(--primary-600); + border-bottom-color: var(--primary-500); +} + +/* ================================ + 3D 查看器 + ================================ */ +.viewer-container { + background: var(--bg-primary); + border: 1px solid var(--border-light); + border-radius: var(--radius-xl); + overflow: hidden; +} + .viewer-frame { width: 100%; height: 500px; - border: 1px solid var(--border-light); - border-radius: var(--radius-md); + border: none; } -.quick-actions { - margin-top: var(--space-8); +/* ================================ + 空状态 + ================================ */ +.empty-state { + text-align: center; + padding: var(--space-12); } -.action-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); - gap: var(--space-4); +.empty-icon { + font-size: 48px; + margin-bottom: var(--space-4); + opacity: 0.5; } -.action-card { - display: flex; - flex-direction: column; - align-items: center; - gap: var(--space-3); - padding: var(--space-6); - background: var(--bg-primary); - border-radius: var(--radius-lg); - border: 1px solid var(--border-light); - cursor: pointer; - transition: all var(--duration-fast) var(--ease-default); -} - -.action-card:hover { - border-color: var(--primary-300); - box-shadow: var(--shadow-md); - transform: translateY(-2px); -} - -.action-icon { - font-size: 1.5rem; -} - -.action-label { - font-size: var(--text-sm); - font-weight: var(--font-medium); - color: var(--text-secondary); -} - -.nav-icon { - margin-right: var(--space-2); -} - -.upload-section { - display: flex; - flex-direction: column; - gap: var(--space-4); - margin-bottom: var(--space-8); -} - -.file-info { - display: flex; - align-items: center; - gap: var(--space-4); - padding: var(--space-3) var(--space-4); - background: var(--bg-primary); - border-radius: var(--radius-md); - border: 1px solid var(--border-light); -} - -.file-name { +.empty-title { + font-size: var(--text-lg); font-weight: var(--font-medium); color: var(--text-primary); + margin-bottom: var(--space-2); } -.file-size { +.empty-desc { font-size: var(--text-sm); color: var(--text-tertiary); } diff --git a/static/vue-app.js b/static/vue-app.js index 4ac19c6..ffbe3ca 100644 --- a/static/vue-app.js +++ b/static/vue-app.js @@ -225,7 +225,7 @@ const App = {
`, }; @@ -333,44 +324,46 @@ const LoginView = { return { state, handleSubmit }; }, template: ` -
-
-
- -

登录

-

登录到 Gemold 系统

+