来源:
notes/documents/网页版笔记面体检报告.md网页版笔记面体检报告:front matter 泄漏、亮色 1:1 与 956px 度量
结论
笔记面能读,但读得不舒服:主体结构(两个 landmark、分组列表、详情、搜索、键盘可达)都在, 坏在正文本身被污染、亮色主题下三处文字直接消失、以及阅读度量是 956px 而不是 640px。 清单:1 个坏掉级、3 个严重级、4 个改进级。
采集方式与它的偏差
线上笔记面在 GitHub OAuth 之后,本机拿不到 Neon 连接串(Vercel 上 21 个 Neon 变量全是
Hidden/Secret,vercel env pull 只写回 [SENSITIVE] 占位;Neon 控制台没有 API key;
会话是服务端不透明 token,sessions.token_hash 才对得上)。所以这一轮用本地夹具重建登录态:
- 前端是
web/里npm run build的真产物; - 接口是
backend/src/lib/notes.ts真身(node --experimental-strip-types直接 import); - 数据是
scripts/generate-notes.mjs从notes/生成的真产物,155 篇; - 只有
/api/me的身份和鉴权守卫是伪造的(固定返回andy)。
因此本文所有关于「未登录/已登录边界、会话过期、OAuth 回跳」的结论一律不作数——那些在上一轮
未登录体检里已经单独验过。夹具不进仓库,只在 127.0.0.1 上跑。
编号步骤
1. 打开笔记列表 —— 可用,但首屏被材料类条目淹没
侧栏 155 篇、6 个分组(知识库 / 书籍 / 文档 / 项目 / 来源 / 专题),aside.notes-sidebar 与
nav.notes-list 是正经 landmark,粘性定位生效,桌面端滚动到正文深处侧栏仍在。

