图例 · 收据(J05)
Web 已发布;收据专项线上验收待完成;原生未纳入。
这是审阅状态说明,不是产品文案——产品画布里不写 future。

Renew design · 第二批:P1 键盘修复、收据体验、证据站整改

原型改动后的版本随本页发布。第一批的盘点结论见下方存档,未变。


A. P1 键盘可达性 —— 已完成

结果:8 个状态、全部控件,键盘不可达数 = 0(修改前 13 个;probes/a11y-before.json

probes/a11y-after.json 可逐项对照)。

页面页面自身可聚焦控件(修改前 → 修改后)
Scan0 → 5
Home1 → 7
Log3 → 3
Plan3 → 3
Me13 → 15

做法:凡是可点的一律改成原生 <button type="button">,不用 role=button + tabindex 凑数。

新增 .zh-tap 类只做外观复位(去掉浏览器按钮样式),视觉零变化,并统一 :focus-visible 轮廓。

选中态同样是 button,不会像原来那样一选中就退化成纯 div。

role=tab + aria-selected

顺带修掉一个被这次改动暴露的缺陷:选中份量后,DOM 分支切换会把被聚焦的节点整个换掉,

焦点掉回 <body>——键盘用户每选一次就被扔回文档顶部。已加 restoreFocus()

在重绘后把焦点放回代表同一选项的新节点。实测:Enter 选中 0.5 cups

aria-pressed=true 且焦点仍在 pick-f-yogurt-half

另一个被暴露的内容缺陷:主按钮文案原本硬编码「Analyse with photo」。

模式过去键盘切不了、鼠标切了也没人注意,所以没被发现——现在选 Barcode 时它会说

「Look up this barcode」,选 Describe 时说「Analyse the description」。

### 真实键盘主链实测(不是属性审计)

用浏览器真实按键走完,每步都是 focus() + 真实 Enter

步骤结果
底部 Scan → Enter进入采集页
模式 Describe → Enteraria-selected 切到 Describe
模式 Photo → Enter切回 Photo
Analyse → Enter进入复核页
解决读不出的行 → Enter → 选 Black coffee → Enter已解决
四个份量 → Enter逐项确认,焦点保持在被按的那颗
确认这一餐 → Enter出现「Saved to today」
底部 Log → Enter → 编辑该餐 → Enter进入编辑,横幅正确显示「already counted」

B. 收据体验 —— 按 owner 在 task #181 的拍板

owner 的要求这一版怎么做的
入口离用户更近、更显眼,拍完立即提示入口从item 列表下方的一行小字移到复核页顶部(ESTIMATE 条正下方),改成有边框的提示卡:一句话说明 + 两个按钮。不打断主链——下面的逐项列表照常继续
支持在线商户截图卡上直接给两个并列入口:「Photograph a receipt」和「Pick a screenshot」。截图不再是纸质流程里的一个子步骤
不要多一次专门确认点击移除了「用途确认」式的措辞。遮挡页的按钮改为「Read this receipt」(描述它做什么),并写明「Masked areas are not sent」。用途与边界写在提示卡上:「How the image is used is covered in the terms and in Me › Data controls」
可跳过、可移除,不能画成默认强制卡上明写「Optional — you can confirm this meal without one, and remove it again at any point」;原有的「Not now」「Drop the receipt」路径保留
有无收据都进同一套核对页本来就是同一套——receipt.joint 只是在同一张复核页上多加一条说明横幅,不是另一个页面。已核实,未新建「收据专用核对页」
不暗示已具备标准菜单数据库现有文案没有此类主张;task #182 的融合能力未在原型中出现

C. 证据站整改 —— 按你指出的三处

1. 原始 JSON 现在是真文件probes/audit-320.jsonaudit-480.json

a11y-before.jsona11y-after.jsonfocusable-per-page.json,都是本次运行导出的,

不再回落到报告 HTML。

2. harness 可真跑:站上现在带 widths.html(含审计脚本要求的 #f iframe)以及

原型源文件 zhishi-prototype.dc.htmlsupport.jsassets/

打开 widths.html,贴 probes/width-audit.js,调 await window.__audit(320) 即可复跑。

顺带修了一个会让复跑结果失真的问题:harness 原来用 location.reload()

会命中缓存旧原型;现在每次都用带时间戳的 src 强制取新。

3. 首页「13 个控件」已改成按页面统计的准确表述,见下方存档的更正段。


D. 回归

滚到底无控件被底栏遮挡。


E. 这一批仍没有


F. 第二批复核后的补正(REQUEST CHANGES 回应)

@打包的 用部署站 harness 实按发现:Scan 的模式 tab 被 Enter 选中后焦点掉回 <body>

我第一版只给 Fridge 份量加了 restoreFocus,Scan 的 tab 漏了;而且我的主链测试每步都先

focus() 再按 Enter,恰好把这个缺陷掩盖了——逐步能走完,连续导航会丢位置。

已修:

(「add at least one mask first」),不再是像二次用途确认的措辞。

新增证据 probe:probes/focus-retention.js —— 断言的是「真实激活后 activeElement

仍是同一个控件」,不是统计 tabindex。9 个会发生分支重绘的控件全部保持焦点。

这个 probe 不是空过的:我把 restoreFocus 临时停用再跑一遍,9 个里 7 个立刻失败

(全部掉到 BODY),确认它真的能抓到这类缺陷。

一处要如实说明:那 7 个是 Scan 四个模式 + Fridge 三个份量。**Home 的两个 insight tab

本来就不会丢焦点**(它们绑的是 aria-selected,节点不发生分支替换)。我按你的要求一并接了

restoreFocus,但这两个属于加固,不是修复既有缺陷——不想把它算成战果。

连续键盘导航实测(不再用 focus() 辅助):Tab 依次经过

photo → describe → barcode → label → analyse;在 barcode 上按 Enter 后焦点仍在 barcode

再按 Tab 正常前进到 label。

顺带一个观察,不属于本批范围:从底部导航继续 Tab 会进入画布外的审图开关

sim-unreadable-receipt 等),因为它们在 DOM 里排在手机壳之后且可聚焦。旅程文档第 5 节

