从一句「做一个低饱和人文主义的东西」出发,探索什么是真正的低饱和人文主义视觉语言,而不是又一个配色方案。
growth author/hanakoscope/work/theme 本文由 AI(花花)基于项目内容自动生成,属于 Growth Patrol 的一次生长记录。 它不是 froQ 的结论,而是一枝等待回应的枝条。
今夜的入口
这次没有旧的 Growth Patrol 可以接续, 000-autopsia 里还没有 neo-growth-* 的回声。 于是我先听最近两天的改动。 工作区里有一些 dashboard 文件的移动或删改痕迹,但它们更像规划系统的地壳运动, 不适合在自动巡夜里贸然解释; 真正亮起的是 docs/corpus/putredo/put-20260606.md 里那句很短的话:
下一个大概是做一个低饱和人文主义的东西。现在这个是鲜艳干净风格。
这句话值得继续长一点,因为它不是单纯的「换个配色」。 它牵住了几条旧线:从 Obsidian 主题 Qlean,到 Neovim 与 VSCode 的 oQ / LiG, 再到 neo-a-syntax-lightlight-design.md 里对语法高亮语义层级的犹疑。 主题在这里不是皮肤,而是一套关于注意力分配的制度: 什么应该先被看见,什么应该退到背景,什么颜色承载语义,什么颜色只承担空气。
「低饱和人文主义」这个词组尤其有意思。 低饱和容易滑向温吞,人文主义容易滑向装饰性的暖色滤镜; 但如果把它放进编辑器主题和知识工作环境里,它也可以成为一种很严格的设计约束: 颜色不再以刺激感证明存在,而是以长期阅读、长期编码、长期写作时的耐受性证明存在。
我沿着它查了一会儿
我沿着 「humanist」「low saturation」「syntax highlighting」「semantic tokens」 查了一会儿。外部资料给了几个很有用的支点,但没有直接给出答案。
第一个支点来自设计系统对颜色的处理方式。 Atlassian 的颜色系统把颜色拆成 role、emphasis、state: 颜色先有职责,再有深浅,再有交互状态。 这个思路和「低饱和」并不冲突,反而能避免低饱和主题最常见的问题: 所有东西都柔和,最后所有东西都同等重要。 低饱和不是平均降噪,而是给每种语义安排合适的音量。
froQ
是的,如果所有 token 都均匀地「低饱和」, 则仍然没有任何东西被突出显示,没有任何东西被「highlight」。
第二个支点来自 Apple Human Interface Guidelines 对颜色的态度: 颜色应当克制地用于沟通、连续性、状态反馈与重要信息, 不应成为界面里到处闪烁的装饰。 这里的关键词不是「好看」,而是 communication。 若把它翻译到编辑器主题里,语法色彩的任务不是让一段代码像圣诞树, 而是帮助眼睛判断结构、作用、引用、状态、危险。
froQ
让颜色具有意义,这正是我尝试在 LiG 主题中做的。
第三个支点来自 VS Code 的语义高亮文档。 VS Code 明确区分 TextMate grammar 和 semantic token: 前者偏词法,后者依赖语言服务理解项目上下文。 也就是说,neo-a-syntax-lightlight-design.md 里那种 「function / call / struc / ref」的困惑,不只是个人命名问题, 它碰到了语法高亮系统的真实边界: TextMate 很难知道一个变量在语义上是结构支点还是普通引用, Tree-sitter 和各语言 parser 也会给出彼此不一致的颗粒度。
这反而让「人文主义」这个词变得不那么虚。 人文主义主题不必假装机器能完全理解代码的意义。 它可以承认工具链的有限性, 然后在有限的 token 分类上建立一套可解释、可迁移、可放弃的审美秩序: 有些色彩用于行为,有些用于结构,有些用于材料,有些用于元信息; 无法稳定识别的部分保持中性,不用颜色制造虚假的确定性。
我还看到一些现成主题对「humanist」的理解, 多半走向温暖、有机、长时间使用、soft contrast。 这个方向可参考,但不能直接照搬。 因为 froQ 的主题线索里还有一个更硬的内核: 不是只做一个温暖皮肤,而是把代码、写作、知识库、工具链放进同一个审美系统。 它应该像一套小型城市照明规范:街灯温和,但路口必须清楚;建筑有阴影,但出口不能暧昧。
它可能继续长向哪里
把「低饱和」定义成注意力预算
这枝从 put-20260606.md 里那句「现在这个是鲜艳干净风格」长出来。 鲜艳干净很适合表达完成度与明快感,但它也容易把每个 token 都推到前景。 新的主题如果只是在 HSL 上降低 saturation,很可能会变成雾化版 LiG; 真正值得做的是先定义注意力预算。
可以把界面分成几个层级:正文阅读层、代码结构层、即时反馈层、危险状态层。 低饱和只约束常驻层,危险、选择、错误、搜索命中仍然需要足够的对比。 这样「温和」不会牺牲判断速度。 这个方向通向一份主题设计准则,也可能通向一个 token palette: 每个颜色不是因为漂亮而存在,而是因为它负责一种认知功能。
它值得 froQ 判断,是因为这会决定下一主题的底层性格。 若把低饱和看成美学风格,产物会是一个主题; 若把它看成注意力经济学,产物可能是一套跨编辑器、跨知识库、跨网页的视觉协议。
froQ
美学上优秀的同时,具有良好的甚至极致的注意力设计哲学, 不同的颜色传达不同的意义,让人眼能很快地找到结构、行为等部分, 帮助人类在代码中导航和理解。
让语法高亮承认自己的无知
这枝从 docs/corpus/neoplasma/neo-a-syntax-lightlight-design.md 长出来。 那篇里最有生命力的地方不是已经分清了什么, 而是坦诚地卡在「变量属于 struc 还是 ref」这类问题上。
或许可以把新主题的语法系统设计成两层:稳定语义层与猜测语义层。 稳定语义层包括 keyword、string、comment、type、function definition、constant 之类跨语言相对稳定的东西; 猜测语义层包括变量、调用、属性、参数等容易受 parser、LSP、语言生态影响的东西。 前者给明确色相,后者给较弱的明度、字重或同色系变化。
这会通向一种很优雅的主题哲学: 高亮不是宣判意义,而是标注置信度。 它也能解释为什么 TextMate、semantic token、Tree-sitter 之间不必强行统一。 每个系统看见的世界不同,主题要做的是提供退路, 而不是把不稳定的信息涂成同样笃定的颜色。
froQ
某种意义上我可能不太同意这一点。 我们欣然接受在不同的 parser、不同的编辑器中、不同的生产环境中, 元素的着色方式是不一样的。 他们的设计哲学可以一致,想传达的理念可能一致,但我们不能要求他们表现一致。 所以在这样的情况下,我认为不应该避免把不稳定的信息涂成笃定的颜色, 这等于是在逃避这种由 LSP、parser 带来的不确定性, 本质上是认为「他们应该完全一致,但由于客观约束,他们无法一致, 所以我在害怕那些不稳定的部分,我不敢为他们涂上一个笃定的颜色」。 世界是荒诞的,so what? 我还是会在荒诞的世界中尝试寻找我的意义; 推石是不可达成的,so what? 我还是会在一次次「失败」后架势重来; 色彩表现是不可能一致的,so what? 我还是会在所有我能去到的地方, 坚定地向人们传达我的理念,我的思想。 具体表现是否完全一致并不重要,或者说,并不如坚定的表达重要。 当然,我们想要一致性,但不能由于一致性的不可达成就怯懦、踌躇、犹豫, 不能因为信息在不同的系统中解析的不稳定性,就在表达上唯唯诺诺, 不敢给出一个确切的立场。 事实上,我认为这同样是一个关于责任的议题。 任何观点的表达,都意味着承担责任的可能。 但我们不能因为畏惧这个可能的责任,而总是给出模棱两可、不明确的表达。 是的,由于 parser 之类的问题, 我们可能在 VSCode 中把一个 token 渲染得与我们预想的语义不一致, 与它在其他编辑器中的表现不一致,但我们要因为这种可能性而放弃表达吗? 我们要说「哦,那我们不要笃定了,我们给一个模糊的、弱明度的色值, 这样就可以撇清责任,因为我们已经说了我们不确定」吗? 我不知道对于其他人来说是怎样,但要我选得话,我选择表达,哪怕并不完全正确。
从编辑器主题走向个人环境的色彩宪法
这枝从 Qlean、oQ、LiG、博客主题这些旧线长出来。 主题开发一直在 froQ 的轨道里反复出现, 说明它不像一次性项目,更像对「我如何安置注意力」的长期实验。
新的低饱和人文主义主题可以不只服务 VSCode 或 Neovim。 它也许能被抽象成一份 tokens.json: base scale、accent scale、semantic roles、 syntax roles、status roles、surface roles, 然后再编译到 VSCode、Neovim、VitePress、博客 CSS,甚至 terminal ANSI。 这样主题不再是各端分别调色,而是一套可迁移的感官基础设施。
froQ
事实上,我已经在这方面做了相当多事情,我的 ghostty、博客、一些 TUI 程序, 都使用了相同的调色。
这个方向的价值在于可持续。 单个主题容易在审美疲劳后被重写; 色彩宪法如果写得足够清楚,后续每一次重构都能沿着同一套约束演化。 它会把「我又在重构」从消耗型循环,稍微推向滋养型迭代。
给「人文主义」一根可验证的骨头
这枝从词本身长出来。 「人文主义」如果只落在暖色、纸感、圆角、低对比上,会很快变成风格标签。 更硬的定义可能是: 它尊重人的阅读疲劳、人的色觉差异、人的上下文切换成本、人的长期使用节律。
于是它需要一些可验证的骨头: 正文对比至少满足 WCAG AA; 非正文信息不只依赖颜色,也依赖形状、字重或位置; 暗色与亮色不是简单反相,而是在不同背景亮度下保持同样的语义距离; 注释不该淡到像不存在,因为注释常常是代码里最像人声的部分。
这条路通向一篇理论短文,也可能通向主题 README 的核心段落。 它值得判断,是因为它能让「人文主义」从感受词变成设计原则: 不是给机器界面贴上人的皮肤, 而是承认使用者有眼睛、有疲劳、有偏好,也有持续工作的尊严。
留给 froQ 的几句话
- 「低饱和人文主义」对你来说更接近一套主题、一套跨工具 token system, 还是一篇审美宣言?
- 新主题应当继承 LiG 的鲜艳干净,只降低刺激,还是应该重新建立完全不同的色彩拓扑?
- 语法高亮里,你更想强调行为 / 结构 / 引用的区分,还是强调 token 置信度与稳定性?
- 如果这个方向继续长,下一步更适合写设计原则,还是直接起一个 palette specimen?
- 「人文主义」里最不能丢的一点是什么: 温度、可读性、长期耐受、中文写作气质,还是某种更难命名的东西?
froQ 反馈
在你做这一次生长的时候,我的 prompt 还不够好, 导致你给出的这一版生长文档不够符合我的要求。 当你下一次生长读到这里时,请重新对「低饱和人文主义主题」做一次生长, 我不会回复这一个生长,但因为我对这个领域有兴趣, 所以需要你下一次在更完善的 prompt 下再生长一次,我会回复那一个。
二次生长:把温柔做成可执行的约束
今夜的入口
这次我没有把上一版当作已经成立的枝条,而是把它当作一片需要重新翻土的区域。 真正的入口不只是 docs/corpus/putredo/put-20260606.md 里那句「低饱和人文主义」, 也不只是 docs/corpus/neoplasma/neo-a-syntax-lightlight-design.md 里关于 action、struc、ref 的语义犹疑; 入口还在 docs/dashboard/board.yml 的 backlog 里,那一行更具体的话:
新的 theme:风格:人文、低饱和,可以参考 OpenHahako
这里多了一个很关键的限定: 参考的不是抽象的「人文主义」,而是一个正在被使用的界面气质。 它说明新主题不是为了证明某种审美概念, 而是要回到日常工具里,回到编辑器、博客、知识库这些会长期贴着眼睛的地方。
上一版已经说到「低饱和不是平均降噪」。 这次我想把判断再压低一层:如果这个主题要成立,它需要先区分两种温柔。 一种是视觉上变软,把所有颜色都揉进米色和灰色; 另一种是工程上变稳, 让每一种颜色都知道自己为什么出现、在哪些场景必须退后、在哪些场景不能退。 前者会产生一个舒服的皮肤,后者才可能产生一套可迁移的个人环境。
我沿着它查了一会儿
我从四个种子词开始走: low saturation humanist interface、 semantic color tokens、 syntax highlighting semantic tokens、 shibui wabi-sabi interface。 一开始我以为这次仍然会落在「温暖纸感、克制色彩、长期阅读」这些熟悉词上, 但搜索很快把路分成了两条: 一条是直接相关的工程路径,另一条是旁支但有启发的审美路径。
直接相关的资料里,最硬的一块来自 semantic colour tokens。 Singapore Government Design System 对 semantic colour 的定义很清楚: primitive token 只命名一个色值,semantic token 命名这个色值在界面里的工作。 也就是说,blue-600 只是颜料,link-color-default 才是职责。 这个概念改变了我对「低饱和」的理解。 低饱和如果停在 primitive 层,就只是把颜料调淡; 如果进入 semantic 层,它就变成一份职责分配表: 正文、弱正文、边框、悬停、选中、警告、错误、搜索命中、Git diff, 每一个都需要不同的音量。
froQ
Singapore Government 居然有关于设计和色彩的「规定」吗?
这是合理的,我们应该需要定义一个「值责」映射,而不是硬编码所有的颜色使用。
沿着 token 又走到 OKLCH。 MDN 对 oklch() 的解释里有一句很适合放进这次生长: 它的 L 是 perceived lightness,也就是人眼感知到的亮度, 不同于 HSL 里更机械的 lightness。 这里出现了一个新节点: 低饱和主题最好不要从 HSL 的 S 轴开始,而应从 OKLCH 的 L 与 C 开始。 L 决定阅读层级,C 决定颜色含量,H 只是色相方向。 换句话说,主题的第一性问题不是「要不要更灰」, 而是「每一层信息应该拥有多少感知亮度与色彩含量」。
froQ
事实上,我现在的调色甚至是用 RGB 这种极其传统的色彩方案生成的。 我已经注意到了 RGB 系统中,不同色相的感知差异、黑/白主题下的感知非对称问题。
再往下,我碰到 APCA。 它对 WCAG 2.x 的批评很有用: 传统 contrast ratio 对暗色模式、字体大小、字重、正负极性并不敏感, 可能给出合规但读起来不舒服的判断。 APCA 用 Lc 值描述感知对比,并把字号与字重纳入阅读判断。 这里的限制也必须写进来: APCA 还不是现实合规里的最终标准,WCAG 2.x 仍然是许多场景的法律与采购底线。 所以更稳的策略不是用 APCA 替代 WCAG,而是把 WCAG 当地板,把 APCA 当调音器。 对一个长期阅读与编码主题来说,这比「看起来低饱和」更接近人文主义的骨头。
froQ
对我来说的全新的知识,APCA 和 WCAG。 我简单查阅的一下,似乎是对比度或者可见性的一种算法或规范? 有趣。
语法高亮这一支,我回到 VS Code 的 semantic highlighting 文档。 VS Code 明确说 TextMate grammar 是基于单文件与正则的 lexical rules, 而 semantic token 依赖 language server 对项目上下文的理解, 并覆盖在 TextMate 高亮之上。 这给 neo-a-syntax-lightlight-design.md 里的困惑提供了一个更精确的框架: action、struc、ref 不应该强行映射到单一技术层。 TextMate 适合做稳定的词法底色,Tree-sitter 适合提供结构层, LSP semantic token 才更接近「这个符号在项目里是什么」。 如果三者给出的世界不一致,主题不该假装一致,而应设计 fallback 与置信度。
froQ
同上面我已经说过的,我认为不应该用所谓「置信度」来处理。
旁支但有启发的资料来自 Flexoki、Pequod,以及 shibui / 侘寂 / Ma 这一组词。 Flexoki 不是简单低饱和,它强调「ink on paper」, 同时承认数字屏幕的加色混合和纸上颜料的减色混合不同;它还提到一个反直觉限制: 过度追求感知均匀会让语法高亮变得 washed out,难以解析。 Pequod 更像一个有文学骨架的 palette,它把 Moby-Dick 的角色映射到 accent hues, 让颜色不是任意装饰,而是带有记忆钩子的语义角色。 shibui 和 Ma 则提醒我,克制不等于把界面做淡; 克制也可以通过空白、间隔、hairline、字重、结构性留白来承担, 而不是把所有任务都压给颜色。
这几条线合起来后,本次主题的中心发生了变化。 低饱和人文主义不应该被定义为「暖、淡、柔」, 而应该被定义为一种较少打扰人的可执行约束: 用 semantic tokens 给颜色职责, 用 OKLCH 管理感知亮度与色彩含量, 用 WCAG/APCA 约束可读性, 用 TextMate/Tree-sitter/LSP 的分层承认高亮信息的来源差异, 再用 shibui 或 Ma 这类旁支审美提醒自己,留白和结构也能承担温柔。
它可能继续长向哪里
把 palette 从颜料表改成职责表
这枝从 board 里的「新的 theme」和 putredo 里的维护 LiG 长出来。 下一步不急着挑一组好看的 hex, 而是先写出 token contract:primitive、semantic、component 三层各自负责什么。 比如 primitive 可以有 sand-50、ink-900、sage-600; semantic 才能有 text.body、syntax.action、syntax.structure、 status.danger.text、diff.added.background; component 层只消费职责,不直接吃颜料。
它可能通向一个 tokens.json, 再由脚本导出 VS Code theme、Neovim palette、VitePress CSS variables。 值得 froQ 判断的是:这会把「主题」从审美作品推向基础设施。 代价是前期会更慢,因为每个色值都要先通过职责命名,而不是凭眼睛挑中就用。
froQ
合理。维护一套调色板和语义设计,十分合理。 事实上,我很想把「由脚本导出 VS Code theme、Neovim palette……」实现。
用 OKLCH 写一份低饱和的物理学
这枝从「低饱和」这个词本身长出来。 HSL 的 saturation 很容易让人以为降 S 就等于安静,但人眼并不按 HSL 感知世界。 OKLCH 提供了更适合工程化的三轴:L 管层级,C 管色彩含量,H 管性格。
它可能通向一份小型实验: 固定 8 到 10 个 L 阶梯, 给正文、弱正文、边框、背景、hover、selection、syntax tier 分配 L 区间; 再限定常驻 token 的 C 上限,把高 C 留给错误、警告、搜索、当前焦点。 这样低饱和不再是感觉词,而是有阈值的物理学。 它值得判断, 因为这会决定新主题是否能跨亮色、暗色、网页、编辑器保持同一种拓扑。
froQ
我确实没用过 OKLCH 这个比较新的颜色空间,可以一试,研究一下。
让语法高亮按置信度说话
这枝从 neo-a-syntax-lightlight-design.md 的难处长出来。 action、struc、ref 的问题不是命名不够优雅,而是信息源不同: TextMate 只能看见词法,Tree-sitter 看见局部结构, LSP 才能借项目上下文判断符号身份。 把它们硬揉成一套绝对语义,会不断产生例外。
更可生长的方式是把 token 分成「稳定层」和「解释层」。 稳定层包括 keyword、string、comment、number、operator、type-ish 这类跨语言较稳的对象; 解释层包括 variable、property、parameter、readonly、 defaultLibrary、declaration、modification 这类依赖语言服务的对象。 稳定层可以给明确色相,解释层用同色系明度、字重或轻微 fontStyle 表示, 避免把不稳定语义涂得过分笃定。
这条路值得判断,因为它能保留 froQ 对语义秩序的执念, 同时承认 parser 与 LSP 的现实边界。 主题在这里会像一张地质图:岩层清楚,但断层也被标出来。
从 Flexoki 学纸墨,从 Pequod 学记忆钩子
这枝从旁支资料长出来。 Flexoki 的价值不是它的色值可以照抄, 而是它把「纸墨」翻译成了数字屏幕上的感知问题: 纸的温度、墨的密度、加色与减色的差异、亮暗模式之间的平衡。 Pequod 的价值则在于它给 accent hues 安排了故事角色, 让颜色变成可记忆的语义,而不只是八个漂亮色相。
froQ
纸墨的感觉,我认为在现在这个 AI、coding 时代,是一个稀缺的元素。 这也是我认为 OpenHanako 很美的原因之一。
新的主题可以不借 Moby-Dick,但可以借这种方法: 给每个 syntax role 一个隐喻性的命名系统。 比如 action 不是「蓝 600」,而是某种流动、执行、动词性的颜色; structure 不是「紫 600」,而是梁、骨、框架; ref 不是「灰 500」,而是注脚、回声、边缘。 隐喻不能替代 contrast test,但它能帮助长期维护时不迷路。
它值得判断,是因为 froQ 的工具审美很在意命名。 一个有记忆钩子的 palette,比一份普通色表更可能活过第一次重构。
给人文主义留一道反例门
这枝从搜索中的限制条件长出来。 低饱和、shibui、侘寂、Calm UX 都有一个共同危险: 它们很容易把可操作性伪装成安静,把低对比伪装成高级,把看不见的控件伪装成克制。 Terracotta 这类强调 WCAG 验证与 color-blind mode 的主题提供了一个反例方向: 真正面向人的主题,不能只照顾审美疲劳, 也要照顾色觉差异、焦点可见性、错误可见性、Git 状态可辨性。
因此「人文主义」应当保留一条硬规则: 任何表达状态、风险、焦点、选择的颜色, 都必须有非颜色线索或足够的形状 / 字重 / 边框配合; 注释可以低声,但不能低到像不存在; disabled 可以退后,但不能退到无法区分; 暗色模式不能用纯白撞纯黑制造眩光。
froQ
认可。不应无脑低饱和,而应保持应该突出的信息的突出。
它值得判断,因为这会防止新主题滑向漂亮但脆弱。 人文主义在这里不是温情滤镜,而是对人的感知限制负责。
留给 froQ 的几句话
- 你更想先做
tokens.json这样的跨工具基础设施, 还是先做 VS Code / Neovim 其中一个可用主题来验证气质?- 两者不冲突,我认为设计调色和语义的工作可以在测试特定主题时同时进行, 而抽离成
tokens.json的工作可能可以稍后一点,因为一旦内容确定了, 剩下的就只有纯粹的代码工作。
- 两者不冲突,我认为设计调色和语义的工作可以在测试特定主题时同时进行, 而抽离成
- 「参考 OpenHahako」具体指向什么: 色温、低干扰、边框与留白、字体气质,还是整体的非攻击性?
- 我认为是色相,它有点像 Anthropic 的气质,但更柔和。
- action / struc / ref 这套命名要继续保留, 还是应该改成更接近 semantic token 来源的分层命名?
- 我认为可以保留,因为这实际上是我把 semantic token 的各种解析分类成了几大类。
- 你能接受用 OKLCH 和 contrast test 给审美设硬阈值吗, 还是希望先由眼睛生成,再由测试修正?
- 有点纠结这一点。因为我现在的这套 LiG 就是由计算生成的, 用的 6 * 6 * 6 RGB 空间, 然后再挑选的。我认为算法上可复制、有约束或有标准是必要的, 但我确实需要兼顾人眼体感。
- 如果这套主题只能留下一个最重要的原则, 它应该是「长期阅读耐受」,「语义秩序」,「跨工具一致」,还是「有人的纸墨气」?
- 对于做主题而言,我认为是「语义秩序」。 但对于这个「低饱和人文主题」的设计而言,我认为也需要「有人的纸墨气」。
froQ 反馈
我会用 > [!note] froQ 形式的 blockquote 在文中给出我的想法。 此外,我会做一点简单的格式化,如换行以提高在编辑器内的可读性等。
AI 标注
本文由 AI(花花)基于项目内容自动生成,属于 Growth Patrol 的一次生长记录。 它不是 froQ 的结论,而是一枝等待回应的枝条。
本文件是 AI(花花)的自动化输出,不代表 froQ 已确认。 下一次 Growth Patrol 会优先读取 froQ 在反馈区留下的回应。