Commit b0da9253 authored by drigle's avatar drigle

style: align shell theme with rectification app

parent fe188a7f
# UI 架构 # UI 架构
## 2026-09-28 Shell 配色同步
- AppShell 与“问题整改”应用最后一次提交保持一致:内容画布使用中性灰白 `oklch(97.4% 0.002 255)`,Sidebar 使用低饱和深藏蓝 `oklch(32% 0.037 255)`;桌面和移动侧栏共用 `--xinyuan-sidebar-*` Token,侧栏直接显示红色鑫元 Logo,不增加底色。
- 当前导航使用提亮的同色系底色与白色文字;普通导航悬停使用较浅的藏蓝色,当前项悬停保持选中底色,避免状态被普通悬停样式覆盖。
- 内容画布顶部使用仅限 AppShell 的轻微渐变:`--xinyuan-canvas-top` 由 4% 侧栏色与 `--background` 混合,并在 18rem 内淡出到画布底色。Navbar 与页面滚动区共享该背景,Card、Surface、字段和浮层仍使用原 HeroUI Token。
- 本次同步仅改变 Shell 视觉层,不改变 Sidebar 路由、面包屑、通知、业务状态、接口或数据协议;内容区仍固定浅色,不新增主题切换。
## 依赖边界 ## 依赖边界
- 每个项目独立拥有 `node_modules` 和锁文件,不依赖相邻仓库。 - 每个项目独立拥有 `node_modules` 和锁文件,不依赖相邻仓库。
...@@ -39,7 +46,7 @@ ...@@ -39,7 +46,7 @@
## 样式所有权 ## 样式所有权
- `theme.css` 提供 HeroUI 核心颜色、半径、阴影、字段和 dark token,必须与技能资产逐字节一致。 - `theme.css` 提供 HeroUI 核心颜色、半径、阴影、字段、dark token 与 AppShell 配色;Shell Token 以 2026-09-28 与“问题整改”同步的值为准。
- `tokens.css` 只能添加 `--rc-*` 别名、布局尺寸、业务语义 chip/chart tokens,不能重定义核心变量。 - `tokens.css` 只能添加 `--rc-*` 别名、布局尺寸、业务语义 chip/chart tokens,不能重定义核心变量。
- 共享 Shell/layout CSS 只负责几何和技能批准的跨应用模式。 - 共享 Shell/layout CSS 只负责几何和技能批准的跨应用模式。
- 应用切换 CSS 仅允许 `46rem/42rem` 弹窗几何和 36px identity well 的共享 bridge class;Card、Surface、Avatar、Chip 与交互状态均由 HeroUI variant/compound API 管理。 - 应用切换 CSS 仅允许 `46rem/42rem` 弹窗几何和 36px identity well 的共享 bridge class;Card、Surface、Avatar、Chip 与交互状态均由 HeroUI variant/compound API 管理。
......
...@@ -2,12 +2,18 @@ ...@@ -2,12 +2,18 @@
唯一实现基准为“审计项目管理”应用。以下合同适用于活动路由及后续新增页面,不允许页面私有外观覆盖 HeroUI/HeroUI Pro。 唯一实现基准为“审计项目管理”应用。以下合同适用于活动路由及后续新增页面,不允许页面私有外观覆盖 HeroUI/HeroUI Pro。
## 2026-09-28 Shell 配色同步
当前 AppShell 使用低饱和深藏蓝侧栏与中性灰白内容画布。`theme.css` 的 `--background` 与 `--xinyuan-sidebar-*` 是这组配色的唯一来源:侧栏背景为 `oklch(32% 0.037 255)`,页面画布为 `oklch(97.4% 0.002 255)`;选中项底色为 `oklch(46% 0.055 255)`,普通项悬停使用同色系较亮底色。品牌主红 `#DA241A` 不变,侧栏直接显示红色 Logo、不加底色。
内容画布顶部使用仅限 AppShell 的轻微渐变:`--xinyuan-canvas-top` 从 4% 侧栏色与 `--background` 的混合色过渡,并在 18rem 处回到画布底色。Navbar 与页面滚动区透出同一层背景;Card、Surface、字段和浮层仍按 HeroUI 语义 Token 渲染。此规则不引入主题切换,也不改变导航或业务交互。
## 主题与品牌 ## 主题与品牌
- 应用显示名统一为“监察稽核管理”。 - 应用显示名统一为“监察稽核管理”。
- 浅色/暗色 Logo 分别使用 `src/assets/identity/xy-logo-red.png` 与 `xy-logo-white.png`。 - AppShell Sidebar 固定使用 `src/assets/identity/xy-logo-red.png`,Logo 直接显示且不添加底色;其他场景如需深色背景适配,仍可使用 `xy-logo-white.png`。
- `src/design-system/theme.css` 是本项目 HeroUI 主题权威;加载顺序为 Tailwind、HeroUI、HeroUI Pro、主题、鑫元 Tokens。 - `src/design-system/theme.css` 是本项目 HeroUI 主题权威;加载顺序为 Tailwind、HeroUI、HeroUI Pro、主题、鑫元 Tokens。
- 品牌主色固定为 `#DA241A`,由 HeroUI `--accent` 与显式 `--primary`、`--primary-50` 至 `--primary-950` 色阶 Token 提供;同时映射 `--color-primary-*` 供 Tailwind 集成使用。primary hover/pressed 使用 `#C91F17`/`#B51B14` 深色阶,focus 固定为品牌红。页面禁止硬编码品牌/表面/状态颜色、渐变、阴影和组件状态。 - 品牌主色固定为 `#DA241A`,由 HeroUI `--accent` 与显式 `--primary`、`--primary-50` 至 `--primary-950` 色阶 Token 提供;同时映射 `--color-primary-*` 供 Tailwind 集成使用。primary hover/pressed 使用 `#C91F17`/`#B51B14` 深色阶。页面禁止硬编码品牌/表面/状态颜色、渐变、阴影和组件状态;渐变仅允许用于上述 AppShell 内容画布顶部,不用于页面或组件表面。
- Surface 层级固定为 L0 background、L1 surface、L2 surface-secondary、稀有 L3 surface-tertiary;Portal 使用 overlay,不把 Card 当 Surface。 - Surface 层级固定为 L0 background、L1 surface、L2 surface-secondary、稀有 L3 surface-tertiary;Portal 使用 overlay,不把 Card 当 Surface。
## Shell ## Shell
......
import xyLogoWhite from '@/assets/identity/xy-logo-white.png'; import xyLogoRed from '@/assets/identity/xy-logo-red.png';
import { AppGrid, ChevronDown, LogOut } from '@/components/AppIcons'; import { AppGrid, ChevronDown, LogOut } from '@/components/AppIcons';
import { APP_DISPLAY_NAME } from '@/constants/app'; import { APP_DISPLAY_NAME } from '@/constants/app';
import { Sheet } from '@heroui-pro/react/sheet'; import { Sheet } from '@heroui-pro/react/sheet';
...@@ -97,7 +97,7 @@ function SidebarContents({ menuGroups, onLogout, onOpenApplicationSwitcher, path ...@@ -97,7 +97,7 @@ function SidebarContents({ menuGroups, onLogout, onOpenApplicationSwitcher, path
<Sidebar.Header> <Sidebar.Header>
<div className="app-sidebar-brand rc-sidebar-brand"> <div className="app-sidebar-brand rc-sidebar-brand">
<div className="app-sidebar-brand-mark rc-sidebar-brand-mark"> <div className="app-sidebar-brand-mark rc-sidebar-brand-mark">
<img alt="鑫元" className="rc-sidebar-logo" src={xyLogoWhite} /> <img alt="鑫元" className="rc-sidebar-logo" src={xyLogoRed} />
</div> </div>
<div className="app-sidebar-brand-main rc-sidebar-brand-main" data-sidebar="label"> <div className="app-sidebar-brand-main rc-sidebar-brand-main" data-sidebar="label">
<span className="app-sidebar-title rc-sidebar-title">{APP_DISPLAY_NAME}</span> <span className="app-sidebar-title rc-sidebar-title">{APP_DISPLAY_NAME}</span>
......
...@@ -429,7 +429,7 @@ ...@@ -429,7 +429,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;
} }
...@@ -1193,7 +1193,11 @@ ...@@ -1193,7 +1193,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,
...@@ -1622,7 +1626,7 @@ ...@@ -1622,7 +1626,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);
...@@ -1654,13 +1658,17 @@ ...@@ -1654,13 +1658,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'] {
......
...@@ -42,7 +42,8 @@ ...@@ -42,7 +42,8 @@
--accent: #DA241A; --accent: #DA241A;
--accent-hover: #C91F17; --accent-hover: #C91F17;
--accent-foreground: oklch(99.11% 0 0); --accent-foreground: oklch(99.11% 0 0);
--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);
...@@ -81,18 +82,17 @@ ...@@ -81,18 +82,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: #DA241A; --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.
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,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