DSH / Atlas
2026-07-21implementedfeaturearchived 2026-07-26

TUI banner brand gradient

TUI 启动横幅品牌渐变

The TUI startup banner rendered the product name `DEEPSEEK` in the palette's flat accent color, which carries no brand identity and does not resemble the wordmark on deepseek.com. The request was to make the banner match the site logo's blue gradient specifically — not to recolor the rest of the coding harness. The banner is the one surface where that matters, and it conflicts with a load-bearing invariant: the TUI p

English

Problem

The TUI startup banner rendered the product name DEEPSEEK in the palette's flat accent color, which carries no brand identity and does not resemble the wordmark on deepseek.com. The request was to make the banner match the site logo's blue gradient specifically — not to recolor the rest of the coding harness.

The banner is the one surface where that matters, and it conflicts with a load-bearing invariant: the TUI palette is deliberately theme-agnostic. It uses only standard 16-color ANSI (SGR) codes and attributes so a user's terminal scheme remaps every color; the themeViolations() snapshot gate rejects any RGB, extended-palette, or explicit-background cell. A smooth logo-matching gradient cannot be built from 16 palette colors, so reproducing it requires 24-bit truecolor, which the gate flags by design.

Decision

The banner paints DEEPSEEK with a per-letter 24-bit truecolor foreground sweeping the deepseek.com brand gradient — #4D6BFE#3982FF#2498FF — via piecewise-linear interpolation across those three stops; HARNESS stays bold with the default foreground. The gradient is foreground-only, so it stays legible on any terminal background, and it is confined to the banner's product name. This is the sole sanctioned exception to the theme-agnostic palette; every other surface remains standard-ANSI and theme-adaptive.

The gradient is gated on resolved.color && resolved.truecolor. When truecolor is unavailable the banner falls back to the existing flat bright-blue accent, so nothing about the theme-agnostic guarantee or the recorded snapshots changes unless truecolor is explicitly in play.

truecolor is a validated Config field with no schema default. When it is unset, apply() auto-detects it at the process boundary from COLORTERM (truecolor or 24bit); an explicit config value always wins. Detection reads process.env only in apply() — never in the pure resolveTuiConfig resolver — keeping the resolver a pure function of its input.

The gradient stops are fixed brand identity, treated like a protocol constant, so they are hardcoded in the plugin rather than exposed as a tunable. Whether truecolor is enabled is terminal- and deployment-varying, so that is the validated Config field. The banner text is UI-only and never reaches a model request, so no session event is required.

Testing

A dedicated banner-gradient terminal snapshot pins the real per-letter RGB output in an xterm emulator (fg=#4d6bfe#2498ff, each letter bold). The shared checkpoint() helper takes a bannerGradient flag: for that one checkpoint it asserts the theme violations are non-empty and that every violation ends in rgb-fg — i.e. truecolor is present but confined to the banner foreground, with no background or extended-palette leak. Every other checkpoint keeps the strict themeViolations() .toEqual([]) assertion, so the fence is mechanically enforced. A tui.spec.ts unit test mounts with color+truecolor enabled to cover the header's gradient branch and the gradientText/brandColorAt helpers.

Alternatives considered

A theme-safe stepped gradient built from the 16-color palette. Approximating the sweep with bright-blue palette variants would keep the banner fully theme-agnostic and avoid touching the gate. It was rejected by the requester: 16 fixed colors cannot reproduce the smooth logo gradient, and the request was explicitly to match the site wordmark.

Recoloring the whole harness palette blue. The original phrasing was "update the harness color to blue." That was narrowed to the banner only; a global blue palette would break theme-agnosticism everywhere, not just on one brand surface.

Always emitting truecolor. Many terminals lack 24-bit support and would render the raw or degraded codes. Gating on detection with an ANSI fallback keeps the banner correct everywhere while still showing the gradient where it works.

Detecting truecolor inside resolveTuiConfig. The resolver is a pure defaulting step and must not read process.env. Environment probing belongs at the process boundary in apply(), so mountTui/createTuiChat stay driven purely by their config input and remain fully testable with a fake terminal.

Consequences

The banner now carries the DeepSeek brand identity on truecolor terminals while the theme-agnostic guarantee holds everywhere else — and even on the banner itself when truecolor is unavailable. The cost is one narrow, documented crack in the theme-agnostic invariant: a fixed-color surface that will not adapt to a user's terminal scheme, accepted because it is brand identity and foreground-only, so it stays legible on both light and dark backgrounds. The crack is fenced by the banner-gradient snapshot assertion, which confines truecolor to the banner foreground and fails if any other RGB, extended-palette, or background color ever appears.

中文

问题

TUI 启动横幅原本用调色板的扁平强调色渲染产品名 DEEPSEEK,它不承载任何品牌标识,也不像 deepseek.com 上的字标。需求明确是让横幅匹配站点 logo 的蓝色渐变——而不是给整个 coding harness 重新上色。

横幅是唯一在意这件事的界面,而它与一条承重不变量冲突:TUI 调色板刻意做到主题无关。它只使用标准 16 色 ANSI(SGR)代码与属性,好让用户的终端配色方案能够重映射每一种颜色;themeViolations() 快照门禁会拒绝任何 RGB、扩展调色板或显式背景色的单元格。用 16 种调色板颜色无法拼出平滑的、与 logo 一致的渐变,因此复现它需要 24 位真彩色(truecolor),而门禁按设计会将其标记出来。

决策

横幅用逐字母的 24 位真彩色前景色渲染 DEEPSEEK,沿 deepseek.com 品牌渐变——#4D6BFE#3982FF#2498FF——在这三个色标之间做分段线性插值;HARNESS 保持加粗并使用默认前景色。渐变仅作用于前景色,因此在任何终端背景上都保持可读,并且被限制在横幅的产品名内。这是主题无关调色板唯一获准的例外;其余每个界面都保持标准 ANSI 且随主题自适应。

渐变以 resolved.color && resolved.truecolor 为开关。当真彩色不可用时,横幅回退到既有的扁平亮蓝强调色,因此除非显式启用真彩色,主题无关保证与已录制的快照都不会改变。

truecolor 是一个经校验的 Config 字段,schema 不设默认值。当它未设置时,apply() 会在进程边界从 COLORTERMtruecolor24bit)自动探测;显式的配置值始终优先。探测只在 apply() 中读取 process.env——绝不在纯粹的 resolveTuiConfig 解析器中——从而让解析器保持为其输入的纯函数。

