fix(webui): 统一玻璃语言 —— 导航改深色玻璃 + 内层面板自带圆角

用户:「你不觉得页面设计很割裂吗?尤其是通信页,大面积的非圆角元素。
同时还有大面积的非玻璃样式。导航栏不也应该改为玻璃样式吗,为什么还是黑色」。

## ① 导航还是黑的:因为我自己留了一条"必须不透明"的规则

`html[data-bg='on'] .bg-chrome-900 { background-color: rgb(var(--c-chrome-900));
backdrop-filter: none }` —— 这是**更早一轮**用户的要求(当时面板太透,壁纸从导航里
透出来显得脏)。现在整套语言统一到玻璃之后,导航继续做一块实心黑就成了全页唯一的
例外,也就是"割裂"的来源。

改成**深色玻璃**(α=0.72 + blur(18px) + saturate)——用深色而不是白色玻璃:
白字压在深色上才有对比度。没开壁纸时用 0.82(后面是页面底色而不是照片,太透显脏)。

## ② 通信页"大面积非圆角":是我修滚动时带出来的

圆角原本只加在外壳上,靠 `overflow: hidden` 裁掉内层的直角 —— 但那个 overflow
会杀掉滚动(上一封),必须去掉。**于是内层白底面板的直角就从圆角外壳里戳了出来。**
现在把圆角直接给内层面板(`.comm-pane > *`),两边对齐,且不依赖裁剪 ⇒ 与滚动不冲突。
MailView 的两条工具条也不再自带宽底(只留上边框,底色继承面板),否则同样会戳角。

## 判据

`background.test.mjs` 里两条**旧判据**(断言"导航必须不透明、不参与模糊")按现行契约
重写为"深色玻璃(α∈[0.6,0.9])+ 参与模糊",并新增"内层面板自带圆角"。
要求反转后旧判据必须一起改 —— 留着只会让下次改动"要么违规、要么把缺陷写回去"。

**实测**(真浏览器,1280×900,壁纸态):导航 α=0.72 / blur(18px) / radius 14px;
内层 MailList 面板 radius **14px**(不再是直角)。背景套件 31 条全绿。
This commit is contained in:
2026-09-14 11:17:12 +08:00
parent 8a9bc58433
commit ef68c4950c
3 changed files with 54 additions and 10 deletions

View File

