- 远程仓库对单次推送体积有限制,6.7 MB 字体无法一次推送,先从版本库移除 - 新增 tools/build-fonts.py:下载官方分包、合并并子集化,一条命令重建 - @font-face 保留,字体缺失时回退系统字体;离线用例改为按可用性断言
43 lines
3.1 KiB
Markdown
43 lines
3.1 KiB
Markdown
# 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)体积很小,继续随仓库提供。
|