---
title: 深浅主题光效裂变与色相排序
description: 为什么 plus-lighter 加色发光在白底上会沦为脏灰色？深浅主题的两套色相顺序，以及 TxPrismGlow 怎样实现。
---

# 深浅主题光效裂变与色相排序

在暗色模式下极其炫丽的发光光束（如 AI 正在思考时的环境漫射光），直接搬到浅色模式下往往会沦为灾难性的脏灰污斑。

## 加色发光（Plus-Lighter）的单向性

在暗色背景下，光效叠加采用加色模式（Additive Blending，CSS `mix-blend-mode: plus-lighter`）：
$$\text{Color}_{\text{Result}} = \min(1, \text{Color}_A + \text{Color}_B)$$
两条光束重合处，亮度相加，不断逼近纯白高光（`(1, 1, 1)`），呈现夜空中交织光柱的通透视觉。

## 为什么光效在浅色模式会坍塌为脏灰？

浅色模式的底板已经是接近纯白的亮底：
- 加色模式在白底上完全失效，因为白色像素无法变得更亮。
- 如果将发光层做普通半透明融合，**两个在色相环上相距大于 120° 的补色（如明黄色与天蓝色）叠加，其平均颜色恰恰是暗浊的灰色**！
- 最终在浅色界面上呈现的不是灵动的光辉，而是一团团像被橡皮擦抹脏了的污渍。

## 浅色模式的相邻色相排序管道

为了在浅色模式下保持光效的鲜亮通透，TuffEx 给一起出发的光束定了**相邻色相准则**：
- 在浅色模式下，一起出发、会互相重叠的光束，色相差不超过 120°。
- 相距超过 120° 的两种色相（如蓝与黄、紫与黄）不安排在同一组出发。

:::TuffDemoWrapper{demo="ConceptLightBlendDemo"}
:::

## TxPrismGlow 的两套色相顺序

`TxPrismGlow` 的六束光在深浅两面用的是同一组色相，浅色面只是换了顺序。`cones.ts` 给每束光写了暗色面的 `hue` 和浅色面的 `lightHue`（oklch 角度），浅色面把 2 号的黄与 4 号的紫对调：

:::TuffCodeBlock{lang="typescript"}
---
code: |
  // prism-glow/src/cones.ts（只列色相）
  export const PRISM_GLOW_CONES = [
    { hue: 350, lightHue: 350 },
    { hue: 95, lightHue: 300 }, // 2 号：暗色面黄，浅色面紫
    { hue: 205, lightHue: 205 },
    { hue: 300, lightHue: 95 }, // 4 号：暗色面紫，浅色面黄
    { hue: 150, lightHue: 150 },
    { hue: 258, lightHue: 258 },
  ]
---
:::

哪些光束一起出发由相位决定：2 号与 6 号在开场的 0.4 × duration 里同行（默认 6 秒时是 2.4 秒，正好一次 CoreBox 搜索），3、4、5 号从右侧一起出发。暗色顺序里同行的 2 号与 6 号是黄与蓝，相差 163°；换成浅色顺序，2 号是紫，与 6 号的蓝只差 42°。暗色面的重叠用 `plus-lighter` 相加趋白，任何色相都能融合；浅色面用 `normal` 混合，重叠处是两种颜色的平均。跟随主色的 accent 调色板总共只跨 100°，不需要浅色顺序。

`prism-glow.test.ts` 的门禁按这条准则计算：开场这段时间里，浅色色相相差超过 120° 的任意两束光，中心始终相隔至少 30cqw，光晕碰不上。同一条测试也断言暗色顺序会撞上（蓝追上黄），作为阳性对照。开场之后各束光周期不同，仍会互相追上，门禁只管开场。
