# 设置项与功能 设置项的行为、默认值、字段名与边界情况。设计取值见 [design-language.md](design-language.md),实现细节见 [engineering-notes.md](engineering-notes.md)。 设置入口:**设置 › 终末地主题设置**。全部文案跟随 DSH 的语言设置(中/英)即时切换,无需刷新。 ## 持久化方式(不再用 localStorage) 历史内存风格:这些开关最初存浏览器 `localStorage`。由于浏览器存储按「协议 + 主机 + 端口」的 origin 隔离,而 DSH Desktop 每次启动都在 127.0.0.1 绑定一个**随机临时端口**,端口一变 origin 就变,上次保存的设置永远读不到,表现为「重启后恢复默认」。已改用 DSH 官方的用户设置命名空间: - **浏览器端(client.js)** 通过 `ctx.settingsScope` 服务绑定命名空间 `dsh-theme-endfield`,读取/写入并订阅变化; - **Host 端(index.js)** 通过 `ctx.settings.register('dsh-theme-endfield', schema)` 声明参数 schema,由 `@deepseek-ai/dsh-settings-file` 落到 `/settings.yaml`(DSH Desktop 的 profile 下同样适用)。 落盘位置由 DSH 决定(`$DSH_HOME` 或 `~/.dsh/...`),与浏览器 origin/端口无关,因此在 **dsh web(浏览器、固定/默认端口)** 和 **DSH Desktop(随机临时端口)** 两种运行方式下设置都能正确持久化——它们跑的都是 127.0.0.1 loopback 页面,DSH 会把连接解析为 `host` 持久化模式。 下表「字段」(缩写)就是命名空间里的存储字段,语义等价于旧 localStorage 键名的尾部。 ## 总览 | 组 | 开关 | 默认 | 命名空间字段 | | --- | --- | --- | --- | | 01 主题 | 终末地主题 | 开 | `enabled`(旧键 `dsh-theme-endfield-enabled`)| | | 主题配色 | 谷地黄 | `palette` | | | 主题圆角 | 直角 | `radius` | | 02 背景 | 等高线背景 | 关 | `contour` | | | 动态等高线 | 开 | `contourAnim` | | | 动态帧率 | 24 FPS | `contourFps` | | | 动态速度 | 标准 | `contourSpeed` | | | 背景水印 | 开 | `watermark` | | | 水印保持显示 | 关 | `watermarkPersist` | | 03 动画 | 启动加载动画 | 关 | `loader` | | 04 娱乐 | 雷霆大字 | 关 | `thunder` | | | 大字入场动画 | 关 | `thunderAnim` | 取值约定(与 localStorage 时代的极性完全一致,现在由 schema 默认值保证):**默认开启**的开关在该 schema 里默认存 `'1'`,客户端读作 `!== '0'`;**默认关闭**的存 `'0'`,读作 `=== '1'`。回滚/清除字段时客户端回到 schema 默认值;异常存储值被 schema 校验拒绝,不会悄悄改变出厂观感。 --- ## 01 主题 ### 终末地主题(总开关) 关闭后移除令牌层与样式表,界面回到应用原生外观,无需刷新。它同时是**所有其他功能的总闸**:关闭会一并拆掉水印、等高线、大字与订阅。 **关闭后设置页仍保持可读。** 这一点需要专门处理:开关按钮的强调色底来自主题自己的样式表,样式表随主题关闭而移除,所以关闭时按钮回退到应用原生令牌(选中态实心底、常态透明描边),而不是留下「黑字落在深色面板上」的不可读状态。 ### 主题配色 在**谷地黄**(默认,`#fff500`)与**武陵青**(`#14d0d0`)之间切换。设置行带一个色块预览,而不只是写颜色名。 切换只是 `` 上加减一个 class,不重新注册令牌层、无 JS 重绘。唯一的例外是等高线画布(canvas 描边不能是 CSS 变量),由 `MutationObserver` 监听 class 变化触发重绘——顺带让「别的标签页改了配色」也能跟着变。 ### 主题圆角 直角(默认)/ 圆角。同样是一个 class:`body.theme-endfield-round` 让整组 `border-radius: 0` 规则失效,恢复应用原生圆角。 --- ## 02 背景 ### 等高线背景(默认关闭) 参考等高线地形图:整屏铺满强调色细线,闭合环线相互嵌套成大小不一的「岛屿」。 线不是贴图也不是手绘路径,而是**标量场的真等值线**——因为动画的连贯性来自场本身:场变形后重新提取,环线会像真实地形一样合并、分裂,平移一张贴图做不到这件事。 - **场** = 若干正负相间的高斯凸起之和(既有山峰也有洼地)+ 三道极缓的长波正弦 - **线** = marching squares 在 21 个等间距高度上取等值线 - **连线** = 线段按边 ID 缝合成连续折线,再以二次曲线绘制 算法细节与实测数据见 [engineering-notes.md § 等高线](engineering-notes.md#等高线背景). **图层挂在应用外框内部**,`inset:0; z-index:0`,落在「外框底色之上、所有定位子元素之下」。正文永远在图层之上,前景对比度不受影响。挂载期间会把外框、对话列、详情列与侧栏的不透明底色置为透明(`:has()` 守卫使功能关闭时全部规则失效)。 **关闭时零逐帧开销**——不是在 rAF 里空转再提前返回,而是整个循环停掉。 ### 动态等高线(默认开启,需先开启等高线背景) 等高线流动变形。动态帧率提供 `24 FPS`、`60 FPS`、`120 FPS` 三档,默认 `24 FPS`;动态速度提供 `1x`、`2x`、`4x` 三档,分别对应慢速、标准、快速,默认 `2x`。帧率写入 `dsh-theme-endfield-contour-fps`,速度写入 `dsh-theme-endfield-contour-speed`,非法值自动回退到默认值。关闭则为静态图案,不做任何逐帧计算。 **尊重系统「减少动态效果」**:`prefers-reduced-motion` 下图案照常渲染(静态纹理不算动效),但场变形不启动——即使开关是开的。此时设置行会说明是系统偏好在生效,而不是让开关看起来失灵。 ### 背景水印(默认开启) `ENDFIELD` 大字水印,默认只在**新建会话页**(hero)显示,居中跟随标题。 - `pointer-events: none`,不拦截点击与文本选择; - 强度按配色分别声明为 CSS 变量 `--edge-wm-alpha`(亮 `0.13` / 暗 `0.085`),配色切换时自动重解析; - 深色模式取更低的 alpha:在近黑底上**叠加**亮度,比在纸底上**减去**亮度显得响得多。 **防浏览器误翻译**:字形由 CSS `content`(`::before`)绘制,元素本身没有任何 DOM 文本节点,逐文本节点遍历的翻译器看不到它;另加 `translate="no"`、`class="notranslate"`、`lang="en"`、`aria-hidden="true"`。 ### 水印保持显示(默认关闭,需先开启背景水印) 开启后,对话页等非新建会话页面也显示水印。 此时水印挂载在**会话列内部**,以 `z-index: -1` 位于正文**之下**(该列在水印挂载期间获得 `isolation: isolate` 与 `position: relative`,卸载后自动还原)。之所以不挂 ``:一个 fixed 的 body 子节点会画在消息文字**之上**,把用户正在读的内容洗白。 --- ## 03 动画 ### 启动加载动画(默认关闭) 参考终末地官方主视觉:整屏黑底,左边缘 10px 强调色进度轨自上而下填充。**刻度 + 百分比 + 状态行跟随进度轨的填充端一起下移**,并做了下边界钳制,接近 100% 时不会滑出屏幕。 播放时序(开启后每次刷新页面播放一次): | 阶段 | 时长 | 表现 | | --- | --- | --- | | 进度 | 约 1750ms(`easeOutCubic`) | 强调色进度轨自上而下填充,读数随之下移 | | 横向铺满 | 520ms | 到 100% 后进度轨从 10px 横向展开成整屏 | | 整屏淡出 | 620ms | 连同整块遮罩淡至透明,节点随即从 DOM 移除 | 设置行提供「预览」按钮,可不刷新页面直接重播一次。 **海报式排版**:品牌块**内部左对齐**(各行共用同一条左侧节奏线)但整体**摆在画面右侧**——这个组合才是参考图的观感。`END` / `FIELD` 上下两行紧排堆叠,不含中文字标。字标尺寸 `clamp(26px, min(5.2vh, 4.8vw), 64px)`,取较小轴,因此无论窗口「矮」还是「窄」品牌块都不会挤进左侧进度轨。已在 520×900 到 2560×1440 共 13 种视口逐一验证无溢出。 工程要点: - **进度由墙钟时间推导**(非逐帧累加),不会漂移; - **双时钟驱动**:`requestAnimationFrame` 负责平滑更新,`setInterval` 兜底——rAF 在后台标签页与无头渲染器中会在首帧后停摆,仅靠它会让全屏遮罩永久留在屏幕上; - **收尾动画也由 JS 驱动,不用 CSS transition**(原因见工程笔记); - **硬性保险丝**:一个独立 `setTimeout` 终点,即使所有时钟停摆也必定移除遮罩; - `prefers-reduced-motion` 下直接跳过铺满与淡出,立即移除遮罩; - `pointer-events: none`:动画进行中也不拦截点击; - 全部字形由 CSS `content` 绘制 + `translate="no"`,防浏览器翻译改写品牌名。 `z-index: 2147483000` —— 加载屏是唯一有资格独占整屏的表面。 --- ## 04 娱乐 ### 雷霆大字(默认关闭) 任务开始 / 结束时,在屏幕正中用白色粗体大字打出「任务开始」/「任务完成」,**3 秒后自动隐藏**,**期间点击屏幕任意处可立即关闭**。设置行提供「预览」按钮。 **状态信号取自唯一权威位**:`@deepseek-ai/dsh-client-runtime` 的 `ConversationSnapshot.running`——应用自己的回合状态标签与停止按钮切换的就是这个字段。不去监听转圈图标或类名:那些类名带构建哈希、并非契约,而且「出现了一个 spinner」和「一个回合开始了」并不是同一件事。 **只认边沿,不认电平。** 一个回合进行中,快照存储会以每秒几十次的频率推送;只有 `false → true` / `true → false` 的跳变才播报。每个会话**第一个可读到的值记为基线并保持静默**,因此「切进一个已经在跑的会话」不会误报「任务开始」——但该会话结束时仍会正常播报「任务完成」。 **点击关闭的监听挂在 `document` 的捕获阶段**,遮罩本身保持 `pointer-events: none`: - 一次按下**同时**完成两件事——关掉大字,并正常抵达用户真正瞄准的元素; - 用 `pointerdown` 而非 `click`:一个事件覆盖鼠标 / 触摸 / 触控笔,且按下即消失; - 用**捕获阶段**:菜单、下拉、拖拽手柄常在自己的处理器里调 `stopPropagation`,冒泡阶段听不到那些按下,大字就会关不掉; - 提前关闭会同时取消 3 秒定时器并摘掉监听器。 如果改成给遮罩加 `pointer-events: auto` 再挂 `onclick`,它会变成**一块持续 3 秒的全屏点击黑洞**:用户为了关掉它而点下去的那次点击会被吃掉。 层级 `z-index: 2147482000`,比加载遮罩低一档。整块 `aria-hidden`——纯装饰不该被读屏软件念出来。 **关闭即零开销**:关掉时不订阅、不留定时器、不建节点。 ### 大字入场动画(默认关闭,需先开启雷霆大字) | 状态 | 表现 | | --- | --- | | **关闭(默认)** | 大字**直接出现**在屏幕正中,保持 3 秒后消失,无缩放、无淡入淡出 | | 开启 | 大字由大缩小「砸」入(`scale(2.4) → 0.94 → 1`)并在末尾淡出 | 与「等高线背景 → 动态等高线」是同一种结构:**图层是一个决定,让它动是另一个决定**。 三个刻意的约束: - **子开关只改入场表现,不改时长。** 3 秒由 JS 定时器持有,不挂在动画结束事件上——否则开关动画会顺带改掉停留时间。 - **未开启动画时,主开关关闭时该行为 disabled。** 一个对当前状态无意义的控件应该看起来就是不可用的。 - **系统「减少动态效果」仍然压过这个开关。** 两个独立原因(开关关闭、系统偏好)汇合到同一条静态分支;此时设置行会说明是系统偏好在生效。 --- ## 其他自动生效的修正 不需要开关、随主题一起生效的可读性修正: | 位置 | 问题 | 结果 | | --- | --- | --- | | 设置 › 模型 行操作(`编辑`) | 白字压在强调底上,1.05:1 | 16.50:1 | | Cordis / 技能 / 工具 检查面板按钮 | 同上 | 16.50:1 | | 附件轮播箭头 | 同上 | 16.50:1 | | 亮色模式「移除」按钮 | `#ff3b30` 红字在面板底上 3.16:1 | 5.16:1 | | 回合状态标签「Deep diving…」 | 渐变文字仍是品牌蓝 | 两配色四个色标全部达 AA | | 提问卡片「推荐」徽标 | 前景与背景令牌被映射成同一值,完全不可见 | 16.50:1 | | 提问卡片选项编号 | 暗色选中行上黑底黑字,1.25:1 | 11.69:1 | | 新建会话页背景光晕 | 写死的 `#6187D8` | 改强调色,按亮度对齐原强度 | 这些的成因分析见 [engineering-notes.md § 已修问题归档](engineering-notes.md#已修问题归档)。