diff --git a/desktop-industrial-plan.md b/desktop-industrial-plan.md deleted file mode 100644 index 4a86158..0000000 --- a/desktop-industrial-plan.md +++ /dev/null @@ -1,62 +0,0 @@ -# 桌面端工业化升级规划(desktop-industrial-plan) - -承接 [desktop-ui-plan.md](desktop-ui-plan.md)(IA/能力规划)。本文聚焦把现有桌面端从 -"深色控制台 MVP"打磨到**工业级桌面产品**的质量提升路线。 - -> 现状基线(2026-06-12 实测):`sundynix-desktop/frontend` = React 19 + TS + Tailwind + -> @xyflow/react,**无 UI 组件库**(README 写的 shadcn/ui 实际未安装),图标用 Unicode 字符, -> Wails Go 桥已生成(`wailsjs/`)但前端从未调用。已有视图:工作台/编排/知识库/报告/运行·观测/记忆。 - -## 诊断:为什么"不够工业级" - -问题不在配色,而在**缺产品级骨架**: - -1. **无设计系统** — 按钮/输入/卡片/徽标全是手搓内联 class、复制粘贴、不一致;强调色 - (violet/cyan) 是散落字面量,无法换肤。 -2. **图标是 Unicode 字符**(▤◆▣▦▸◇⌧⚙)— 最掉档次。 -3. **Wails Go 桥未用** — 本质是"套了窗口的网页":无原生文件框、拖拽入库、本地读盘、 - 原生通知、自定义标题栏、"用系统 Word 打开报告"。这是"工业级桌面"最大缺口。 -4. **无应用级 UX** — 无 toast / 全局错误边界 / 命令面板(⌘K) / 快捷键 / 确认弹窗 / 骨架屏。 -5. **健康灯 5 个只 2 个真**(NATS/Milvus/Neo4j 灰)— 缺网关 `/health` 聚合。 -6. **状态全在 App useState,刷新即丢** — 无运行历史/最近项持久化。 -7. **输出裸 `
`** — 报告是 Markdown 却不渲染;无自动滚动/复制/速率。
-8. **布局密度** — 为 1280 设计但窗口 min 1100,面板挤;固定高度;无可拖拽分隔。
-
-## 升级阶段(按性价比/依赖排序)
-
-### A. 设计系统地基(最高优先,其它都依赖它)
-- 装 `lucide-react` 图标;自建轻量 primitives(不引整套 shadcn,保零重依赖、clone 即跑):
-  `Button` `Input` `Textarea` `Select` `Card` `Badge` `Tabs` `Tooltip` `Dialog` `Toast`
-  `Skeleton` `EmptyState`,统一 `cn()`。
-- Tailwind 令牌补全:语义色(brand/accent/success/warn/danger)+ 半径/间距/字阶 token;
-  强调色字面量收敛到 token。
-- 6 个视图 + shell 迁到 primitives,去掉复制粘贴。
-
-### B. 真·桌面集成("工业级桌面"最大缺口)
-- 启用 Wails Go 桥:`app.go` 增 `OpenFileDialog`/`SaveFileDialog`/`SaveReport`/
-  `OpenInSystem`/`ReadFile`,前端经 `wailsjs` 调。
-- 知识库**拖拽 + 原生选择框**入库;报告**原生"另存为 .docx"** + "用系统 Word 打开"。
-- 原生通知(报告完成弹系统通知)、最近文件、窗口标题随任务变。
-- 自定义无边框标题栏(macOS 红绿灯内嵌 + 可拖拽区)。
-
-### C. 应用级 UX 骨架
-- 全局 `ToastProvider`(替代散落 err 文本)、`ErrorBoundary`、确认 `Dialog`。
-- 命令面板 `⌘K`(跳转/新建报告/搜知识库/运行)+ 全局快捷键。
-- 骨架屏 + 有插画的空状态(取代"规划中"文字)。
-
-### D. 内容与可信度
-- Markdown 渲染(报告/输出)+ 代码高亮 + 复制 + 流式自动跟随底部 + tokens/s 速率表。
-- 网关 `GET /health` 聚合 NATS/Milvus/Neo4j/PG/Redis → 5 灯全真。
-- 运行历史持久化(Wails 配置或 localStorage),RunsView 列出历史可回看。
-
-### E. 布局与密度
-- 可拖拽分隔的面板、响应式断点、记忆面板宽度。
-
-## 建议路线
-先 **A(设计系统)** 打底 → **B(真桌面集成)**,这两个一起把"网页套壳"扭转成"工业级桌面应用",
-感知提升最大。C/D/E 增量补。
-
-## 边界/原则
-- **零重依赖**:自建 primitives 而非整套组件库,守住 "clone 即跑、无重 native 依赖" 目标。
-- 不破坏既有真实链路(任务流/工具调用/Token 流/执行事件/报告)。
-- 深色优先;令牌化后保留未来切浅色的可能。
diff --git a/desktop-ui-plan.md b/desktop-ui-plan.md
deleted file mode 100644
index 6753ca5..0000000
--- a/desktop-ui-plan.md
+++ /dev/null
@@ -1,133 +0,0 @@
-# sundynix-agentix · 桌面端 UI 规划
-
-> 第 1 层 Client(`sundynix-desktop`,Wails + React 19 + React Flow)的产品级 UI 规划。
-> 目标:不止是连 Gateway 的 UI,而是承载 **RAG 知识库 / 报告生成 / 垂直行业平台级复制** 的驾驶舱。
-> 定位已定:**真 Desktop** —— 用上 Wails 本地能力(文件 I/O、TS/Go 强绑定、本地配置、离线嵌入)。
-
-## 0 · 设计原则 & 角色
-
-- **三类用户,一个壳**:**构建者**(搭 Agent 图、建知识库)/ **操作者**(跑工作流、看报告)/ **管理员**(开垂直、管租户)。UI 按 BUILD / RUN / MANAGE 分组,按角色露不同模块。
-- **专业工具范式**:IDE / 节点编辑器布局——左导航 + 主区 + 右检查器 + 底部抽屉。信息密度高。
-- **可信优先**:RAG 必带**引用**;记忆**可看可改**;生成**有评测门**。透明是平台级底线。
-- **垂直白标**:整个壳由当前垂直 Pack 的配置驱动(名称/主题/启用模块/术语/默认模板)。换行业 = 换配置,不改 UI。
-
-## 1 · 信息架构(左导航)
-
-```
-■ 工作台          首页:概览 / 最近 / 快捷
-─ BUILD ─
-◆ 编排 Studio     React Flow Agent 图构建器(核心)
-▣ 知识库 (RAG)    KB 管理 / 入库 / 检索调试 / 图谱
-▤ 报告            模板 / 生成 / 产出库
-─ RUN ─
-▸ 运行 · 观测     实时执行 / 轨迹 / 历史
-─ MANAGE ─
-◇ 记忆            画像 / 会话历史
-⌧ 市场 · Packs    垂直包 / Agent 模板 / 开通
-⚙ 管理            租户 / 用户计费 / 护栏 / 模型 / 设置
-```
-
-## 2 · 全局外壳
-
-```
-┌──────────────────────────────────────────────────────────────────┐
-│ [垂直▾ 法律版] · 搜索/命令(⌘K) · ●GW ●NATS ●Milvus ●Neo4j · 用户▾ │ 顶栏
-├────┬──────────────────────────────────────────┬───────────────────┤
-│ 左 │              主区(随模块切换)              │   右:检查器/详情   │
-│ 导 ├──────────────────────────────────────────┴───────────────────┤
-│ 航 │   底部抽屉:输出 / 轨迹 / 工具调用 / 引用 / 评测   ▴展开▾收起    │
-└────┴──────────────────────────────────────────────────────────────┘
-```
-- **垂直切换器**:切租户上下文 + 白标。
-- **⌘K 命令面板**:跳转 / 跑模板 / 开库 / 查文档。
-- **健康灯**:GW/NATS/Milvus/Neo4j/LLM 在线状态(可观测性)。
-- **底部抽屉全局常驻**:任何模块跑任务,流式/轨迹/引用都在此看。
-
-## 3 · 各模块详规
-
-### ① 工作台
-概览卡(KB 数 / 文档数 / 近期运行 / 待办报告 / 配额计费)· 快捷区(跑模板 / 新建图 / 入库)· 最近列表。
-
-### ② 编排 Studio(核心)
-左节点面板 · 中画布 · 右检查器 · 顶工具栏。
-
-节点类型(按颜色分类,沿用架构图配色):
-
-| 节点 | 干什么 | 配置(检查器) |
-|---|---|---|
-| 输入 | 用户提问 / 文件 / 变量 | 来源、占位符 |
-| 检索(RAG) | 绑定某 KB 混合检索 | 选 KB、topK、融合权重、rerank、元数据过滤 |
-| Agent/LLM | 调模型生成 | 模型、系统提示词、温度、可用工具 |
-| 工具 | 绑定 MCP 工具 | parse_document/render_doc/外部API… + 参数 |
-| 记忆 | 注入画像/历史/语义 | 勾选注入项 |
-| 分支 | 条件路由 | 条件表达式 |
-| 并行/Map | fan-out(逐章节) | 拆分依据 |
-| 汇聚 | reduce/合并 | 合并策略 |
-| 渲染 | UniOffice 出 docx/pdf | 模板、样式 |
-| 输出 | 展示/导出/落盘 | 目标(屏/文件) |
-| 子图 | 嵌套可复用模板 | 选模板 |
-
-顶工具栏:加节点 · ▶运行 · ■停止 · 保存/打开 `.dsl.json`(Wails 落盘) · **校验**(按后端 DSL schema 标红) · 版本。
-运行时:节点逐个点亮 + 状态徽标(待/跑/流/完/错/降级) + token 数/耗时。
-
-### ③ 知识库(RAG)—— 流水线,每段都露出
-左 KB 列表 · 中主区(Tab) · 右文档/块详情。
-- **入库监控**:拖文件/文件夹 → 流水线进度(解析→切块→向量化→三路建索引)、队列深度、失败重试。
-- **检索调试台**:query → 三路召回 + 融合 + rerank 中间结果,每条带来源徽标(Bleve/Milvus/Neo4j)+ 分数。
-- **文档/块浏览**:切块、向量邻居、引用回链。
-- **知识图谱**:Neo4j 实体-关系可视化(GraphRAG 的脸)。
-- **检索评测**:跑 golden 集,召回质量/忠实度(接 harness eval)。
-
-### ④ 报告 —— 长程多节点编排的成品界面
-左大纲树 · 中预览 · 右章节检查器;顶部进度。
-- 模板库(尽调/行业分析/合规,预制 Eino 子图)· 大纲编辑(增删改/拖排序/指定 KB)。
-- 生成中:各章节独立进度(检索/撰写/复核),并行 fan-out 可见。
-- 中预览:实时拼装(目录/图表/表格/内联引用)。
-- 导出条:→ docx/pdf(UniOffice) → Wails 原生保存落盘。产出库:历史/重跑/版本对比。
-
-### ⑤ 运行 · 观测
-实时回 Studio 看节点点亮 + 抽屉五 Tab:输出(SSE) / 轨迹(节点时间线) / 工具调用 / 引用 / 评测。运行历史可复盘。
-
-### ⑥ 记忆(透明可控)
-"模型记得我什么"(画像逐条,改/删,来源)· 会话 & 历史(多轮,可清空)· 注入开关。
-
-### ⑦ 市场 · Packs(垂直复制入口)
-垂直包市场(法律/医疗/金融包)· Agent 模板市场(拉进 Studio 当子图)· 开通向导(选包→配置→建租户→入库→注册模板→应用配置)。
-
-### ⑧ 管理
-租户/工作区(多租户隔离/配额)· 用户 & 计费 · 护栏(脱敏/免责/强制引用)· 模型 & 连接(LLM 池/embedding/后端地址/健康)· 设置(本地目录/主题/离线)。
-
-## 4 · 跨模块复用组件(设计系统)
-
-引用 chip `[1]`(悬浮:源文档+块+分数+来源徽标)· 来源徽标(三色) · 节点卡(统一状态机) · 流式 token 视图 · KB/模型/工具选择器 · 运行时间线(甘特) · 评测徽章。
-
-## 5 · 垂直白标
-顶栏切垂直 → 壳按 Pack 的 `branding` 重渲染:名称/Logo、主色、启用模块、术语标签、默认模板、护栏横幅。同一引擎,不同皮 + 内容。
-
-## 6 · 状态设计
-空态(引导) · 加载/流式(骨架+token+进度) · 降级(横幅:"语义检索降级,已用全文兜底") · 错误/重试。
-
-## 7 · 落地优先级
-
-| 层级 | 做什么 | 价值 |
-|---|---|---|
-| **MVP** | 外壳(顶栏+导航+健康灯+⌘K) · ② Studio 类型化节点+检查器+校验 · 运行抽屉(输出+轨迹) | 搭图→跑→看 闭环 |
-| **平台核心** | ③ 知识库(入库+检索台+引用) · ④ 报告(模板+大纲+预览+导出) · ⑥ 记忆做厚 | RAG/报告 成形 |
-| **平台级** | ⑦ 市场+开通向导 · ⑧ 多租户/护栏 · ⑤ 白标 · 图谱/评测台 | 垂直复制 |
-
-> UI 的"平台核心/平台级"依赖后端先就绪:③④依赖 RAG 核心链(embedding + 入库 worker + 真实混合检索),⑦依赖多租户 + Pack 格式。UI 与后端并行排,在"知识库/报告"界面会合。
-
-## 8 · 后端依赖链(提醒)
-
-```
-Embedding + 真实 LLM   ← 命门(现为桩)
-   ↓
-RAG 核心(入库worker + 真Hybrid检索 + rerank)   ← 拱心石
-   ↓
-报告生成(多节点 Eino 图 + UniOffice 渲染)
-   ↓
-多租户 + Pack 格式 + Provisioning   ← 垂直复制
-```
-
----
-*(本规划随实现推进更新。当前进度见 git log 与 memory。)*
diff --git a/sundynix-desktop/frontend/src/components/ExecTrace.tsx b/sundynix-desktop/frontend/src/components/ExecTrace.tsx
index dfc6968..e4f6b1c 100644
--- a/sundynix-desktop/frontend/src/components/ExecTrace.tsx
+++ b/sundynix-desktop/frontend/src/components/ExecTrace.tsx
@@ -78,7 +78,7 @@ export function ExecTrace({ events, phase, compact }: { events: ExecEvent[]; pha
                 
{n.label} - {m.name} + {m.name} {n.ms != null && n.ms > 0 && {n.ms} ms} {n.status === "running" && 运行中…}
diff --git a/sundynix-desktop/frontend/src/index.css b/sundynix-desktop/frontend/src/index.css index d8407d3..0991970 100644 --- a/sundynix-desktop/frontend/src/index.css +++ b/sundynix-desktop/frontend/src/index.css @@ -2,6 +2,50 @@ @tailwind components; @tailwind utilities; +/* 主题令牌::root=亮色,.dark=暗色。值为 RGB 三元组,供 tailwind 的 rgb(var() / α) 取用。 + 亮色走 shadcn 中性灰(zinc),暗色为精炼中性暗(zinc 系,替代原偏蓝的 ink)。 */ +:root { + --ink-950: 249 249 250; /* 页面底 */ + --ink-900: 255 255 255; /* 顶栏/面板 */ + --ink-850: 255 255 255; /* 卡片 */ + --ink-800: 244 244 245; /* hover/抬升 */ + --ink-700: 228 228 231; + --ink-600: 212 212 216; + --line: 228 228 231; /* 边框 zinc-200 */ + --slate-100: 24 24 27; /* 最强文字 */ + --slate-200: 24 24 27; /* 主文字 */ + --slate-300: 63 63 70; + --slate-400: 82 82 91; + --slate-500: 113 113 122; /* 次要 */ + --slate-600: 161 161 170; /* 弱 */ + --slate-700: 212 212 216; + --sb-thumb: 212 212 216; + --sb-thumb-hover: 161 161 170; + --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.06), 0 8px 24px rgba(0, 0, 0, 0.06); + color-scheme: light; +} + +.dark { + --ink-950: 10 10 12; + --ink-900: 20 20 24; + --ink-850: 24 24 27; + --ink-800: 31 31 35; + --ink-700: 38 38 43; + --ink-600: 50 50 56; + --line: 39 39 42; /* zinc-800 */ + --slate-100: 244 244 245; + --slate-200: 228 228 231; + --slate-300: 212 212 216; + --slate-400: 161 161 170; + --slate-500: 138 138 147; + --slate-600: 113 113 122; + --slate-700: 82 82 91; + --sb-thumb: 39 39 42; + --sb-thumb-hover: 63 63 70; + --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.25); + color-scheme: dark; +} + html, body, #root { @@ -10,25 +54,25 @@ body, } body { - background: #0b0d12; - color: #cbd2de; + background: rgb(var(--ink-950)); + color: rgb(var(--slate-300)); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; } -/* 深色滚动条 */ +/* 滚动条随主题 */ ::-webkit-scrollbar { width: 10px; height: 10px; } ::-webkit-scrollbar-thumb { - background: #242b3c; + background: rgb(var(--sb-thumb)); border-radius: 8px; border: 2px solid transparent; background-clip: padding-box; } ::-webkit-scrollbar-thumb:hover { - background: #323a4f; + background: rgb(var(--sb-thumb-hover)); background-clip: padding-box; } ::-webkit-scrollbar-track { @@ -44,9 +88,4 @@ body { color: transparent; } -/* 输入控件深色统一 */ -input, -textarea, -select { - color-scheme: dark; -} +/* 输入控件随主题(color-scheme 由 :root/.dark 设定,控件自动继承) */ diff --git a/sundynix-desktop/frontend/src/lib/theme.ts b/sundynix-desktop/frontend/src/lib/theme.ts new file mode 100644 index 0000000..db608c8 --- /dev/null +++ b/sundynix-desktop/frontend/src/lib/theme.ts @@ -0,0 +1,35 @@ +// 主题(亮/暗)管理:持久化到 localStorage,切换在 上加/去 .dark 类。 +// 默认亮色(暗色为可选)。初始化在 applyInitialTheme(main 启动时调,先于渲染避免闪烁)。 +import { useCallback, useEffect, useState } from "react"; + +export type Theme = "light" | "dark"; + +const KEY = "sdx-theme"; + +export function getStoredTheme(): Theme { + const t = localStorage.getItem(KEY); + return t === "dark" ? "dark" : "light"; // 默认亮色 +} + +function apply(theme: Theme): void { + document.documentElement.classList.toggle("dark", theme === "dark"); +} + +// applyInitialTheme 在渲染前调用,依据存储值设好 .dark 类(避免首屏闪烁)。 +export function applyInitialTheme(): void { + apply(getStoredTheme()); +} + +// useTheme 暴露当前主题与切换函数(写 localStorage + 切 .dark 类)。 +export function useTheme(): { theme: Theme; toggle: () => void; setTheme: (t: Theme) => void } { + const [theme, setThemeState] = useState(getStoredTheme); + + useEffect(() => { + apply(theme); + localStorage.setItem(KEY, theme); + }, [theme]); + + const setTheme = useCallback((t: Theme) => setThemeState(t), []); + const toggle = useCallback(() => setThemeState((t) => (t === "dark" ? "light" : "dark")), []); + return { theme, toggle, setTheme }; +} diff --git a/sundynix-desktop/frontend/src/main.tsx b/sundynix-desktop/frontend/src/main.tsx index 27481e0..389456e 100644 --- a/sundynix-desktop/frontend/src/main.tsx +++ b/sundynix-desktop/frontend/src/main.tsx @@ -2,6 +2,9 @@ import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; import "./index.css"; +import { applyInitialTheme } from "./lib/theme"; + +applyInitialTheme(); // 先于渲染设好主题类,避免首屏闪烁 ReactDOM.createRoot(document.getElementById("root")!).render( diff --git a/sundynix-desktop/frontend/src/shell/TopBar.tsx b/sundynix-desktop/frontend/src/shell/TopBar.tsx index f2d68da..f2484d5 100644 --- a/sundynix-desktop/frontend/src/shell/TopBar.tsx +++ b/sundynix-desktop/frontend/src/shell/TopBar.tsx @@ -1,8 +1,9 @@ import type { CSSProperties } from "react"; -import { User, ChevronDown, Search as SearchIcon, LogOut } from "lucide-react"; +import { User, ChevronDown, Search as SearchIcon, LogOut, Sun, Moon } from "lucide-react"; import type { AuthUser } from "../lib/api"; import { useHealth } from "../lib/health"; import { isMacDesktop } from "../lib/desktop"; +import { useTheme } from "../lib/theme"; import { cn } from "../ui"; // Wails 拖拽区/控件 CSS 变量(浏览器忽略,桌面端生效)。 @@ -22,6 +23,7 @@ function Light({ on, label }: { on: boolean; label: string }) { // 顶栏:品牌 · 垂直切换 · 健康灯 · 登录用户 + 登出(深色 + 毛玻璃)。 export function TopBar({ user, onLogout, onCommand }: { user: AuthUser; onLogout: () => void; onCommand?: () => void }) { const h = useHealth(); + const { theme, toggle } = useTheme(); return (
+ {user.name || user.email} diff --git a/sundynix-desktop/frontend/src/ui/Badge.tsx b/sundynix-desktop/frontend/src/ui/Badge.tsx index 40f5ccc..65ca06d 100644 --- a/sundynix-desktop/frontend/src/ui/Badge.tsx +++ b/sundynix-desktop/frontend/src/ui/Badge.tsx @@ -4,7 +4,7 @@ import { cn } from "./cn"; type Tone = "neutral" | "brand" | "accent" | "success" | "warn" | "danger"; const tones: Record = { - neutral: "bg-white/5 text-slate-400", + neutral: "bg-ink-800 text-slate-400", brand: "bg-brand/15 text-brand-400", accent: "bg-accent/15 text-accent-400", success: "bg-success/15 text-success", diff --git a/sundynix-desktop/frontend/src/ui/Tabs.tsx b/sundynix-desktop/frontend/src/ui/Tabs.tsx index aaf3e7f..fc05d76 100644 --- a/sundynix-desktop/frontend/src/ui/Tabs.tsx +++ b/sundynix-desktop/frontend/src/ui/Tabs.tsx @@ -33,7 +33,7 @@ export function Tabs({ > {t.label} {t.count != null && t.count > 0 && ( - {t.count} + {t.count} )} {active && } diff --git a/sundynix-desktop/frontend/tailwind.config.js b/sundynix-desktop/frontend/tailwind.config.js index a90131b..654ee80 100644 --- a/sundynix-desktop/frontend/tailwind.config.js +++ b/sundynix-desktop/frontend/tailwind.config.js @@ -1,20 +1,31 @@ /** @type {import('tailwindcss').Config} */ export default { content: ["./index.html", "./src/**/*.{ts,tsx}"], + darkMode: "class", theme: { extend: { colors: { - // 深色 AI 控制台分层表面 + // 分层表面 / 边框 / 文字均由 CSS 变量驱动(RGB 三元组,保留 /透明度 修饰符)。 + // 变量在 index.css 的 :root(亮) 与 .dark(暗) 两套值间切换 —— 一处定义,全 app 换肤。 ink: { - 950: "#0b0d12", - 900: "#0f121a", - 850: "#141824", - 800: "#1a1f2d", - 700: "#232a3b", - 600: "#323a4f", + 950: "rgb(var(--ink-950) / )", + 900: "rgb(var(--ink-900) / )", + 850: "rgb(var(--ink-850) / )", + 800: "rgb(var(--ink-800) / )", + 700: "rgb(var(--ink-700) / )", + 600: "rgb(var(--ink-600) / )", }, - line: "#242b3c", - // 语义令牌 —— 强调色统一从这里取,便于整体换肤(紫=brand,青=accent)。 + line: "rgb(var(--line) / )", + slate: { + 100: "rgb(var(--slate-100) / )", + 200: "rgb(var(--slate-200) / )", + 300: "rgb(var(--slate-300) / )", + 400: "rgb(var(--slate-400) / )", + 500: "rgb(var(--slate-500) / )", + 600: "rgb(var(--slate-600) / )", + 700: "rgb(var(--slate-700) / )", + }, + // 语义强调色 —— 两套主题通用(紫=brand,青=accent)。 brand: { DEFAULT: "#7c5cf6", 400: "#a78bfa", 500: "#8b5cf6", 600: "#6d28d9" }, accent: { DEFAULT: "#22d3ee", 400: "#22d3ee", 500: "#06b6d4" }, success: { DEFAULT: "#34d399", 500: "#10b981" }, @@ -22,14 +33,13 @@ export default { danger: { DEFAULT: "#fb7185", 500: "#f43f5e" }, }, borderRadius: { - // 统一圆角档位 lg: "0.625rem", // 10px —— 卡片/面板 md: "0.5rem", // 8px —— 控件 }, boxShadow: { glow: "0 0 0 1px rgba(139,92,246,0.45), 0 0 18px rgba(139,92,246,0.28)", "glow-cyan": "0 0 0 1px rgba(34,211,238,0.4), 0 0 16px rgba(34,211,238,0.22)", - card: "0 1px 2px rgba(0,0,0,0.4), 0 8px 24px rgba(0,0,0,0.25)", + card: "var(--shadow-card)", }, }, },