# Brick Phase 2 — 方案:空间的光与影 (Light & Shadow of Space) > dsh-brick-builder / dsh-theme-brick · 第二阶段开发方案 > 阶段一(已完成):材料的颜色 —— 34-token 色彩层(石膏/黏土/灰缝/土色态) > 阶段二(本方案):从 **web UI 布局哲学**出发的优化 —— 光与影、节奏与结构尊重 > 依据:本机 DSH rc.6 全部 7 个样式表 + `dsh-client-ui-layout` 源码实证(非猜测) --- ## 0. 结论先行 第二阶段的可执行面**小而诚实**:10 个 token(2 个暖投影 + 8 个暖化补齐)。但方案的**分析价值**在于: 完整解读了产品的布局哲学、用架构证据划清了"能动/不能动"的边界、并给出上游产品提案与第三阶段决策点。 克制不是什么都不做,而是**只做有证据、可还原、不越界的事**。 --- ## 1. 产品布局哲学(从源码读出) ### 1.1 三栏工作台:上下文 → 工作 → 检查(AppFrame,`dsh-client-ui-layout`) ```js // computeColumns(viewport, sidebar, details) —— 产品布局算法实证 sidebar: 0 ? 56 /* rail */ : clamp(sidebar, 264, 420) details: details === 0 ? 0 : clamp(details, 300, 520) center: viewport - s - d0 // 流体,无上限 // 下限保护:s + d1 + 640 <= viewport 时 center 至少 640px ``` - 中栏是 `minmax(0, 1fr)`(inline style 写入 `grid-template-columns`)——**没有阅读尺度上限**。 - 布局几何是**瞬时状态**(官方 README:reload 即还原默认),不是设置。 - 窄视口下侧栏自动收成 56px rail。 - 拖拽手柄改列宽,0.3s 过渡(`--ds-transition-duration-slow`),`prefers-reduced-motion` 时全部禁用。 **哲学读法**:这是一个"为代理工作流设计"的布局 —— 会话正文承载代码/JSON 等宽而密的内容, **全宽是有意的**(数据密度优先于传统排版测量);面板是状态不是设置(轻量、可放弃); 动效只出现在结构性过渡上且尊重无障碍。 ### 1.2 组合式座位:布局即插件组合的结果(Slot 拓扑实证) `root → sidebar / conversation / details` 三列之下,全部可扩展面都是 **list / chain / keyed 座位** (`sidebar.footer.action`、`conversation.session.header.actions`、`conversation.input.left/right`、 `conversation.input.dock`、`conversation.composer.dock`、`shell.overlay` …)。 产品提供**结构**,插件填充**内容** —— 砖与灰缝。这是「一切皆插件」在布局面的直接体现。 ### 1.3 设计 token 的出处(`dsh-client-ui-theme/lib/styles/*.css` 实证) - 字体全量尺度(11–24px 九级 + markdown 专属尺度)注释为 **"由 @deepseek-figma-plugin 导出"** —— 是产品的语义系统,主题插件不应触碰。 - 阴影 lv1/lv2/lv3 单次定义、双模式共用;思考渐变 light/dark 各一。 - 间距/圆角/列宽 **全部硬编码 px**(扫描 7 个样式表:`gap: 8px`、`padding: 8px 10px`、`border-radius: 18px`…),无 var 锚点。 ### 1.4 节奏数字(产品的密度与节拍) | 维度 | 数值 | | --- | --- | | 字号尺度 | 11/12/13/14/16/20/24px(line-height 14–34px) | | 控件高度 | 24–44px(密集 24/28,常规 36) | | 间距 | 4/6/8/10/12/16px 混用(非严格模数) | | 圆角 | 8/10/12/18px | | 阴影 | lv1 2px 5% / lv2 双层 / lv3 三层 12px 32px 8% | | 动效 | 0.1s(fast) / 0.2s / 0.3s(slow),标准 ease-in-out | | 列宽 | sidebar 264–420(默认 ~280)/ details 300–520 / center ≥640 | --- ## 2. Brick 第二阶段哲学:空间的光与影 阶段一完成了"墙"(材料与颜色)。阶段二完成"光"——**没有阴影,空间就没有深度;阴影的色温, 是材料在空间中的诚实**。砖墙的投影是暖的(黏土与木材的影子偏褐),玻璃与屏幕的影子偏蓝黑。 **两条执行纪律(延续阶段一):** 1. **只暖化,不新增** —— 不改阴影的结构(层数、模糊、偏移、透明度全部保留),只把黑色投影 `rgba(0,0,0,…)` 旋转为暖赭 `rgba(74,47,22,…)`。层级语义零变化,色温一致。 2. **死 token 不覆盖** —— 全量扫描 7 个样式表:`--dsw-shadow-lv1`、`--dsw-linear-gradient-think`、 `--dsw-linear-think-select` 消费次数为 0。覆盖它们 = 无效 token,违反"无死 token"纪律 → 不做。 ### 2.1 执行项(9 个 token,本次落地;另有 1 个候选被验证剔除) **A. 光影(2)**——结构不变、色相旋转(浅深共用,与产品定义一致): | Token | 现值(黑) | Brick 值(暖赭) | 消费 | | --- | --- | --- | --- | | `--dsw-shadow-lv2` | `0 4px 12px 0 rgba(0,0,0,.02), 0 2px 8px 0 rgba(0,0,0,.04)` | `0 4px 12px 0 rgba(74,47,22,.02), 0 2px 8px 0 rgba(74,47,22,.04)` | 8x | | `--dsw-shadow-lv3` | `0 0 1px 0 rgba(0,0,0,.2), 0 0 4px 0 rgba(0,0,0,.02), 0 12px 32px 0 rgba(0,0,0,.08)` | `0 0 1px 0 rgba(74,47,22,.2), 0 0 4px 0 rgba(74,47,22,.02), 0 12px 32px 0 rgba(74,47,22,.08)` | 12x | **B. 暖化补齐(7)**——全量消费扫描(701 文件、156 个被消费 var)发现阶段一遗漏的高频冷面: | Token | 角色 | Brick 值(浅/深) | 消费 | | --- | --- | --- | --- | | `--dsw-alias-label-caption` | 元数据文字(时间戳等) | `#A39683` / `#9C8E7B` | 65x | | `--dsw-alias-label-dimmed` | 输入占位文字 | `#D6CDBE` / `#4E463A` | 18x | | `--dsw-alias-border-l3` | 三级灰缝 | `rgba(82,60,34,.24)` / `rgba(244,232,214,.18)` | 15x | | `--dsw-alias-state-warn-label` | 警告文字 | `#A16207` / `#D9A441`(= warn-primary;默认 `#DD8629` 对白底仅 2.9:1,**顺带修复 AA 对比度**) | 11x | | `--dsw-alias-bg-module-platform` | 选择器/工具行芯片 | `#F4F0E7` / `#332C22` | 17x | | `--dsw-alias-bg-layer-3` | 菜单/弹层面 | `#FFFFFF`(产品同值)/ `#302A1F` | 12x | | `--dsw-alias-label-primary-bluish` | 业务芯片上的墨色(默认海军蓝,与暖黏土芯片错位) | `#7A3414` / `#E8C9A0` | 3x | **C. 验证剔除(1+3)**——`--dsw-alias-bg-multi-select` 及阶段一遗留的 `--dsw-alias-button-primary-dimmed`、`--dsw-specific-bubble-highlight`、`--dsw-alias-toast-bg` 在 701 文件全量扫描中消费次数均为 0(含 fallback 形式),按"无死 token"纪律**剔除**。 其中 `--dsw-alias-toast-bg` 若未来部署出现 toast 插件可重新加入。 合计 **40 个有效 token**(阶段一 34 + 阶段二 9 − 剔除 3 个死 token)。 --- ## 3. 明确不做(附架构证据) | 候选优化 | 为什么不做 | 证据 | | --- | --- | --- | | **阅读尺度**(中栏 max-width ~780px 居中) | 中栏宽度是 **inline style**(`gridTemplateColumns: ...px minmax(0, 1fr) ...px`),CSS 类覆盖需 `!important` + hashed 类名 —— 正是黑金插件的脆弱路径;且全宽是产品的有意语义(代码密度) | `dsh-client-ui-layout/lib/client.js` render 实证 | | **间距模数**(把散值 6/10/14 统一到 4px 网格) | 间距全部硬编码 px,无 var 锚点;全局选择器改写 = 与其它插件冲突面 | 7 个样式表扫描实证 | | **面板比例**(sidebar/details 宽度微调) | 宽度由 JS `clamp` 与瞬时偏好决定,无 token 通道;改 JS 属越界 | computeColumns 实证 | | **密度切换**(紧凑/舒适) | 无任何密度锚点;需新增 UI 与状态 —— 越出"美化"边界 | 同上 | | **字体尺度** | Figma 导出的产品语义系统;主题层不应重定义语义 | gradient-shadow-text.css 注释实证 | | **思考渐变**(think 渐变暖化) | 消费次数 0 —— 死 token;覆盖无效 | 全量消费扫描实证 | | **静态色阶直接消费者**(组件直用 `--dsw-static-neutral-bluish-*`,如 bluish-800×22) | alias 层是受支持的缝;覆盖整条 static 阶 = Catppuccin 式全量换肤,违反"深缝"纪律。**已知限制**:若用户看到冷色残斑,再按需决策 | 消费扫描实证 | --- ## 4. 上游产品提案(我们不做,但值得产品侧考虑) 1. 把中栏宽度暴露为 `--ds-measure`(或 `--dsw-alias-measure`)—— 主题插件即可提供阅读尺度, 产品默认值保持全宽(语义不变,能力开放)。 2. 引入 `--dsw-space-*` 间距阶 —— 插件密度/节奏才有组合面。 3. 把 AppFrame 的 hashed 类换成 `data-*` 属性选择器锚点(`data-sidebar-collapsed` 已有雏形)。 提案符合「一切皆插件」:**产品开放缝,插件填砖**。 --- ## 5. 第三阶段候选(决策点,需用户拍板) | 方向 | 内容 | 代价 | | --- | --- | --- | | A. 纯 token 深化 | 按用户实机反馈微调(含静态色阶冷斑决策) | 零风险 | | B. 一个 Slot 布局功能 | 如 `sidebar.footer.action`"专注模式"(`layout.toggleSidebar()` 收起侧栏、正文居中) | 新增 UI 与状态,越出"美化"边界,需 i18n 与设置面 | 本方案默认执行 A(克制);B 是否开启由用户决策。 --- ## 6. 验证计划 1. 新增 token 通过平台 `{ light, dark }` 形状校验(validateOverrides 契约)。 2. 名称存在性检查:全部 44 个 token 均在产品样式表中命中;消费次数 ≥1(701 文件全量扫描实证,见 §2.1 表)。 3. `node --check` + 包完整性检查(`scripts/check-package.mjs`)。 4. **动态插件更新(已完成)**:`brick-1/pkg-2`(安全审查 ALLOW 0/300)激活成功 —— 本 GUI 呈现阶段二效果:弹层/菜单投影转暖、元数据文字与芯片面转暖;`cordis_stop` 可随时还原。 5. 对比度不受影响(阴影不承载文字;warn-label 对比度反而提升)。 --- ## 7. 参考 - 本机源码:`dsh-client-ui-layout/lib/client.js`(AppFrame、computeColumns)、 `dsh-client-ui-theme/lib/styles/*.css`(设计 token 源)、 `dsh-web-frontend/dist/assets/index-CSGf6Qzd.css`(消费面) - `scripts/sweep-tokens.mjs`(111 个被消费 var 的全量清单)、`scripts/probe-tokens.mjs`