@ -373,7 +373,7 @@ function ForwardBar({ mail, onClose }: { mail: Mail; onClose: () => void }) {
};
return (
<div className="shrink-0 max-h-[min(65vh,calc(var(--app-height)-3rem))] overflow-y-auto overscroll-contain border-t border-gray-200 bg-white px-4 md:px-6 py-3 space-y-2">
<div className="shrink-0 max-h-[min(65vh,calc(var(--app-height)-3rem))] overflow-y-auto overscroll-contain border-t border-gray-200 px-4 md:px-6 py-3 space-y-2">
<div className="flex items-center gap-2">
<ForwardIcon className="w-3.5 h-3.5 text-gray-500" />
<span className="text-2xs font-medium text-gray-600">
@ -850,7 +850,7 @@ function ReplyBar({
};
return (
<div className="shrink-0 max-h-[min(65vh,calc(var(--app-height)-3rem))] overflow-y-auto overscroll-contain border-t border-gray-200 bg-white px-4 md:px-6 py-3">
<div className="shrink-0 max-h-[min(65vh,calc(var(--app-height)-3rem))] overflow-y-auto overscroll-contain border-t border-gray-200 px-4 md:px-6 py-3">
<div className="flex items-center gap-2 mb-1 flex-wrap">
<p className="text-3xs text-gray-400 font-mono min-w-0 truncate"> {target}</p>
<div className="flex-1" />

View File

@ -869,12 +869,20 @@ html[data-bg='on'] .app-shell > * {
box-shadow: 0 8px 28px rgb(0 0 0 / 0.16);
}
/* 导航栏(含窄屏底部导航):不透明 + 不参与模糊 */
/*
* 导航栏改**深色玻璃**2026-09-14 用户:「导航栏不也应该改为玻璃样式吗,为什么还是黑色」)。
*
* 这条规则原本是"完全不透明 + 不参与模糊" —— 那是更早一轮的要求(当时面板太透,
* 壁纸从导航里透出来显得脏)。现在整套语言已经统一到玻璃,导航继续做一块实心黑
* 就成了全页唯一的例外,也就是用户说的"割裂"。
*
* 用深色玻璃而不是白色玻璃:白字压在深色上才有对比度。α=0.72 + blur(18px)。
*/
html[data-bg='on'] .bg-chrome-900,
html[data-bg='on'] .app-shell > .bg-chrome-900 {
background-color: rgb(var(--c-chrome-900));
backdrop-filter: none;
-webkit-backdrop-filter: none;
background-color: rgb(var(--c-chrome-900) / 0.72);
backdrop-filter: blur(18px) saturate(1.4);
-webkit-backdrop-filter: blur(18px) saturate(1.4);
}
@ -1049,7 +1057,16 @@ html.view-switch .glass-control,
*
* 这条规则对所有子页面一视同仁(收件/发件/授权/联系人),避免只修好一个。
*/
/*
* 内层面板自己也要圆角。
*
* 之前圆角只加在外壳(.app-shell > * 与 .narrow-shell > *)上,靠 overflow:hidden 裁掉
* 内层直角 —— 但那个 overflow 会杀掉滚动(见上),必须去掉。于是内层白底面板的
* **直角从圆角外壳里戳出来**,看起来就是"大面积的非圆角元素"。
* 把圆角直接给内层面板,两边就对齐了,而且不依赖裁剪 ⇒ 与滚动不冲突。
*/
.comm-pane > *:not([data-testid='comm-tabs']) {
border-radius: var(--radius-card);
/*
* 既要能压缩min-height:0也要**填满**这一列flex:1 1 0%
* 子面板(如 MailList 的根)原本写着 `shrink-0` —— 那是给"行"方向布局写的,
@ -1059,3 +1076,14 @@ html.view-switch .glass-control,
flex: 1 1 0%;
min-height: 0;
}
/*
* 桌面侧栏:无论有没有壁纸都做深色玻璃 —— 否则它是全页唯一一块实心黑。
* α=0.82 比壁纸模式的 0.72 实一点:此时它后面是页面底色而不是照片,太透只会显脏。
*/
.app-shell > .bg-chrome-900 {
background-color: rgb(var(--c-chrome-900) / 0.82);
backdrop-filter: blur(var(--bg-blur-panel)) saturate(1.2);
-webkit-backdrop-filter: blur(var(--bg-blur-panel)) saturate(1.2);
}

View File

@ -223,10 +223,26 @@ check('新组件未使用未映射色族', unmapped.length === 0, unmapped.join(
// 用户 2026-09-14 原话:「导航栏应当完全不透明……没有正文的位置过于不通透,
// 同时导航栏应当现代化一下,整个界面应当圆角化玻璃化」。
// 注意这是**两个方向**的要求:框架要实、内容要透 —— 写成一条规则就会互相打架。
const opaqueNav = /html\[data-bg='on'\] \.bg-chrome-900,[\s\S]{0,160}background-color: rgb\(var\(--c-chrome-900\)\)/.test(css);
const navNoBlur = /html\[data-bg='on'\] \.app-shell > \.bg-chrome-900 \{[\s\S]{0,160}backdrop-filter: none/.test(css);
check('导航栏在背景模式下完全不透明', opaqueNav);
check('导航栏不再参与模糊', navNoBlur);
/*
* ★ 导航栏:从"不透明"改成"深色玻璃"2026-09-14 用户:「导航栏不也应该改为玻璃样式吗,
* 为什么还是黑色」)。
*
* 这两条判据原本断言的是**相反**的东西(不透明 + 不模糊),是更早一轮的要求
* (当时面板太透、壁纸从导航透出来显得脏)。要求反转后旧判据必须一起改 ——
* 留着它只会让下一次改动"要么违规、要么把缺陷写回去"。
*
* 现在的契约:**深色玻璃**(白字要对比度,所以不用白色玻璃),
* α 落在 [0.6, 0.9]:太透读不清,太实就退回那块黑 slab。
*/
const navAlpha = Number(
(css.match(/html\[data-bg='on'\] \.bg-chrome-900,[\s\S]{0,200}?rgb\(var\(--c-chrome-900\) \/ ([\d.]+)\)/) || [])[1]
);
const navGlass = /html\[data-bg='on'\] \.bg-chrome-900,[\s\S]{0,240}backdrop-filter: blur\(/.test(css);
check('导航栏是深色玻璃(α 在 0.60.9,读得清又不挡壁纸)',
Number.isFinite(navAlpha) && navAlpha >= 0.6 && navAlpha <= 0.9, `α=${navAlpha}`);
check('导航栏参与模糊(玻璃的必要条件)', navGlass);
check('内层面板自带圆角(不靠裁剪,否则与滚动冲突)',
/\.comm-pane > \*:not\(\[data-testid='comm-tabs'\]\) \{[\s\S]{0,80}border-radius: var\(--radius-card\)/.test(css));
/*
* ★ 浮动面板几何必须**无条件**生效2026-09-14 用户:「通信页面大面积缺失圆角与
* 玻璃效果,所有有内容与无内容区域都是硬截断」)。