# Brick — 设计方案 (Design Doc) > dsh-brick-builder / dsh-theme-brick > A restrained, token-only theme layer for DeepSeek Harness Web (DSH 0.1.0-rc.6). --- ## 0. 摘要 本仓库开发一个 DSH Web 美化插件:**Brick(砖)**。 - **形态**:一个纯 Client 的 Cordis 插件,通过主题服务 `theme.overrideTokens()` 叠一层 token 覆盖层。无 DOM hack、无全局 CSS、无新增 UI、无设置项。 - **理念**:`dsh-brick-builder` 这个名字就是答案 —— DSH 最重要的哲学是「一切皆插件」,插件之于 Harness,正如砖之于墙:每一块都可承重、可替换、可组合。所以这个美化插件的审美哲学是**砌筑**:材料诚实(温润的石膏/纸/黏土,而非发光的玻璃)、灰缝即线条(结构性发丝线)、一砖一色(唯一一个火烧黏土色作为强调色)、以及贯穿始终的**克制**。 - **兼容性**:只读写主题系统的 token 层,与任何已安装插件(包括本机 `fexp-file-explorer`、`sent-msg-locator` 等)通过同一套 token 面组合,卸载即完全还原。 --- ## 1. 调研摘要(取其精华,去其糟粕) ### 1.1 生态调研 | 来源 | 做法 | 评价 | | --- | --- | --- | | [Catppuccin-dsh-theme](https://github.com/zhijun-dai/Catppuccin-dsh-theme) | 通过 ThemeRuntime `register()` 注册整主题;纯 CJS `window.__ModuleLoader__.load` bundle;`dsh.bundle.patch` + `dsh.client` 打包;具体色值(无 var 间接) | ✅ **精华**:完全走受支持的主题面,打包格式与官方 ui-* 包一致 | | [dsh-theme-blackgold](https://github.com/frostgao/dsh-theme-blackgold) | 大量全局 CSS 选择器考古(`button:has(> svg[viewBox=...])`)、sheen 扫光动画、手写动画 keyframes | ❌ **糟粕**:依赖内部 DOM 结构,UI 一改即碎;全局选择器与其他插件互相污染;动画属于装饰性华丽,违反克制原则 | | [awesome-deepseek-harness](https://github.com/libukai/awesome-deepseek-harness) | 生态指南:`dsh plugin --profile web add ` 安装 bundle 插件 | ✅ 确认安装面与「一切皆插件」语境 | | 本地 rc.6 源码(`@deepseek-ai/dsh-client-ui-theme`) | `ThemeRuntime.overrideTokens(source, tokens)`:按 seq 叠加层、后层逐 token 胜出、disposer 移除、`theme/change` 事件;无 token 名白名单,但值必须为 `{ light, dark }` 对 | ✅ **权威契约**:这就是本插件唯一要用的 API | ### 1.2 平台契约(验证于本机 rc.6) - 主题服务:`ctx.theme`(Client)。`overrideTokens(source, tokens)` 返回 disposer;同 source 重复调用会整体替换并重置于栈顶(HMR 友好)。 - 受支持 token 面(`Theme.listTokens` 列出的 13 个):`--dsw-alias-bg-base / bg-layer-1 / bg-layer-2 / bg-overlay / border-l1 / border-l2 / brand-primary / label-primary / label-secondary / state-error-primary / state-success-primary / state-warn-primary / --dsw-specific-sidebar-fill`。 - 基础样式表显示:alias token 由 static 色阶推导(`--dsw-static-neutral-bluish-*` 冷灰蓝阶 + `--dsw-static-deepseek-*` 品牌蓝阶 + red/green/amber 阶)。`brand-primary` 在浅色下是**近黑墨色**(主按钮是墨色+白字),品牌蓝实际由 `state-business-*`、`button-info-*`、`--dsw-alias-brand-primary-new-colorprimary-new-color`、`--dsw-static-blue-45x/5xx`(轨迹/ContextMeter)、`--dsw-specific-bubble`(用户气泡淡蓝)承载。 - **推论**:默认设计的"品牌蓝"不是一个 token,而是一组 token。要让强调色真正变成黏土色,必须把这些"蓝色通道"整体旋转色相 —— 这是本方案的核心手法:**只转色相,不改结构**。 ### 1.3 结论 - 用 `overrideTokens` 做**覆盖层**(而非 `register` 注册新主题):不改用户偏好、不污染主题注册表、与其它插件的覆盖层按序组合、卸载即还原 —— 这是「一切皆插件」在主题面的正确姿势。 - 全部使用**具体色值**,不写 var() 间接(与 Catppuccin 相同,避免跨层解析歧义)。 - 零 DOM 操作、零全局 CSS、零动画、零新增 UI。黑金插件的每一条反模式都写进本方案的「不做清单」。 --- ## 2. 设计哲学:砌筑 (Masonry) `dsh-brick-builder` —— 砖。砖是墙的基本单元:**模数化、可承重、可替换、诚实**。插件之于 DSH 正是如此。因此本主题的每一处变化都服从砌筑逻辑: 1. **每块砖都可承重** —— 每个视觉变化必须服务于结构(层级、可读性、可交互性),不为装饰而装饰。改动的都是"结构件":面、缝、墨、色、态。 2. **材料的诚实** —— 界面应该像材料本身:浅色下是石灰水刷过的石膏墙与纸面,深色下是窑内壁与炭灰。默认配色的冷灰蓝阶被替换为暖中性色(黏土、砂岩、麦秆纸),**去掉"发光的玻璃感",留下"有重量的材料感"**。 3. **灰缝即线条** —— 默认边框是 `rgba(0,0,0,.04)` 级别的"几乎看不见",这是现代 SaaS 的流行病:用阴影代替线条。砖墙的灰缝是**真实存在、间距均匀的结构线**。本主题把边框做成带暖色调的、略微更实的灰缝(l1 发丝、l2 稍强),线条是砌筑的结果,不是装饰。 4. **一砖一色** —— 全界面只有一个强调色:**火烧黏土(terracotta)**,深色模式下化为**余烬(ember)**。它通过产品自己承载品牌蓝的那组通道注入,所以无处不在又始终克制。 5. **克制是纪律,不是懒惰** —— 明确不做:阴影、渐变、动画、圆角改造、字体改动、背景图、徽标涂改(黑金插件那种把 HARNESS 徽标涂金并加扫光的做法是反面教材)。任何让"第一眼很惊艳"的东西都被排除。 ### 2.1 一处有意的二元:文字是温的,代码是冷的(已撤销,见下) `--dsw-alias-markdown-*`(代码块、行内代码、引用)阶段一**有意不改**,理由曾是:代码是机器语言的寄存器,保持默认的冷灰蓝调,与暖色自然语言正文形成有意的二元 —— 人在说话时是温的,机器在说话时是冷的。 > **阶段三决策(`PLAN-PHASE3-DEEPENING.md` D2)**:用户选择「纯 token 深化」后此二元**撤销** —— 近乎不可见的冷调不是设计声明而是意外;代码块随静态色阶一并暖化,融入同一面墙。若未来要恢复二元,应改为显著冷代码面并重新评估。 --- ## 3. 色板 (Palette) > 对比度均按 WCAG AA 目标校验(正文 ≥ 4.5:1;强调/状态至少 ≥ 3:1 用于图形元素)。下表为实测值(WCAG 相对亮度公式)。 ### 3.1 浅色 (Light) —— 石灰石膏与纸 | 角色 | 值 | 说明 | | --- | --- | --- | | 基面 bg-base | `#FAF8F3` | 石灰水刷过的石膏,暖而不黄 | | 升层面 bg-layer-1 | `#FFFFFF` | 纯纸面;与基面的暖度差制造真实层次 | | 嵌套面 bg-layer-2 | `#F3EFE6` | 黏土洗过的次层 | | 浮层 bg-overlay | `#F0EADF` | 灰浆色浮层(弹层/菜单) | | 侧栏 sidebar-fill | `#F2EDE2` | 石膏面板,与正文面微差 | | 灰缝 l1 / l2 | `rgba(82,60,34,.10)` / `rgba(82,60,34,.18)` | 暖褐发丝线,真实的缝 | | 墨 label-primary | `#241B12` | 暖近黑,正文 15.9:1 | | 次墨 label-secondary | `#5E5549` | 陈墨,6.9:1 | | 淡墨 label-tertiary | `#8B8172` | 石色弱化文字,3.6:1(同级默认 3.8,弱化角色按 3:1) | | **强调 brand / business / info / blue** | `#A84A22` | **火烧黏土**,白字 5.7:1 | | 成功 success | `#4C7A3E` | 苔藓绿(土色系),4.8:1 | | 警告 warn | `#A16207` | 赭石,4.6:1 | | 错误 error | `#B03A2E` | 砖红,5.7:1 | ### 3.2 深色 (Dark) —— 窑与余烬 | 角色 | 值 | 说明 | | --- | --- | --- | | 基面 bg-base | `#171310` | 窑灰暖黑,非冷蓝黑 | | 升层面 bg-layer-1 | `#1E1914` | 略抬升的暖黑 | | 嵌套面 bg-layer-2 | `#262018` | 次层 | | 浮层 bg-overlay | `#332B20` | 暖深灰浮层 | | 侧栏 sidebar-fill | `#121009` | 窑内壁,比基面更深 | | 灰缝 l1 / l2 | `rgba(244,232,214,.07)` / `.14` | 暖白灰缝 | | 墨 label-primary | `#F1E7D5` | 暖象牙,15.1:1 | | 次墨 label-secondary | `#C4B7A1` | 暖石色,9.4:1 | | 淡墨 label-tertiary | `#9C8F78` | 5.8:1 | | **强调 brand / business / info / blue** | `#E0843F` | **余烬**,深底 6.6:1 | | 成功 success | `#84A269` | 柔苔绿,6.5:1 | | 警告 warn | `#D9A441` | 赭金,8.2:1 | | 错误 error | `#E0705A` | 柔砖红,5.8:1 | 深色强调逻辑:浅色主按钮 = 墨色(平台默认是深色按钮),本主题浅色主按钮 = 黏土;深色主按钮 = 暖象牙(平台默认是近白按钮)。**保持平台"对比度驱动反转"的结构,只旋转色相** —— 强调色在两种模式中都由同一组"状态/信息/轨迹"通道承载。 --- ## 4. Token 映射(完整覆盖层) 共 **40 个有效 token**(阶段一 34 − 3 死 token + 阶段二 9)。阶段三(`PLAN-PHASE3-DEEPENING.md`,用户决策 A)追加 44 个静态色阶 token(仅覆盖被消费的阶步,含 bluish 19 / deepseek 7 / red-green-amber 11 / neutral 6 / blue-900 1),现共 **84 个有效 token** —— 全量消费扫描(701 文件)确认无一死 token。 | 组 | Token(浅/深值) | | --- | --- | | **面** | bg-base, bg-layer-1, bg-layer-2, bg-overlay, sidebar-fill | | **缝** | border-l1, border-l2 | | **墨** | label-primary, label-secondary, label-tertiary | | **强调(黏土/余烬)** | brand-primary, brand-primary-new-colorprimary-new-color, state-business-primary, state-business-tertiary, button-info-fill, button-info-hover, static-blue-500, static-blue-450 | | **态** | state-error-primary, state-success-primary, state-warn-primary | | **气泡** | specific-bubble, specific-bubble-highlight | | **侧栏导航** | specific-sidebar-nav-item-hover, specific-sidebar-nav-item-active, specific-sidebar-nav-item-active-accent | | **交互** | interactive-bg-hover, interactive-bg-active | | **浮层墨面** | toast-bg, tooltip-bg | | **滚动条(灰缝的负空间)** | scrollbar-bg-l2, scrollbar-hover-l2 | 明确不改(记录在案):阶段一曾列 `--dsw-alias-markdown-*`(有意二元)与 shadow/gradient 系;阶段二已按方案暖化 shadow-lv2/lv3(只暖化不新增);阶段三撤销二元并暖化全部被消费静态阶。仍不改:tool-bar 硬编码 rgba、`--dsw-hovercard-bg` 硬编码(无 var 锚点,需 hashed 选择器 = 黑金陷阱)、字体尺度(Figma 导出语义)。 --- ## 5. 兼容性(与其它已安装插件) - **与本机已装插件**(fexp-file-explorer、sent-msg-locator 及任何 bundle 插件):本插件零 Slot、零事件、零全局样式,唯一交互面是 `theme.overrideTokens`。其它插件的覆盖层按 seq 顺序逐 token 组合,后层胜出、卸载还原 —— 这是平台设计的组合面,不存在冲突面。 - **与其它主题插件**:同时安装多个主题插件时,后加载者的同名 token 生效(平台语义)。Brick 是"层"不是"主题",卸载后回到用户的 light/dark/system 偏好原貌。 - **与产品升级**:不依赖任何 DOM 结构/选择器,rc.x 升级即使改动内部组件也不影响本插件。 - **HMR/重载**:同 source 重新覆盖 = 整体替换并置顶,插件更新后无需清理。 --- ## 6. 验证 1. `node --check` 校验 lib 产物语法。 2. Bundle 冒烟测试(镜像浏览器加载器):注册 factory → 物化 → 导出 `{ TOKENS, inject, apply }`,零 require;34 个 token 全部通过 `validateOverrides` 的 `{ light, dark }` 形状校验;`apply()` 返回 disposer,dispose 语义正常。 3. **Token 名存在性**:逐一扫描产品全部样式表(web-frontend dist + client-ui-theme styles,354 个 `--dsw-*` 名),34 个 Brick token 全部命中 —— 无死 token(`overrideTokens` 不校验名称,此项检查排除了"拼写错误导致静默失效")。 4. WCAG AA 实测:17 组关键前景/背景对比全部达标(正文 4.5:1,弱化角色 3:1),数值见 §3 色板表。 5. **动态实机验证(已完成)**:以动态 Cordis 插件(`brick-1/pkg-1`,安全审查 ALLOW 0/300)加载同一份 client 逻辑并激活成功 —— 本 GUI 页面即呈现 Brick 层(面、缝、墨、色、态全部生效);运行期间可随时 `cordis_stop` 还原默认。 6. 停止插件 → 主题层移除 → 页面还原默认(disposer 语义)。 --- ## 7. 明确不做(Roadmap 之外) - 不注册可选主题、不做设置页、不加开关(「一切皆插件」:要关就卸)。 - 不做深色专属渐变/光效/扫光(黑金教训)。 - 不自定义字体与字号(字体属于系统语义,不属于主题层)。 - 不做动画(`prefers-reduced-motion` 之下也没有动画可降级,这是最彻底的克制)。 --- ## 8. 参考 - [Catppuccin-dsh-theme](https://github.com/zhijun-dai/Catppuccin-dsh-theme) —— token 化主题与打包范本 - [dsh-theme-blackgold](https://github.com/frostgao/dsh-theme-blackgold) —— 反模式清单来源 - [awesome-deepseek-harness](https://github.com/libukai/awesome-deepseek-harness) —— 生态与安装约定 - 本机 `@deepseek-ai/dsh-client-ui-theme`(rc.6)`ThemeRuntime` 源码 —— 权威契约