dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Monet (Material Design 3) dynamic-color wallpaper theming for DeepSeek Harness
Monet wallpaper theming for the DeepSeek Harness desktop app, built on Material Design 3 dynamic color. The wallpaper seed goes through the official Material color pipeline (HCT → quantize → Score → tonal palettes) and maps the M3 roles onto the Harness design tokens per color scheme.
Quantizer-style 采样 + Score 评分)--dsw-alias-* 全套别名令牌(100+ 项,亮暗各自取值)由 theme.overrideTokens 注入backdrop-filter 直接作用于壁纸m3ui 控件样式(开关/滑块/芯片/卡片)+ 壳层配色交叉淡入 + 设置页入场动画,可一键关闭并尊重系统「减少动态效果」localStorage(dsh.m3monet.v1),跟随系统亮暗自动切换壁纸画在 .BynINW_frame 的背景上,而布局的子列会在其上再铺自己的底色,导致壁纸被完全遮住
(源码见 @deepseek-ai/dsh-client-ui-layout/lib/client.js):
| 图层 | 覆盖色 | 处理方式 |
|---|---|---|
[data-windows-titlebar] .BynINW_centerCol | --dsw-alias-bg-base | 开启壁纸时按「主体毛玻璃不透明度」或「界面不透明度」改为 color-mix(... transparent) |
.BynINW_sidebarCol | --dsw-specific-sidebar-fill | 开启壁纸时按「侧边栏毛玻璃不透明度」或「界面不透明度」改为半透明 |
.BynINW_sidebarCol ._2H3hWW_root | 同上(第二层) | 壁纸开启时置为 background: transparent,避免两层叠加 |
[data-windows-titlebar] .BynINW_frame:before | --dsw-specific-sidebar-fill | 改为主题纯色(surfaceContainer),并清掉 backdrop-filter |
--dsw-alias-bg-layer-1/2/3 | 卡片/面板底色 | 取「界面不透明度 + 14%」,保持正文可读性 |
.wCInkW_mask(设置页全屏遮罩) | --dsw-alias-bg-mask-1 | 遮罩 token 恢复为半透明 scrim(stock #0000003d 语义),并加 backdrop-filter 毛玻璃 |
.wCInkW_panel(设置页 800px 面板) | --dsw-alias-bg-layer-2 | 开启壁纸时改为按「主体毛玻璃不透明度 / 界面不透明度」的 color-mix(... transparent) + 毛玻璃 |
--dsw-alias-bg-mask-1/2/3、bg-mask-photo/drop、bg-skeleton、border-inverted(2)在 stock 主题里都是半透明叠加层; 早期版本把它们错误地映射成了不透明scrim,会让设置页遮罩变成纯黑(壁纸完全看不见),现已按语义修正。
毛玻璃 backdrop-filter 按分组分别作用于侧边栏(.BynINW_sidebarCol)与主体(.BynINW_centerCol),
二者直接坐在 frame 背景上,因此模糊的正是壁纸本身;标题栏条不参与模糊。
该模糊不能直接写在列元素上:
backdrop-filter(与filter、transform一样)会让元素成为其position:fixed后代的包含块,而侧边栏的折叠按钮._2H3hWW_toggle恰好是position:fixed; left:12px; top:calc((var(--dsh-windows-titlebar-height) - 28px) / 2)——靠它落在 Windows 标题栏那一行。模糊一旦写在列上,按钮就以「侧边栏列」为基准定位,整体下移一个标题栏高度, 压到deepseek HARNESS品牌行上(因为列本身已经被 frame 的padding-top推低了一个标题栏高度)。 因此改为在列内绘制::before毛玻璃层:position:relative;z-index:0+::before{inset:0;z-index:-1;pointer-events:none;backdrop-filter:…}。 该层位于列内容之下(z-index:-1,不会把侧边栏自己的文字糊掉),且自身没有任何后代, 不会再改变任何元素的定位基准。主体列同理。
侧边栏底部(_2H3hWW_footArea,账号行上方)原有软性阴影边界,现替换为
border-top: 1px solid var(--dsw-alias-border-l2) 的主题色横线。
设置页与主题表面按 Google Material 3(Material You)规范重构:
--m3-ease-standard/emphasized、--m3-dur-short…medium4)、形状令牌
(--m3-radius-xs…xl)与全套 m3ui-* 控件样式,经 data-m3-monet-base 样式表注入一次、永不重写——
重写样式表会重启 CSS 动画;随设置变化的规则仍在独立的动态样式表(data-m3-monet)里。shadow 角色而非硬编码灰色)。
颜色全部走 --m3-* 令牌并回退到 --dsw-alias-*,插件禁用时控件自动退回主题令牌样式。frame、侧边栏、主体列与内部侧边栏根的背景/边框/文字色以
250ms ease-standard 过渡(列 ::before 毛玻璃层同步过渡)。只过渡颜色属性,不对宿主元素使用
transform/will-change(避免再次触碰 fixed 定位包含块问题)。prefers-reduced-motion: reduce 时自动全部禁用。壁纸每次变化都会重新走一遍取色流程,用「壁纸标记」(wallpaperTag)判断是否需要重算:
function hashString(str) { // FNV-1a
let hash = 0x811c9dc5;
for (let i = 0; i < str.length; i += 1) {
hash ^= str.charCodeAt(i);
hash = Math.imul(hash, 0x01000193) >>> 0;
}
return hash.toString(16) + '-' + str.length;
}
wallpaperTag = kind + ':' + hashString(value);
早期版本用 kind + value.slice(0, 64) 当标记,而所有 JPEG data URL 的前 64 个字符都是同一段
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD…,于是换壁纸后标记不变、被判定为「已提取过」而跳过重算,
主题就一直停留在上一张壁纸的颜色。改为内容哈希(并附上长度)后,任何换图都会触发重新提取。
palette.source === 'wallpaper';若当前色源为「预设色板」,会自动切到「壁纸自动」。seeds: [] + extractError: true,设置页给出提示而不是静默沿用旧色。设置 > 插件 > 莫奈美化 > 配置(settings.section 槽位,页面内容可上下滚动)--dsw-* CSS 变量绘制 UI,不引入任何客户端 UI 包。@material/material-color-utilities(Apache-2.0,见 THIRD_PARTY_NOTICES.md)。node scripts/build.mjs # 由 src/engine-core.js + src/engine-ext.js 生成 lib/engine.js 并内联进 client.js
node scripts/test.mjs # 引擎单元测试(HCT 已知值、Scheme 角色、Monet 取色、Token 映射)
node scripts/smoke-client.mjs # 浏览器端冒烟:模块装载、槽位注册、Token 注入、壁纸取色
包体结构:index.js(Host 空实现)、client.js(浏览器端全量逻辑)、cordis.patch.yml(一行插件行)。
plugin_manager install_bundle:application: applied,无警告;包以 link: 形式装入 profiles/desktop。cordis_inspect_query):仅 settings.section 出现 monet-theme(order 120,active: true);main 与 sidebar.panellist 均不注册(按需求:不在主页面/左侧栏显示)。Theme.listTokens 中已出现本插件注册的 --m3-* 自定义令牌,证明 theme.overrideTokens 在页面端生效;覆盖值为 {light, dark} 双方案,符合 requiresLightAndDark: true 约束。#4285f4 → HCT (265.98, 62.27, 56.55);Scheme.light(blue).primary = #005ac1、dark = #adc6ff(Material You 蓝的规范值)。scripts/smoke-client.mjs 覆盖:断言壁纸开启时 --dsw-alias-bg-base/--dsw-specific-sidebar-fill 变为 color-mix 半透明、_2H3hWW_root 置透明;并断言无壁纸图源时表面保持不透明、总开关关闭时不注入覆盖。#b90063 / blur 20 / opacity 55,旧代码会退回默认值);②侧边栏与主体毛玻璃独立(断言两个 veil 分别用 80% 与 60%、两条 backdrop-filter 各自参数);③顶部标题栏为纯色且 backdrop-filter:none;④侧边栏底部为 border-top: 1px solid var(--dsw-alias-border-l2) 横线。另含旧版扁平 glass 配置的迁移断言。--dsw-alias-bg-mask-1 为 24% 半透明 scrim(非不透明)、bg-skeleton 半透明、border-inverted 亮色为 transparent;壁纸开启时 .wCInkW_mask 与 .wCInkW_panel 均带 backdrop-filter,面板背景为 60%(主体毛玻璃不透明度)的 color-mix;无壁纸时不下发 .wCInkW_panel 规则。greenFromArgb > blueFromArgb)、最终 --dsw-alias-brand-primary 亮色不再是 #6750a4(实测 #006e21,种子 #48a850)且主题被重复应用;场景 6 断言开启壁纸后色源自动从 preset 切到 wallpaper。settle(260ms) 越过 120ms 防抖窗口后才断言,要求最终生效的主题既不是旧种子 #6750a4、也不等于旧种子推出的 brand-primary。把修复临时还原(applySoon 用旧快照 + applyFresh 不取消防抖)后该断言确实失败(实测回落到 #6750a4),证明断言不是空转。.BynINW_sidebarCol::before /
.BynINW_centerCol::before 上,并列元素本身不带 backdrop-filter(/\.BynINW_sidebarCol\{[^}]*backdrop-filter/
与 /\.BynINW_centerCol\{[^}]*backdrop-filter/ 都必须不命中)——一旦把模糊写回列元素,这两条断言立即失败。prefers-reduced-motion、壳层过渡被 html.m3-monet-on:not(.m3-motion-off) 门控、base 不含 backdrop-filter;
遍历设置页渲染树(含函数组件调用与 children 拍平)断言控件使用 m3ui-switch/chip/card/slider/dot 类、
行带 m3ui-row-in 入场类;motion:false 时断言 m3-motion-off 根标记出现(默认不出现)。git clone https://github.com/Regex520/dsh-m3-monet.git
克隆后把该目录作为本地 bundle 装入 Harness profile(以 link: 方式登记,因此改工作区文件即改已装包内容),
重载应用后生效:设置 → 插件 → 莫奈美化 → 配置。
@material/material-color-utilities(Apache-2.0),出处与许可全文见 THIRD_PARTY_NOTICES.md。