视觉预设与外观切换
Paper、Slate 与外观菜单已随 OINK 1.2.0 发布。当前行为与证据由 架构契约、 已接受决策和 验收记录管理。 随后的 Ink/Terminal 实验提供真实可切换输出;本提案继续承载两者的设计定稿。10 月 4 日注入样式生成的截图仍是研究原型, 与 10 月 5 日真实主题输出截图分开看待。
状态与影响面
| 字段 | 值 |
|---|---|
| 状态 | 第一阶段随 1.2.0 发布;Ink/Terminal 显式启用 |
| 负责人 | OINK 维护者 |
| 日期 | 2026-10-04 |
| 基线 | 主题 main(v1.1.0 之后,含未发布的 1.2.0 工作);文档站固定 v1.1.0 |
| 受影响契约 | 架构:信任、CSS 与无障碍(字体角色、强调色角色、行内代码颜色)、外壳(主题控件)、Landing、配置决策、品牌指南 |
| 第一阶段 | Paper 预设、Slate 预设、默认改为 Paper、读者在 Paper 与 Slate 间切换 |
| 后续阶段 | Ink/Terminal 视觉定稿;Folio 与 Canvas 只保留名称 |
背景与依据
以下基线与限制记录 10 月 4 日实施前的研究输入。
OINK 目前只有一套视觉,本文称为 Slate:冷灰蓝画布(#f1f4f8 / #0b1119)、
海军蓝文字、钢蓝链接(#245f94)、铜色点缀;Inter 用于界面与正文,Chakra Petch
用于展示标题与字标,IBM Plex Mono 用于代码与技术标注;Landing 首屏有蓝图网格与
光晕;行内代码为一组深红色。它由 assets/scss/td/_brand.scss 的 Bootstrap 自定义
属性、assets/scss/td/shell/_tokens.scss 的外壳 token,以及
assets/scss/td/_tokens-typography.scss 的字体角色定义。
PG.CENTER 是独立站点,具有维护者希望成为 OINK 未来默认的暖色编辑式阅读风格。
其展示层 token 位于该项目的 media/css/pgsql.css。在本地预览上测量
(2026-10-04,浅色与深色;首页、Docs 索引、长篇手册页、组件手册页):
| 角色 | 浅色 | 深色 | 说明 |
|---|---|---|---|
| 画布 | #f7f6f3 |
#161513 |
暖白 / 暖黑 |
| 抬升表面 | #ffffff |
#1d1c19 |
卡片、代码块 |
| 次级表面 | #efede8 |
#262420 |
表头、悬停 |
| 墨色正文 | #21201c |
#ece9e3 |
|
| 次级文字 | #56534c |
#b6b1a7 |
|
| 线与淡底 | 墨色 4.5–22 % 透明度 | 浅墨色相近透明度 | 不使用带色相的灰 |
| 圆角 | 12 px / 8 px | 相同 | |
| 阴影 | 0 2px 10px rgba(33,32,28,.07) |
以黑色为基 | 暖、柔 |
| 动效 | 160 ms cubic-bezier(.2,.7,.2,1) |
相同 |
字体方面,IBM Plex Sans(可变字重 400–600)用于界面与正文;IBM Plex Mono 用于代码、 日期与版本;Chakra Petch 只用于字标。组件手册页是最好的长文样板:导语 17 px、 最宽 70ch;h2 后跟一条延伸到边缘的细线;带表头底色、无斑马纹的外框表格; 单色提示块加 3 px 竖线。
以下 PG.CENTER 元素属于站点身份,不是可复用的阅读规则:PostgreSQL 品牌蓝
#336791 系列、酒红正文链接、版本状态色、版本条、搜索类型徽标、Wiki 色调、
双色首屏,以及导入的 PostgreSQL 手册约 144 字符的行长。两个值不满足 WCAG AA
(弱化文字 3.67:1、链接悬停 4.22:1),下文予以修正而非照搬。
用于对照的 OINK 文档测量值:正文 16 px / 1.7、行长约 76ch、h1 36 px / 700、 h2 24 px / 600、代码 14 px。PG.CENTER Docs 索引:15.5 px / 1.7,约 120ch。
现有限制
- 颜色只与
data-bs-theme绑定,没有属性能选择第二套调色板;多个表面绕过 token:Landing 主按钮(#2f6793与海军蓝光晕)、网格、遮罩 (rgba(4,10,18,.45))、打印颜色、asciinema 表面与 giscus 样式表。 - 约 85 处字面圆角与若干字面阴影,使扁平预设在没有圆角与阴影尺度前无法实现。
- 明暗控件靠悬停或聚焦展开。触屏读者无法到达“跟随系统”;触发按钮混用
aria-pressed与aria-expanded;Esc 不能关闭。Landing 手机抽屉没有主题控件。 contrast-on-canvas.html硬编码了 Slate 画布亮度,用于theme_color警告。dark_mode默认false,站点不开启就既没有深色调色板也没有菜单。
目标与非目标
目标:
- 一个站点配置键选择默认视觉预设;默认改为 Paper;
- Slate 保留可选,选择它的站点得到与当前一致的输出;
- 读者可即时切换 Paper 与 Slate,无需刷新,并与浅色/深色/跟随系统彼此独立;
- 禁用 JavaScript 或存储不可用时,站点配置的默认风格照常呈现;
- 预设共享模板、组件与布局几何,只改变配色与字体;
- 只用本地字体、普通 Hugo 构建,不引入新的运行时框架或必需构建工具。
非目标:
- 第一阶段实现 Ink、Terminal、Folio 或 Canvas;
- 复制 PG.CENTER 品牌色、版本界面或页面结构;
- 按页面或栏目切换预设(栏目颜色仍由
theme_color负责); - 第一阶段按预设改变布局几何、密度或导航结构;
- 在现有明暗处理之外为 Swagger UI、ReDoc 或第三方嵌入换肤。
预设模型
此表与下文第一阶段配置保留原始范围。后续实验增加显式 ink/terminal 配置及
菜单列表选项;true 仍提供稳定选项与站点默认值。当前行为由
架构契约管理。
| 预设 | 方向 | 第一阶段 | 读者菜单 |
|---|---|---|---|
paper |
温暖的编辑式极简 | 实现,默认 | 是 |
slate |
技术极简(当前 OINK) | 实现 | 是 |
ink |
排版极简,受瑞士风格启发 | 规格 + 研究原型 | 否 |
terminal |
终端工具式功能设计 | 规格 + 研究原型 | 否 |
folio |
学术与书籍出版 | 仅保留名称 | 否 |
canvas |
活泼几何与创作者 | 仅保留名称 | 否 |
保留名称在实现前会被校验拒绝,警告中列出可用的稳定预设。
配置
preset选择站点默认值。无效或保留值通过现有校验路径警告并回退到paper; 发布门禁会把警告变成失败。preset_menu控制读者选择。false不渲染风格分组、不输出预设初始化脚本;true提供所有稳定预设;列表提供子集,且必须包含preset。沿用dark_mode的先例,默认false;文档站开启,Starter 采纳不在本轮范围内。preset只能在站点级设置,不支持页面与栏目覆盖:逐页切换视觉身份会破坏读者 预期与已保存的选择。- 只要
dark_mode.show_menu或风格选择任一开启,外观菜单就存在。dark_mode: false且preset_menu: true的站点只显示“风格”分组。
与现有配置的关系
优先级由低到高:
:root/[data-bs-theme]上的 Slate 基础 token(选择器不变)。[data-td-preset=X]上的预设 token。params.ui.typography: system:在所有预设块之后把字体角色收拢为系统字体, 因此在任何预设下都不请求品牌字体。params.ui.fonts:在样式表之后以:root内联输出;特异性相同、源顺序靠后, 因此覆盖预设字体角色。显式字体永远优先。theme_color/theme_color_dark:只作用于页面与栏目的强调背景,覆盖预设 强调色;从不触碰链接或行内代码。- 站点
_styles_project.scss:位于样式包最后。
typography: technical 仍表示“使用预设自带字体”。具体是哪些字体由预设决定
(Paper:Plex Sans;Slate:Inter + Chakra Petch)。
读者状态
两个彼此独立的维度:
| 维度 | 属性 | 存储 | 取值 |
|---|---|---|---|
| 风格 | <html> 上的 data-td-preset |
localStorage['td-preset'] |
稳定预设名 |
| 明暗 | data-bs-theme(及 .dark-mode、供应商 data-theme 镜像) |
localStorage['td-color-theme'] |
light、dark、auto |
| 情形 | 结果 |
|---|---|
| 初次访问 | 服务端输出 data-td-preset="<站点预设>" 与 data-td-site-preset,不依赖脚本 |
| 读者选择预设 | 立即应用、保存,并派发 td-preset-change |
| 读者选择标有“默认”的预设 | 删除存储键;之后站点默认值变化能到达该读者 |
| 下一页、刷新、切换语言 | head 内联脚本在首次绘制前应用已保存的值 |
| 已保存的值不再提供 | 删除,使用站点默认值 |
| 存储不可用 | 选择只作用于当前页面,菜单提示不会保存 |
| 禁用 JavaScript | 站点默认预设以浅色调色板呈现,与当前主题无脚本时一致;风格与明暗控件不可用 |
| 切换风格 | 从不写入 td-color-theme;切换明暗从不写入 td-preset |
| 其他标签页修改 | 通过 storage 事件同步 |
内联脚本位于样式表之前,与现有明暗脚本并列。它用构建时嵌入的允许列表校验已保存的
值,设置属性,并按预设与明暗更新 theme-color meta 与首绘画布颜色。只有菜单提供
多于一个预设时才输出。与菜单无关,head.html 中静态的首绘 <style> 与单个
解析后的 theme-color meta 改为按站点默认预设的画布颜色渲染,取代原先硬编码的
#0b0d12、#ffffff 与 #000000。
切换时,运行时设置 data-td-preset-switching 一帧以抑制颜色过渡;记录第一个可见
标题或块作为滚动锚点;应用属性后恢复锚点偏移,并在 document.fonts.ready 后再校正
一次,因为 Plex Sans 与 Inter 的字形度量不同。焦点、已打开的菜单与表单状态保持不变。
第一阶段不使用淡入淡出或 View Transition。
外观菜单
比较了三个方案:
| 方案 | 评估 |
|---|---|
| 保留悬停菜单,增加一行风格 | 触屏与键盘缺口仍在;只能靠悬停发现 |
| 风格与明暗分成两个按钮 | 拥挤的导航栏多一个图标;手机抽屉更长 |
| 一个“外观”展开按钮 + 两组单选 | 选定:单一入口,触屏与键盘均可用,可扩展到更多预设 |
行为:
- 触发器:一个图标按钮(
aria-expanded、aria-controls,标签“外观”),替换 导航栏与外壳页脚行中现有的主题按钮。太阳表示当前亮色状态,月亮表示暗色。 快捷键t继续切换浅色/深色。 - 面板:非模态弹出层,包含两个原生
fieldset单选组。10 月 5 日修订后, 风格 使用两列图标与名称按钮,图标采用预设主题色,不显示字母预览或实验标记; 站点默认值在悬停提示与无障碍名称中注明。明暗 为浅色 / 深色 / 跟随系统分段 控件,英文分组名为 Style 和 Light。选择立即生效,面板保持打开以便比较。 - 键盘:Enter/Space 或 ArrowDown 打开并聚焦已选中的单选;方向键在组内移动 (原生单选行为);Tab 在组间移动;Esc 关闭并把焦点还给触发器;焦点离开面板或 点击外部时关闭。
- 反馈:选中项使用淡色背景与强调色边框,键盘焦点另有轮廓线。变化由原生 单选语义播报,不额外增加 live region。
- 恢复默认:选择站点默认预设即清除已保存的选择,无需单独的重置按钮。
- 手机(< 768 px):触发器保留在紧凑页头,并在文档抽屉页脚与 Landing 手机抽屉的
新行中提供。面板以底部表单打开,44 px 触控目标,同样两组,带关闭按钮。底部表单是用
showModal()打开的模态<dialog>,处于顶层:原型显示,粘性页头的backdrop-filter否则会成为position: fixed表单的包含块,抽屉的层叠上下文 也会把它遮住。 - 命令面板:在
switch_theme旁新增switch_preset动作。
dark-mode.js 保留存储键与属性,但需同步明暗单选的 checked 状态并监听其
change 事件,取代目前的 aria-pressed 按钮。
Token 架构
所有预设编译进现有的单一 main.css。字体通过 @font-face 声明,只有规则实际使用时
才下载;因此提供一个预设只增加 CSS 字节,在被选中前不增加字体字节。
规则:
- Token 对等:每个深色块重新声明其浅色块的全部 token,Slate 深色值不会泄漏 到其他预设。由检查器强制。
- 深色孤岛:后代选择器形式覆盖嵌套的
data-bs-theme="dark"孤岛 (Landing 代码板、预览)。 - 字体角色只用 (0,1,0),
params.ui.fonts因而继续优先。 - 强调色间接层:预设设置
--td-preset-accent(及-rgb、-hover),--td-accent默认取它;theme_color继续写入--td-accent,因此在两种明暗下 都能覆盖预设。 - Slate 不依赖属性:
data-td-preset="slate"不匹配任何覆盖块,现有站点对品牌 token 的覆盖行为与今天完全相同。 - 几何共享:第一阶段预设不改变栅格列、侧栏宽度或断点。
- 预设专属规则少而局部:每个预设一个 partial,限定在
[data-td-preset=X]下; 两个预设都需要的东西就提升为 token。
Paper 之前(第一阶段)需要的新共享 token:--td-shell-scrim、Landing 的
--td-grid / --td-glow / 主按钮 token、--td-callout-tint、--td-code-inline-bg、
--td-hairline,以及 brand 字体角色(--td-brand-font-family,默认
var(--td-display-font-family)),使字标保留 Chakra Petch,而 Paper 的展示标题
使用 Plex Sans。
原第二阶段计划提出全局圆角、阴影与密度尺度。10 月 5 日实验改为仅作用于主题 自有组件的规则;更广泛的 token 重构不作为试用设计的前提。
契约变化:之前的架构契约把行内代码固定为一组深红色。第一阶段把 --bs-code-color 改为
预设 token(Slate 保留深红,Paper 使用墨色底片)。theme_color 仍然从不触碰它。
字体
| 预设 | 界面 / 正文 / 标题 | 展示 | 品牌(字标) | 元信息 | 代码 | 新增字节 |
|---|---|---|---|---|---|---|
| Paper | IBM Plex Sans | IBM Plex Sans | Chakra Petch | IBM Plex Sans | IBM Plex Mono | Plex Sans |
| Slate | Inter | Chakra Petch | Chakra Petch | IBM Plex Mono | IBM Plex Mono | 无 |
| Ink | Inter | Inter | Inter | Inter(等宽数字) | IBM Plex Mono | 无 |
| Terminal | 界面用 Plex Mono,正文用 Plex Sans | IBM Plex Mono | IBM Plex Mono | IBM Plex Mono | IBM Plex Mono | Paper 之后无 |
Paper 将 @fontsource-variable/ibm-plex-sans(OFL-1.1)vendor 到 third_party/
并登记 VENDOR.json:拉丁、扩展拉丁、西里尔、扩展西里尔、希腊与越南语子集,正体与斜体,字重 100–700。PG.CENTER
仅正体、400–600 的子集为 40,240 B(latin)+ 25,868 B(latin-ext);准确体积在
vendor 时记录。需要斜体,因为 OINK 正文使用强调,PG.CENTER 的合成斜体不可接受。
完整的小型子集保留现有语言覆盖,浏览器按实际字符范围加载;12 个字体文件均登记于 VENDOR.json。
中日韩文字使用排在拉丁字体之后的系统字体栈:-apple-system, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Noto Sans CJK SC', 'Noto Sans SC', sans-serif。IBM Plex Sans SC 因文件达到 MB 级被否决。等宽字体栈在通用
monospace 之前插入 CJK 无衬线字体,使混排代码的中文字形可预期。
typography: system 仍不请求任何品牌字体:system 块位于所有预设块之后,并重置
包括 brand 在内的全部角色。
衬线:第一阶段不使用衬线。拉丁衬线标题与中文无衬线标题并列显得不一致;Windows 默认中文衬线在标题字号下渲染较差;衬线还要多一套字体。第一阶段之后可基于本提案的 同内容对照样稿,评审一个可选的、仅用于展示标题的衬线。
预设规格
共享基础
属于所有预设,而不是 Slate:
- 布局几何、断点、侧栏/目录宽度、约 76ch 正文行长;
- 正文 1rem / 1.7,界面 0.875rem,元信息 0.8125rem;
- 字号比例(h1 2.25rem、h2 1.5rem、h3 1.25rem、h4 1rem)——第一阶段预设只调字重与 字距,不调字号;
- 焦点环:2 px 强调色描边、2 px 偏移,绝不移除;强制颜色模式回退不变;
- 语义状态色(note、tip、important、warning、caution)保持色相;预设只改变淡底强度 与边框;
- 第一阶段语法高亮沿用现有 Chroma 浅色/深色调色板;
- 动效 token 100/150/250 ms;
prefers-reduced-motion关闭过渡; - WCAG AA:两种明暗下正文 4.5:1,大字与界面边界 3:1。
Paper
温暖的编辑式极简。 暖纸色、墨色文字、安静的细线、柔和阴影,舒展但不松散的阅读 节奏。它服务长篇阅读:大面积画布蓝光更少,界面对比更克制,Plex Sans 字怀开阔, 16 px 下易读。
| Token | 浅色 | 深色 |
|---|---|---|
画布 --bs-body-bg |
#f7f6f3 |
#161513 |
抬升 --td-brand-elev、--td-pre-bg |
#ffffff |
#1f1e1a / #121110 |
| 次级表面 | #efede8 |
#1f1e1a |
| 正文 | #21201c(15.09:1) |
#ece9e3 |
| 次级文字 | #56534c(7.10:1) |
#b6b1a7 |
| 三级文字 | #6b665d(5.27:1) |
#958f84(5.68:1) |
| 边框 | 墨色 12 % | 浅墨色 13 % |
| 链接 / 悬停 | #2b5f8c(6.23:1)/ #1d68a5(5.43:1) |
#7db5e6(8.36:1)/ #a3cdf3 |
| 强调(铜色) | #9c5530(5.17:1) |
#d99a6c |
| 行内代码 | 墨色字、墨色 6 % 底片 | 浅墨色字、8 % 底片 |
| 阴影 sm / md | 0 2px 10px / 0 14px 38px,墨色 7 % / 13 % |
黑色 35 % / 50 % |
| 圆角 | 代码 12 px、卡片 12 px、控件 8 px | 相同 |
Paper 专属规则:标题 Plex Sans 600,字距 −0.006em(h1 −0.012em);h2 后接延伸到 边缘的细线;外框表格(圆角 10、表头底色、无斑马纹);提示块使用 4 %(深色 6 %)语义 淡底与单条 3 px 竖线;细线引用块;Landing 去掉网格与光晕,主按钮取自 token 并带暖色 阴影,首屏标题 600 / −0.025em;导航选中行使用暖中性底并混入 9 %(深色 12 %)强调色。 链接保持蓝色:这是阅读惯例,不是装饰。悬停与弹出层使用 160 ms ease-out;滚动时 不做动效。
Slate
技术极简。 即当前 OINK 外观,保持不变:冷灰蓝画布、海军蓝墨色、钢蓝与铜色、
Inter 正文、Chakra Petch 展示、Plex Mono 标签与元信息、蓝图网格与首屏光晕、深红
行内代码、8–12 px 圆角。选择 preset: slate 必须复现 v1.1 的 token 值,由检查器
比较。网格、光晕、Chakra 展示标题、等宽元信息与深红行内代码属于 Slate 身份;布局、
焦点、状态色与外壳结构属于共享基础。
Ink
排版极简,受瑞士风格启发的信息设计。 黑、白与中性灰,一个红色强调;层级由字号、 字重与对齐承担,而不是颜色、阴影或圆角表面。
| Token | 浅色 | 深色 |
|---|---|---|
| 画布 | #ffffff |
#0b0b0b |
| 正文 | #141414 |
#ededed |
| 次级 / 三级 | #474747 / #636363 |
#b5b5b5 / #8f8f8f |
| 表面 | #f4f4f4 |
#161616 |
| 链接 | 墨色加下划线;悬停为红 | 浅墨色加下划线;悬停为红 |
| 强调 | #c8102e(5.88:1) |
#ff5c4d |
| 圆角 / 阴影 | 0 / 无 | 0 / 无 |
与 Slate 的区别:画布无色相、无蓝色、无网格纹理、无阴影、无圆角;链接靠下划线而非 色相识别;标题使用 Inter 700–800 紧字距,而不是 Chakra Petch。与 Paper 的区别: 中性而非暖色,平面而非柔和,粗线分隔而非细线,下划线链接而非蓝色链接。标志性规则: h2 上方 2 px 黑线;h1 800 / −0.035em;h4、表头与提示块标题大写加字距;导航选中行用 3 px 红色竖条而不是底色;等宽数字。
Terminal
终端工具式功能设计。 体现在结构与信息表达上,而不是 CRT 特效:等宽界面、命令与 路径表达、紧凑控件、明确的面板边界、琥珀或青绿强调。
| Token | 浅色 | 深色 |
|---|---|---|
| 画布 | #f4f5f2 |
#0c0f0e |
| 正文 | #1d211f |
#d3dbd6 |
| 次级 | #4a514d |
#9aa59f |
| 表面 | #e9ebe6 |
#141a18 |
| 链接(青绿) | #0a6560(6.31:1) |
#4cc9bd |
| 强调(琥珀) | #935400(5.47:1) |
#f0a73a |
| 圆角 | 2 px | 2 px |
等宽范围:导航、标题、标签、元信息、面包屑、按钮与代码使用 IBM Plex Mono。正文段落、
列表与表格正文使用 Plex Sans,中文使用平台回退字体,因为长段等宽文字与中英混排
等宽行都难以阅读。
标志性规则:标题前的 ## 前缀用 content: '## ' / '' 渲染,辅助技术会忽略它;
方括号提示标签([NOTE]);导航选中行反色并带 ▸ 标记;1 px 强边框面板;首屏静态
▍ 光标。没有扫描线、辉光、闪烁或打字动画。
差异矩阵
| Paper | Slate | Ink | Terminal | |
|---|---|---|---|---|
| 色温 | 暖 | 冷 | 中性 | 中性偏绿 |
| 浅色画布 | #f7f6f3 |
#f1f4f8 |
#ffffff |
#f4f5f2 |
| 深色画布 | #161513 |
#0b1119 |
#0b0b0b |
#0c0f0e |
| 正文字体 | Plex Sans | Inter | Inter | Plex Sans |
| 标题字体 | Plex Sans 600 | Inter 600–700 | Inter 700–800 | Plex Mono |
| 展示 / 字标 | Plex Sans / Chakra | Chakra / Chakra | Inter / Inter | Plex Mono |
| 链接信号 | 蓝色 | 钢蓝 | 下划线 + 红色悬停 | 青绿 |
| 强调色 | 铜色 | 铜色 | 红色 | 琥珀 |
| 圆角 | 8–12 | 8–12 | 0 | 2 |
| 阴影 | 柔和暖色 | 海军蓝调 | 无 | 无 |
| 章节分隔 | h2 尾随细线 | 无 | 2 px 顶线 | ## 标记 |
| 选中行 | 暖色底 | 强调色底 | 红色竖条 | 反色 + ▸ |
| 行内代码 | 墨色底片 | 深红 | 墨色底片 | 带框墨色底片 |
| Landing 纹理 | 无 | 网格 + 光晕 | 无 | 无 |
| 界面密度 | 标准 | 标准 | 标准 | 紧凑 |
页面密度
密度跟随页面任务,而不是预设:Landing 首屏允许最大的展示字号与品牌表达;Docs 正文 保持 1rem / 1.7 与约 76ch;侧栏、目录、参数表、搜索结果与命令面板保持紧凑行 (0.875rem,行高 1.4–1.5)。第一阶段预设可以改变这些区域的配色,但不改变间距。 Terminal 的紧凑界面属于第二阶段的密度 token。
运行时表面
| 表面 | 第一阶段影响 |
|---|---|
| Blog、Book、分类 | 仅 token;Book 题注保持正文字体 |
| 搜索对话框与命令面板 | 遮罩 token 化;选中行使用 --td-shell-primary-dim |
| Mermaid、ECharts | 颜色在初始化时依 data-bs-theme 固化。只有图表采用预设颜色时才需观察 data-td-preset;第一阶段保持仅随明暗变化 |
| asciinema | 表面 token;只有代码字体变化才需重新挂载(第一阶段不变) |
| giscus | 每个预设与明暗各需一份样式表,并在 td-preset-change 时重新下发 |
| Swagger UI、ReDoc | 保持供应商样式与现有明暗处理 |
| 打印 | 海军蓝与冷灰 token 化;打印始终使用当前预设的浅色调色板 |
| 404 | 其自有 <html> 必须带上新属性 |
无障碍、安全与输出
- 每套调色板在两种明暗下的正文、次级与三级文字、链接与强调色均满足 WCAG AA(见上文
数值)。
theme_color对比度警告按站点默认预设的画布计算。 - 菜单使用原生单选,不使用
role="menu"。除手机底部表单(模态并恢复焦点)外不捕获焦点。 prefers-reduced-motion与强制颜色模式保持现有行为。- 初始化脚本内联、静态,来自已校验的配置;已保存的值使用前先与构建时允许列表比对。
- 不新增外部字体或脚本请求。输出只增加两个
<html>属性、一段内联脚本与 CSS。
兼容与迁移
默认改为 Paper 会改变所有未设置 preset 的站点。
- 想保留当前外观的站点加上
params.ui.preset: slate;升级说明以这一行开头。 Slate 输出必须等于v1.1的 token。 - 在
_styles_project.scss中覆盖品牌 token 的站点::root上的浅色覆盖在 Paper 下仍按源顺序生效;[data-bs-theme='dark']上的深色覆盖会被 Paper 深色块压过。 这类站点应选择 Slate,或把覆盖改写到[data-td-preset='paper'][data-bs-theme='dark']。升级说明与品牌指南需说明。 theme_color、typography与fonts的含义与优先级不变。dark_mode: false的站点仍只有一套浅色调色板,只是变为 Paper。- 改变默认值的版本必须把它列为可见变化。该版本是次版本(
1.x)还是主版本, 是待决问题。 - 在发布默认值变化前,消费方盘点应报告哪些站点覆盖了品牌 token。
实施计划
第一阶段,按依赖顺序;每步注明负责的检查器。
- Token 化 Slate 泄漏点:Landing 主按钮、网格、光晕、遮罩、打印颜色、asciinema
表面;增加
--td-preset-accent、brand字体角色,以及contrast-on-canvas.html的按预设画布亮度。Slate 的计算颜色必须保持等价。 检查器:check-landing.py、check-output.py、check-font-tokens.py。 - Vendor IBM Plex Sans:
third_party/、VENDOR.json、许可证文件。 检查器:check-vendor.py。 - 预设 token:新增
assets/scss/td/_presets.scss(在_brand.scss之后导入); 当前实现将 Paper 保留在这个文件中,不另建presets/_paper.scss。 字体预设块放在system重置之前。检查器:扩展check-font-tokens.py(Plex Sans 字体族、system 块顺序、浅深块 token 对等)。 - 配置:
hugo.yaml默认值(preset: paper、preset_menu: false);一个 resolver partial,供validate.html、document-attrs.html、layouts/404.html与head.html(初始化脚本、theme-color、首绘画布)使用;重新生成 schema。 检查器:check-params.py(接受、无效、保留值)、generate-config-schema.py --check、check-namespace.py。 - 外观菜单:共享 partial,供
navbar.html、shell/footer-line.html与 Landing 手机抽屉使用;preset.js运行时(或dark-mode.js的一节);dark-mode.js单选同步;命令面板动作switch_preset;32 个语言目录的 i18n 字符串。 检查器:check-shell.py、check-actions.py、i18n 检查器、tests/js/preset.test.js、tests/js/dark-mode.test.js。 - 第三方表面:按预设的 giscus 样式表与重新下发。
- 文档:EN/ZH 架构、外壳与 Landing 契约;品牌指南(预设、迁移、字体); 配置参考;变更日志与升级说明。
- 站点验证:
make -C ../oink.pgsty.com check、browser(增加预设切换、持久化、 存储失败、无 JS、EN/ZH、桌面/手机、浅色/深色用例),以及用于视觉评审的dev。
验收标准
以下保留最初的验收目标,已执行检查与剩余限制分别记录在10 月 5 日验收记录中:
- 未设置
preset时,输出带data-td-preset="paper",禁用 JavaScript 也呈现 Paper。 preset: slate在检查器样例上产生与v1.1相同的计算颜色与字体角色。- 切换风格不改变
td-color-theme;切换明暗不改变td-preset;两者在导航、刷新与 切换语言后保持。 - 无效的已保存值被删除;存储失败时页面可用并显示不保存提示。
- 在 Chromium、Firefox 与 WebKit 的正常及降速 CPU 下,预设之间无首绘闪色。
- 切换后滚动位置与锚点相差不超过一行。
- 任何预设下
typography: system都不触发字体请求;params.ui.fonts覆盖预设字体。 - Paper 与 Slate 下,
theme_color在两种明暗中都覆盖强调色。 - 菜单可完全通过键盘、触屏与屏幕阅读器操作;axe 不报告新增违规。
- 所有调色板在两种明暗下满足对比度表。
- 预设不新增外部字体或脚本依赖;Giscus 等显式配置的服务单独说明。
--panicOnWarning构建通过。
待决问题
- 第一阶段已选择
preset_menu: false,文档站开启。原问题:false(与dark_mode一样需显式开启)还是true。 - 发布准备目标已确定为
1.2.0:醒目说明 Paper 成为默认,并提供preset: slate兼容设置;已随 1.2.0 正式发布。 - 第一阶段已选择
brand。原问题:字标字体角色命名:brand还是wordmark。 - 第一阶段之后,是否把仅用于展示标题的衬线作为 Paper 选项。
- 第二阶段图表(Mermaid、ECharts)是否采用预设颜色。
Ink 与 Terminal 后续清单
已实验实现:两套色板、现有字体角色、正文链接与选中信号、标题处理、局部几何、 Terminal 紧凑导航、Giscus 色板、打印与现有切换机制。不新增字体文件、动画或 运行时。真实输出与验证范围见实验记录。
晋升稳定预设前,仍需评审 Ink 长页红色强调密度与中文下划线;Terminal 编号标题、 等宽换行与密集参数表;Windows/Android 回退字体,以及人工屏幕阅读器朗读。 本次实验明确保留 Mermaid/ECharts 与 API 供应商组件仅随明暗变化;全局几何与 密度 token、预设图表色板需要另行决定。
决策记录
| 日期 | 变化 |
|---|---|
| 2026-10-04 | 创建草案:Paper/Slate 第一阶段范围、Ink/Terminal 研究规格、外观菜单选择与 token 架构 |
| 2026-10-05 | 第一阶段已在本地实现;默认值、brand 角色、图表仅随明暗的范围已接受;发布版本未定,本轮没有发布 |
| 2026-10-05 | 随后实现显式开启的 Ink/Terminal 实验;保留稳定菜单策略;视觉定稿仍未完成 |
| 2026-10-05 | 按 1.2.0 做发布准备;简洁的风格/明暗控件与当前状态图标取代早期色样方案;未创建标签或部署 |