问题是排序把 books/*/source_materials 这类素材推到了最前:一屏之内 9 条里 7 条标题以
「Source Materials」结尾,唯一一眼能认出的入口是 Knowledge Base。设计笔记里已经把
「材料与解读分不出来」列为要解决的问题,这张图是它的原始证据。
健康度:可用,但入口选择成本高。
2. 点开一篇文档类笔记 —— 坏掉:正文顶部泄漏 front matter,且标题重复一次
正文最上方原样渲染出 note_id: note_e828e525b5d94df6 content_type: project,紧接一个
--- 分隔线,然后才是文章自己的 # 一级标题——而这个标题在详情头部已经显示过一次,
并且正文里的那次被渲染成 51.2px(h1 { font-size: 3.2em } 来自 Vite 模板)。

根因不在前端渲染,在数据层:web/scripts/generate-notes.mjs 的 toNote() 把整份文件原文
塞进 body,front matter 一起进了产物;marked 把 --- 当分隔线、把中间两行当普通段落。
notes/documents/ 下 108 篇全部带 front matter(notes/ 总共 155 篇),也就是说 70% 的
笔记打开就是这个样子。顺带一提,title 是用 /^#\s+(.+)$/m 从全文抓的,恰好抓对,
所以列表里标题是干净的——问题只在正文。
健康度:坏掉。
3. 搜索「投资」—— 检索本身可用,命中数却看不见
输入「投资」命中 52 篇,逐条标「标题命中」,键盘可以一路走完。但 命中 52 篇 在亮色下不可见
(见第 4 步的根因),而且每条摘录都被 front matter 污染成
--- note_id: note_6d5ebac3e1d94883 content_type: synthesis --- # 地平线跌破…,
真正有用的那句正文被挤到第三行之后。

同一个 bug 的第二次受伤:excerpt 也是 body.slice(0, 240)。
健康度:可用,但摘要基本失效。
4. 切到亮色系统主题看同一屏 —— 坏掉:三处文字对比度 1:1
.muted 是写死的 rgba(255,255,255,.6),App.css 里没有任何亮色覆盖,于是落在白底上:
白字的 60% 叠白底,还是白,对比度 1.00:1。实测受影响的有三处:
.note-detail-head p(documents/01_….md · 6.1 KiB · 更新于 …)——整行消失;.notes-count(155 篇笔记/命中 52 篇)——整行消失;.muted(头部的用户名andy)——消失。
对照同一屏的暗色版本,那三处都在(约 6.5:1,达标):


这是上一轮未登录体检里同一个 bug 的另一处落点,说明它不是登录页的问题,是主题机制的问题:
全站没有 token,颜色散在各处写死,亮色只靠 index.css 末尾那半套覆盖,漏一处就瞎一处。
健康度:坏掉。
5. 打开材料类笔记(Momenta Global PHIP)—— 可读,但度量与字体都不是阅读用的
这篇短,四条要点,中文长句没有出现。但它暴露的是共性:正文块宽 956px、字体
Inter、16px/27.2px。设计笔记定的目标是每行 34 个汉字(约 640px)、正文思源宋体、最小 17px。
956px 意味着中文一行能塞 50 个字以上,回到行首要靠找;Inter 也没有中文正文该有的字面。
另外详情头部仍是 path · 6.1 KiB · 更新于 … 的中缀式元数据,设计里已经决定把它拆进页边档号。

健康度:可读,但离定版设计还有距离。
6. 390px 移动端 —— 结构没塌,但亮色下同样丢字
侧栏折叠成 364px 高的块(max-height: 40vh),无横向溢出,未选笔记时正文区提示
「从左侧选一篇笔记。」。亮色下 andy 与 155 篇笔记 一并消失,暗色下正常。
移动端工具栏被挤成「Folio + andy + 退出登录」三件套,andy 这个身份信号本身价值不高。


健康度:可用。
高优先级改动(按影响排序)
- 在生成器里剥掉 front matter,正文头部不再重复标题。 这是 108 篇笔记的共同问题,改一处
(
generate-notes.mjs解析 front matter →body从第一个#之后开始,或前端渲染前剥离) 即可同时修好详情页与搜索摘录两处。改完notes.json会变,属于数据产物变更,要重新生成。 - 把主题做成一等公民。 五个色彩角色落成 CSS 变量(素纸
#F1F3F4/ 夜纸同源),.muted、.error、.notes-count、.note-detail-head p全部改用变量。验收就是亮暗两套下 全部 ≥ 4.5:1——现在恰好卡在 1.00。 - 正文度量收到 640px 左右,字号 17px 起,阅读区换宋体。 这是设计笔记里的定版决定, 现行 956px / Inter / 16px 与它冲突。
- 列表按「解读优先、材料折叠」排序。 材料类条目要有可见的次级身份(设计里的页边档号就是干这个的), 否则 155 篇里最前面永远是素材。
无障碍风险
- 能从截图确认的:亮色下三处文本对比度 1:1(等于没有文本);正文有一级标题层级重复,
同一屏出现两个同名 h1,屏幕阅读器的标题列表会重复朗读;
.notes-group用 12px 小字加字距做分组标题, 亮色下 3.95:1,低于 AA 的 4.5:1。 - 不能从截图确认、需要单独测的:侧栏 155 个
button的键盘走查(上一轮只验到登录页焦点可见)、 搜索输入 700ms 防抖期间是否有 live region 播报结果数、屏幕阅读器朗读顺序、 200% 缩放、强制色模式、Safari / Firefox 三个未覆盖项。 - 本轮只测 Chromium 一种内核。
证据边界
- 登录态是夹具伪造的,所有与鉴权、会话、OAuth 相关的结论都不在本文生效范围。
- 本文只覆盖「已登录后读一篇笔记」这条主路径,没覆盖:空搜索结果、超长查询被拒(400
query_too_long)、笔记不存在(404)、代码块与表格的长横向溢出、外部图片(生成器只收.md, 笔记内图片在线上必然裂,这条上一轮已经记在实施计划里)。 - 未采到已登录状态的移动端横屏与平板宽度。
与设计笔记的落差
设计笔记(note_ce68034f2e624b83)定的是「脊 → 索引 → 页 → 页边档号」四层外壳,本文的第 1、5 步
正好是「索引」与「页」两层现在的样子:索引没有身份分层,页没有档号、没有行宽约束。
好消息是坏掉的两处(front matter、主题)都在数据层和 token 层,与外壳改造互不冲突,
可以先把这两处修掉再动外壳。