Files
blog/.spec/specs/archive/2026-11-02_blog-5i-fonts-polish/spec.md
T
wait4xandGLM-5.3 edc34a8a8c chore(spec): 归档 blog-5i——九任务收敛
Spec: 2026-11-02_blog-5i-fonts-polish

Co-authored-by: GLM-5.3
2026-11-03 12:47:13 +08:00

9.0 KiB
Raw Blame History

Phase 5i:字体加载根治、交互缺陷修复与书架/开源页再设计 - 项目范围

1. 问题定义

  • 项目目标:①字体切换全部失效的根因修复(不是字体没做,是加载门禁错了)②按需扩展更多字族 ③Artalk「加载失败」误报与瞬间评论区配色脱同步 ④图库灯箱右上关闭被遮挡点不动,且右侧文字要能换字体/颜色 ⑤取消「彩色 ≤3 处/页」限制 ⑥开源页项目墙恢复居中 ⑦书架页重做 ⑧GitHub README 的动效图与更多展示形式回归(自托管,不再外链)
  • 目标用户:站长(写得更自由、字体真的能换)与读者(交互不再有假失败、书架更耐看)
  • 核心价值:把「看起来能用」变成「真的能用」——本轮多数是用户实测踩到的静默失效,根因都在加载门禁与层级覆盖

2. 假设与待确认

2.1 已确认事实(本轮实测取证,2026-11-02)

  • 字体失效根因:src/layouts/BaseLayout.astro:76 把 serif/kai/kuaile/hwmc 四份字体 CSS 全部关在 track === 'reading' 里;技术轨与全站页面(默认 track='tech')从不加载它们 → .font-kai 计算值虽为 "LXGW WenKai Screen" 但该 @font-face 不在文档字体集内(document.fonts 实测仅 Noto Sans/JetBrains),浏览器回退系统宋体/衬线,表现为「字体没换」
  • 汇文明朝链路:/fonts/subset/hwmc/fonts.css 由 public 手工切片提供(339 片 unicode-range),仅在阅读轨被 preload;技术轨整条链路不加载
  • Artalk 误报根因:ArtalkComments.astro:126 if (document.getElementById('artalk-lib')) return initArtalk(); —— 软导航后脚本标签已在但 window.Artalk 尚未就绪,走 initArtalk() → !lib → showRetry(true) 永久显示失败提示;而评论随后正常渲染(用户所见「总显示失败但实际正常」)
  • 瞬间评论区配色脱同步:Artalk 主题变量块选择器是 #artalk-container 与 body .atk-layer-wrap;瞬间的容器 id 为 mom-atk-<slug>,不在作用域内 → 回落到 Artalk 默认色
  • 灯箱关闭失灵根因:#lb-close 位于 (1220,16,44×44),document.elementFromPoint 命中的是 .lb-meta.lb-l2(右侧信息栏压在按钮上),点击被信息栏吃掉 → lb.close() 永不触发(生产实测 open 保持 true)
  • 书架页现状:色脊卡 + 年份分组网格;信息密度低、悬停无反馈、无简介/评分等可读线索
  • README 动效资源清单(7 类):readme-typing-svg、github-readme-stats、streak-stats、activity-graph、贡献蛇(daily Action 产出的 SVG)、shields 徽章、komarev 访客

2.2 关键假设

  • 字体按「内容实际用到的字族」按需加载即可兼顾体积与正确性(构建期扫正文/页面文案里的 font-* 类)
  • README 动效图均为 SVG(含 SMIL/CSS 动画),可在构建期抓取并自托管,运行时零第三方请求,动效保留
  • 灯箱信息栏与关闭钮的层叠冲突用 z-index + 命中区域划分即可解,无需改结构

2.3 待确认问题

  • 字体扩展款式(用户选:宋系 / 楷系 / 手写系 / 现代黑系各补几款)
  • 书架重做方向(A 色脊墙精修 / B 封面网格 / C 书脊展开卡)
  • README 动效图确认「构建期抓取 + 自托管」路线

2.4 可选解释与取舍

  • 字体:只按需加载,不做「全站全字族常开」(那会把单页体积拉到数 MB)
  • README 动效:自托管后仍保留原服务生成逻辑(GitHub Action / 第三方接口),只是把产物入仓并在构建期更新
  • 彩色限制取消后仍保留「灰阶外壳」红线(导航/页脚/按钮/背景不染色),只取消正文次数限制

2.5 已证伪路径

  • 「字族没做」判断错误:@font-face 与切片文件都在,问题在加载门禁(本轮实测推翻)
  • 外链 README 图直接保留:既有 502/超时与外链依赖问题(上一阶段已判弃),改自托管

3. 功能范围