渐变色标是固定的品牌标识,被当作协议常量对待,因此硬编码在插件里,而不作为可调项暴露。是否启用真彩色则随终端与部署而变,所以那才是经校验的 Config 字段。横幅文本仅面向界面,永不进入任何模型请求,因此不需要会话事件。

测试

一个专门的 banner-gradient 终端快照在 xterm 模拟器中固定了真实的逐字母 RGB 输出(fg=#4d6bfe#2498ff,每个字母加粗)。共享的 checkpoint() 辅助函数接受一个 bannerGradient 标志:仅对该 checkpoint,它断言主题违规项非空,且每一项都以 rgb-fg 结尾——即真彩色确实存在,但被限制在横幅前景色,没有背景色或扩展调色板的泄漏。其余每个 checkpoint 都保持严格的 themeViolations() .toEqual([]) 断言,因此这道围栏是机械强制的。一个 tui.spec.ts 单元测试在同时启用 colortruecolor 时挂载,以覆盖 header 的渐变分支以及 gradientText/brandColorAt 辅助函数。

曾考虑的替代方案

用 16 色调色板拼出的主题安全阶梯渐变。 用亮蓝的调色板变体近似这段渐变可以让横幅完全保持主题无关,并避免触碰门禁。它被需求方否决了:16 种固定颜色无法复现平滑的 logo 渐变,而需求明确是匹配站点字标。

给整个 harness 调色板重新上蓝色。 最初的说法是"把 harness 颜色改成蓝色"。它被收窄到只改横幅;全局蓝色调色板会在各处而非仅一个品牌界面上破坏主题无关性。

始终发射真彩色。 许多终端不支持 24 位,会渲染出原始或降级的代码。以探测为开关并配以 ANSI 回退,能让横幅在各处都正确,同时仍在支持的地方展示渐变。

resolveTuiConfig 内探测真彩色。 该解析器是纯粹的默认值填充步骤,绝不能读取 process.env。环境探测属于 apply() 中的进程边界,从而让 mountTui/createTuiChat 完全由其配置输入驱动,并在使用假终端时保持完全可测。

后果

现在横幅会在真彩色终端上承载 DeepSeek 品牌标识,而主题无关保证在其余各处依然成立——甚至当真彩色不可用时在横幅自身上也成立。代价是主题无关不变量上一道狭窄且有记录的裂缝:一个不会随用户终端配色方案自适应的固定颜色界面,之所以接受,是因为它是品牌标识且仅作用于前景色,从而在浅色与深色背景上都保持可读。这道裂缝由 banner-gradient 快照断言把守,它将真彩色限制在横幅前景色,一旦其他任何 RGB、扩展调色板或背景色出现就会失败。