Commit 494e6f4a authored by David Yang's avatar David Yang

style: refine sidebar and app canvas palette

parent 20a651b9
# 鑫元 UI 架构 # 鑫元 UI 架构
## 2026-09-28 Shell 配色
- AppShell 采用中性灰白内容画布与低饱和深藏蓝 Sidebar。页面画布由 `theme.css` 的 `--background: oklch(97.4% 0.002 255)` 提供;侧栏背景为 `oklch(32% 0.037 255)`。桌面和移动侧栏共用 `--xinyuan-sidebar-*`,选中导航为提亮的蓝色底与白字,侧栏红色 Logo 直接显示、不加底色;页面仍固定浅色,不提供主题切换。
- 内容画布在 AppShell 顶部使用 4% 侧栏蓝色与 `--background` 混合的轻微渐变,至 18rem 淡出到灰白底色;Navbar 和滚动区共用这一层,页面 Card 与 HeroUI 组件保持原有表面 Token。
- 当前导航使用较亮的同色系底色提高与侧栏的区分度,悬停时保持选中底色;普通导航使用略亮于侧栏的同色系悬停色。
- 此调整仅涉及 Shell 视觉层,不改变 Sidebar 路由、通知入口、页面状态或业务数据协议。
## 2026-09-02 审计项目管理基准 ## 2026-09-02 审计项目管理基准
- 当前 `develop` 分支的共享架构与 `/Users/liuchenlong/Desktop/job/audit_project_manager` 当前实现对齐。 - 当前 `develop` 分支的共享架构与 `/Users/liuchenlong/Desktop/job/audit_project_manager` 当前实现对齐。
- AppShell 固定浅色内容画布和深色 Sidebar;禁止主题切换、主题持久化及局部暗色容器。 - 当时的 AppShell 基准为浅色内容画布和深色 Sidebar;当前配色以上方 2026-09-28 调整为准。继续禁止主题切换、主题持久化及局部暗色容器。
- Sidebar 分组使用 HeroUI `Disclosure` compound API,Navbar 使用 HeroUI Pro `Sidebar.Trigger` 与通知 `Badge.Anchor`;用户菜单使用 `Dropdown.Trigger`。 - Sidebar 分组使用 HeroUI `Disclosure` compound API,Navbar 使用 HeroUI Pro `Sidebar.Trigger` 与通知 `Badge.Anchor`;用户菜单使用 `Dropdown.Trigger`。
- DataGrid、Autocomplete、Modal、ECharts 适配器直接使用 HeroUI/HeroUI Pro 官方结构;问题整改图表点击回调通过适配器透传,业务状态和数据协议不变。 - DataGrid、Autocomplete、Modal、ECharts 适配器直接使用 HeroUI/HeroUI Pro 官方结构;问题整改图表点击回调通过适配器透传,业务状态和数据协议不变。
......
# 鑫元问题整改系统设计规范 # 鑫元问题整改系统设计规范
## 2026-09-28 Shell 配色调整
当前 AppShell 使用低饱和深藏蓝侧栏与中性灰白内容画布。`theme.css` 的 `--background` 和 `--xinyuan-sidebar-*` 是这组配色的唯一来源:侧栏背景 `oklch(32% 0.037 255)`,页面画布为 `oklch(97.4% 0.002 255)`;侧栏文字为近白色,悬停项为稍亮的蓝色,选中项为提亮的蓝色底与白字。品牌主红 `#DA241A` 不变。侧栏红色 Logo 直接显示,不加底色。桌面与移动侧栏共用这些 Token,导航结构、交互及数据状态不变。后续配色调整以本节和实际 Token 为准。
当前选中项底色为 `oklch(46% 0.055 255)`,与深藏蓝侧栏明确区分。普通项悬停使用侧栏同色系;当前项悬停时保留选中底色和白色文字,不被普通悬停色覆盖。
内容画布顶部使用仅限 AppShell 的轻微渐变:`--xinyuan-canvas-top` 从深藏蓝侧栏色与 `--background` 混合 4% 得到,在顶部至 18rem 处过渡回 `--background`。Navbar 与页面滚动区透出同一层背景;Card、Surface、字段和浮层仍按 HeroUI 原有 Token 渲染。
## 2026-09-02 基准同步 ## 2026-09-02 基准同步
本项目 `develop` 分支统一以 `/Users/liuchenlong/Desktop/job/audit_project_manager` 当前实现为唯一 UI 基准。右侧内容区固定浅色、Sidebar 固定深色;不得新增主题切换按钮、Sun/Moon 图标、主题存储或局部暗色模式。Shell、Sidebar 分组、Navbar 通知、DataGrid、Autocomplete、Modal、ECharts 和全局 Tailwind 加载顺序以基准项目对应文件为准。问题整改专属路由、Subject/View、接口和业务回调只保留自身实现。 此前以 `/Users/liuchenlong/Desktop/job/audit_project_manager` 的深色 Sidebar 与浅色内容区作为 UI 基准;Shell 配色现由上方 2026-09-28 调整覆盖。仍不提供主题切换按钮、Sun/Moon 图标、主题存储或局部暗色模式。Sidebar 分组、Navbar 通知、DataGrid、Autocomplete、Modal、ECharts 和全局 Tailwind 加载顺序沿用原基准。问题整改专属路由、Subject/View、接口和业务回调只保留自身实现。
## 2026-08-31 基准同步补充 ## 2026-08-31 基准同步补充
...@@ -25,7 +33,7 @@ ...@@ -25,7 +33,7 @@
## 2. 主题权威 ## 2. 主题权威
- `src/design-system/theme.css` 是浅色、暗色、品牌色、语义色、圆角和字体的唯一主题权威,以 HeroUI 官方主题工具导出值为基础,并在文件内固化批准的 L1/L2/Overlay 映射。它必须与 `/Users/liuchenlong/Desktop/theme.css` 及共享 Skill 基线逐字节一致;升级 HeroUI 时重新导出基础值、复核三项语义映射并整体批准新基线。 - `src/design-system/theme.css` 是浅色、暗色、品牌色、语义色、圆角和字体的唯一主题权威,以 HeroUI 官方主题工具导出值为基础,并在文件内固化批准的 L1/L2/Overlay 映射。Shell 配色以本项目 2026-09-28 调整为准;升级 HeroUI 时重新导出基础值、复核三项语义映射与 Shell Token。
- `src/design-system/tokens.css` 仅保留 Login/AppShell 别名、页面几何和批准的数据可视化扩展 Token,不得覆盖 HeroUI 的组件 Token、控件高度、DataGrid、Tabs、Modal、Card、Checkbox 或 Pagination 外观。 - `src/design-system/tokens.css` 仅保留 Login/AppShell 别名、页面几何和批准的数据可视化扩展 Token,不得覆盖 HeroUI 的组件 Token、控件高度、DataGrid、Tabs、Modal、Card、Checkbox 或 Pagination 外观。
- 内容页面使用 HeroUI 的 `background`、`surface`、`foreground`、`muted`、`accent`、`success`、`warning`、`danger` 等语义 Token,不新增 hex、zinc/slate/sky/rose 等私有调色板。 - 内容页面使用 HeroUI 的 `background`、`surface`、`foreground`、`muted`、`accent`、`success`、`warning`、`danger` 等语义 Token,不新增 hex、zinc/slate/sky/rose 等私有调色板。
- HeroUI `danger` 固定为鑫元红系:浅色 `oklch(45.32% 0.1661 27.03)`(鑫元主红 `#9E1B1B`),深色 `oklch(62% 0.16 27.03)`(同色相增亮)。删除、驳回、退出和失败状态继续使用 HeroUI `danger` / `danger-soft`,软色由 HeroUI 公式自动生成;禁止恢复洋红、亮粉或页面私有危险色。 - HeroUI `danger` 固定为鑫元红系:浅色 `oklch(45.32% 0.1661 27.03)`(鑫元主红 `#9E1B1B`),深色 `oklch(62% 0.16 27.03)`(同色相增亮)。删除、驳回、退出和失败状态继续使用 HeroUI `danger` / `danger-soft`,软色由 HeroUI 公式自动生成;禁止恢复洋红、亮粉或页面私有危险色。
...@@ -46,7 +54,7 @@ Surface 用于表达页面内的包含关系,Overlay 用于表达浮动关系 ...@@ -46,7 +54,7 @@ Surface 用于表达页面内的包含关系,Overlay 用于表达浮动关系
| 层级 | Token 与固定值 | 什么时候使用 | 页面写法 | | 层级 | Token 与固定值 | 什么时候使用 | 页面写法 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| L0 页面画布 | `--background`:浅色 `oklch(97.02% 0.0045 27.03)`,约 `#F8F4F3`;深色 `oklch(12% 0.0045 27.03)`,约 `#070505` | AppShell、页面底色、无框工具栏所在画布 | 不新建表面;使用页面容器 | | L0 页面画布 | `--background`:浅色 `oklch(97.4% 0.002 255)`;深色沿用 HeroUI 暗色 Token | AppShell、页面底色、无框工具栏所在画布 | 不新建表面;使用页面容器 |
| L1 主内容 | `--surface`:浅色 `oklch(100% 0.0022 27.03)`,约 `#FFFFFE`;深色 `oklch(21.03% 0.009 27.03)`,约 `#1C1716` | 第一层内容面板、筛选 Surface、Card、直接位于页面画布上的搜索框 | `Surface default`、Card 默认、字段 `primary` | | L1 主内容 | `--surface`:浅色 `oklch(100% 0.0022 27.03)`,约 `#FFFFFE`;深色 `oklch(21.03% 0.009 27.03)`,约 `#1C1716` | 第一层内容面板、筛选 Surface、Card、直接位于页面画布上的搜索框 | `Surface default`、Card 默认、字段 `primary` |
| L2 次要层 | `--surface-secondary`:浅色 `oklch(95.24% 0.0036 27.03)`,约 `#F2EEEE`;深色 `oklch(25.70% 0.0067 27.03)`,约 `#262222` | L1 内的筛选框、表单控件、次按钮、真正的次级内容区 | 字段或按钮 `secondary`;结构区使用 `surface-secondary` | | L2 次要层 | `--surface-secondary`:浅色 `oklch(95.24% 0.0036 27.03)`,约 `#F2EEEE`;深色 `oklch(25.70% 0.0067 27.03)`,约 `#262222` | L1 内的筛选框、表单控件、次按钮、真正的次级内容区 | 字段或按钮 `secondary`;结构区使用 `surface-secondary` |
| L3 第三层 | `--surface-tertiary`:浅色 `oklch(93.73% 0.0036 27.03)`,约 `#EDE9E9`;深色 `oklch(27.21% 0.0067 27.03)`,约 `#2A2625` | 仅限 L2 内仍需嵌套的静态内容区;极少使用 | 只使用语义 Surface Token,不作为字段 variant | | L3 第三层 | `--surface-tertiary`:浅色 `oklch(93.73% 0.0036 27.03)`,约 `#EDE9E9`;深色 `oklch(27.21% 0.0067 27.03)`,约 `#2A2625` | 仅限 L2 内仍需嵌套的静态内容区;极少使用 | 只使用语义 Surface Token,不作为字段 variant |
...@@ -60,13 +68,13 @@ Surface 用于表达页面内的包含关系,Overlay 用于表达浮动关系 ...@@ -60,13 +68,13 @@ Surface 用于表达页面内的包含关系,Overlay 用于表达浮动关系
- 页面 Surface 层级不延伸到 Portal。筛选 Autocomplete/DatePicker 的真实 Popover 与普通表单、详情、Dropdown、Tooltip、Modal 一样,统一使用 HeroUI 官方 `overlay` 表面、前景色、圆角和阴影,不传入背景类覆盖默认浮层。 - 页面 Surface 层级不延伸到 Portal。筛选 Autocomplete/DatePicker 的真实 Popover 与普通表单、详情、Dropdown、Tooltip、Modal 一样,统一使用 HeroUI 官方 `overlay` 表面、前景色、圆角和阴影,不传入背景类覆盖默认浮层。
- Popover 内 SearchField 可继续使用 `secondary` 作为 overlay 内部控件层,但不得改变 Popover 根表面,也不得给筛选浮层建立私有 light/dark 分支。 - Popover 内 SearchField 可继续使用 `secondary` 作为 overlay 内部控件层,但不得改变 Popover 根表面,也不得给筛选浮层建立私有 light/dark 分支。
- 父子层级需要区分时不得解析成相同背景;没有嵌套语义时也不得为制造色差凭空增加一层 Surface。 - 父子层级需要区分时不得解析成相同背景;没有嵌套语义时也不得为制造色差凭空增加一层 Surface。
- 禁止以 `bg-white`、zinc/slate/gray、透明叠色、渐变、模糊、页面私有 light/dark selector 代替主题 Surface。透明仅用于已由父层提供边界的工具栏、列表标题、行或纯布局组。 - 禁止以 `bg-white`、zinc/slate/gray、透明叠色、模糊、页面私有 light/dark selector 代替主题 Surface;渐变仅限上述 AppShell 内容画布顶部,不用于页面或组件表面。透明仅用于已由父层提供边界的工具栏、列表标题、行或纯布局组。
## 4. Login 与 AppShell ## 4. Login 与 AppShell
- 应用名称统一为“问题整改”,供 Login、Sidebar、Navbar、应用切换和浏览器标题共用。 - 应用名称统一为“问题整改”,供 Login、Sidebar、Navbar、应用切换和浏览器标题共用。
- Login 使用 HeroUI Card/Input/Button/Alert,保留已批准的 Logo、居中布局、验证码和浏览器 autofill 修正;这些规则只能作用于 `.login-*` 范围。 - Login 使用 HeroUI Card/Input/Button/Alert,保留已批准的 Logo、居中布局、验证码和浏览器 autofill 修正;这些规则只能作用于 `.login-*` 范围。
- Sidebar、Navbar 使用 HeroUI Pro,Logo 浅色使用 `xy-logo-red.png`、暗色使用 `xy-logo-white.png`。 - Sidebar、Navbar 使用 HeroUI Pro;当前侧栏直接显示 `xy-logo-red.png`,不加 Logo 底色。
- `src/design-system/shell.css` 只负责应用壳布局、导航定位、折叠、Logo 和响应式,不得延伸到列表、筛选、Tabs、Card、DataGrid 或弹窗正文。 - `src/design-system/shell.css` 只负责应用壳布局、导航定位、折叠、Logo 和响应式,不得延伸到列表、筛选、Tabs、Card、DataGrid 或弹窗正文。
- 侧边栏只有一个导航组时,不在菜单列表上方重复显示应用名称;组名继续作为 `Sidebar.Menu` 的可访问性标签。只有存在两个及以上确需区分的业务分组时才显示 `Sidebar.GroupLabel`。 - 侧边栏只有一个导航组时,不在菜单列表上方重复显示应用名称;组名继续作为 `Sidebar.Menu` 的可访问性标签。只有存在两个及以上确需区分的业务分组时才显示 `Sidebar.GroupLabel`。
- 通知中心不占用 Sidebar 导航层级。存在真实通知功能时,在 Navbar 右侧操作组中使用 HeroUI `Badge.Anchor + Badge + Button + Tooltip`,通知按钮位于主题切换左侧,主题切换始终最右;按钮沿用 36px 中性圆形 Navbar 动作规范,图标为 16px Ant Design Bell。未读数只能来自真实接口,0 时不显示角标,超过 99 显示 `99+`,点击仍进入应用原通知路由。 - 通知中心不占用 Sidebar 导航层级。存在真实通知功能时,在 Navbar 右侧操作组中使用 HeroUI `Badge.Anchor + Badge + Button + Tooltip`,通知按钮位于主题切换左侧,主题切换始终最右;按钮沿用 36px 中性圆形 Navbar 动作规范,图标为 16px Ant Design Bell。未读数只能来自真实接口,0 时不显示角标,超过 99 显示 `99+`,点击仍进入应用原通知路由。
......
import xyLogoWhite from '@/assets/xy-logo-white.png'; import xyLogoRed from '@/assets/xy-logo-red.png';
import { APPLICATION_DISPLAY_NAME } from '@/config/application'; import { APPLICATION_DISPLAY_NAME } from '@/config/application';
import { Sheet } from '@heroui-pro/react'; import { Sheet } from '@heroui-pro/react';
import { Sidebar, useSidebar } from '@heroui-pro/react/sidebar'; import { Sidebar, useSidebar } from '@heroui-pro/react/sidebar';
...@@ -121,7 +121,7 @@ function SidebarContents({ ...@@ -121,7 +121,7 @@ function SidebarContents({
<img <img
alt="鑫元" alt="鑫元"
className="rc-sidebar-logo" className="rc-sidebar-logo"
src={xyLogoWhite} src={xyLogoRed}
/> />
</div> </div>
<div <div
......
...@@ -400,7 +400,7 @@ ...@@ -400,7 +400,7 @@
.app-shell-content-scroll { .app-shell-content-scroll {
min-width: 0; min-width: 0;
background: var(--rc-bg-canvas); background: transparent;
overscroll-behavior: contain; overscroll-behavior: contain;
} }
...@@ -1174,7 +1174,11 @@ ...@@ -1174,7 +1174,11 @@
overflow: hidden; overflow: hidden;
border: 0; border: 0;
border-radius: 0; border-radius: 0;
background: var(--rc-bg-canvas); background: linear-gradient(
180deg,
var(--xinyuan-canvas-top) 0,
var(--rc-bg-canvas) 18rem
);
} }
.dark .rc-app-main.sidebar__main, .dark .rc-app-main.sidebar__main,
...@@ -1603,7 +1607,7 @@ ...@@ -1603,7 +1607,7 @@
} }
} }
/* Fixed split-shell theme: dark navigation, permanently light content canvas. */ /* Muted navy navigation beside the permanently light content canvas. */
.template-dashboard-shell .app-sidebar-glass, .template-dashboard-shell .app-sidebar-glass,
.rc-mobile-sidebar.app-sidebar-glass { .rc-mobile-sidebar.app-sidebar-glass {
color: var(--rc-sidebar-foreground); color: var(--rc-sidebar-foreground);
...@@ -1635,13 +1639,17 @@ ...@@ -1635,13 +1639,17 @@
color: var(--rc-sidebar-item-selected-foreground) !important; color: var(--rc-sidebar-item-selected-foreground) !important;
} }
.template-dashboard-shell .sidebar__menu-item:hover .sidebar__menu-item-content,
.template-dashboard-shell .template-dashboard-shell
.sidebar__menu-item[data-hovered='true'] .sidebar__menu-item:not([data-current='true']):hover
.sidebar__menu-item-content,
.template-dashboard-shell
.sidebar__menu-item:not([data-current='true'])[data-hovered='true']
.sidebar__menu-item-content, .sidebar__menu-item-content,
.rc-mobile-sidebar .sidebar__menu-item:hover .sidebar__menu-item-content,
.rc-mobile-sidebar .rc-mobile-sidebar
.sidebar__menu-item[data-hovered='true'] .sidebar__menu-item:not([data-current='true']):hover
.sidebar__menu-item-content,
.rc-mobile-sidebar
.sidebar__menu-item:not([data-current='true'])[data-hovered='true']
.sidebar__menu-item-content, .sidebar__menu-item-content,
.app-sidebar-user-trigger.dropdown__trigger:hover, .app-sidebar-user-trigger.dropdown__trigger:hover,
.app-sidebar-user-trigger.dropdown__trigger[data-hovered='true'] { .app-sidebar-user-trigger.dropdown__trigger[data-hovered='true'] {
......
...@@ -15,7 +15,8 @@ ...@@ -15,7 +15,8 @@
--accent: #DA241A; --accent: #DA241A;
--accent-foreground: oklch(99.11% 0 0); --accent-foreground: oklch(99.11% 0 0);
--accent-hover: #C91F17; --accent-hover: #C91F17;
--background: oklch(97.02% 0.0000 29.20); --background: oklch(97.4% 0.002 255);
--xinyuan-canvas-top: color-mix(in oklab, var(--xinyuan-sidebar-background) 4%, var(--background));
--border: oklch(90.00% 0.0000 29.20); --border: oklch(90.00% 0.0000 29.20);
--danger: oklch(45.32% 0.1661 27.03); --danger: oklch(45.32% 0.1661 27.03);
--danger-foreground: oklch(99.11% 0 0); --danger-foreground: oklch(99.11% 0 0);
...@@ -54,18 +55,17 @@ ...@@ -54,18 +55,17 @@
--font-sans: var(--font-inter); --font-sans: var(--font-inter);
/* /*
* Xinyuan fixed split-shell contract. * Xinyuan fixed light canvas with a muted navy Sidebar.
* The application canvas always uses this light theme. The Sidebar is the * Navigation colors are kept separate from HeroUI surfaces.
* only persistent dark plane and must consume these semantic tokens.
*/ */
--xinyuan-sidebar-background: oklch(16% 0.020 255); --xinyuan-sidebar-background: oklch(32% 0.037 255);
--xinyuan-sidebar-border: oklch(26% 0.022 255); --xinyuan-sidebar-border: oklch(41% 0.036 255);
--xinyuan-sidebar-foreground: oklch(97% 0.004 255); --xinyuan-sidebar-foreground: oklch(97% 0.005 255);
--xinyuan-sidebar-muted: oklch(76% 0.018 255); --xinyuan-sidebar-muted: oklch(82% 0.018 255);
--xinyuan-sidebar-item-hover: oklch(22% 0.026 255); --xinyuan-sidebar-item-hover: oklch(39% 0.042 255);
--xinyuan-sidebar-item-selected: oklch(28% 0.016 255); --xinyuan-sidebar-item-selected: oklch(46% 0.055 255);
--xinyuan-sidebar-item-selected-foreground: oklch(99% 0.002 255); --xinyuan-sidebar-item-selected-foreground: oklch(99% 0.002 255);
--xinyuan-sidebar-focus: oklch(78% 0.105 29.20); --xinyuan-sidebar-focus: oklch(85% 0.070 255);
/* /*
* ECharts is the required chart renderer for Xinyuan applications. * ECharts is the required chart renderer for Xinyuan applications.
...@@ -131,7 +131,7 @@ ...@@ -131,7 +131,7 @@
[data-theme="dark"] { [data-theme="dark"] {
color-scheme: dark; color-scheme: dark;
/* Theme Colors (Dark Mode) */ /* Theme Colors (Dark Mode) */
/* Keep brand and focus stable when the Sidebar uses its dark plane. */ /* Keep brand and focus stable across HeroUI theme contexts. */
--accent: #DA241A; --accent: #DA241A;
--accent-foreground: oklch(99.11% 0 0); --accent-foreground: oklch(99.11% 0 0);
--accent-hover: #C91F17; --accent-hover: #C91F17;
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
--rc-text-muted: var(--muted); --rc-text-muted: var(--muted);
--rc-text-empty: color-mix(in oklab, var(--muted) 72%, var(--background)); --rc-text-empty: color-mix(in oklab, var(--muted) 72%, var(--background));
/* Fixed dark Sidebar aliases. The content canvas remains light. */ /* Muted navy Sidebar aliases. The content canvas remains light. */
--rc-sidebar-background: var(--xinyuan-sidebar-background); --rc-sidebar-background: var(--xinyuan-sidebar-background);
--rc-sidebar-border: var(--xinyuan-sidebar-border); --rc-sidebar-border: var(--xinyuan-sidebar-border);
--rc-sidebar-foreground: var(--xinyuan-sidebar-foreground); --rc-sidebar-foreground: var(--xinyuan-sidebar-foreground);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment