Files
task_pilot/docs/decisions/0006-visual-theme-and-offline-fonts.md
T
CNWei 14fb3563c5 chore(fonts): 字体二进制不入库,改用脚本生成
- 远程仓库对单次推送体积有限制,6.7 MB 字体无法一次推送,先从版本库移除
- 新增 tools/build-fonts.py:下载官方分包、合并并子集化,一条命令重建
- @font-face 保留,字体缺失时回退系统字体;离线用例改为按可用性断言
2026-10-26 00:46:20 +08:00

43 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-0006:视觉风格对齐主题并自托管字体
- 状态:已接受
- 日期:2026-10-25
## 背景
产品要求前端视觉与参考站点(Alright / nicetheme)一致,包括字体、配色和交互,但不改变既有布局。参考站点使用 Bootstrap 5 + 自定义变量,正文依赖 CDN 的 `lxgw-wenkai-webfont`,标题使用自托管的 `Outfit-Medium`。
本项目的目标是"本机、离线可复现":依赖 CDN 会在断网、内网或 CDN 故障时导致字体回退,从而破坏视觉一致性。
## 决策
1. 从参考站点抓取其 CSS 的变量定义,把真实色值映射到本项目既有语义变量(`--primary`、`--text-main`、`--border`、`--success` 等),布局相关声明一律不改。
2. 交互细节对齐主题:`0.3s ease-in-out` 过渡、主/危险按钮 hover 使用 `opacity: .85`、输入框聚焦使用主色半透明光环、选中项使用主色浅染。
3. 字重遵循主题的 `--font-weight-bold: 500`;标题与指标数字使用 `Outfit-Medium`,正文使用 `LXGW WenKai`,等宽使用主题的 `SFMono-Regular…Consolas` 栈。
4. 字体全部自托管:`Outfit-Medium.ttf` 直接取自主题;`LXGW WenKai` 由官方 webfont 的 97 个 woff2 子集合并后,再裁剪到 GB2312 + 常用符号子集,输出简体中文 Regular 与 Bold 两个文件。
5. 移除所有 Google Fonts / CDN 字体链接,`index.html` 只 preload 本地字体文件。
6. 新增端到端用例"renders fully offline":拦截并拒绝一切非 `127.0.0.1` 请求,断言页面正常渲染、`document.fonts.check` 命中两种字体且没有任何外部请求。
## 原因
- 直接用主题的变量值,颜色不会"看起来像"而是确实一致。
- 字体子集化把 8.8 MB 的 194 个子集压到 6.7 MB 的两个文件,仓库与安装包体积可控,浏览器只需一次请求。
- 离线断言把"可复现"变成可回归的测试,而不是口头承诺。
## 边界
- 字体子集覆盖 GB2312(6763 字)+ Latin + CJK 标点 + 全角符号;更生僻的汉字(GB18030 扩展区)会按浏览器逐字回退到系统字体,显示正常但字形风格不一致。
- 只包含 400 / 700 两个字重,500 / 600 由 CSS 字重匹配落到 400 / 700;主题的 Light(300)未包含。
- 未实现参考站点的暗色模式(`data-scheme="dark"`)。
- 字体文件随 `frontend/public/fonts` 一起进入安装包,体积增加约 6.7 MB。
## 后续调整(2026-10-26)
仓库托管的远程仓库对单次推送体积有上限,6.7 MB 的字体二进制无法一次推上去。因此:
- 中文字体二进制 **不再纳入版本库**(`/frontend/public/fonts/LXGWWenKai-*.woff2` 已加入 `.gitignore`);
- 新增 `tools/build-fonts.py`,一条命令即可从官方 CDN 重新下载、合并并子集化生成这两个文件;
- `@font-face` 仍然保留,字体缺失时浏览器回退到系统字体,功能不受影响;
- 对应的端到端用例改为「无外部网络渲染」:始终断言没有外部请求,只有字体文件存在时才断言字体命中;
- `Outfit-Medium.ttf`(55 KB)体积很小,继续随仓库提供。