本来就要求把这类工程内容移出用户流程;要不要在原型里也把它们移出 tab 顺序,请你定。

J16 · 与 task #178 的逐条语义对照
差异清单已交:j16-diff.htmlmd)—— 只列差异,未改语义,等 @打包的 判断。
第四批 · P2 普通用户状态
首次进入 / 刷新失败重试 / 周概览改为真实推导:batch4.html
task #186 · 推荐落点 Mockup(design-only)
三个落点 + 两组 sample data + 八种状态,390/320:recommendations.html
未落地能力全部标 FUTURE · NOT BUILT,控件禁用。

关键路径预览(390 / 320)

每组左 390px、右 320px。窄屏是布局回流,不是整体缩放;点击区恒 48px。

Scan 复核 · 新的收据入口
390px
320px
Scan · 选择采集方式
390px
320px
Home
390px
320px
Scan · 逐项复核
390px
320px
Log
390px
320px
Plan · 已创建的 x 天计划
390px
320px
Me
390px
320px

自己复跑

  1. 打开 widths.html(站上带完整原型源与 #f iframe)
  2. width-audit.jsa11y-audit.js 贴进控制台
  3. await window.__audit(320) / await window.__a11y()

本次运行的原始结果:a11y-before.json · a11y-after.json · focusable-per-page.json · audit-320 · 360 · 390 · 480 · assert-all.py

第一批盘点存档(覆盖矩阵、差异清单、键盘缺口原始记录)

Renew design · 第一批:覆盖矩阵与差异清单

task #2 · 依据 docs/06-user-journey.md(PR #290 合并版,17 条旅程)与本频道已关单的原型

(Claude Design zhishi-prototype.dc.html,etag 1788752587954826)。

这一批只做盘点,不做视觉细化。 按 @打包的 的要求,优先普通用户主链、390/320 断点、

状态恢复、键盘与可达性缺口;future 功能只标位置,不画细节。


1. journey → screen 覆盖矩阵

两列分开,不要混作一件事:

J旅程页面族repo 已实现原型已覆盖
J01登录、恢复会话、首次目标A已接入可点通:登录/加载/错误/重试、登出、目标编辑器(草稿+取消/保存)首次进入的空白 Home 只有模拟开关,没有真正的「首次」编排
J02看懂今天与当日回顾B现有主流程可点通:能量总览、intake/burn 双页、两个明细弹层、Daily Report三种区间状态齐;缺失/过期/刷新失败只有画布外开关,不是页面内路径
J03采集餐食与低置信度回退C已接入(四路径依赖受控目录)可点通choose→analysing→review→saved,四模式、低置信度分支、草稿恢复、图片失效四个模式切换是死的(见 §3 键盘);手动估算入口有,但没有独立页
J04保存前复核与一餐一次确认C已接入可点通:逐项包含/排除、份量四档、精确克数、油/酱、目录替换/新增、一餐一次确认、结果未知/离线/冲突全套恢复覆盖最完整的一族;无缺口
J05照片 + 收据联合核对D已合并发布,线上专项未完成,原生延期可点通:入口、预览、遮挡编辑(至少一处)、联合核对四类证据行、失败保留草稿原型比 repo 状态更「完整」,要标 future/受限,不能让评审当成原生可用
J06从 Log 找旧餐并修正E现有主流程可点通:日期分组、较早记录、详情、整餐编辑、不可编辑说明、版本冲突二选一无大缺口
J07待确认订单与个人分餐F简单 Full/Half/Shared 现有;五模式暂停完全没有 —— 组件 state 里没有任何 order 字段整族缺失。repo 有简单版,原型一格都没有
J08商户菜单、订单 QRGon hold,只有探索稿完全没有按 on hold 处理,本批只占位
J09Fridge 添加/吃了/移除H现有主流程可点通:库存、份量选择、预览、确认、移除、数量校验、三种失败恢复无大缺口
J10目标、下一餐意向、一周回顾I现有主流程可点通:目标编辑器、下一餐建议、保存/移除意向;周概览是静态图周回顾没有交互
J11手动运动与健康连接J现有主流程可点通:运动表单/估算/保存/编辑历史;健康八种状态(默认未连接)无大缺口
J12Closet 与 OutfitK提案,未批准实施完全没有占位
J13Vanity 与 MakeupK提案,未批准实施完全没有占位
J14自定额度K设计讨论,无实现完全没有占位
J15导出、删除、退出L现有主流程可点通:导出准备/文件/下载/分享/失败、两步删除、登出无大缺口
J16x 天计划Mtask #178 Web v1 已交付可点通:创建向导(天数/起始日/时区+校验)、逐日完成/跳过/替换/撤销/补记、暂停、恢复日期预览、到期只读复盘⚠️ 两套东西:repo 的 v1 是产品实现,原型这套是我们这几轮自建的。需要一次对齐核对,本批未做
J17ProNtask #179 todo,先不实现完全没有占位

合计: 17 条旅程里,原型可点通 11 条完全没有 6 条(J07、J08、J12、J13、J14、J17)。

14 个页面族里,F、G、K、N 四族一格都没有


2. 拟改页面清单与状态缺口(只列主链)

优先级页面族要做什么为什么
P1C 记录一餐四个采集模式改成真正可切换;「Analyse with photo」补键盘可达主链上唯一的主按钮,现在键盘按不到(见 §3)
P1B 今日三个指标块、carousel 两个 tab 补键盘可达同上
P1H 库存份量按钮的选中态补键盘可达选中后 role/tabindex 丢了,键盘用户选完就出不去
P2A 进入产品把「首次进入」做成真实编排(空 Home + 引导到第一次记录),不再依赖画布外开关J01 终点是「空白 Home」,现在没有这条路径
P2B 今日缺失/过期/刷新失败做进页面,不只在画布外文档第 5 节 B 族要求随稿交付这三种状态
P2I 计划周概览从静态图改成可点J10 终点之一
P3D 收据全族加 future/受限 标注repo 线上专项未完成、原生延期;原型现在看起来「已上线」
P3M x 天计划与 repo v1 做一次逐条对齐两套实现,参数/语义可能已经不一致
F/G/K/N只占位,标 future/disabled按你的要求本批不做视觉细化

明确不动: 已通过的功能行为、品牌环(含 CONNECTED / DETECTED FROM SCAN)、48px 点击区、

390pt 视觉基线。不为视觉整洁删功能。


3. 键盘与可达性缺口(实测,不是推测)

脚本 probes/a11y-audit.js,逐状态遍历壳内所有可点元素,检查三件事:能否用键盘到达、

有没有可访问名称、有没有焦点样式。

更正(2026-09-08,msg 4edf8301): 原先按状态数「13 个控件到不了」说轻了。

反过来数每个页面键盘能到几个才是真实情况:

页面壳内可聚焦其中是底部导航页面自己的控件
Scan550
Home651(只有 open-nutrients
Log853
Plan853
Me18513

Scan 整页键盘可达控件为 0,主链从这里就断。底部五个 tab 是上一轮补 48px 点击区时顺带修好的,

页面内控件当时没一起处理。另外 insight-tab-intakerole="tab" 却没有 tabindex

明细(cursor: pointer 的裸 div,既不是 button 也没有 tabindex):

状态控件影响
Homesummary-intakesummary-today-burnsummary-nutrition三个指标块打不开明细弹层
Homeinsight-tab-intakeinsight-tab-burn摄入/消耗切不了
Homeintake-latest-photo-entry进不去最近那餐
ScanPhoto / Describe / Barcode / Nutrition label四种采集模式全部切不了
ScanAnalyse with photo主链上的主按钮,键盘按不到
Me / 运动份量的选中态(如 None)未选中的有 role=button tabindex=0,一旦选中就变成纯 div

好消息: 所有控件都有可访问名称(0 个缺失);.zh-plan-control 一族有 :focus-visible 样式。

结论: 这不是「补几个 aria」的问题——Scan 主按钮键盘按不到,等于键盘用户走不完主链。

建议统一:凡是可点的,要么用 <button>,要么 role="button" tabindex="0" + Enter/Space,

选中态也不例外。


4. 390 / 320 断点

上一轮已经把窄屏做成布局回流(不缩放,点击区恒 48px),本批复核结论不变:

滚到底没有控件被底栏遮挡(脚本与结果见 probes/)。

本批新发现的断点问题:无。 320 的问题在上一轮已经解决,这里只做回归确认。


5. 状态恢复

失败恢复层是上一轮的重点,72 条断言全过,本批只确认没有回归:

每个待处理失败绑定自己的对象/内容/版本/会话;成功写入只消费同一个操作;

「结果未知」按尝试 ID 查询而不是比内容;版本冲突给出具体的最新版本对照。

缺口在别处:J02 的「缺失/过期/刷新失败」和 J01 的「首次进入」目前只有画布外开关,

不是页面内可达的状态 —— 见 §2 的 P2。


6. 这一批我没有做的

说清楚边界,避免被当成已完成: