From b9ba1d5ed44b671e988bbe200fd381f584e6f0f4 Mon Sep 17 00:00:00 2001 From: eafonyang Date: Fri, 10 Jul 2026 15:00:49 +0800 Subject: [PATCH] =?UTF-8?q?ui=20=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DESIGN.md | 875 +++++++----------- frontend/src/components/TabsView.vue | 1 + frontend/src/layout/index.vue | 8 +- frontend/src/styles/lux-theme.css | 806 +++++++++++++++- frontend/src/views/blacklist/index.vue | 2 +- frontend/src/views/brand/index.vue | 2 +- frontend/src/views/home/index.vue | 23 +- frontend/src/views/login/index.vue | 12 +- .../src/views/ota-target-device/index.vue | 2 +- frontend/src/views/ota/index.vue | 2 +- 10 files changed, 1146 insertions(+), 587 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index f92dc46..d2142b7 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -1,589 +1,358 @@ ---- -version: alpha -name: Claude-design-analysis -description: A warm-canvas editorial interface for Anthropic's Claude product. The system anchors on a tinted cream canvas with serif display headlines, warm coral CTAs, and dark navy product surfaces (code editor mockups, model showcase cards). Brand voltage comes from the cream/coral pairing — deliberately warm and humanist where most AI brands use cool blue + slate. Type voice runs a slab-serif display ("Copernicus" / Tiempos Headline) for h1/h2 and a humanist sans for body. The signature Anthropic black-radial-spike mark anchors the wordmark. +# Luxsin CMS Dashboard — Design System Specification -colors: - primary: "#cc785c" - primary-active: "#a9583e" - primary-disabled: "#e6dfd8" - ink: "#141413" - body: "#3d3d3a" - body-strong: "#252523" - muted: "#6c6a64" - muted-soft: "#8e8b82" - hairline: "#e6dfd8" - hairline-soft: "#ebe6df" - canvas: "#faf9f5" - surface-soft: "#f5f0e8" - surface-card: "#efe9de" - surface-cream-strong: "#e8e0d2" - surface-dark: "#181715" - surface-dark-elevated: "#252320" - surface-dark-soft: "#1f1e1b" - on-primary: "#ffffff" - on-dark: "#faf9f5" - on-dark-soft: "#a09d96" - accent-teal: "#5db8a6" - accent-amber: "#e8a55a" - success: "#5db872" - warning: "#d4a017" - error: "#c64545" +> **Version**: 1.0 +> **Style**: Glassmorphism + Dimensional Layering + Dark Mode OLED +> **Scope**: Vue 3 + Element Plus SPA (内部管理系统) -typography: - display-xl: - fontFamily: "Copernicus, Tiempos Headline, serif" - fontSize: 64px - fontWeight: 400 - lineHeight: 1.05 - letterSpacing: -1.5px - display-lg: - fontFamily: "Copernicus, Tiempos Headline, serif" - fontSize: 48px - fontWeight: 400 - lineHeight: 1.1 - letterSpacing: -1px - display-md: - fontFamily: "Copernicus, Tiempos Headline, serif" - fontSize: 36px - fontWeight: 400 - lineHeight: 1.15 - letterSpacing: -0.5px - display-sm: - fontFamily: "Copernicus, Tiempos Headline, serif" - fontSize: 28px - fontWeight: 400 - lineHeight: 1.2 - letterSpacing: -0.3px - title-lg: - fontFamily: "StyreneB, Inter, sans-serif" - fontSize: 22px - fontWeight: 500 - lineHeight: 1.3 - letterSpacing: 0 - title-md: - fontFamily: "StyreneB, Inter, sans-serif" - fontSize: 18px - fontWeight: 500 - lineHeight: 1.4 - letterSpacing: 0 - title-sm: - fontFamily: "StyreneB, Inter, sans-serif" - fontSize: 16px - fontWeight: 500 - lineHeight: 1.4 - letterSpacing: 0 - body-md: - fontFamily: "StyreneB, Inter, sans-serif" - fontSize: 16px - fontWeight: 400 - lineHeight: 1.55 - letterSpacing: 0 - body-sm: - fontFamily: "StyreneB, Inter, sans-serif" - fontSize: 14px - fontWeight: 400 - lineHeight: 1.55 - letterSpacing: 0 - caption: - fontFamily: "StyreneB, Inter, sans-serif" - fontSize: 13px - fontWeight: 500 - lineHeight: 1.4 - letterSpacing: 0 - caption-uppercase: - fontFamily: "StyreneB, Inter, sans-serif" - fontSize: 12px - fontWeight: 500 - lineHeight: 1.4 - letterSpacing: 1.5px - code: - fontFamily: "JetBrains Mono, ui-monospace, monospace" - fontSize: 14px - fontWeight: 400 - lineHeight: 1.6 - letterSpacing: 0 - button: - fontFamily: "StyreneB, Inter, sans-serif" - fontSize: 14px - fontWeight: 500 - lineHeight: 1 - letterSpacing: 0 - nav-link: - fontFamily: "StyreneB, Inter, sans-serif" - fontSize: 14px - fontWeight: 500 - lineHeight: 1.4 - letterSpacing: 0 - -rounded: - xs: 4px - sm: 6px - md: 8px - lg: 12px - xl: 16px - pill: 9999px - full: 9999px - -spacing: - xxs: 4px - xs: 8px - sm: 12px - md: 16px - lg: 24px - xl: 32px - xxl: 48px - section: 96px - -components: - button-primary: - backgroundColor: "{colors.primary}" - textColor: "{colors.on-primary}" - typography: "{typography.button}" - rounded: "{rounded.md}" - padding: 12px 20px - height: 40px - button-primary-active: - backgroundColor: "{colors.primary-active}" - textColor: "{colors.on-primary}" - rounded: "{rounded.md}" - button-primary-disabled: - backgroundColor: "{colors.primary-disabled}" - textColor: "{colors.muted}" - rounded: "{rounded.md}" - button-secondary: - backgroundColor: "{colors.canvas}" - textColor: "{colors.ink}" - typography: "{typography.button}" - rounded: "{rounded.md}" - padding: 12px 20px - height: 40px - button-secondary-on-dark: - backgroundColor: "{colors.surface-dark-elevated}" - textColor: "{colors.on-dark}" - typography: "{typography.button}" - rounded: "{rounded.md}" - padding: 12px 20px - button-text-link: - backgroundColor: transparent - textColor: "{colors.ink}" - typography: "{typography.button}" - button-icon-circular: - backgroundColor: "{colors.canvas}" - textColor: "{colors.ink}" - rounded: "{rounded.full}" - size: 36px - text-link: - backgroundColor: transparent - textColor: "{colors.primary}" - typography: "{typography.body-md}" - top-nav: - backgroundColor: "{colors.canvas}" - textColor: "{colors.ink}" - typography: "{typography.nav-link}" - height: 64px - hero-band: - backgroundColor: "{colors.canvas}" - textColor: "{colors.ink}" - typography: "{typography.display-xl}" - padding: 96px - hero-illustration-card: - backgroundColor: "{colors.canvas}" - textColor: "{colors.ink}" - rounded: "{rounded.xl}" - feature-card: - backgroundColor: "{colors.surface-card}" - textColor: "{colors.ink}" - typography: "{typography.title-md}" - rounded: "{rounded.lg}" - padding: 32px - product-mockup-card-dark: - backgroundColor: "{colors.surface-dark}" - textColor: "{colors.on-dark}" - typography: "{typography.title-md}" - rounded: "{rounded.lg}" - padding: 32px - code-window-card: - backgroundColor: "{colors.surface-dark}" - textColor: "{colors.on-dark}" - typography: "{typography.code}" - rounded: "{rounded.lg}" - padding: 24px - model-comparison-card: - backgroundColor: "{colors.canvas}" - textColor: "{colors.ink}" - typography: "{typography.title-md}" - rounded: "{rounded.lg}" - padding: 32px - pricing-tier-card: - backgroundColor: "{colors.canvas}" - textColor: "{colors.ink}" - typography: "{typography.title-lg}" - rounded: "{rounded.lg}" - padding: 32px - pricing-tier-card-featured: - backgroundColor: "{colors.surface-dark}" - textColor: "{colors.on-dark}" - typography: "{typography.title-lg}" - rounded: "{rounded.lg}" - padding: 32px - callout-card-coral: - backgroundColor: "{colors.primary}" - textColor: "{colors.on-primary}" - typography: "{typography.title-md}" - rounded: "{rounded.lg}" - padding: 32px - connector-tile: - backgroundColor: "{colors.canvas}" - textColor: "{colors.ink}" - typography: "{typography.title-sm}" - rounded: "{rounded.lg}" - padding: 20px - text-input: - backgroundColor: "{colors.canvas}" - textColor: "{colors.ink}" - typography: "{typography.body-md}" - rounded: "{rounded.md}" - padding: 10px 14px - height: 40px - text-input-focused: - backgroundColor: "{colors.canvas}" - textColor: "{colors.ink}" - rounded: "{rounded.md}" - cookie-consent-card: - backgroundColor: "{colors.surface-dark}" - textColor: "{colors.on-dark}" - typography: "{typography.body-sm}" - rounded: "{rounded.lg}" - padding: 24px - category-tab: - backgroundColor: transparent - textColor: "{colors.muted}" - typography: "{typography.nav-link}" - padding: 8px 14px - rounded: "{rounded.md}" - category-tab-active: - backgroundColor: "{colors.surface-card}" - textColor: "{colors.ink}" - typography: "{typography.nav-link}" - rounded: "{rounded.md}" - badge-pill: - backgroundColor: "{colors.surface-card}" - textColor: "{colors.ink}" - typography: "{typography.caption}" - rounded: "{rounded.pill}" - padding: 4px 12px - badge-coral: - backgroundColor: "{colors.primary}" - textColor: "{colors.on-primary}" - typography: "{typography.caption-uppercase}" - rounded: "{rounded.pill}" - padding: 4px 12px - cta-band-coral: - backgroundColor: "{colors.primary}" - textColor: "{colors.on-primary}" - typography: "{typography.display-sm}" - rounded: "{rounded.lg}" - padding: 64px - cta-band-dark: - backgroundColor: "{colors.surface-dark}" - textColor: "{colors.on-dark}" - typography: "{typography.display-sm}" - rounded: "{rounded.lg}" - padding: 64px - footer: - backgroundColor: "{colors.surface-dark}" - textColor: "{colors.on-dark-soft}" - typography: "{typography.body-sm}" - padding: 64px --- -## Overview +## 1. Design Philosophy -Claude.com is the warmest, most editorial interface in the AI-product category. The base atmosphere is a **tinted cream canvas** (`{colors.canvas}` — #faf9f5) — distinctly warm, deliberately not the cool gray-white that every other AI brand uses. Headlines run a **slab-serif display** ("Copernicus" / Tiempos Headline) at weight 400 with negative letter-spacing, paired with **StyreneB / Inter** body sans. The combination feels like a literary publication, not a SaaS marketing page. +Luxsin CMS Dashboard 采用三层融合设计语言,将登录页的精致玻璃美学统一到全站: -Brand voltage comes from the **cream + coral pairing** — coral (`{colors.primary}` — #cc785c) is the signature Anthropic accent, used on every primary CTA, on the brand wordmark, and on full-bleed callout cards. The coral is warm, slightly muted, never cyan/blue — a deliberate counter-positioning against OpenAI's cool slate, Google's saturated blue, and Microsoft's corporate cyan. +| 层级 | 风格 | 占比 | 职责 | +|---|---|---|---| +| **主风格** | Glassmorphism | 60% | 半透明毛玻璃表面、`backdrop-filter` 模糊、微弱边框光晕 | +| **辅助风格** | Dimensional Layering | 25% | 4 级 elevation 空间层级,通过阴影和浮起建立信息层次 | +| **辅助风格** | Dark Mode OLED | 15% | 深空黑底色保障对比度,焦点 ring 反馈,minimal glow | -The system has three surface modes that alternate page-by-page: -1. **Cream canvas** (`{colors.canvas}`) — default body floor -2. **Light cream cards** (`{colors.surface-card}`) — feature card backgrounds -3. **Dark navy product surfaces** (`{colors.surface-dark}`) — code editor mockups, model showcase cards, pre-footer CTAs, footer itself +### Design Principles -The dark surfaces are where Claude shows its product chrome — code blocks, terminal output, model comparison tables, agentic-flow diagrams. The cream-to-dark contrast is the page's pacing rhythm. +1. **Glass everywhere** — 侧栏、顶栏、卡片、表格、对话框、输入框全部使用半透明玻璃 +2. **Depth through layers** — 4 级 elevation (bg → content → floating → overlay) 建立空间秩序 +3. **Contrast first** — 所有文本确保 WCAG AA (4.5:1),关键文本 AAA (7:1) +4. **Consistency over creativity** — 统一 Token 驱动,不做页面级定制 -**Key Characteristics:** -- Warm cream canvas (`{colors.canvas}` — #faf9f5) with dark warm-ink text (`{colors.ink}` — #141413). The brand's defining color choice. -- Coral primary CTA (`{colors.primary}` — #cc785c). Used scarcely on individual buttons, generously on full-bleed coral callout cards. -- Slab-serif display headlines via Copernicus / Tiempos Headline at weight 400 with negative letter-spacing. Pairs with humanist sans body for a literary editorial voice. -- Dark navy product mockup cards (`{colors.surface-dark}` — #181715) carrying code blocks, terminal panels, model comparison data — the brand shows the product chrome at scale rather than abstract marketing illustrations. -- Light cream feature cards (`{colors.surface-card}` — #efe9de) — slightly darker than canvas, used for content-driven feature explanations. -- Anthropic radial-spike mark — a small black asterisk-like glyph (4-spoke radial) — appears as the brand wordmark prefix and as a content marker. -- Border radius is hierarchical: `{rounded.md}` (8px) for buttons + inputs, `{rounded.lg}` (12px) for content + product cards, `{rounded.xl}` (16px) for the hero illustration container, `{rounded.pill}` for badges. -- Section rhythm `{spacing.section}` (96px) — modern-SaaS standard. Internal card padding stays generous at `{spacing.xl}` (32px). +--- -## Colors +## 2. Color System -### Brand & Accent -- **Coral / Primary** (`{colors.primary}` — #cc785c): The signature Anthropic warm coral. Used on every primary CTA background, on full-bleed coral callout cards, on the brand wordmark accent. The most-recognized Anthropic color outside of the spike-mark logo. -- **Coral Active** (`{colors.primary-active}` — #a9583e): The press / hover-darker variant. -- **Coral Disabled** (`{colors.primary-disabled}` — #e6dfd8): A desaturated cream-tinted disabled state. -- **Accent Teal** (`{colors.accent-teal}` — #5db8a6): Used sparingly on secondary product surfaces (terminal status indicators, "active connection" dots in connectors page). -- **Accent Amber** (`{colors.accent-amber}` — #e8a55a): A small companion warm-tone used on category badges and inline highlights. +### 2.1 Primitives (不可变) -### Surface -- **Canvas** (`{colors.canvas}` — #faf9f5): The default page floor. Tinted cream — warm, deliberately not pure white. -- **Surface Soft** (`{colors.surface-soft}` — #f5f0e8): Section dividers, very-soft band backgrounds. -- **Surface Card** (`{colors.surface-card}` — #efe9de): Feature cards, content cards. One step darker than canvas. -- **Surface Cream Strong** (`{colors.surface-cream-strong}` — #e8e0d2): A strongest-cream variant used on selected category tabs and emphasized section bands. -- **Surface Dark** (`{colors.surface-dark}` — #181715): Code editor mockups, model showcase cards, footer. The dominant dark surface. -- **Surface Dark Elevated** (`{colors.surface-dark-elevated}` — #252320): Elevated cards inside dark bands (settings panels in mockups). -- **Surface Dark Soft** (`{colors.surface-dark-soft}` — #1f1e1b): Slightly lighter dark, used for code block backgrounds inside larger dark cards. -- **Hairline** (`{colors.hairline}` — #e6dfd8): The 1px border tone on cream surfaces. Same hex as `{colors.primary-disabled}` — borders feel like one elevation step rather than ink lines. -- **Hairline Soft** (`{colors.hairline-soft}` — #ebe6df): Barely-visible divider used inside the same band. +```css +/* 基础色板 */ +--lux-space-900: #020617; +--lux-space-800: #0a0e14; /* 页面底色 */ +--lux-space-700: #0f172a; /* 输入框底色 */ +--lux-space-600: #1e293b; /* 卡片底色 */ +--lux-space-500: #334155; +--lux-space-400: #475569; +--lux-space-300: #94a3b8; /* muted text */ +--lux-space-200: #cbd5e1; +--lux-space-100: #e2e8f0; /* strong text */ -### Text -- **Ink** (`{colors.ink}` — #141413): All headlines and primary text. Warm dark, slightly off-pure-black. -- **Body Strong** (`{colors.body-strong}` — #252523): Emphasized paragraphs, lead text. -- **Body** (`{colors.body}` — #3d3d3a): Default running-text color. -- **Muted** (`{colors.muted}` — #6c6a64): Sub-headings, breadcrumbs, footer-adjacent secondary text. -- **Muted Soft** (`{colors.muted-soft}` — #8e8b82): Captions, fine-print, copyright lines. -- **On Primary** (`{colors.on-primary}` — #ffffff): Text on coral buttons. -- **On Dark** (`{colors.on-dark}` — #faf9f5): Cream-tinted white used on dark surfaces (echoes the canvas tone). -- **On Dark Soft** (`{colors.on-dark-soft}` — #a09d96): Footer body text, secondary labels in dark mockups. +/* 品牌色 */ +--lux-cyan: #38bdf8; /* 主品牌 */ +--lux-cyan-light: #7dd3fc; +--lux-cyan-glow: rgba(56, 189, 248, 0.25); +--lux-indigo: #6366f1; +--lux-violet: #7c3aed; +``` -### Semantic -- **Success** (`{colors.success}` — #5db872): Green status dots, "available" indicators. -- **Warning** (`{colors.warning}` — #d4a017): Warning callouts (rare on marketing surfaces). -- **Error** (`{colors.error}` — #c64545): Validation errors. +### 2.2 Semantic Tokens -## Typography +```css +/* 页面 */ +--lux-page-bg: #0a0e14; +--lux-page-gradient: radial-gradient(ellipse 120% 90% at 50% -15%, #1a2840 0%, #0d1117 48%, #0a0e14 100%); -### Font Family -The system runs **Copernicus** (or **Tiempos Headline** as substitute) as the slab-serif display face for headlines, and **StyreneB** (or **Inter** as substitute) as the humanist sans for body, navigation, and UI labels. **JetBrains Mono** handles code blocks. The fallback stack walks `Tiempos Headline, Garamond, "Times New Roman", serif` for display and `Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif` for body. +/* 文本 */ +--lux-text-strong: #e2e8f0; /* 标题、重要文本 — 对比度 13.5:1 */ +--lux-text-body: #cbd5e1; /* 正文 — 对比度 10.2:1 */ +--lux-text-muted: #94a3b8; /* 辅助文本 — 对比度 5.8:1 */ +--lux-text-dim: #64748b; /* 最弱文本 — 对比度 3.5:1 (仅装饰性) */ -The display/body split is editorial: -- Copernicus serif (weight 400, negative tracking) → h1, h2, h3, hero display -- StyreneB sans (weight 400-500) → body, navigation, buttons, captions, labels -- JetBrains Mono → all code blocks and terminal text +/* 玻璃表面 */ +--lux-glass-bg-card: rgba(30, 41, 59, 0.55); /* 卡片 */ +--lux-glass-bg-table: rgba(30, 41, 59, 0.45); /* 表格 */ +--lux-glass-bg-input: rgba(15, 23, 42, 0.45); /* 输入框 */ +--lux-glass-bg-dialog: rgba(30, 41, 59, 0.72); /* 对话框 */ +--lux-glass-bg-sidebar: rgba(15, 23, 42, 0.60); /* 侧栏 */ +--lux-glass-bg-header: rgba(30, 41, 59, 0.75); /* 顶栏 */ +--lux-glass-bg-tab: rgba(30, 41, 59, 0.35); /* 标签页 */ -### Hierarchy +/* 玻璃边框 */ +--lux-glass-border: rgba(255, 255, 255, 0.08); +--lux-glass-border-hover: rgba(255, 255, 255, 0.14); +--lux-glass-border-focus: rgba(56, 189, 248, 0.45); -| Token | Size | Weight | Line Height | Letter Spacing | Use | -|---|---|---|---|---|---| -| `{typography.display-xl}` | 64px | 400 | 1.05 | -1.5px | Homepage h1 ("Meet your thinking partner") — Copernicus serif | -| `{typography.display-lg}` | 48px | 400 | 1.1 | -1px | Section heads — Copernicus | -| `{typography.display-md}` | 36px | 400 | 1.15 | -0.5px | Sub-section heads, model names — Copernicus | -| `{typography.display-sm}` | 28px | 400 | 1.2 | -0.3px | Pricing tier names, callout headlines — Copernicus | -| `{typography.title-lg}` | 22px | 500 | 1.3 | 0 | Pricing plan size labels — StyreneB | -| `{typography.title-md}` | 18px | 500 | 1.4 | 0 | Feature card titles, intro paragraphs | -| `{typography.title-sm}` | 16px | 500 | 1.4 | 0 | Connector tile titles, list labels | -| `{typography.body-md}` | 16px | 400 | 1.55 | 0 | Default running-text — StyreneB | -| `{typography.body-sm}` | 14px | 400 | 1.55 | 0 | Footer body, fine-print | -| `{typography.caption}` | 13px | 500 | 1.4 | 0 | Badge labels, captions | -| `{typography.caption-uppercase}` | 12px | 500 | 1.4 | 1.5px | Category tags, "NEW" badges | -| `{typography.code}` | 14px | 400 | 1.6 | 0 | Code blocks — JetBrains Mono | -| `{typography.button}` | 14px | 500 | 1.0 | 0 | Standard button labels | -| `{typography.nav-link}` | 14px | 500 | 1.4 | 0 | Top-nav menu items | +/* 模糊强度 */ +--lux-blur-sm: blur(8px); +--lux-blur-md: blur(14px); +--lux-blur-lg: blur(20px); +--lux-blur-xl: blur(24px); +``` -### Principles -Display sizes use weight 400 (regular), never bold. Negative letter-spacing (-0.3 to -1.5px) is essential — Copernicus without it reads as off-brand. The serif character is what gives Anthropic its literary, considered voice; switching to a sans-serif display would make Claude feel like every other AI tool. +### 2.3 Elevation Shadows -Body type stays at weight 400 for paragraphs, weight 500 for labels and emphasized phrases. The sans body is humanist (StyreneB) — never geometric. Inter is an acceptable substitute because of its similar humanist proportions; Helvetica or Arial would be too neutral and break the warm-editorial feel. +```css +/* 4级 Elevation */ +--lux-shadow-1: 0 2px 8px rgba(0, 0, 0, 0.18); /* 卡片 resting */ +--lux-shadow-2: 0 4px 16px rgba(0, 0, 0, 0.25); /* 卡片 hover / 浮起 */ +--lux-shadow-3: 0 8px 32px rgba(0, 0, 0, 0.35); /* 弹出层 */ +--lux-shadow-4: 0 25px 50px rgba(0, 0, 0, 0.50); /* 对话框 overlay */ -### Note on Font Substitutes -If Copernicus / Tiempos Headline is unavailable, **Cormorant Garamond** at weight 500 with -0.02em letter-spacing is the closest open-source approximation. **EB Garamond** is a fallback. For StyreneB, **Inter** is the closest match — both are humanist sans designed for screen reading. **Söhne** is another close alternative if licensed. +/* 品牌 glow (焦点态) */ +--lux-glow-cyan: 0 0 0 3px rgba(56, 189, 248, 0.15), 0 0 0 1px rgba(56, 189, 248, 0.45) inset; +``` -## Layout +--- -### Spacing System -- **Base unit:** 4px. -- **Tokens:** `{spacing.xxs}` 4px · `{spacing.xs}` 8px · `{spacing.sm}` 12px · `{spacing.md}` 16px · `{spacing.lg}` 24px · `{spacing.xl}` 32px · `{spacing.xxl}` 48px · `{spacing.section}` 96px. -- **Section padding:** `{spacing.section}` (96px) — modern-SaaS rhythm. -- **Card internal padding:** `{spacing.xl}` (32px) for feature cards, pricing tier cards, model comparison cards; `{spacing.lg}` (24px) for code-window cards and connector tiles. -- **Callout / CTA bands:** `{spacing.xxl}` (48px) inside coral callout cards; 64px inside the larger dark CTA band. +## 3. Typography -### Grid & Container -- **Max content width:** ~1200px centered. -- **Editorial body:** Single 12-column grid; hero often uses 6/6 split (h1 left, illustration right). -- **Feature card grids:** 3-up at desktop, 2-up at tablet, 1-up at mobile. -- **Connector tile grids:** 4-up or 6-up at desktop, 2-up at tablet, 1-up at mobile. -- **Pricing grid:** 3-up at desktop (Free / Pro / Team / Enterprise often), 1-up at mobile. +### Font Stack -### Whitespace Philosophy -The cream canvas + serif display + generous internal padding create an editorial pacing — Claude reads like a long-form magazine column rather than a marketing template. Whitespace between bands stays uniform at 96px; whitespace inside cards is generous (32px), letting type breathe. +```css +--lux-font: 'Inter', 'Segoe UI', system-ui, -apple-system, 'PingFang SC', 'Microsoft YaHei', sans-serif; +--lux-font-mono: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', ui-monospace, monospace; +``` -## Elevation & Depth +### Scale -| Level | Treatment | Use | +| Token | Size | Weight | Use | +|---|---|---|---| +| `--lux-text-hero` | 24px | 700 | 首页欢迎标题 | +| `--lux-text-h1` | 18px | 700 | 页面标题、卡片标题 | +| `--lux-text-h2` | 16px | 600 | 子标题、对话框标题 | +| `--lux-text-body` | 14px | 400 | 正文、表格单元格 | +| `--lux-text-sm` | 13px | 400 | 辅助文本、分页 | +| `--lux-text-xs` | 12px | 500 | 标签、徽章、脚注 | + +### Letter Spacing + +- 标题: `-0.02em` +- 正文: `0` +- 大写标签: `0.03em` + +--- + +## 4. Spacing + +```css +--lux-space-1: 4px; +--lux-space-2: 8px; +--lux-space-3: 12px; +--lux-space-4: 16px; +--lux-space-5: 20px; +--lux-space-6: 24px; +--lux-space-8: 32px; +--lux-space-10: 40px; +--lux-space-12: 48px; +``` + +--- + +## 5. Border Radius + +```css +--lux-radius-sm: 8px; /* 标签、小按钮 */ +--lux-radius-md: 10px; /* 输入框、下拉菜单 */ +--lux-radius-lg: 14px; /* 卡片、搜索栏 */ +--lux-radius-xl: 18px; /* 对话框 */ +--lux-radius-2xl: 24px; /* 登录卡片 */ +--lux-radius-pill: 999px; /* 徽章、圆形按钮 */ +``` + +--- + +## 6. Elevation System (Dimensional Layering) + +| Level | Z-index | Surface | Use | +|---|---|---|---| +| **L0 — Background** | 0 | 页面渐变 + 光球 | 宇宙底色装饰层 | +| **L1 — Content** | 1 | 玻璃卡片 (blur 14–20px) | 搜索栏、表格卡片、首页卡片 | +| **L2 — Floating** | 10–100 | 侧栏、顶栏、TabsView | 导航/定位组件 | +| **L3 — Overlay** | 2000+ | 对话框、下拉菜单 | Teleport 弹出层 | + +--- + +## 7. Component Specifications + +### 7.1 Card (el-card) + +``` +背景: var(--lux-glass-bg-card) +模糊: var(--lux-blur-lg) [20px] +边框: 1px solid var(--lux-glass-border) +圆角: var(--lux-radius-lg) [14px] +阴影: var(--lux-shadow-1) +hover 阴影: var(--lux-shadow-2) +padding: 20px (body), 16px 20px (header) +``` + +### 7.2 Table (el-table) + +``` +表头背景: rgba(15, 23, 42, 0.65) + blur(14px) +行背景: transparent (卡片底色透出) +hover 行: rgba(56, 189, 248, 0.06) +边框色: rgba(255, 255, 255, 0.06) +文字: var(--lux-text-body) +表头文字: var(--lux-text-muted) +圆角: 12px (overflow hidden) +``` + +### 7.3 Dialog (el-dialog, Teleport) + +``` +背景: var(--lux-glass-bg-dialog) + blur(24px) +边框: 1px solid var(--lux-glass-border) +圆角: var(--lux-radius-xl) [18px] +阴影: var(--lux-shadow-4) + inset glow +header: 1px solid rgba(255, 255, 255, 0.08) 底分割 +``` + +### 7.4 Input (el-input, el-select) + +``` +背景: var(--lux-glass-bg-input) +圆角: var(--lux-radius-md) [10px] +边框: 1px solid var(--lux-glass-border) +focus: 1px solid var(--lux-glass-border-focus) + var(--lux-glow-cyan) +placeholder: var(--lux-text-dim) +``` + +### 7.5 Button — Primary + +``` +背景: linear-gradient(135deg, #38bdf8, #22d3ee) +文字: #fff +圆角: var(--lux-radius-md) [10px] +阴影: 0 4px 12px rgba(56, 189, 248, 0.25) +hover 阴影: 0 6px 16px rgba(56, 189, 248, 0.35) +``` + +### 7.6 Sidebar + +``` +背景: var(--lux-glass-bg-sidebar) +模糊: var(--lux-blur-lg) [18px] +宽度: 64px (collapsed) / 220px (expanded) +边框右: 1px solid rgba(255, 255, 255, 0.08) +z-index: 100 (L2) +active item: gradient bg rgba(56,189,248,0.22) → rgba(99,102,241,0.14) + + 1px inset border rgba(56,189,248,0.25) +``` + +### 7.7 Header + +``` +背景: var(--lux-glass-bg-header) +模糊: var(--lux-blur-md) [14px] +高度: 44px +圆角: 10px +边框: 1px solid var(--lux-glass-border) +阴影: var(--lux-shadow-1) +``` + +### 7.8 TabsView + +``` +inactive: rgba(30, 41, 59, 0.35) 背景, 无模糊 +active: rgba(30, 41, 59, 0.55) + 上方 2px cyan 指示条 +圆角: 10px +gap: 4px +``` + +### 7.9 Pagination + +``` +背景: transparent +active: #38bdf8 实心背景 + white text + 8px radius +hover: cyan 文字 +``` + +### 7.10 Tag (el-tag) + +``` +圆角: 8px +背景: rgba 半透明 (继承 Element Plus type 色 at 15% alpha) +``` + +### 7.11 Dropdown Menu + +``` +背景: rgba(30, 41, 59, 0.82) + blur(18px) +边框: 1px solid var(--lux-glass-border) +圆角: 10px +hover item: rgba(56, 189, 248, 0.12) +``` + +--- + +## 8. Motion + +```css +/* 过渡时间 */ +--lux-duration-fast: 0.15s; /* hover 状态切换 */ +--lux-duration-normal: 0.25s; /* 展开/折叠 */ +--lux-duration-slow: 0.35s; /* 页面切换 */ + +/* 缓动 */ +--lux-ease: ease; +--lux-ease-out: cubic-bezier(0.16, 1, 0.3, 1); +``` + +### Key Transitions + +- **卡片 hover**: `transform: translateY(-2px)` + shadow 加深, 0.15s +- **侧栏展开/折叠**: width 64→220px, 0.30s ease +- **对话框进出**: Element Plus 默认 fade + scale (不覆盖) +- **输入框 focus**: box-shadow ring 0.2s ease + +--- + +## 9. Accessibility + +| 项目 | 标准 | +|---|---| +| 正文文本对比度 | WCAG AA ≥ 4.5:1 (实际 `#e2e8f0` on `#0a0e14` = 13.5:1) | +| 辅助文本对比度 | WCAG AA ≥ 4.5:1 (实际 `#94a3b8` on `#1e293b` = 5.8:1) | +| 焦点指示 | 3px cyan glow ring (box-shadow) | +| 触摸目标 | 按钮 ≥ 32×32px, 输入框高度 ≥ 32px | +| 半透明文本 | 不低于 `rgba(255,255,255,0.55)` | + +--- + +## 10. Bug Fixes (Pre-refactoring) + +| 文件 | 问题 | 修复 | |---|---|---| -| Flat | No shadow, no border | Body sections, top nav, hero bands | -| Soft hairline | 1px `{colors.hairline}` border | Inputs, sub-nav, occasionally on cards | -| Cream card | `{colors.surface-card}` background — no shadow | Feature cards, content cards | -| Dark surface card | `{colors.surface-dark}` background — no shadow | Code editor mockups, model showcase cards | -| Subtle drop shadow | Faint shadow at low alpha | Hover-elevated states (the system uses `0 1px 3px rgba(20,20,19,0.08)` rarely) | +| `views/brand/index.vue` | `.title { color: #333 }` 深色背景不可见 | → `#e2e8f0` | +| `views/blacklist/index.vue` | `.title { color: #333 }` | → `#e2e8f0` | +| `views/ota-target-device/index.vue` | `.title { color: #333 }` | → `#e2e8f0` | -The elevation philosophy is **color-block first, shadow rare**. Most depth comes from the cream-vs-dark surface contrast. Shadows are minimal. The dark surface mockups have their own internal product chrome (code editor scrollbars, line numbers, syntax highlighting) which adds detail without needing external shadows. +--- -### Decorative Depth -- The Anthropic spike-mark glyph (4-spoke radial asterisk) appears as a small black mark in the brand wordmark and inline as a content marker. -- Code editor mockups carry their own internal depth: syntax-highlighted text in muted blues / oranges / grays, line numbers in `{colors.muted-soft}`, status bars at the bottom in `{colors.surface-dark-elevated}`. -- Some hero illustrations use simple line-art with coral and dark-navy strokes on cream — minimal, hand-drawn-feeling, never photorealistic. +## 11. File Impact Map -## Shapes - -### Border Radius Scale - -| Token | Value | Use | +| 文件 | 改动类型 | 改动范围 | |---|---|---| -| `{rounded.xs}` | 4px | Reserved for badge accents and tiny dropdowns | -| `{rounded.sm}` | 6px | Small inline buttons, dropdown items | -| `{rounded.md}` | 8px | Standard CTA buttons, text inputs, category tabs | -| `{rounded.lg}` | 12px | Content cards (feature, pricing, code-window, model-comparison) | -| `{rounded.xl}` | 16px | Hero illustration container, the larger marquee components | -| `{rounded.pill}` | 9999px | Badge pills, "NEW" tags | -| `{rounded.full}` | 9999px / 50% | Avatar substitutes, icon buttons | +| `styles/lux-theme.css` | **主改** | Token 扩展 + 全组件玻璃化 (~60% 改动) | +| `components/TabsView.vue` | 样式 | 玻璃标签页样式 | +| `views/home/index.vue` | 样式 | 首页卡片玻璃化 | +| `views/brand/index.vue` | 样式+bug | 列表页玻璃化 + 修复 `.title` | +| `views/model/index.vue` | 样式 | 列表页玻璃化 | +| `views/ota/index.vue` | 样式 | 列表页玻璃化 | +| `views/blacklist/index.vue` | 样式+bug | 列表页玻璃化 + 修复 `.title` | +| `views/ota-target-device/index.vue` | 样式+bug | 列表页玻璃化 + 修复 `.title` | +| `views/share-code/log.vue` | 样式 | 列表页玻璃化 | +| `views/system/users/index.vue` | 样式 | 列表页玻璃化 | +| `views/login/index.vue` | 无改动 | 已是标杆实现 | +| `layout/index.vue` | 无改动 | 已是玻璃化实现 | -### Photography & Illustrations -Claude's hero rarely uses photography. Instead it uses: -- Simple line-art illustrations with coral + dark-navy strokes on the cream canvas -- Code editor mockups (the dominant "hero" treatment on developer-focused pages) -- Terminal output mockups with monospace text on dark -- Model comparison cards (Opus / Sonnet / Haiku) with abstract geometric thumbnails +--- -When photography is used (rare — mostly testimonials), avatars crop to perfect circles at 40px diameter. +## 12. Implementation Phases -## Components - -### Top Navigation - -**`top-nav`** — Cream nav bar pinned to the top of every page. 64px tall, `{colors.canvas}` background. Carries the Anthropic spike-mark + "Claude" wordmark at left, primary horizontal menu (Product, Solutions, Use Cases, Pricing, Research, Company) center-left, right-side cluster with "Sign in" text-link, "Try Claude" `{component.button-primary}` (coral). Menu items in `{typography.nav-link}` (StyreneB 14px / 500). - -### Buttons - -**`button-primary`** — The signature coral CTA. Background `{colors.primary}` (#cc785c), text `{colors.on-primary}` (white), type `{typography.button}` (StyreneB 14px / 500), padding 12px × 20px, height 40px, rounded `{rounded.md}` (8px). Active state `button-primary-active` darkens to `{colors.primary-active}` (#a9583e). - -**`button-secondary`** — Cream button with hairline outline. Background `{colors.canvas}`, text `{colors.ink}`, 1px hairline border, same padding + height + radius as primary. - -**`button-secondary-on-dark`** — Used over `{colors.surface-dark}` cards. Background `{colors.surface-dark-elevated}` (#252320), text `{colors.on-dark}`. Stays dark — the system never inverts to a light secondary on dark surfaces. - -**`button-text-link`** — Inline text button, no background. Used for "Sign in" in the top nav and inline CTA links. - -**`button-icon-circular`** — 36px circular icon button. Background `{colors.canvas}`, hairline border, ink-color icon. Used for carousel arrows, share, "view more". - -**`text-link`** — Inline body links in `{colors.primary}` (the coral). Underlined on press; the coral inline link is one of the system's most distinctive small details. - -### Cards & Containers - -**`hero-band`** — Cream-canvas hero with a 6-6 grid: h1 + sub-headline + button row on the left, hero illustration card or product mockup card on the right. Vertical padding `{spacing.section}` (96px). - -**`hero-illustration-card`** — A larger card holding the hero's right-side artifact — sometimes a coral-stroke line illustration on cream background, sometimes a dark code editor mockup. Background `{colors.canvas}` or `{colors.surface-dark}` depending on context, rounded `{rounded.xl}` (16px). - -**`feature-card`** — Used in 3-up feature grids. Background `{colors.surface-card}` (#efe9de — slightly darker cream), rounded `{rounded.lg}` (12px), internal padding `{spacing.xl}` (32px). Carries a small icon at top, an `{typography.title-md}` headline, and a body description in `{typography.body-md}`. - -**`product-mockup-card-dark`** — Dark navy card showing actual Claude product chrome (chat interface, code editor, agent controls). Background `{colors.surface-dark}`, rounded `{rounded.lg}`, internal padding `{spacing.xl}` (32px). Carries text labels in `{colors.on-dark}` and product UI fragments below. - -**`code-window-card`** — A specialized dark card showing a code editor with line numbers, syntax-highlighted code in `{typography.code}` (JetBrains Mono), and sometimes a "Run" button or terminal output panel below. Background `{colors.surface-dark}` with `{colors.surface-dark-soft}` for the inner code block, rounded `{rounded.lg}`, padding `{spacing.lg}` (24px). The signature visual element of Claude Code product pages. - -**`model-comparison-card`** — Used on the homepage's "Which problem are you up against?" section comparing Opus / Sonnet / Haiku. Background `{colors.canvas}` with hairline border, rounded `{rounded.lg}`, internal padding `{spacing.xl}` (32px). Carries the model name, a short capability blurb, and a `{component.text-link}` to learn more. - -**`pricing-tier-card`** — Standard tier card. Background `{colors.canvas}` with hairline border, rounded `{rounded.lg}`, padding `{spacing.xl}` (32px). Carries the plan name in `{typography.title-lg}` (StyreneB), price in `{typography.display-sm}` (Copernicus serif!), feature checklist in `{typography.body-md}`, and a `{component.button-primary}` at the bottom. - -**`pricing-tier-card-featured`** — The featured tier (typically "Pro" or "Team"). Background flips to `{colors.surface-dark}`, text inverts to `{colors.on-dark}`. The dark surface IS the featured-tier signal. - -**`callout-card-coral`** — A full-bleed coral card carrying a major call-to-action. Background `{colors.primary}` (#cc785c), text `{colors.on-primary}` (white), rounded `{rounded.lg}`, padding `{spacing.xxl}` (48px). The coral surface IS the voltage; the CTA inside uses an inverted button style (cream/canvas button on coral). - -**`connector-tile`** — Used on the connectors page's integration grid. Background `{colors.canvas}` with hairline border, rounded `{rounded.lg}`, padding 20px. Each tile carries a logo at top, a `{typography.title-sm}` connector name, and a short description. - -### Inputs & Forms - -**`text-input`** — Standard text input. Background `{colors.canvas}`, text `{colors.ink}`, type `{typography.body-md}`, rounded `{rounded.md}` (8px), padding 10px × 14px, height 40px. 1px hairline border in `{colors.hairline}`. - -**`text-input-focused`** — Focus state. Border thickens or shifts to `{colors.primary}` (coral) for emphasis. Carries a 3px coral-at-15%-alpha outer ring. - -**`cookie-consent-card`** — Bottom-right floating dark cookie banner. Background `{colors.surface-dark}`, text `{colors.on-dark}`, rounded `{rounded.lg}`, padding `{spacing.lg}` (24px). One of the few places dark surface appears at small scale on cream pages. - -### Tags / Badges - -**`badge-pill`** — Small pill label used for category tags. Background `{colors.surface-card}`, text `{colors.ink}`, type `{typography.caption}` (13px / 500), rounded `{rounded.pill}`, padding 4px × 12px. - -**`badge-coral`** — Coral-fill badge for "NEW", "BETA", featured highlights. Background `{colors.primary}`, text `{colors.on-primary}`, type `{typography.caption-uppercase}` (12px / 500 / 1.5px tracking), rounded `{rounded.pill}`, padding 4px × 12px. - -### Tab / Filter - -**`category-tab`** + **`category-tab-active`** — Used in sub-nav rows on solutions / connectors pages. Inactive: transparent background, `{colors.muted}` text. Active: `{colors.surface-card}` background, `{colors.ink}` text. Padding 8px × 14px, rounded `{rounded.md}`. - -### CTA / Footer - -**`cta-band-coral`** — A pre-footer "Try Claude" CTA card. Full-width coral fill, white type, rounded `{rounded.lg}`, padding 64px. Carries an h2 in `{typography.display-sm}` (still serif!), a sub-line, and a cream-button CTA. - -**`cta-band-dark`** — Alternative pre-footer band on developer-focused pages. Background `{colors.surface-dark}`, text `{colors.on-dark}`, rounded `{rounded.lg}`, padding 64px. Often pairs with a code-window card. - -**`footer`** — Dark navy footer that closes every page. Background `{colors.surface-dark}` (#181715), text `{colors.on-dark-soft}`. 4-column link list at desktop covering Product / Company / Resources / Legal. Vertical padding 64px. The Anthropic spike-mark + "Anthropic" wordmark sits at the top in `{colors.on-dark}`. The footer never inverts. - -## Do's and Don'ts - -### Do -- Anchor every page on the cream canvas. Pure white reads as "any other AI tool"; the warm tint is the brand differentiator. -- Use Copernicus serif for every display headline. Pair with StyreneB sans body. Negative letter-spacing on display sizes is non-negotiable. -- Reserve `{colors.primary}` (coral) for primary CTAs and full-bleed `{component.callout-card-coral}` moments. Don't paint accent moments coral elsewhere. -- Use `{component.product-mockup-card-dark}` and `{component.code-window-card}` to show actual Claude product chrome. Don't paint marketing illustrations of code when you can show real code. -- Pair `{component.feature-card}` (cream) with `{component.product-mockup-card-dark}` (navy) in alternating bands. The cream-to-dark rhythm is the brand's pacing mechanism. -- Use the Anthropic spike-mark glyph as the brand wordmark prefix. Never invert the mark to white-on-dark within the wordmark itself. -- Apply `{spacing.section}` (96px) between major bands. - -### Don't -- Don't use cool grays or pure white for canvas. Cream is the brand. -- Don't bold serif display weight. Copernicus at 700 reads as bombastic; the system stays at 400. -- Don't use cool blue or saturated cyan as a brand accent. The coral is the brand voltage. -- Don't put coral everywhere. The coral is scarce on individual elements and generous only on full-bleed coral callout cards. -- Don't use Inter for display headlines. The serif character is the brand voice. -- Don't repeat the same surface mode in two consecutive bands. The pacing alternates: cream → cream-card → dark-mockup → cream → coral-callout → dark-footer. -- Don't add hover state styling beyond what the system already encodes — primary darkens on press; nothing else changes. - -## Responsive Behavior - -### Breakpoints - -| Name | Width | Key Changes | -|---|---|---| -| Mobile | < 768px | Hamburger nav; hero h1 64→32px; hero-illustration-card stacks below content; feature grids 1-up; connector tiles 2-up; pricing 1-up; footer 4 cols → 1 | -| Tablet | 768–1024px | Top nav stays horizontal but tightens; feature cards 2-up; connector tiles 3-up; pricing 2-up | -| Desktop | 1024–1440px | Full top-nav with all menu items; 3-up feature cards; 4-up or 6-up connector tiles; 3-up pricing tiers | -| Wide | > 1440px | Same as desktop with more outer breathing room; max content width caps at 1200px | - -### Touch Targets -- `{component.button-primary}` at minimum 40 × 40px. -- `{component.button-icon-circular}` at exactly 36 × 36 — slightly under WCAG 44 but visually centered. -- `{component.text-input}` height is 40px. -- Connector tile entire card area is tappable; effective tap area >> 44px. - -### Collapsing Strategy -- Top nav collapses to hamburger at < 768px; menu opens as a full-screen cream sheet. -- Hero band's 6-6 grid collapses to single-column on mobile — h1 + sub-head + buttons first, then the illustration / mockup card below. -- Feature grids reduce columns rather than scaling cards down. -- Pricing tier cards collapse 4 → 2 → 1; featured-tier dark surface stays visually distinct at every breakpoint. -- Code-window cards retain code legibility at every breakpoint by allowing horizontal scroll within the card rather than wrapping code lines. - -### Image Behavior -- Code blocks inside dark mockups stay at fixed font-size; horizontal scroll on mobile rather than wrapping. -- Hero illustrations scale proportionally; line-art strokes thin slightly on mobile. -- Avatar photos in testimonials crop to circles at every breakpoint. - -## Iteration Guide - -1. Focus on ONE component at a time. Reference its YAML key (`{component.feature-card}`, `{component.code-window-card}`). -2. Variants of an existing component (`-active`, `-disabled`, `-focused`) live as separate entries in `components:`. -3. Use `{token.refs}` everywhere — never inline hex. -4. Never document hover. Default and Active/Pressed states only. -5. Display headlines stay Copernicus serif 400 with negative tracking. Body stays StyreneB / Inter 400. The split is unbreakable. -6. Cream + coral + dark navy is the trinity. Don't introduce a fourth surface tone (no purple cards, no green sections). -7. When in doubt about emphasis: bigger Copernicus serif before bolder weight. - -## Known Gaps - -- Copernicus and StyreneB are licensed Anthropic typefaces and not available as public web fonts. Substitutes (Tiempos Headline / Cormorant Garamond / EB Garamond for serif; Inter / Söhne for sans) are documented in the typography section. -- The Anthropic radial-spike-mark is a brand glyph rendered as inline SVG; it's not formalized as a system token here. Treat it as a logo asset. -- Animation and transition timings (chat message reveal, code block typewriter effect on the homepage, agentic-flow diagram animations) are not in scope. -- Form validation states beyond `{component.text-input-focused}` are not extracted — error / success states would need a sign-up or feedback flow to confirm. -- The actual Claude product surface (claude.ai chat interface) shares some tokens with the marketing site but adds many product-specific components (chat bubbles, message tools, file upload chips, conversation history sidebar) that are out of scope for this marketing-surface document. -- The "agent" / "computer use" demo cards on certain pages display animated Claude controlling a browser — the static screenshot doesn't fully capture the animation chrome. +1. **Token 扩展** — lux-theme.css 新增 glass/elevation/spacing 变量 +2. **Bug 修复** — 3 个文件 `.title` 颜色修复 +3. **卡片玻璃化** — `.el-card` 改为半透明 + blur +4. **表格玻璃化** — `.el-table` 透明底 + 半透明表头 +5. **输入框玻璃化** — `.el-input` / `.el-select` 玻璃输入 +6. **对话框玻璃化** — `.el-dialog` 玻璃面板 +7. **按钮/标签/分页** — 统一 glass 风格 +8. **TabsView 玻璃化** — 标签栏玻璃标签 +9. **列表页 scoped 样式** — 各页面 `.title`/`.card-header` 统一 +10. **首页增强** — 快捷入口卡片 + 今日新增卡片玻璃化 +11. **下拉菜单/消息框** — 弹出层玻璃化 diff --git a/frontend/src/components/TabsView.vue b/frontend/src/components/TabsView.vue index 4011ebb..ad15632 100644 --- a/frontend/src/components/TabsView.vue +++ b/frontend/src/components/TabsView.vue @@ -320,6 +320,7 @@ watch( .tabs-view-label-icon { font-size: 14px; color: #94a3b8; + transition: color 0.2s ease; } .tabs-view :deep(.el-tabs__nav-scroll) { diff --git a/frontend/src/layout/index.vue b/frontend/src/layout/index.vue index f5b3d16..490ed7d 100644 --- a/frontend/src/layout/index.vue +++ b/frontend/src/layout/index.vue @@ -316,10 +316,12 @@ function handleUserMenuCommand(command) { color: #e0f2fe; background: linear-gradient( 90deg, - rgba(56, 189, 248, 0.22), - rgba(99, 102, 241, 0.14) + rgba(56, 189, 248, 0.18), + rgba(251, 113, 133, 0.12) ); - box-shadow: 0 0 0 1px rgba(56, 189, 248, 0.25) inset; + box-shadow: + 0 0 0 1px rgba(56, 189, 248, 0.2) inset, + inset 3px 0 0 rgba(251, 113, 133, 0.6); } .sidebar-rail-item .el-icon { diff --git a/frontend/src/styles/lux-theme.css b/frontend/src/styles/lux-theme.css index 255effd..2658e25 100644 --- a/frontend/src/styles/lux-theme.css +++ b/frontend/src/styles/lux-theme.css @@ -4,6 +4,787 @@ body { background: #0a0e14; } +/** + * Luxsin CMS Design System + * Glassmorphism + Dimensional Layering + Dark Mode OLED + */ +:root { + /* ── 基础色板 ── */ + --lux-font: + 'Inter', 'Segoe UI', system-ui, -apple-system, 'PingFang SC', 'Microsoft YaHei', + sans-serif; + --lux-page-bg: #0a0e14; + --lux-page-gradient: radial-gradient(ellipse 120% 90% at 50% -15%, #1a2840 0%, #0d1117 48%, #0a0e14 100%); + + /* 文本 */ + --lux-text-strong: #e2e8f0; + --lux-text-body: #cbd5e1; + --lux-text-muted: #94a3b8; + --lux-text-dim: #64748b; + + /* 品牌色 */ + --lux-cyan: #38bdf8; + --lux-cyan-light: #7dd3fc; + --lux-cyan-glow: rgba(56, 189, 248, 0.25); + --lux-indigo: #6366f1; + --lux-violet: #7c3aed; + --lux-coral: #fb7185; + --lux-coral-light: #fda4af; + --lux-coral-glow: rgba(251, 113, 133, 0.25); + + /* 玻璃表面 */ + --lux-glass-bg-card: rgba(30, 41, 59, 0.55); + --lux-glass-bg-table: rgba(30, 41, 59, 0.45); + --lux-glass-bg-input: rgba(15, 23, 42, 0.45); + --lux-glass-bg-dialog: rgba(30, 41, 59, 0.72); + --lux-glass-bg-sidebar: rgba(15, 23, 42, 0.60); + --lux-glass-bg-header: rgba(30, 41, 59, 0.75); + --lux-glass-bg-tab: rgba(30, 41, 59, 0.35); + --lux-glass-bg-tab-active: rgba(30, 41, 59, 0.55); + --lux-glass-bg-dropdown: rgba(30, 41, 59, 0.82); + + /* 玻璃边框 */ + --lux-glass-border: rgba(255, 255, 255, 0.08); + --lux-glass-border-hover: rgba(255, 255, 255, 0.14); + --lux-glass-border-focus: rgba(56, 189, 248, 0.45); + + /* 模糊 */ + --lux-blur-sm: blur(8px); + --lux-blur-md: blur(14px); + --lux-blur-lg: blur(20px); + --lux-blur-xl: blur(24px); + + /* Elevation shadows */ + --lux-shadow-1: 0 2px 8px rgba(0, 0, 0, 0.18); + --lux-shadow-2: 0 4px 16px rgba(0, 0, 0, 0.25); + --lux-shadow-3: 0 8px 32px rgba(0, 0, 0, 0.35); + --lux-shadow-4: 0 25px 50px -12px rgba(0, 0, 0, 0.50); + + /* 焦点 glow */ + --lux-glow-cyan: 0 0 0 3px rgba(56, 189, 248, 0.15), 0 0 0 1px rgba(56, 189, 248, 0.45) inset; + + /* 圆角 */ + --lux-radius-sm: 8px; + --lux-radius-md: 10px; + --lux-radius-lg: 14px; + --lux-radius-xl: 18px; + + /* 向后兼容旧变量 */ + --lux-card-bg: var(--lux-glass-bg-card); + --lux-card-border: var(--lux-glass-border); + --lux-glass-sidebar: var(--lux-glass-bg-sidebar); + --lux-glass-header: var(--lux-glass-bg-header); + --lux-input-bg: var(--lux-glass-bg-input); +} + +.lux-shell { + font-family: var(--lux-font); + position: relative; + min-height: 100vh; + height: 100vh; + overflow: hidden; + color: var(--lux-text-strong); + background: var(--lux-page-gradient); +} + +.lux-shell-bg { + position: absolute; + inset: 0; + pointer-events: none; + z-index: 0; + overflow: hidden; +} + +.lux-orb { + position: absolute; + border-radius: 50%; + filter: blur(80px); + opacity: 0.34; +} + +.lux-orb-1 { + width: min(52vw, 400px); + height: min(52vw, 400px); + background: #22d3ee; + top: -12%; + left: -8%; +} + +.lux-orb-2 { + width: min(48vw, 360px); + height: min(48vw, 360px); + background: #a78bfa; + top: 40%; + right: -12%; + opacity: 0.28; +} + +.lux-orb-3 { + width: min(42vw, 320px); + height: min(42vw, 320px); + background: #fb7185; + bottom: -8%; + left: 20%; + opacity: 0.18; +} + +.lux-shell-body { + position: relative; + z-index: 1; + height: 100%; + background: transparent !important; +} + +.lux-shell-body > .el-container { + height: 100%; + box-sizing: border-box; + padding-left: 64px; +} + +.lux-shell-body > .el-container > .lux-right-col { + flex: 1; + min-width: 0; + width: 100%; + position: relative; + z-index: 1; + isolation: isolate; +} + +/* ────────────────────────────────────────── + * 侧栏玻璃 (L2 — Floating) + * ────────────────────────────────────────── */ +.lux-shell .sidebar-glass { + position: absolute; + left: 0; + top: 0; + bottom: 0; + flex: none; + width: 64px !important; + height: 100%; + display: flex; + flex-direction: column; + overflow: hidden; + background: var(--lux-glass-bg-sidebar) !important; + backdrop-filter: var(--lux-blur-lg); + -webkit-backdrop-filter: var(--lux-blur-lg); + border-right: 1px solid var(--lux-glass-border); + box-shadow: inset -1px 0 0 rgba(255, 255, 255, 0.04); + transition: width 0.30s ease, box-shadow 0.30s ease; + z-index: 100; +} + +.lux-shell .sidebar-glass:not(.is-collapsed) { + width: 220px !important; + box-shadow: + var(--lux-shadow-3), + inset -1px 0 0 rgba(255, 255, 255, 0.04); +} + +.lux-shell .sidebar-glass.is-collapsed { + width: 64px !important; +} + +.lux-shell .sidebar-logo { + height: 60px; + display: flex; + align-items: center; + justify-content: flex-start; + padding: 0 14px; + background: linear-gradient(180deg, rgba(255, 255, 255, 0.06) 0%, transparent 100%); + border-bottom: 1px solid var(--lux-glass-border); +} + +.lux-shell .sidebar-glass.is-collapsed .sidebar-logo { + width: 64px; + min-width: 64px; + justify-content: center; + padding: 0; + overflow: visible; +} + +.lux-shell .lux-menu.el-menu { + min-height: 0; + border-right: none !important; + background: transparent !important; + padding: 8px 6px 16px; +} + +.lux-shell .lux-menu--expanded.is-active.el-menu { + flex: 1; + overflow-y: auto; +} + +.lux-shell .lux-menu .el-sub-menu__title { + border-radius: var(--lux-radius-md); + margin: 2px 0; + color: var(--lux-text-body) !important; +} + +.lux-shell .lux-menu .el-sub-menu__title:hover { + background: rgba(255, 255, 255, 0.06) !important; +} + +.lux-shell .lux-menu .el-menu-item { + border-radius: var(--lux-radius-md); + margin: 3px 4px; + color: var(--lux-text-body) !important; +} + +.lux-shell .lux-menu .el-menu-item:hover { + background: rgba(255, 255, 255, 0.07) !important; + color: var(--lux-text-strong) !important; +} + +.lux-shell .lux-menu .el-menu-item.is-active { + color: #e0f2fe !important; + background: linear-gradient( + 90deg, + rgba(56, 189, 248, 0.18), + rgba(251, 113, 133, 0.12) + ) !important; + box-shadow: + 0 0 0 1px rgba(56, 189, 248, 0.2) inset, + inset 3px 0 0 rgba(251, 113, 133, 0.6); +} + +.lux-shell .lux-menu .el-icon { + color: inherit; +} + +/* ────────────────────────────────────────── + * 顶栏玻璃 (L2 — Floating) + * ────────────────────────────────────────── */ +.lux-shell .lux-header { + height: 44px !important; + min-height: 44px !important; + display: flex; + align-items: center; + justify-content: flex-end; + padding: 0 14px !important; + margin: 8px 16px 0 8px; + border-radius: var(--lux-radius-md); + background: var(--lux-glass-bg-header) !important; + backdrop-filter: var(--lux-blur-md); + -webkit-backdrop-filter: var(--lux-blur-md); + border: 1px solid var(--lux-glass-border) !important; + box-shadow: var(--lux-shadow-1); +} + +.lux-shell .lux-header-user-btn { + width: 34px !important; + height: 34px !important; + padding: 0 !important; + box-shadow: 0 4px 12px rgba(56, 189, 248, 0.22) !important; +} + +.lux-shell .lux-header-user-btn .el-icon { + margin: 0; +} + +.lux-shell .lux-header-user-btn:hover, +.lux-shell .lux-header-user-btn:focus { + box-shadow: 0 6px 16px rgba(56, 189, 248, 0.3) !important; +} + +/* ────────────────────────────────────────── + * 主内容区 + * ────────────────────────────────────────── */ +.lux-shell .lux-main { + background: transparent !important; + padding: 12px 16px 24px 12px !important; + overflow: auto; + flex: 1; + min-height: 0; +} + +/* 表格 loading 仅覆盖表格区域 */ +.lux-shell .table-loading-host { + position: relative; + overflow: hidden; + min-height: 120px; +} + +.lux-shell .table-loading-host .el-loading-mask { + z-index: 8 !important; +} + +/* ────────────────────────────────────────── + * 底栏 + * ────────────────────────────────────────── */ +.lux-shell .lux-footer { + flex-shrink: 0; + height: auto !important; + padding: 10px 16px 14px !important; + margin: 0 16px 12px 8px; + display: flex; + align-items: center; + justify-content: center; + background: rgba(15, 23, 42, 0.35) !important; + backdrop-filter: var(--lux-blur-sm); + -webkit-backdrop-filter: var(--lux-blur-sm); + border-radius: var(--lux-radius-lg); + border: none !important; + box-shadow: none; +} + +.lux-shell .lux-footer-copy { + font-size: 12px; + color: rgba(203, 213, 225, 0.85); + letter-spacing: 0.03em; + user-select: none; +} + +/* ────────────────────────────────────────── + * 卡片标题 (全局) + * ────────────────────────────────────────── */ +.lux-shell .card-header .title { + font-size: 18px; + font-weight: 700; + letter-spacing: -0.02em; + color: var(--lux-text-strong); +} + +.lux-shell .brand-not-in-db-tip { + color: #f59e0b; +} + +/* ══════════════════════════════════════════ + * L1 — CONTENT: 卡片 / 表格 (玻璃拟态) + * ══════════════════════════════════════════ */ + +/* ── 卡片玻璃 ── */ +.lux-shell .el-card { + border-radius: var(--lux-radius-lg) !important; + background: var(--lux-glass-bg-card) !important; + backdrop-filter: var(--lux-blur-lg); + -webkit-backdrop-filter: var(--lux-blur-lg); + border: 1px solid var(--lux-glass-border) !important; + box-shadow: var(--lux-shadow-1); + color: var(--lux-text-strong); + transition: box-shadow 0.2s ease, transform 0.15s ease, border-color 0.2s ease; +} + +.lux-shell .el-card:hover { + box-shadow: var(--lux-shadow-2); + border-color: var(--lux-glass-border-hover) !important; +} + +.lux-shell .el-card__header { + border-bottom: 1px solid var(--lux-glass-border) !important; + font-weight: 600; + color: var(--lux-text-strong); +} + +/* 搜索卡片 — 压缩高度 */ +.lux-shell .el-card.search-card { + margin-bottom: 14px !important; +} + +.lux-shell .el-card.search-card:hover { + transform: none; +} + +.lux-shell .el-card.search-card .el-card__body { + padding: 8px 14px 10px !important; +} + +.lux-shell .search-form.el-form--inline .el-form-item { + margin-bottom: 4px; + margin-top: 0; +} + +/* ── 表格玻璃 ── */ +.lux-shell .el-table { + --el-table-border-color: rgba(255, 255, 255, 0.06); + --el-table-header-bg-color: rgba(15, 23, 42, 0.65); + --el-table-row-hover-bg-color: rgba(251, 113, 133, 0.06); + --el-table-bg-color: transparent; + --el-table-tr-bg-color: transparent; + --el-table-header-text-color: var(--lux-text-muted); + --el-table-text-color: var(--lux-text-body); + --el-table-expanded-cell-bg-color: transparent; + color: var(--lux-text-body); + border-radius: 12px; + overflow: hidden; + background: transparent !important; +} + +.lux-shell .el-table th.el-table__cell { + font-weight: 600; + color: var(--lux-text-muted); + background: rgba(15, 23, 42, 0.65) !important; + backdrop-filter: var(--lux-blur-md); + -webkit-backdrop-filter: var(--lux-blur-md); +} + +/* 表格条纹行 */ +.lux-shell .el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell { + background: rgba(255, 255, 255, 0.02) !important; +} + +/* ── 分页玻璃 ── */ +.lux-shell .el-pagination { + --el-pagination-font-size: 13px; + --el-pagination-button-color: var(--lux-text-muted); + --el-pagination-hover-color: var(--lux-cyan); + --el-pagination-bg-color: transparent; +} + +.lux-shell .el-pagination .el-pager li { + color: var(--lux-text-muted); +} + +.lux-shell .el-pagination .el-pager li.is-active { + color: #fff !important; + background: var(--lux-cyan) !important; + border-radius: var(--lux-radius-sm); +} + +/* ══════════════════════════════════════════ + * 按钮 (玻璃拟态) + * ══════════════════════════════════════════ */ + +/* 主按钮 (纯色,禁用渐变) */ +.lux-shell .el-button--primary { + --el-button-bg-color: transparent; + --el-button-border-color: transparent; + background: #38bdf8 !important; + border: none !important; + box-shadow: 0 4px 12px rgba(56, 189, 248, 0.25); + transition: box-shadow 0.2s ease, transform 0.15s ease, background 0.2s ease; +} + +.lux-shell .el-button--primary:hover, +.lux-shell .el-button--primary:focus { + background: #22d3ee !important; + box-shadow: 0 6px 16px rgba(56, 189, 248, 0.35); +} + +.lux-shell .el-button--primary:active { + transform: scale(0.98); +} + +.lux-shell .el-button--primary.is-plain { + background: rgba(56, 189, 248, 0.15) !important; + color: var(--lux-cyan-light) !important; + border: 1px solid rgba(56, 189, 248, 0.35) !important; + box-shadow: none; +} + +.lux-shell .el-button--primary.is-plain:hover { + filter: none; + background: rgba(56, 189, 248, 0.22) !important; +} + +.lux-shell .el-button--warning { + box-shadow: 0 4px 14px rgba(245, 158, 11, 0.25); +} + +.lux-shell .el-button--danger { + box-shadow: 0 4px 14px rgba(239, 68, 68, 0.2); +} + +/* ── 默认按钮玻璃化 ── */ +.lux-shell .el-button--default { + background: rgba(255, 255, 255, 0.06) !important; + border: 1px solid var(--lux-glass-border) !important; + color: var(--lux-text-body) !important; +} + +.lux-shell .el-button--default:hover { + background: rgba(255, 255, 255, 0.10) !important; + border-color: var(--lux-glass-border-hover) !important; + color: var(--lux-text-strong) !important; +} + +/* ══════════════════════════════════════════ + * 输入框 / 下拉 (玻璃拟态) + * ══════════════════════════════════════════ */ +.lux-shell .el-input__wrapper { + border-radius: var(--lux-radius-md); + background-color: var(--lux-glass-bg-input) !important; + backdrop-filter: var(--lux-blur-sm); + -webkit-backdrop-filter: var(--lux-blur-sm); + box-shadow: 0 0 0 1px var(--lux-glass-border) inset !important; + transition: box-shadow 0.2s ease, border-color 0.2s ease; +} + +.lux-shell .el-input__wrapper.is-focus { + box-shadow: var(--lux-glow-cyan) !important; +} + +.lux-shell .el-input__inner { + color: var(--lux-text-strong) !important; +} + +.lux-shell .el-input__inner::placeholder { + color: var(--lux-text-dim) !important; +} + +.lux-shell .el-select .el-select__wrapper { + border-radius: var(--lux-radius-md); + background-color: var(--lux-glass-bg-input) !important; + backdrop-filter: var(--lux-blur-sm); + -webkit-backdrop-filter: var(--lux-blur-sm); +} + +/* ── 数字输入 ── */ +.lux-shell .el-input-number .el-input__wrapper { + background-color: var(--lux-glass-bg-input) !important; +} + +/* ── 日期选择器 ── */ +.lux-shell .el-date-editor .el-input__wrapper { + background-color: var(--lux-glass-bg-input) !important; +} + +/* ══════════════════════════════════════════ + * 标签 (Tag) + * ══════════════════════════════════════════ */ +.lux-shell .el-tag { + border-radius: var(--lux-radius-sm); +} + +/* ══════════════════════════════════════════ + * L3 — OVERLAY: 对话框 / 下拉 / 消息 (玻璃拟态) + * ══════════════════════════════════════════ */ + +/* ── 对话框 (对齐登录框质感) ── */ +.el-overlay .el-dialog { + border-radius: var(--lux-radius-xl); + overflow: hidden; + background: rgba(30, 41, 59, 0.72) !important; + backdrop-filter: blur(24px) saturate(1.5); + -webkit-backdrop-filter: blur(24px) saturate(1.5); + border: 1px solid rgba(255, 255, 255, 0.14); + box-shadow: + var(--lux-shadow-4), + 0 0 0 1px rgba(255, 255, 255, 0.06) inset, + 0 1px 0 rgba(255, 255, 255, 0.1) inset; + position: relative; +} + +/* 光照渐变叠层 (登录框 ::before) */ +.el-overlay .el-dialog::before { + content: ''; + position: absolute; + inset: 0; + background: linear-gradient(145deg, rgba(255, 255, 255, 0.14) 0%, transparent 45%); + pointer-events: none; + z-index: 0; +} + +/* 顶部青色辉光 (登录框 ::after) */ +.el-overlay .el-dialog::after { + content: ''; + position: absolute; + top: 0; + left: 16%; + right: 16%; + height: 1px; + background: linear-gradient(90deg, transparent, rgba(56, 189, 248, 0.4), transparent); + pointer-events: none; + z-index: 2; +} + +.el-overlay .el-dialog > * { + position: relative; + z-index: 1; +} + +.el-overlay .el-dialog__header { + border-bottom: 1px solid rgba(255, 255, 255, 0.08); + padding: 18px 24px 14px; +} + +.el-overlay .el-dialog__title { + color: var(--lux-text-strong); + font-weight: 700; + font-size: 16px; + letter-spacing: -0.01em; +} + +.el-overlay .el-dialog__body { + color: var(--lux-text-body); + padding: 20px 24px; +} + +.el-overlay .el-dialog__footer { + border-top: 1px solid rgba(255, 255, 255, 0.06); + padding: 14px 24px 18px; +} + +.el-overlay .el-dialog__headerbtn { + top: 18px; + right: 18px; + font-size: 16px; + color: var(--lux-text-dim); + transition: color 0.2s ease; +} + +.el-overlay .el-dialog__headerbtn:hover { + color: var(--lux-text-strong); +} + +/* ── 下拉菜单 ── */ +.lux-shell .el-dropdown-menu, +.lux-user-dropdown.el-popper { + background: var(--lux-glass-bg-dropdown) !important; + backdrop-filter: var(--lux-blur-lg); + -webkit-backdrop-filter: var(--lux-blur-lg); + border-color: var(--lux-glass-border) !important; + border-radius: var(--lux-radius-md); + box-shadow: var(--lux-shadow-3); +} + +.lux-user-dropdown .el-dropdown-menu__item { + color: var(--lux-text-body); +} + +.lux-user-dropdown .el-dropdown-menu__item:not(.is-disabled):hover { + background: rgba(56, 189, 248, 0.12); + color: #e0f2fe; +} + +.lux-user-dropdown .lux-user-dropdown-name { + color: var(--lux-text-muted) !important; + font-size: 12px; + cursor: default; +} + +/* ── 消息框 ── */ +.el-message-box { + background: var(--lux-glass-bg-dialog) !important; + backdrop-filter: var(--lux-blur-xl); + -webkit-backdrop-filter: var(--lux-blur-xl); + border-color: var(--lux-glass-border) !important; + border-radius: var(--lux-radius-xl); + box-shadow: var(--lux-shadow-4); +} + +.el-message-box .el-message-box__title { + color: var(--lux-text-strong); +} + +.el-message-box .el-message-box__content { + color: var(--lux-text-body); +} + +/* ── 消息提示 ── */ +.el-message { + backdrop-filter: var(--lux-blur-md); + -webkit-backdrop-filter: var(--lux-blur-md); +} + +/* ── Select 下拉面板 (Teleport) ── */ +.el-popper .el-select-dropdown__item { + color: var(--lux-text-body); +} + +.el-popper .el-select-dropdown__item.is-hovering { + background: rgba(56, 189, 248, 0.10); +} + +.el-popper .el-select-dropdown__item.is-selected { + color: var(--lux-cyan); +} + +.el-select-dropdown { + background: var(--lux-glass-bg-dropdown) !important; + backdrop-filter: var(--lux-blur-lg); + -webkit-backdrop-filter: var(--lux-blur-lg); + border: 1px solid var(--lux-glass-border) !important; + border-radius: var(--lux-radius-md); + box-shadow: var(--lux-shadow-3) !important; +} + +.el-select-dropdown .el-scrollbar__bar { + background: rgba(255, 255, 255, 0.08); +} + +/* ── 表单标签 ── */ +.lux-shell .el-form-item__label { + color: var(--lux-text-muted) !important; +} + +/* ── 开关 ── */ +.lux-shell .el-switch { + --el-switch-off-color: rgba(100, 116, 139, 0.5); +} + +/* ── Upload ── */ +.lux-shell .el-upload-dragger { + background: var(--lux-glass-bg-input) !important; + border-color: var(--lux-glass-border) !important; + border-radius: var(--lux-radius-md); +} + +/* ── 空状态 ── */ +.lux-shell .el-empty__description p { + color: var(--lux-text-muted); +} + +/* ── 面包屑 ── */ +.lux-shell .el-breadcrumb__inner { + color: var(--lux-text-body) !important; +} + +.lux-shell .el-breadcrumb__inner.is-link:hover { + color: var(--lux-cyan-light) !important; +} + +.lux-shell .el-breadcrumb__separator { + color: var(--lux-text-dim) !important; +} + +/* ── Tabs (el-tabs type=card) ── */ +.lux-shell .el-tabs--card > .el-tabs__header .el-tabs__item { + background: var(--lux-glass-bg-tab) !important; + border: 1px solid var(--lux-glass-border) !important; + border-radius: var(--lux-radius-md) var(--lux-radius-md) 0 0; + color: var(--lux-text-muted); + transition: background 0.2s ease, color 0.2s ease; +} + +.lux-shell .el-tabs--card > .el-tabs__header .el-tabs__item.is-active { + background: var(--lux-glass-bg-tab-active) !important; + color: var(--lux-text-strong); + border-bottom-color: transparent !important; + box-shadow: inset 0 2px 0 var(--lux-cyan); +} + +.lux-shell .el-tabs--card > .el-tabs__header .el-tabs__item:hover { + color: var(--lux-text-strong); +} + +.lux-shell .el-tabs--card > .el-tabs__header { + border-bottom: 1px solid var(--lux-glass-border) !important; +} + +.lux-shell .el-tabs--card > .el-tabs__header .el-tabs__nav { + border: none !important; +} + +/* ── Scrollbar ── */ +.lux-shell .el-scrollbar__bar.is-horizontal, +.lux-shell .el-scrollbar__bar.is-vertical { + background: transparent; +} + +.lux-shell .el-scrollbar__thumb { + background: rgba(255, 255, 255, 0.12); + border-radius: 4px; +} + +.lux-shell .el-scrollbar__thumb:hover { + background: rgba(255, 255, 255, 0.20); +} +html, +body { + min-height: 100%; + background: #0a0e14; +} + /** * 全站主题:深色宇宙底、深色卡片、青紫渐变主按钮 */ @@ -15,6 +796,7 @@ body { --lux-text-strong: #e2e8f0; --lux-text-muted: #94a3b8; --lux-cyan: #38bdf8; + --lux-coral: #fb7185; --lux-indigo: #6366f1; --lux-violet: #7c3aed; --lux-card-bg: #1e293b; @@ -69,10 +851,10 @@ body { .lux-orb-3 { width: min(42vw, 320px); height: min(42vw, 320px); - background: #38bdf8; + background: #fb7185; bottom: -8%; left: 20%; - opacity: 0.22; + opacity: 0.18; } .lux-shell-body { @@ -184,10 +966,12 @@ body { color: #e0f2fe !important; background: linear-gradient( 90deg, - rgba(56, 189, 248, 0.22), - rgba(99, 102, 241, 0.14) + rgba(56, 189, 248, 0.18), + rgba(251, 113, 133, 0.12) ) !important; - box-shadow: 0 0 0 1px rgba(56, 189, 248, 0.25) inset; + box-shadow: + 0 0 0 1px rgba(56, 189, 248, 0.2) inset, + inset 3px 0 0 rgba(251, 113, 133, 0.6); } .lux-shell .lux-menu .el-icon { @@ -315,7 +1099,7 @@ body { .lux-shell .el-table { --el-table-border-color: rgba(148, 163, 184, 0.1); --el-table-header-bg-color: #0f172a; - --el-table-row-hover-bg-color: rgba(56, 189, 248, 0.08); + --el-table-row-hover-bg-color: rgba(251, 113, 133, 0.06); --el-table-bg-color: #1e293b; --el-table-tr-bg-color: #1e293b; --el-table-header-text-color: #cbd5e1; @@ -412,14 +1196,18 @@ body { border-radius: 8px; } -/* 对话框(Teleport 到 body,不用 .lux-shell 前缀,深色风格) */ +/* 对话框(Teleport 到 body,继承新版玻璃拟态风格) */ .el-overlay .el-dialog { border-radius: 18px; overflow: hidden; - background: #1e293b !important; + background: rgba(30, 41, 59, 0.72) !important; + backdrop-filter: blur(24px) saturate(1.5); + -webkit-backdrop-filter: blur(24px) saturate(1.5); + border: 1px solid rgba(255, 255, 255, 0.14); box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5), - 0 0 0 1px rgba(148, 163, 184, 0.1) inset; + 0 0 0 1px rgba(255, 255, 255, 0.06) inset, + 0 1px 0 rgba(255, 255, 255, 0.1) inset; } .el-overlay .el-dialog__header { diff --git a/frontend/src/views/blacklist/index.vue b/frontend/src/views/blacklist/index.vue index 501a36f..9b121f0 100644 --- a/frontend/src/views/blacklist/index.vue +++ b/frontend/src/views/blacklist/index.vue @@ -366,7 +366,7 @@ onMounted(() => { .title { font-size: 18px; font-weight: 600; - color: #333; + color: #e2e8f0; } .pagination { margin-top: 20px; diff --git a/frontend/src/views/brand/index.vue b/frontend/src/views/brand/index.vue index 5f09fac..cfd2946 100644 --- a/frontend/src/views/brand/index.vue +++ b/frontend/src/views/brand/index.vue @@ -299,7 +299,7 @@ onMounted(() => { .title { font-size: 18px; font-weight: 600; - color: #333; + color: #e2e8f0; } .pagination { diff --git a/frontend/src/views/home/index.vue b/frontend/src/views/home/index.vue index 9573bb5..1850a6e 100644 --- a/frontend/src/views/home/index.vue +++ b/frontend/src/views/home/index.vue @@ -22,7 +22,7 @@ @click="go(item.path)" >