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 @@
-
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 = {