DESIGN.md@lumina-frontend · diff
git:20260709.c1e6d6e to git:20260709.80784ec
103 added, 116 removed. Audit A to A.
- # Lumina Design State — "Luminous" Theme
+ # Lumina Design State v2 — "Studio Indigo"
> This file is the persistent source of truth for Lumina's UI design.
> The frontend design skill reads this before every UI task.
> Update this file when design tokens, patterns, or principles change.
## Brand Identity
- - **Name**: Luminous
- - **Primary**: Indigo-Violet `#7c3aed` — confident, creative, premium
- - **Accent**: Amber `#f59e0b` — warmth, energy, attention
- - **Philosophy**: Dark-first, deep space backgrounds with glowing accents. Like a nebula — dark voids with luminous points of light.
+ - **Name**: Studio Indigo
+ - **Primary**: Indigo `#4f46e5` (Tailwind Indigo-600) — professional, trustworthy, modern
+ - **Accent**: Indigo `#6366f1` (Indigo-500, same family — NO separate warm accent)
+ - **Philosophy**: 企业级、克制、专业。参考 Linear / Notion 的设计语言——单一品牌色 + 中性灰 + 语义色。
+ - **Themes**: 亮色默认(`#ffffff` 基底)+ 暗色可选(`<html class="dark">` 切换)
+ ## Migration Notes (v1 → v2)
+
+ | 维度 | v1 "Luminous" | v2 "Studio Indigo" |
+ |---|---|---|
+ | 主色 | 紫 #7c3aed × 琥珀 #f59e0b | 靛蓝 #4f46e5 单色 |
+ | 辅色 | 琥珀到处用 | 无独立辅色,靛蓝同系 |
+ | 渐变 | 到处双色渐变 | 仅 logo,其余纯色 |
+ | 发光 glow | 大量 0 0 20px | **全砍**,改 focus ring 0 0 0 3px |
+ | 主题 | 暗色唯一 | **亮色默认 + 暗色可切** |
+ | 组件 | EP 原子 + 1800 行覆盖 | `Lum*` 业务组件封装(Phase 2) |
+
## Color System
- ### Brand Colors
+ ### Brand Colors (Tailwind Indigo)
| Token | Value | Usage |
|-------|-------|-------|
- | `--lumina-primary` | `#7c3aed` | Buttons, links, active states, focus |
- | `--lumina-primary-light` | `#a78bfa` | Hover states, secondary accents |
- | `--lumina-primary-dark` | `#5b21b6` | Pressed states |
- | `--lumina-accent` | `#f59e0b` | Highlights, badges, warm accents |
- | `--lumina-accent-light` | `#fbbf24` | Accent hover |
+ | `--lumina-primary` | `#4f46e5` | Buttons, links, active states, focus |
+ | `--lumina-primary-light` | `#818cf8` | Hover accents |
+ | `--lumina-primary-dark` | `#3730a3` | Pressed states |
+ | `--lumina-accent` | `#6366f1` | Secondary brand (same family) |
- ### Semantic Colors
+ ### Semantic Colors (亮暗通用)
| Token | Value | Usage |
|-------|-------|-------|
| `--lumina-success` | `#10b981` | Success messages, completed status |
| `--lumina-warning` | `#f59e0b` | Warnings, pending status |
- | `--lumina-danger` | `#ef4444` | Errors, delete actions, failed status |
- | `--lumina-info` | `#3b82f6` | Info messages, informational tags |
+ | `--lumina-danger` | `#ef4444` | Errors, delete actions |
+ | `--lumina-info` | `#3b82f6` | Info messages |
- ### Surface Palette (Dark-first)
+ ### Surface Palette — 亮色(默认 `:root`)
| Token | Value | Usage |
|-------|-------|-------|
- | `--lumina-bg-base` | `#0f172a` | Page background, deepest layer |
- | `--lumina-bg-elevated` | `#1e293b` | Cards, panels, elevated surfaces |
- | `--lumina-bg-card` | `#1e293b` | Card backgrounds |
- | `--lumina-bg-input` | `#0f172a` | Input fields (recessed) |
+ | `--lumina-bg-base` | `#ffffff` | Page background |
+ | `--lumina-bg-elevated` | `#f8fafc` | Panels, sidebar, header |
+ | `--lumina-bg-card` | `#ffffff` | Cards |
+ | `--lumina-bg-input` | `#ffffff` | Input fields |
+ | `--lumina-bg-hover` | `rgba(0,0,0,0.03)` | Hover overlay |
+ | `--lumina-bg-active` | `rgba(79,70,229,0.06)` | Active/selected |
+
+ ### Surface Palette — 暗色(`.dark` 覆盖)
+ | Token | Value | Usage |
+ |-------|-------|-------|
+ | `--lumina-bg-base` | `#0f172a` | Page background |
+ | `--lumina-bg-elevated` | `#1e293b` | Panels, sidebar |
+ | `--lumina-bg-card` | `#1e293b` | Cards |
| `--lumina-bg-hover` | `rgba(255,255,255,0.04)` | Hover overlay |
- ### Text Hierarchy
+ ### Text Hierarchy — 亮色
| Token | Value | Usage |
|-------|-------|-------|
- | `--lumina-text-primary` | `#f1f5f9` | Headlines, primary content |
- | `--lumina-text-regular` | `#cbd5e1` | Body text, default |
- | `--lumina-text-secondary` | `#94a3b8` | Labels, descriptions |
- | `--lumina-text-muted` | `#64748b` | Placeholders, disabled |
+ | `--lumina-text-primary` | `#0f172a` | Headlines |
+ | `--lumina-text-regular` | `#334155` | Body text |
+ | `--lumina-text-secondary` | `#64748b` | Labels |
+ | `--lumina-text-muted` | `#94a3b8` | Placeholders |
+ ### Border — 亮色
+ | Token | Value | Usage |
+ |-------|-------|-------|
+ | `--lumina-border` | `#e2e8f0` | Default borders |
+ | `--lumina-border-light` | `#f1f5f9` | Subtle dividers |
+ | `--lumina-border-hover` | `#4f46e5` | Hover/focus borders |
+
## Typography
| Role | Font | Weight |
|------|------|--------|
| Display (titles) | Outfit | 600-700 |
| Body | IBM Plex Sans | 400-500 |
| Code/Mono | JetBrains Mono | 400 |
- Font sizes: 12px (xs) → 14px (base) → 18px (lg) → 24px (2xl) → 36px (4xl)
-
## Spacing Scale
4px (xs) → 8px (sm) → 16px (md) → 24px (lg) → 32px (xl) → 48px (2xl) → 64px (3xl)
- All spacing MUST use these steps or 8px grid multiples.
-
## Motion
| Token | Duration | Usage |
|-------|----------|-------|
- | `--lumina-transition-fast` | 150ms | Hover, toggle, small state changes |
- | `--lumina-transition-base` | 250ms | Card transitions, dialog open |
- | `--lumina-transition-slow` | 400ms | Page transitions, large element animations |
+ | `--lumina-transition-fast` | 150ms | Hover, toggle |
+ | `--lumina-transition-base` | 200ms | Card transitions |
+ | `--lumina-transition-slow` | 350ms | Page transitions |
Easing: `cubic-bezier(0.4, 0, 0.2, 1)` for all transitions.
- ## Shadow System
+ ## Shadow System (企业级 elevation — 去 glow)
| Token | Value | Usage |
|-------|-------|-------|
- | `--lumina-shadow-sm` | 0 1px 2px rgba(0,0,0,0.3) | Subtle elevation |
- | `--lumina-shadow-md` | 0 4px 12px rgba(0,0,0,0.4) | Cards, dropdowns |
- | `--lumina-shadow-lg` | 0 8px 24px rgba(0,0,0,0.5) | Modals, overlays |
- | `--lumina-shadow-glow` | 0 0 20px primary-glow | Active/featured elements |
-
- ## Component Patterns
-
- ### Stat Cards (Dashboard)
- - Gradient icon circle (48px, brand color light-8 background)
- - Staggered entrance animation (0.08s delay per card)
- - Clickable cards navigate to detail page
- - Glass morphism on hover (slight lift + shadow)
-
- ### Sidebar
- - **Layout: flex-shrink:0**(方案 A,不用 fixed)
- - Dark gradient background (`--lumina-bg-base` → `#1a1040` → `--lumina-bg-base`)
- - 3px gradient active indicator bar (primary → accent)
- - Collapse to 64px with icon-only display
- - Menu items from DB permission table (dynamic)
- - Menu area `overflow-y: auto`(菜单多时可滚动)
- - Collapsed state: `.el-menu--collapse` 图标居中
- - Submenu: `.el-menu--inline` 有独立背景 + 缩进
- - Mobile (`@media 768px`): `position: fixed` + `translateX(-100%)` 抽屉式
+ | `--lumina-shadow-sm` | `0 1px 2px rgba(0,0,0,0.05)` | Subtle elevation |
+ | `--lumina-shadow-md` | `0 4px 12px rgba(0,0,0,0.08)` | Cards, dropdowns |
+ | `--lumina-shadow-lg` | `0 8px 24px rgba(0,0,0,0.12)` | Modals |
+ | `--lumina-shadow-glow` | `0 0 0 3px rgba(79,70,229,0.12)` | Focus ring (NOT glow) |
- ### Header
- - **Layout: sticky + flex-shrink:0**(方案 A,不用 fixed)
- - Glass backdrop blur (backdrop-filter: blur(12px))
- - Gradient bottom border (1px, primary → transparent)
- - Avatar with glow ring on hover
- - Language switch as segmented button
- - `.header-left` 有 `min-width: 0`(防 flex 溢出)
- - Mobile: 隐藏面包屑 + 语言切换
+ ## Theme Switching
- ### Login Page
- - Radial gradient orbs (purple top-left, amber bottom-right)
- - Animated drift (18s ease-in-out infinite)
- - Glass morphism card (backdrop-blur + translucent bg)
- - Hexagonal SVG logo with gradient stroke
+ - **默认**: 亮色(`:root` 定义所有 token)
+ - **暗色**: `<html class="dark">` 触发 `.dark` 选择器覆盖 token
+ - **切换**: `appStore.toggleTheme()` → `document.documentElement.classList.toggle('dark')`
+ - **持久化**: `localStorage('lumina-app')` via pinia-persist
+ - **初始化**: `main.ts` → `useAppStore().initTheme()` 在 mount 前应用
+ - **EP 暗色**: `element-plus/theme-chalk/dark/css-vars.css` 已引入
- ### Tables
- - Dark header row (`--lumina-bg-elevated`)
- - Alternating row tint via `--lumina-bg-hover` on even rows
- - **Action column: 前 2 个高频按钮 + `el-dropdown` 折叠其余**(按钮 ≥ 4 时)
- - Status tags use semantic colors with `size="small"`
- - `overflow-x: auto` on `.page-content`(横向溢出可滚动,不裁切)
+ ## Layout Architecture (方案 A — Flex)
- ### Layout Architecture (方案 A — Flex)
- `#app { display: flex; height: 100vh; overflow: hidden }`
- `.lumina-layout { display: flex }` — Sidebar + Main 横向 flex
- - `.main-container { flex: 1; min-width: 0 }` — **关键:min-width:0 允许收缩**
- - `.page-content { overflow-x: auto }` — 横向溢出改滚动
- - **不用 fixed + margin-left 补偿**(之前的方案 C 已废弃)
- - **不用 z-index 战争**(Sidebar 和 Header 同级 flex 子项)
+ - `.main-container { flex: 1; min-width: 0 }` — 关键:允许收缩
+ - Header `position: sticky; top: 0`
+ - Sidebar `flex-shrink: 0; width: 220px/64px`
+ - **不用 fixed + margin-left 补偿**
- ### Forms
- - Labels above inputs (not inline)
- - Input background = `--lumina-bg-input` (recessed)
- - Focus border = `--lumina-border-focus` (primary color)
- - Submit button full-width in dialogs
+ ## Component Patterns
- ## Page-Specific Overrides
+ ### Sidebar
+ - 背景: `var(--lumina-bg-elevated)` 纯色(去渐变)
+ - Active indicator: 3px 左侧竖条 `var(--lumina-primary)`
+ - Collapse to 64px
- ### Dashboard
- - 4-column stat card row (responsive: 2 cols on tablet, 1 on mobile)
- - Quick actions as vertical button stack in right panel
- - Recent tasks table with compact rows
+ ### Header
+ - 背景: `var(--lumina-bg-base)` 纯色 + 1px border-bottom
+ - 主题切换按钮(Sun/Moon 图标)
+ - 语言切换 segmented button
- ### Agent Chat
- - Full-height layout (sidebar + chat area)
- - Streaming text with cursor animation
- - Debug panel collapsible on right
- - RAG sources as collapsible accordion
+ ### Tables
+ - Action column: 前 2 个高频按钮 + `el-dropdown` 折叠其余
+ - `overflow-x: auto` on page-content
- ### Workflow Designer
- - Vue Flow canvas with dark background
- - Custom node components with brand-colored ports
- - YAML sync panel as side drawer
+ ### Buttons (v2 — 纯色企业级)
+ - Primary: `background: var(--lumina-primary)` 纯色,hover 变 `--lumina-primary-dark`
+ - **去渐变、去微光伪元素、去 glow shadow、去 translateY**
- ## Element Plus Overrides
+ ## Planned Components (Phase 2)
- The following EP components have custom styling in `index.scss`:
- - `el-card` — dark bg, custom radius, hover lift
- - `el-table` — dark header, striped rows, custom borders
- - `el-button` — gradient primary, ghost secondary
- - `el-input` / `el-select` — recessed dark bg, focus glow
- - `el-dialog` — glass morphism header, dark body
- - `el-menu` — sidebar gradient, active indicator
- - `el-tag` — semantic color mapping, small size default
- - `el-pagination` — dark theme adapted
+ | Component | Purpose |
+ |-----------|---------|
+ | `LumTablePanel` | 搜索表单 + 表格 + 分页组合 |
+ | `LumFormDialog` | 表单对话框标准封装 |
+ | `LumStatCard` | 统计卡片(Dashboard) |
+ | `LumToolbar` | 工具栏(搜索 + 操作按钮) |
+ | `LumEmptyState` | 空状态 |
+ | `LumSearchInput` | 搜索输入(防抖 + icon) |
## What NOT to Do
- - ❌ Hardcode hex colors in `.vue` files — always use `var(--lumina-*)`
- - ❌ Use `transition: all` — use `@include transition-colors()` or `@include transition-interact()` mixin
+ - ❌ Hardcode hex colors in `.vue` files — use `var(--lumina-*)`
+ - ❌ Use `transition: all` — use `@include transition-colors()` mixin
+ - ❌ Use `position: fixed` for Header/Sidebar — use flex
+ - ❌ Use `box-shadow: 0 0 20px` glow — use elevation shadow or focus ring
+ - ❌ Use gradient backgrounds on buttons — use solid colors
+ - ❌ Define scoped `:root` token overrides in page components
+ - ❌ Stack `overflow: hidden` on multiple ancestors
+ - ❌ Put 6+ buttons in a table action column — use `el-dropdown`
- ❌ Mix font families — stick to Outfit/IBM Plex/JetBrains Mono
- - ❌ Create card styles per page — use consistent `--lumina-bg-card` + `--lumina-radius-md`
- ❌ Use `z-index: 9999` — use `--lumina-z-*` scale
- - ❌ Forget empty/loading/error states
- - ❌ Test only in light mode — dark is the primary theme
- - ❌ Use `position: fixed` for Header/Sidebar — use **flex layout** (方案 A)
- - ❌ Stack `overflow: hidden` on multiple ancestors — blocks horizontal scroll
- - ❌ Put 6+ buttons in a table action column — use `el-dropdown` to fold extras