3.1 核心功能(MVP)

  • T1 字族按需加载根治 + 字族扩展机制:BaseLayout 由「轨道门禁」改为「内容诉求驱动」,扫描正文与页面文案中的 font-* 类决定加载哪些字体 CSS;补字体扩展清单与接入流程
  • T2 Artalk 误报与配色同步:失败提示改为「真失败才提示」(脚本 onerror / 库未就绪超时且未挂载才提示),重置挂载状态机;主题变量覆盖全部 Artalk 实例容器(含瞬间逐条)
  • T3 灯箱:右上关闭恢复可点(层级与命中区域),右侧信息栏文字支持 markdown + 排版类(字体/颜色)
  • T4 取消彩色强调次数限制(文档 + 后台 hint + 示例文章同步)
  • T5 开源页项目墙恢复居中排版
  • T6 书架页重做(按用户选定方向)
  • T7 README 动效图自托管与展示创新(typing / stats / streak / activity-graph / snake 等构建期抓取入仓,配合原生数据卡与热力图组合呈现)

3.2 扩展功能

  • 字体扩展的实际接入(款式待用户定)

3.3 不在范围内

  • 换 CMS、评论系统替换、Artalk 服务端改造

4. 最小实现路径

  • 最简可行:字体先修门禁(用现有 6 族验证通过),再谈扩展;灯箱只改层级与命中;README 动效先接 3 类(typing / stats / snake),验证体积与稳定性后再补
  • 暂不引入:字体子集化的自动重跑编排、灯箱信息栏的富文本编辑器 UI
  • 不做的抽象:通用「动效资源托管」服务

5. 技术决策

  • 技术栈:Astro 7.4.4 + @fontsource(自托管字体 CSS)+ Artalk v2 + 构建期 SVG 抓取缓存(复用 README 缓存模式)
  • 证据协议:evidence: runs
  • 本轮允许改动:src/layouts/BaseLayout.astro、src/styles/{global,tokens}.css、src/components/{ArtalkComments,MomentComments}.astro、src/components/geek/{ViewMeta,ProjectWall,GithubProfile}.astro、src/components/pages/{GalleryPage,BooksPage}.astro、src/pages/{gallery,books}.astro、src/lib/{projects,site-content}.ts、content/site/.yaml、content/photos/.json(caption 富文本)、content/.github-assets/(新缓存目录)、public/admin/、scripts/build-perf/、infra/deploy/build.sh、docs/*、tests/e2e.mjs
  • 本轮不应触碰:nginx/ESA、构建发布链主干顺序、双语路由结构、Artalk 服务端配置
  • Git integration branch:spec/2026-11-02_blog-5i-fonts-polish

5.1 验证策略

  • 范围级别:package
  • 变更对象:字体加载策略、Artalk 挂载状态机与主题作用域、灯箱层级与富文本、书架与开源页版式、自托管动效资源
  • 快速检查:pnpm astro build(node26)+ python3 scripts/build-perf/config-check.py .
  • 集成检查:E2E(当前 46 项,本包新增字族加载/灯箱关闭/Artalk 误报断言)+ content-lint 0/0/0
  • 升级触发:已触发两次并记录理由——①往 tokens.css 补 emoji 回退链(触及全局字体栈)②BaseLayout 字体加载策略改写(触及全站首屏资源)。两次都执行了全站视觉复核(glm-5.3-flash:max,≤6 图/轮,两轮共 9 张)与生产实测。以下情况同样升级:Artalk 挂载状态机、灯箱层级、构建闸门顺序。
  • 全项目检查:生产实测五条(字体真加载 document.fonts 命中、灯箱点关闭真关、评论失败提示不再误报、瞬间评论区配色与页面一致、开源页动效图零外链);升级条件——仅当改动触及 BaseLayout 字体策略或 Artalk 挂载状态机时升级为全站视觉复核,本包因两者都动,已排一轮视觉终审

6. 成功标准与验证方式

  • 技术轨文章里的 .font-kai/.font-song/.font-huiwen/.font-kuaile 真加载对应字体(document.fonts 命中且渲染变化) -> verify: task_0001
  • 评论失败提示只在真失败时出现,正常挂载不提示 -> verify: task_0002
  • 瞬间评论区配色与页面主题一致(明暗双态) -> verify: task_0003
  • 灯箱右上关闭按钮点击必关(含缩放/信息栏展开态) -> verify: task_0004
  • 灯箱右侧文字支持字体与颜色类 -> verify: task_0005
  • 彩色强调不再有限次约束且文档同步 -> verify: task_0006
  • 开源页项目墙内容居中 -> verify: task_0007
  • 书架页信息密度与视觉达设计稿并过视觉终审 -> verify: task_0008
  • README 动效图自托管且生产零第三方请求 -> verify: task_0009

7. 风险与约束

  • 灰阶外壳红线不变,仅取消正文彩色次数限制
  • 自制切片/新增字体必须守单页增量 ≤150KB 阈值,超阈值只做子集化或降级为系统回退
  • README 动效自托管:抓取失败必须回落(隐藏该块,绝不炸构建),且产物必须入仓保证构建确定性
  • Artalk 状态机改动需覆盖三条触发路径(IO / 锚点 / 滚底),不得回归「评论区空着」
  • 多车道并行:BaseLayout、ArtalkComments、GalleryPage、BooksPage 各归单一车道,admin config 与 docs 由 orchestrator 统一改