From 8b11ea9f13fa685aa4fc8b450df28ef07bae1465 Mon Sep 17 00:00:00 2001 From: ase-sketch <209823082+ase-sketch@users.noreply.github.com> Date: Tue, 29 Sep 2026 22:33:35 +0800 Subject: [PATCH] =?UTF-8?q?fix(override):=20=E5=8D=8A=E9=80=8F=E6=98=8E?= =?UTF-8?q?=E4=BE=A7=E6=A0=8F=E5=BC=80=E5=90=AF=E6=97=B6=E9=92=89=E4=BD=8F?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E9=A1=B5=E8=83=8C=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 设置页全屏背板(--cx-sm-surface-backdrop)复用 --dsw-alias-bg-sidebar;translucentSidebar 把该令牌改写成 rgba(·, 0.72) 后,全屏 overlay 透出压在下面的主窗口,设置页导航与主侧栏文字重影。settings-modal.css §1 早已裁决背板必须不透明(毛玻璃版 2026-09-27 被否决删除),本修补把开关与裁决对齐:覆盖层按主题向 div[data-cx-sm-panel] 钉回实色侧栏色(浅色连 --cx-sm-card-edge 一起钉,深色卡边由皮肤的 border-l1 分主题规则保持)。 - scripts/check.mjs 新增回归断言:背板双色钉实色、浅色卡边钉实色、深色卡边不被压 - 双语 README 半透明条目补记该行为 --- README.md | 3 +++ README.zh-CN.md | 2 ++ client.js | 9 +++++++++ scripts/check.mjs | 11 +++++++++++ src/client/override.js | 9 +++++++++ 5 files changed, 34 insertions(+) diff --git a/README.md b/README.md index 29672ad..56f474e 100644 --- a/README.md +++ b/README.md @@ -257,6 +257,9 @@ dark default, 60): - The translucent sidebar has no window layer to reveal on the web, and in dark the sidebar shares the surface colour, so it is invisible there — the switch therefore also turns the sidebar row fills translucent, otherwise it would be completely silent in dark. Recorded as a gap, not presented as an equivalent. +- With the switch on, the settings page backdrop stays pinned to the solid sidebar colour: the settings panel is a + full-window overlay whose backdrop reuses the sidebar token, and a translucent backdrop would show the main window + bleeding through it. - The skin paints the canvas itself: `html` and `body` both carry this skin's base colour in either theme (`html` follows through `:has(body[data-ds-dark-theme])`, because the host stamps the theme marker on `body` only). Transitions are suppressed for the two frames after a theme change (`html[data-codex-ui-switching] *`, set by the browser half on diff --git a/README.zh-CN.md b/README.zh-CN.md index 37f77b3..c58d65c 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -237,6 +237,8 @@ npm run verify 免得把调色板搬进覆盖层。 - 半透明侧边栏在 Web 上没有窗口层,只能透出页面底色;深色下侧栏与内容同面,开了看不出差别 —— 所以开关同时把侧栏行填充转半透明,否则整个开关在深色下完全无声。这是如实记录的差距,不是等价实现。 +- 开关打开时设置页背板仍钉为实色侧栏色:设置页是全屏 overlay,背板复用的正是侧栏令牌,半透明会透出压在 + 下面的主窗口。 - 画布由皮肤自己画:`html` 与 `body` 在两个主题下都取本皮肤的底色(`html` 那一份用 `:has(body[data-ds-dark-theme])` 跟上 —— 宿主只把主题标记打在 `body` 上)。切主题后的两帧内关掉全部过渡(`html[data-codex-ui-switching] *`,属性由浏览器半在 `ctx.on('theme/change')` 时打上)。这两条都是防「闪」:前者堵住「某一帧没人画底」而露出宿主默认画布,后者堵住整页交叉淡出。 diff --git a/client.js b/client.js index 66cfbfe..77936e0 100644 --- a/client.js +++ b/client.js @@ -1403,6 +1403,15 @@ function themeOverrideCss(values = {}) { const decls = dark.map(([k, v]) => ' ' + k + ': ' + v + ';').join('\n'); blocks.push(sel('dark') + ' {\n' + decls + '\n}'); } + if (values.translucentSidebar === true) { + /* 设置页背板(--cx-sm-surface-backdrop)复用 --dsw-alias-bg-sidebar:开关把它改成 + rgba 后,全屏设置页会透出压在下面的主窗口,导航与主侧栏文字重影。 + 背板设计裁决为不透明(settings-modal.css §1),这里按主题钉回实色侧栏色; + 浅色连卡边(--cx-sm-card-edge 同吃一令牌)一起钉;深色的卡边皮肤另有 + border-l1 分主题规则且元素数更多,本规则压不过、也不需要压。 */ + blocks.push(sel('light') + ' div[data-cx-sm-panel] {\n --cx-sm-surface-backdrop: ' + SKIN_DEFAULTS.light.sidebar + ';\n --cx-sm-card-edge: ' + SKIN_DEFAULTS.light.sidebar + ';\n}'); + blocks.push(sel('dark') + ' div[data-cx-sm-panel] {\n --cx-sm-surface-backdrop: ' + SKIN_DEFAULTS.dark.sidebar + ';\n}'); + } return blocks.join('\n\n'); } diff --git a/scripts/check.mjs b/scripts/check.mjs index b02b992..d05fc3b 100644 --- a/scripts/check.mjs +++ b/scripts/check.mjs @@ -163,6 +163,17 @@ attempt('覆盖层:默认值不产生任何 CSS', () => { assert(override.themeOverrideCss({ translucentSidebar: false, modelPicker: true, contrastLight: 45, contrastDark: 60 }) === '', '默认档位下输出了 CSS'); return '空串'; }); +attempt('覆盖层:半透明侧栏钉住设置页背板', () => { + /* 设置页全屏背板吃 --dsw-alias-bg-sidebar(settings-modal.css §1 裁决为不透明), + 半透明开关把它改写成 rgba 后整页透出主窗口、导航与主侧栏文字重影 —— 必须钉回实色。 */ + const css = override.themeOverrideCss({ translucentSidebar: true }); + assert(css.includes('div[data-cx-sm-panel]'), '半透明开启时缺少设置页面板规则'); + assert(css.includes('--cx-sm-surface-backdrop: ' + override.SKIN_DEFAULTS.light.sidebar), '浅色背板未钉回实色'); + assert(css.includes('--cx-sm-surface-backdrop: ' + override.SKIN_DEFAULTS.dark.sidebar), '深色背板未钉回实色'); + assert(css.includes('--cx-sm-card-edge: ' + override.SKIN_DEFAULTS.light.sidebar), '浅色卡边未钉回实色'); + assert(!/body\[data-ds-dark-theme\] div\[data-cx-sm-panel\] \{[^}]*--cx-sm-card-edge/.test(css), '深色卡边压掉了皮肤的 border-l1 分主题规则'); + return '背板双色 + 浅色卡边'; +}); attempt('覆盖层:色值与字体栈校验', () => { assert(override.isHex('#339cff') && override.isHex('#ABCDEF'), '合法十六进制被拒'); for (const bad of ['339cff', '#339c', '#339cfff', 'red', '', ' #339cff; }', null, undefined]) assert(!override.isHex(bad), '非法色值被接受:' + String(bad)); diff --git a/src/client/override.js b/src/client/override.js index 0f3a836..cee1471 100644 --- a/src/client/override.js +++ b/src/client/override.js @@ -212,6 +212,15 @@ export function themeOverrideCss(values = {}) { const decls = dark.map(([k, v]) => ' ' + k + ': ' + v + ';').join('\n'); blocks.push(sel('dark') + ' {\n' + decls + '\n}'); } + if (values.translucentSidebar === true) { + /* 设置页背板(--cx-sm-surface-backdrop)复用 --dsw-alias-bg-sidebar:开关把它改成 + rgba 后,全屏设置页会透出压在下面的主窗口,导航与主侧栏文字重影。 + 背板设计裁决为不透明(settings-modal.css §1),这里按主题钉回实色侧栏色; + 浅色连卡边(--cx-sm-card-edge 同吃一令牌)一起钉;深色的卡边皮肤另有 + border-l1 分主题规则且元素数更多,本规则压不过、也不需要压。 */ + blocks.push(sel('light') + ' div[data-cx-sm-panel] {\n --cx-sm-surface-backdrop: ' + SKIN_DEFAULTS.light.sidebar + ';\n --cx-sm-card-edge: ' + SKIN_DEFAULTS.light.sidebar + ';\n}'); + blocks.push(sel('dark') + ' div[data-cx-sm-panel] {\n --cx-sm-surface-backdrop: ' + SKIN_DEFAULTS.dark.sidebar + ';\n}'); + } return blocks.join('\n\n'); }