和项目里同一份源码,附带 support.js 与 assets,所以能真的跑起来。
五栏:Home / Log / Scan / Plan / Me。共享餐记录、逐项复核、可选收据分支都在里面。
默认播种两餐(1,520–1,740)。SALMON 那条用来验「编辑载入本餐成分」和「重复保存不加餐」。
三餐 1,990–2,310,超出区间应显示 190–810。
预置一个 3 天前开始的 7 天计划,用来验过去/今天/未来的操作差异、补记、暂停恢复和到期回顾。
商户直连的 Log 订单流存档,整页盖「NOT BUILT」。首页品牌视觉已经放回产品页,不在这里。
下面每一行都是连续操作下的实测值——上一行的状态是下一行的起点。你按同样顺序点应该得到一样的数字。
| 路径 | 应该看到 |
|---|---|
| Scan → 识别 → 进入复核 | 四行:主菜 / 西兰花 / 气泡水 / 一条读不出的饮料。总计 495–600,确认按钮禁用,提示有一行待核对 |
| Resolve 那条饮料 → 选 Black coffee | 总计 495–605,确认按钮解禁 |
| 主菜改 0.75× | 385–475 |
| 接着给主菜加「油」 | 475–565(+90) |
| 接着排除主菜 | 55–85 — 油随菜一起消失,没有残留在总数里 |
| 再把其余全部排除 | 总计 0–0,确认按钮禁用,提示至少留一项 |
| 复核页 → Add a receipt to cross-check | 收据预览;可导入截图 / 重拍 / 暂不添加返回照片草稿 / 编辑遮挡 |
| 编辑遮挡,不加任何遮挡 | 「用这张辅助核对」禁用,提示至少遮挡一处 |
| 遮挡一处 → 用这张辅助核对 | 只读遮挡后的副本;处理中页面写明「餐食仍未计入」 |
| 联合核对 | 主菜/西兰花「照片和收据都有」;气泡水冲突(收据 2、照片 1);Black coffee「只在照片里」;Oat cookie「只在收据上」。后两类默认待核对,不默认吃了,确认按钮禁用 |
| 冲突选「保留照片的 1」;cookie 选「没吃」 | 解禁;cookie 不计入 |
| 连点两次「确认这一餐」 | Log 只多一条,495–605;Home 合计同步 |
| 处理中点「Simulate an unreadable receipt」 | 失败页;可重试或放弃收据,照片阶段的选择全部保留 |
| 开始识别后立刻切到 Home,等 3 秒再回 Scan | 停在采集选择页,晚到的结果不会把你拽回复核页 |
| In range → 编辑 SALMON → 连点三次保存 | 仍 2 餐,餐名不变,落点是 Log(不是 Scan 成功页) |
| 接着再走一次完整采集并确认 | 这次应该多一餐,共 3 餐 |
| Over range 场景 | 合计 1,990–2,310,超出 190–810 |
| 联合核对后点「Drop the receipt」 | 回到添加收据之前的照片草稿:cookie 消失、水恢复、总计与之前一致 |
| 只解决水的冲突,不动 cookie | 确认仍然禁用 —— cookie 标「Waiting for your call」,不算已排除 |
| 冲突选「I had 1 of them」 | Bought 2 不变,旁边多一行 You had 1;两者分开计算 |
| 切到 Barcode 模式,或从 Log 编辑旧餐 | 不出现收据入口 |
| 编辑旧餐时看顶部 | 写「This meal is already counted — your changes are not saved yet」,不再是 Nothing counts yet |
| 键盘:Tab 到任意 chip 按 Enter/空格 | 与点击等效;禁用项不响应 |
| Plan 组 | |
| 复核页:所有行都已解决,但份量一个没碰 | 确认仍禁用,提示「默认 1× 不算你的答复」;逐项点一次份量后才解禁 |
目标编辑器:体重填 68.5 | 接受(允许一位小数) |
体重填 501 | 显示「Weight must be between 25 and 500 kg」,Save 置灰 |
| 下限一路加到等于上限 | 允许相等,不再强制 100 kcal 间隔 |
| Plan → Start a plan → 选天数 → See every day | 逐日预览,每天一条含标题/详情/理由;确认前不创建任何东西 |
| 「进行中的计划」变体 → 看各天按钮 | 过去只有 Mark done(补记);今天三个都有;未来只有 Skip / Replace |
| 补记一个过去的日子 | 标「Done · backfilled today」,写明补记的是哪一天 |
| 暂停 → Resume | 先出日期调整预览:已完成/跳过的不动,只有待做的移动;从明天起算且不与占用日期撞车 |
| End this plan | 只读回顾,计数齐全,无任何操作按钮;写明「没记录不等于失败」 |
新建计划:天数框填 45 / 开始日填 2026-13-45 | 各自报错,「See every day」置灰;填 11 + 2026-08-20 可继续,预览 11 天 |
目标编辑器体重填 68.55 | 接受(不再限制小数位);501 报范围错;abc 报「Numbers only」 |
| Me 组 | |
| Fridge:不选任何份量 | 「I ate this」禁用 |
| 选 0.5 cup 酸奶 → 预览 → 确认吃了 | 预览写明约 51–59 kcal;确认后库存 3 → 2.5 cups,Home 从 440–520 变 491–579,Log 多一条 |
| Add food 加一样 → 再 Remove 掉 | 库存增减,Home 数字全程不变——加和删都不算吃 |
| 选超过库存的量 | 拦下并说明「没有记录、也没有从货架扣掉」 |
| 手动运动:Run / 40 min / Hard | 先给估算 449–607 kcal(标明「未保存」),保存后进历史;Home 的进食数字不变 |
| Health 默认状态 | Not connected,且写明网页上不会弹真实系统授权 |
| 画布外 HEALTH SCENARIOS 八个开关 | 未连接/已连接/部分授权(未授权项显示 Not shared 而不是 0)/今日无数据(四项都显示 No entries today)/数据过时/已撤销/不可用/刷新失败 |
| Data wallet:导出 | 准备中 → 文件 + 时间 + 下载/分享;画布外可切「Export fails」看失败态 |
| 删除产品数据 | 两步确认,任一步可取消;结果页写明「不等于注销登录,你仍处于登录状态」 |
| Sign out | 清理演示会话,并写明已确认的餐食仍然保留 |
| 画布外「DEMO DATE」日期控制 | |
| 进行中的计划 → 画布外 +1 day 点四次(越过 15 日截止) | 自动变 PLAN REVIEW · READ ONLY · REACHED ITS END DATE,七天的操作按钮全部消失,不能再补记 |
| 先清空 Fridge、目标改 2200–2450,再新建计划 | 逐日文案用创建时快照:写「Fridge 当时是空的,自己挑食材」「无法据此指定具体食材」,理由里出现 2,200–2,450;有库存时点名实际物品(Greek yogurt / Rye bread) |
| 对未来某天点 Replace | 换成具体可执行的替代行动(含详情与理由),不是占位文字 |
| 暂停后 Resume 预览 | 「保持原日」里同时列出已完成/已跳过和暂停日之前仍待做的项;待做项从明天连续排,第一个就落在重启日 |
| 第六批修正 | |
开始日填 2026-02-30 / 2026-04-31 | 报「That date does not exist」并置灰(原来被 JS 归一化后照样能建) |
| 开始日填过去日期 | 报「A new plan cannot start before today」 |
| 建计划时选 America/New_York → 暂停 → Resume | 恢复文案显示 America/New_York,不再回落上海 |
| 恢复后同一天有两条行动 | 「有记录天数」按餐食日期去重,不按行动行数 |
| Data wallet 两步删除完成后 | 餐食/库存/计划/运动真的清空,Home/Log/Plan/Me 同步空态;登录保留 |
| 导出 → Download / Share | 下载真实 JSON(仅本演示数据),Share 走系统分享、不可用时回退下载;时间是本次导出时间 |
| 部分授权 → Refresh | 不再变成全授权,未共享项仍是 Not shared;无数据状态刷新后仍是 No entries today |
Add food 填 2abc / Infinity / 0 | 各自报错且无法添加;目录外的食物不再凭空得到 90 kcal,标为能量未知且吃不进记录 |
| 运动历史 → Edit this session;重复点保存 | 可编辑;重复保存不再抛错也不重复新增 |
| 留着 ¾ 草稿和收据快照 → Sign out → Sign back in | 草稿全清、回到采集选择页;已确认的餐食仍在 |
| Fridge 记的餐 → Log 里点 Edit | 不再进空白复核页,改为详情页说明「这餐来自 Fridge,没有逐项复核可重开」并留返回入口 |
| 第七批修正 | |
| 复核里只保留气泡水 | 营养全部 0g,不再凭空得到 22g 蛋白;营养由保留项 × 份量 × 数量算出 |
| 主菜改半份 / 输入 200 g(基准 400 g) | kcal 与营养同步减半;首页、弹层、日报、详情读同一份计算 |
| 画布外 DEMO DATE 调到 8/13 | 首页 0–0 且营养空态;调到 8/11 显示当天两条历史餐的合计 |
| Log 「See earlier records (2)」 | 展开出真实的历史日期分组,每条可点进详情;删除后不会再冒出固定旧记录 |
| 计划 9–15 日,8/11 与 8/12 各有餐 | 「有记录天数」= 2,按餐食日期落在起止区间去重,不看当天有没有排行动 |
| 保存失败 → 恢复 Normal → 点「Retry the same save」 | 重试本身就完成保存,不用再按确认;期间确认按钮禁用并显示保存中 |
| 版本冲突 → 「Re-check against the saved version」 | 同时列出已存版本与你的草稿两个区间,二选一,草稿不丢 |
| 删除产品数据(目标编辑器开着、有下一餐打算、有运动草稿) | 草稿全清(goalDraft/planIntent/exDraft),已存列表清空,登录保留;采集代次 +1 让迟到操作失效 |
| Share | 分享同一个 JSON 文件;平台不支持则说明并指向 Download;取消就是取消,不会自动改成下载 |
| 复核页「Replace with another catalogue item」/「+ 目录餐」 | 可替换/新增真实目录条目(含 kcal 区间),总计随之变化 |
| 画布外 Unfinished draft / Photo no longer available / Saved but refresh failed | 草稿可恢复或重来;照片失效可重选;已保存但刷新失败明说「已保存,不要再存一次」 |
| Sign out → 模拟登录错误 → 重试 → 登录 | 加载态、错误态、重试入口齐全,已存餐食不受影响 |
| 第八批修正 | |
| 输入 200 g(基准 400 g)/替换成 Lentil soup | 营养随之重算:蛋白 25→14(克数)→17(替换成扁豆),不再沿用原菜营养 |
| Log 编辑旧餐改 0.5× 保存 | 营养同步减半(24→12g 蛋白 …),首页摘要跟着变;不再保留旧值也不会变成 Not provided |
| 离线时对计划做 完成/跳过/替换/结束 | 四个都被拦下并说明「没有改动」;恢复 Normal 后同样操作通过 |
| 重试进行中执行 删除产品数据 / 登出 | 挂起的回调作废,不会把已删数据写回;连点三次重试也只产生一条 |
| 结果未知状态点「Discard the draft」 | 回到采集选择页,之后也不会有迟到写入 |
| 第九批修正 | |
| 输入 200 g 后再点 1× / 0.5× | 克数与份量是同一数量的两种输入,一律从基准重算:1× 回到 495–600,0.5× 是基准的一半,不叠乘 |
| 克数填了但没点 Use,或填了非法值 | 确认被拦下并说明「不会被悄悄忽略」 |
| 只留气泡水 + 一杯燕麦拿铁 | 纤维/铁显示 Not provided(拿铁没公布),不会被水的已知 0 盖掉 |
| Fridge 吃 2 片黑麦面包 | 营养按该食物的单位营养 × 数量算(蛋白 6g、碳水 30g),不再是所有食物同一组数 |
| 油 / 酱 | 带自己的营养(油 10g 脂肪、酱 1/4/4),不只是加热量 |
| 离线时 Fridge 添加/吃了/移除 | 三个入口都被拦下,库存和当天记录不变,选择保留 |
| 离线时保存运动 | 失败提示就在运动表单里,输入保留 |
| 保存失败后把主菜改半份,再点「Retry the same save」 | 存下的是原始那次请求(495–605),不是改过的草稿 |
| 重试前先取消编辑、再打开 SALMON | SALMON 保持 1,080–1,220;只取消不切换也不会新增一餐——待保存绑定了会话与目标餐,离开即作废 |
| 照片保存未知(预留 meal-4)→ 从 Fridge 吃一片面包 → 回来重试 | 面包拿到 meal-5,照片重试落在 meal-4,ID 不再撞车 |
| 结束计划失败 → 恢复 → 结束旧计划 → 新建 11 天 | 旧错误条已消失,不会把新计划结束(待处理操作绑定了 plan.id 与会话) |
| 运动保存失败 → 放弃 → 另填 Run 40 → 保存 | 只存下 Run 40;旧的 Walk 待处理操作在放弃时就作废 |
| Plan 失败时切到 Me | Me 的运动区不会出现 Plan 的错误条(每个错误只在自己的界面) |
| 待处理操作的目标已不存在时点重试 | 不执行,改为说明「这条待处理的修改所指的对象已不存在,什么都没有改动」 |
| 运动预览页 | 新增「放弃这次记录」;「Edit」保留已填内容(之前会重置回 Walk 30) |
| 版本冲突下点重试 | 不再空转:冲突只给「重读现状」,重读后才出现「仍然应用我的修改」,也可「放弃我的修改」;离线/结果未知仍是直接重试 |
| 单独触发 Fridge 失败 | 三种模式的说明都能显示(之前挂在 planBlocked 上,Fridge 路径不设它,于是一句都不出) |
| Plan/Fridge/运动失败后 | 三种模式各自文案(离线=没发出去/结果未知=不能断言未写入/版本冲突=别处改过),并提供「重试这次操作」;恢复后重试只执行一次 |
| Fridge 添加失败 → 返回 | 回到表单且 Banana / 2 仍在,不再被清空 |
| 输入 200 g 后 | 份量档不再同时显示选中;切回 1× 时 note 与克数输入一起清除 |
| 保存失败时的餐 ID | 第一次尝试就预留(如 meal-5),重试写入的就是这一条;连点三次重试仍只有一条、ID 唯一;重试途中删除数据不留下悬空预留 |
| 画布外「Saved but refresh failed」→ 正常确认一餐 | 餐真的写进了 Log,横幅说明已保存并给「再读一次结果 / 打开 Log」 |
| Plan 逐日行动 | 点名具体目录餐及区间(如 Cook Chicken and rice bowl 520–600 kcal),Replace 也用同一目录。理由按「一顿主餐的份额」比对,不再拿单餐去比全天区间:1,500–1,800 的目标写「约 600 kcal」,2,200–2,450 写「约 817 kcal」 |
| 320 / 390 / 480 宽度 (此结论已被下面的「320px 窄屏适配」一节取代) | 当时的结论是「320 横滚有意为之」。现在已改成布局回流,320 不再横滚——以下面那一节为准。 |
| prefers-reduced-motion | 扫描动画等全部停止 |
| 打开 Log 行详情再返回 | 焦点进入浮层,关闭后回到打开它的那一行 |
| 画布外 DATA & SAVE 开关 | No records yet/Refresh failed/Offline/Save fails/Version conflict 五种;营养缺失显示 Not provided 而不是 0,并标出「N of M meals did not publish this」+ 来源与更新时间 |
| 第十批修正 — 失败恢复层 | |
| 这一组回应「恢复操作要绑定自己的对象、内容和版本,成功或放弃后清理,再补冲突与结果未知的实际恢复」。 订正:这一批交付时我写「三个界面各自持有自己的待处理失败」,当时并不成立——Plan 与运动共用一个槽,只是显示上分开了。第十一批才真正分开,见下一节。 | |
| 7 天计划「结束」离线失败 → 恢复 Normal → 正常结束旧计划 | 错误条当场消失(成功写入会消费掉同一界面的待处理失败);再建 11 天新计划时已经没有旧 Retry 可点。若用探针把旧操作塞回去再点重试,得到的是「所指对象已不存在,什么都没有改动」,新计划保持 active |
| Walk 30 保存失败 → 不取消,直接把表单改成 Run 40 → 点旧的重试 | 存下的是 Walk 30(待处理操作带着自己那份草稿快照),不是表单里的 Run 40 |
| 创建 7 天计划「结果未知」→ 把草稿改成 11 天 → 重试 | 创建的是 7 天,重试内容已固定 |
| 运动保存失败 → 删除产品数据 / 登出 | 待处理操作一并清空(Plan、运动、Fridge 三处都清) |
| Fridge 添加失败(三种模式各试一次) | 三段说明都能显示且各自正确;切回 Normal 后文案不变 —— 失败的性质属于那一次尝试,不随当前网络倒改 |
| Plan 暂停失败后切到 Me | 运动区与 Fridge 区都不出现 Plan 的错误条 |
| 结果未知 → 「查一下是否已生效」 | 不再只是叫你小心:真去比对当前数据,给出「确实生效了 —— 再发一次会重复」或「从未到达 —— 再发一次是安全的」,后者才给「再发一次」。Plan / 运动 / Fridge 三处都有 |
| 版本冲突 → 「重读现状」 | 重读会真的载入另一版本:Plan 里那天变成别处标的 Skipped、Fridge 里酸奶从 3 变 2 cups、运动列表多出别处记的 Cycle 25。面板并列写出「最新: …」与「你的,尚未应用: …」,然后三选一:保留最新 / 在其之上应用我的 / 放弃我的 |
| 冲突时选「在其之上应用我的」 | 只执行一次:那天从 Skipped 变 Done、Eggs 加进库存而酸奶保持别处改的 2 cups、Walk 30 与 Cycle 25 并存 |
| 创建计划遇到版本冲突 | 重读后写明「别处已经开了一个 7 天计划,同时只能跑一个」,不再给无法生效的「应用我的」按钮,只留保留最新 / 放弃 |
| Fridge 失败面板 | 「Back to what I entered」只在添加时出现(那才有表单可回);另有明确的「Drop my change」,吃了/移除失败后离开即作废,不留悬空的待处理操作 |
| 第十一批修正 — 待处理槽与尝试身份 | |
| 回应第十批复核的四节。第 2、3 节(Fridge 重试不用快照、成功后未清理导致旧重读覆盖新状态)在报告送达前已改完;第 1、4 节按 @打包的 建议的「稳定尝试 ID + 模拟结果记录」重做。 | |
| 暂停计划离线失败 → 到 Me → 运动保存也失败 → 取消运动 → 回 Plan | Plan 的错误条还在,暂停操作没有被丢掉;恢复 Normal 点重试,计划正常变 paused。Plan 与运动现在是两个独立的槽,各自取消、清理、查询 |
| 库存已有 3 杯酸奶,再添加 1 杯遇「结果未知」→ 查询 | 回「从未到达」(之前误判为已生效)。查询问的是这一次尝试的 ID,不再看有没有同名食物 |
| 已有一条 Walk 30,第二条 Walk 30 失败 → 查询 | 回「从未到达」;同理,计划里那天本来就是 done 时也不会被认作本次生效 |
| 画布外新开关「Unknown · reply lost」下失败 → 查询 | 回「确实到了,只是回音丢了,本机还没跟上」,按钮是「把这次结果取回」而不是重发;取回只补这一条,期间做的其他修改都保留 |
| 结果未知 → 断网后再查询 | 回「还是判断不了:你离线,查不到这次尝试」,给「再查一次」;不假装给答案,也没有重复发送 |
| 重试后仍然失败 | 沿用同一个尝试 ID,不会每次重试都变成一次新尝试 |
| 成功写入消费待处理失败的范围 | 只消费同一个操作:标记今天完成不会吃掉「跳过明天」那条待处理的;真正结束计划才会消费待处理的「结束计划」。 第十批我用的是「同一界面任何成功写入都消费」,那会连带丢掉无关的待处理操作。 |
| 计划暂停后,那条待处理的「某天完成」 | 面板自动隐藏——计划已不是 active,那个操作无法执行,与其留一个按了没反应的按钮,不如不显示 |
| 每个错误面板顶部 | 都写明这条待处理的操作是什么(HELD CHANGE · Skip that day. / HELD SESSION · Save Walk · 30 min · Moderate.),说明、原操作、查询结果在同一屏内可见 |
| Walk 30「回音丢失」→ 把表单改成 Run 40 → 点「取回这次结果」 | 存下的是 Walk 30(这次尝试自己的内容),表单里的 Run 40 也还在,没有被顺手清掉。7 天计划同理:草稿改成 11 天后取回,建的是 7 天,向导里的 11 天草稿保留 恢复快照原来只写在「重试」这一条路径上,「取回」没有,于是取回走了当前表单。现在移进 runHeld,两条路径共用。 |
| 创建计划遇冲突 → 点「重读现状」 | 面板继续显示:比较仍在,写明「没有可以叠加的东西」,只留保留最新 / 放弃我的;消失的只有那个本来就无法生效的「再次创建」 之前整块面板挂在「这个操作还能不能再执行」上,重读把另一台设备的计划载入后,条件立刻变假,比较和取舍入口一起没了。 |
| 原选择是「半杯酸奶 + 1 片面包」,期间酸奶被别处移除 → 重试 | 不记录,提示这条待处理的修改和货架对不上、什么都没改 之前只在「当前还在的库存」里查数量是否够,整件消失的那项不在遍历范围内,于是悄悄确认了一顿只剩面包的饭。 |
| @colin-pie 抽查的两处 | |
| 首页品牌圈里的「黑球」 | 是星巴克(麦当劳上面那个)。第一次只缩小提亮没解决——它的 logo 是一个实心圆盘,灰度之后依然是深色圆盘。现在改用只取美人鱼图形、去掉圆盘底的派生资源(assets/starbucks-mark.svg),和旁边三个一样是浅底上的图形标;四个圈的分量也一并调匀了 |
| Me 里 None / 0.5 cups 份量按钮 | 原来只有 min-height: 48px、没有垂直居中,文字贴着上沿,加上盒子接近正方形,短标签就成了圆球。现在固定 48px 高、min-width: 84px、内容居中,是一排等高的胶囊;「Remove from Fridge」的间距也收紧了。点击区仍是 48px |
| 桌面端评审控制台 | 窗口 ≥1040px 时侧放:手机稿在左、控制台在右,顶部对齐、sticky 跟随滚动,页面总高从约 1,900px 降到约 1,040px。窄窗口保持原来的上下堆叠。「后续方案区」那行说明并入右栏,避免 1440px 下三栏溢出 |
| 库存变动导致重试被拒时 | 提示里保留「你原来选的」只读摘要(0.5 cups Greek yogurt + 1 slice Rye bread),说明是哪一项对不上,并给「只选还在的」和「重来」;「只选还在的」只把仍在货架上的份量选回来,不替你确认,仍要自己按「I ate this」 |
| Fridge 失败条的存活 | 它原来挂在 fridgeStep 上,所以打开任何别的 Fridge 步骤(比如去移除一件库存)就把它藏了,回不去那条待处理操作。现在跟 Plan/运动一样跟着自己的槽走。同时,Fridge 的成功写入也改成只消费同一个操作——移除一件库存不再顺手清掉一条待处理的「我吃了」 |
| 有一条待处理的「我吃了」→ 打开某件库存的移除对话框 → 取消 | 原失败条仍在。取消只取消当前这一步;只有取消它自己那一步(吃了预览/添加表单/移除对话框本身)才退休对应的待处理操作 |
| 添加 1 根香蕉「回音丢失」→ 改填 2 根并保存 | 1 根那次仍然待处理,可以继续查询(结果是「确实到了」)。同名同量才算同一次操作;换成 Eggs 或换数量都不算 |
| 离线移除酸奶失败 → 打开面包的移除对话框 → 取消 | 酸奶那条仍在。取消现在同时核对目标身份,不只是操作类型:remove 比 fridgeTargetId、add 比名称+数量、eat 比整份选择上一版只比类型,所以同类型不同目标会被误清。 |
| 320px 窄屏适配(原清单最后一项) | |
| 做法:布局回流,不缩放。所有控件尺寸、字号中只有首页那一处展示型大字随宽度降档;点击区一律保持 48px。≥390px 的稿子逐像素不变。 | |
| 窗口 320px | 页面不再横向滚动。手机壳从固定 390px 改为随窗口收窄(≤419px 生效),五个页面都在壳内回流 |
| 首页右上角的品牌簇(黄色色块+四个圈) | 原来是按 390 手工摆的绝对定位。改成 left: calc(100% - Npx),在 390 上取值与原稿完全相同,窄于 390 时整簇随右边缘一起移动,内部构图不变 |
| 首页大数字与品牌簇相撞(320 下确实会撞) | ≤389px 时展示字号降档(54→40px,「kcal eaten」26→21px),品牌簇整体上提;实测四个矩形不再相交,「KCAL TO RANGE」也不再压住下一行 |
| Me 的份量按钮在 320 下 | 换行成两排,每颗仍是 48px 高——这就是「回流不缩小」的意思 |
| 底部五栏 | 顺带修掉一个一直存在的问题:标签的点击区原来只有 20px 高(handler 挂在文字上,父容器 52px 但不可点)。现在每个标签自己 min-height/min-width: 48px,栏高 74→78px |
| 四档宽度实测(320 / 360 / 390 / 480 × 五个页面 = 20 组):横向溢出全部为 0;壳内没有任何元素越界;最小可交互尺寸四档全部正好 48px;滚到底时没有任何控件被底栏遮挡(Scan 那颗凸起的相机键本就跨在栏上,属设计)。脚本:width-audit.js,结果文件:width-audit-results.md | |
| 关键长页的实际滚动可达性 | 把滚动容器从头扫到尾,扫不到的再补一次 scrollIntoView(人就是这么做的)。每个控件只有在完整落在壳内且完全避开底栏、并且 elementFromPoint 命中它自己或它的子元素时才算通过——命中祖先容器不算,那说明上面盖着别的东西;整个落在底栏下方的按钮永远拿不到通过。覆盖 11 个状态:五个页面 + 餐食逐项复核(未解决/全部解决)+ 收据采集 + 收据联合核对到最终确认 + 计划恢复预览 + Me 确认。四档宽度无一失败。 五个主操作点击后断言的是指名的结果而不是「文字变了」:餐真的存进去(`saved:false→true`)、计划真的从 paused 变 active、酸奶真的从 3 扣到 2.5;故意禁用的那个确认按钮则断言什么都没变。 |
按流程顺序。手机壳是 390×844,长页面在壳内滚动,所以截图只到可视区。

























































