Review changes batch 6 of 6

This commit is contained in:
2026-07-20 06:52:33 +08:00
parent db97d3da27
commit 5a31a75da0
160 changed files with 9206 additions and 572 deletions
@@ -0,0 +1,143 @@
# G01 次要文字可读性优化实施计划
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 提高 G01“加入申请”卡片说明与状态文字在浅色山水背景上的可读性,同时保持原有信息层级、卡片尺寸和滚动结构。
**Architecture:** 样式所有权继续留在 `pages/genealogy/g01-my-genealogies.vue`,不修改共享 `GenealogyCard.vue`。静态视觉契约锁定四类文字的字号、颜色和字重;现有 G01 运行 smoke 与五档截图验证没有重叠、裁切和滚动回归。
**Tech Stack:** uni-app、Vue 3、SCSS、PowerShell 静态契约、Node.js Chrome DevTools Protocol 运行 smoke。
## Global Constraints
- 只修改 G01 申请卡片说明与状态样式,不修改共享家谱卡、28% 公共背景或其他页面。
- 申请说明固定为 `28rpx / 500 / #62584c / 1.4`;状态固定为 `27rpx / 600`,审核中 `#7f4f16`,被拒绝 `#a7160c`,已退出 `#62584c`
- 卡片高度、内边距、相邻 `12rpx` 间距、箭头、文案和点击行为保持不变。
- H5 证据不等于 Android/HBuilderX 已通过,也不等于 G01 整页已验收。
- 不使用多代理或 worktree,不执行 `git add``commit``push``reset``checkout`
---
### Task 1: 用视觉契约锁定可读性样式
**Files:**
- Modify: `tests/g01-visual-contract.ps1`
- Test: `tests/g01-visual-contract.ps1`
**Interfaces:**
- Consumes: G01 的 `.application-record__copy``.application-record__status` 及两个状态修饰类。
- Produces: 已确认字号、颜色、行高和字重的静态合同。
- [ ] **Step 1: 写入失败断言**
在申请卡片间距断言之后加入:
```powershell
if ($page -notmatch '(?s)\.application-record__copy\s*\{[^}]*color:\s*#62584c;[^}]*font-size:\s*28rpx;[^}]*font-weight:\s*500;[^}]*line-height:\s*1\.4;') { throw 'G-01 application descriptions do not use the approved readable style.' }
if ($page -notmatch '(?s)\.application-record__status\s*\{[^}]*color:\s*#7f4f16;[^}]*font-size:\s*27rpx;[^}]*font-weight:\s*600;') { throw 'G-01 application statuses do not use the approved readable base style.' }
if ($page -notmatch '(?s)\.application-record__status--rejected\s*\{[^}]*color:\s*#a7160c;') { throw 'G-01 rejected status must preserve the approved semantic red.' }
if ($page -notmatch '(?s)\.application-record__status--muted\s*\{[^}]*color:\s*#62584c;') { throw 'G-01 muted status does not use the approved readable color.' }
```
- [ ] **Step 2: 运行契约并确认 RED**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1
```
Expected: FAIL,错误包含 `application descriptions do not use the approved readable style`
---
### Task 2: 实施最小样式修改
**Files:**
- Modify: `pages/genealogy/g01-my-genealogies.vue`
- Test: `tests/g01-visual-contract.ps1`
**Interfaces:**
- Consumes: Task 1 的四组视觉契约。
- Produces: 仅 G01 申请卡片生效的增强可读性样式。
- [ ] **Step 1: 替换申请文字样式**
```scss
.application-record__status {
flex: 0 0 auto;
margin-left: 16rpx;
color: #7f4f16;
font-size: 27rpx;
font-weight: 600;
}
.application-record__status--rejected { color: #a7160c; }
.application-record__status--muted { color: #62584c; }
.application-record__copy {
display: block;
margin-top: 10rpx;
color: #62584c;
font-size: 28rpx;
font-weight: 500;
line-height: 1.4;
}
```
- [ ] **Step 2: 运行契约并确认 GREEN**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1
```
Expected: `PASS G-01 visual contract`
- [ ] **Step 3: 证明契约可捕获回归**
临时把说明字号恢复为首轮 `26rpx`,运行契约确认失败;随后恢复 `28rpx` 并再次确认通过。临时变化不得保留。
---
### Task 3: 运行、截图和状态更新
**Files:**
- Modify: `docs/交接记录.md`
- Modify: `docs/验收规划.md`
- Modify: `design-qa.md`
- Evidence: `docs/design/screens/runtime/2026-07-16/g01-text-legibility-audit/`
**Interfaces:**
- Consumes: Task 2 已通过静态契约的 G01 页面。
- Produces: 五档响应式证据、修改前后 412×915 对比和准确的交接状态。
- [ ] **Step 1: 运行 G01 静态与运行回归**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-empty-state-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1
node tests/g01-empty-state-runtime-smoke.js http://localhost:5173
```
Expected: 三组均输出 `PASS`
- [ ] **Step 2: 生成五档截图并检查布局**
覆盖 `320×568``360×640``360×800``412×915``412×1000`;确认长说明不与状态或箭头重叠,卡片高度和 12rpx 间距不变,底栏与独立滚动正常。
- [ ] **Step 3: 更新状态文档**
写明用户确认并实施 G01 申请次要文字增强;H5 只形成内部候选,Android/HBuilderX 与 G01 整页验收仍未完成。
- [ ] **Step 4: 最终检查**
Run:
```powershell
git diff --check
git status --short
```
Expected: `git diff --check` 退出码为 0;不覆盖、删除或清理任何已有工作区内容。
@@ -0,0 +1,144 @@
# G 模块公共背景 28% 透明度实施计划
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 让 9 个活动 G 页面通过共享背景组件统一使用 28% 不透明度的连续长背景画层,同时保持宣纸底色、内容层和现有布局不变。
**Architecture:** `components/GenealogyPageBackground.vue` 继续作为背景显示规则的唯一所有者,只在图片画层增加 `opacity: 0.28``tests/genealogy-shared-background-contract.ps1` 锁定该值及单一所有权,页面级运行 smoke 和截图负责验证布局与可读性没有回归。
**Tech Stack:** uni-app、Vue 3、SCSS/CSS、PowerShell 契约测试、Node.js Chrome DevTools Protocol 运行 smoke。
## Global Constraints
- 只修改共享背景图片画层,不修改背景 PNG、母版、裁切、贴底方式或页面滚动结构。
- G01、G03、G05、G06、G08、G09、G10、G11、G12 统一生效;各页面不得重复定义透明度。
- H5 截图仅作为内部候选;Android/HBuilderX 真机或模拟器仍待复核。
- 不使用多代理、worktree,不执行 `git add``commit``push``reset``checkout`
- 保留所有已有修改、未跟踪文件、测试、文档和证据。
---
### Task 1: 用共享背景契约锁定 28% 不透明度
**Files:**
- Modify: `tests/genealogy-shared-background-contract.ps1`
- Test: `tests/genealogy-shared-background-contract.ps1`
**Interfaces:**
- Consumes: `.genealogy-page-background__art` 作为共享长背景图片画层。
- Produces: 背景透明度唯一值 `opacity: 0.28` 的仓库契约。
- [ ] **Step 1: 写入会失败的透明度与单一所有权断言**
在组件画层断言之后加入:
```powershell
Assert-Contract ($componentSource -match '(?s)\.genealogy-page-background__art\s*\{[^}]*opacity:\s*0\.28;') 'shared artwork must use the approved 28% opacity'
```
在每个 G 页面循环中加入:
```powershell
Assert-Contract ($pageSource -notmatch '(?s)\.genealogy-page-background__art\s*\{[^}]*opacity:') "$route must not override the shared background opacity"
```
- [ ] **Step 2: 运行契约并确认按预期失败**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/genealogy-shared-background-contract.ps1
```
Expected: FAIL,错误包含 `shared artwork must use the approved 28% opacity`
---
### Task 2: 在共享组件实现 28% 画层不透明度
**Files:**
- Modify: `components/GenealogyPageBackground.vue`
- Test: `tests/genealogy-shared-background-contract.ps1`
**Interfaces:**
- Consumes: Task 1 的 `opacity: 0.28` 契约。
- Produces: 9 个活动 G 页面共用的淡化背景,无页面级覆盖。
- [ ] **Step 1: 最小修改共享画层样式**
将画层规则改为:
```css
.genealogy-page-background__art {
position: absolute;
bottom: 0;
right: 0;
left: 0;
display: block;
width: 100%;
opacity: 0.28;
}
```
- [ ] **Step 2: 运行契约并确认通过**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/genealogy-shared-background-contract.ps1
```
Expected: `PASS G genealogy shared background contract`
- [ ] **Step 3: 证明契约能捕获回归**
临时把 `opacity: 0.28` 改回无透明度,运行同一契约并确认失败;随后恢复 `opacity: 0.28`,再次运行并确认通过。临时变化不得保留。
---
### Task 3: 运行回归、截图并更新内部状态
**Files:**
- Modify: `docs/交接记录.md`
- Modify: `docs/验收规划.md`
- Modify: `docs/design/G01_列表背景候选与换机重建.md`
- Modify: `design-qa.md`
- Evidence: `docs/design/screens/runtime/2026-07-16/`
**Interfaces:**
- Consumes: Task 2 已通过契约的共享组件。
- Produces: 五档 G01 H5 内部候选证据、其余 G 页面运行回归结果,以及不夸大验收层级的交接记录。
- [ ] **Step 1: 顺序运行 G 页面 smoke,避免调试端口竞争**
Run:
```powershell
node tests/g01-empty-state-runtime-smoke.js http://localhost:5173
node tests/g03-create-flow-runtime-smoke.js http://localhost:5173
node tests/g05-overview-runtime-smoke.js http://localhost:5173
node tests/g06-search-flow-runtime-smoke.js http://localhost:5173
node tests/g08-g10-application-flow-runtime-smoke.js http://localhost:5173
node tests/g11-g12-settings-poems-runtime-smoke.js http://localhost:5173
```
Expected: 六组脚本全部输出 `PASS`,无浏览器异常或 `console.error`
- [ ] **Step 2: 生成并检查 G01 五档截图**
尺寸为 `320×568``360×640``360×800``412×915``412×1000`。截图必须确认:背景比原候选明显变淡;标题、卡片、文字、按钮和底栏未同步变淡;左右不裁剪;内部列表滚动后底栏仍固定。
- [ ] **Step 3: 更新权威状态文档**
文档统一写明:用户确认共享背景画层为 28% 不透明度;当前只有 H5 内部候选证据;G01 及其余 G 页面没有因此获得整页验收;Android/HBuilderX 与 4GB Android 长图性能仍待复核。
- [ ] **Step 4: 最终一致性检查**
Run:
```powershell
git diff --check
git status --short
```
Expected: `git diff --check` 退出码为 0;只报告已有换行符提示,不覆盖或清理工作区中的任何既有修改。
@@ -0,0 +1,83 @@
# G 类型页面 C 背景贴底自适应 Implementation Plan
> **For agentic workers:** 本计划由当前主代理在同一会话内执行;用户明确禁止多代理、worktree、git add、commit、push、reset 和 checkout。
**Goal:** 让现有 C 背景保持完整比例并贴底显示,把山水视觉集中到 G 页面下半区,减少加入申请区域的大块纯色空白。
**Architecture:** 保持 `GenealogyPageBackground.vue` 为 9 个 G 页面的唯一背景入口,不增加图片资产。只把现有图片从 `top: 0` 改为 `bottom: 0`,继续使用 `widthFix` 和满屏宣纸底色。
**Tech Stack:** uni-app、Vue 单文件组件、CSS、PowerShell 契约测试、Chrome CDP 截图。
## Global Constraints
- 只使用现有 `genealogy-page-background.png`,不生成或重做图片。
- 背景完整显示、左右不裁剪、不拉伸。
- 9 个活动 G 页面继续共用一个公共组件。
- 不改变 G01 内容、卡片、交互、路由或固定区/滚动区结构。
- 不使用多代理或 worktree,不执行任何 Git 写操作。
---
### Task 1: 背景贴底契约与最小实现
**Files:**
- Modify: `tests/genealogy-shared-background-contract.ps1`
- Modify: `components/GenealogyPageBackground.vue`
**Interfaces:**
- Consumes: 现有公共背景组件和 C 运行资产。
- Produces: `bottom: 0`、全宽、`widthFix` 的固定背景图层。
- [ ] **Step 1: 写失败契约**
在公共背景契约中要求 `.genealogy-page-background__art` 包含 `bottom: 0`,并禁止 `top: 0`
- [ ] **Step 2: 运行契约确认失败**
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/genealogy-shared-background-contract.ps1`
Expected: 因当前组件仍使用 `top: 0` 而失败。
- [ ] **Step 3: 最小修改公共组件**
将图片定位从 `top: 0` 改为 `bottom: 0`,不修改资产、宽度、模式、层级或 9 个页面。
- [ ] **Step 4: 运行契约确认通过**
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/genealogy-shared-background-contract.ps1`
Expected: `PASS G genealogy shared background contract`
### Task 2: 运行截图与回归
**Files:**
- Modify: `design-qa.md`
- Modify: `docs/交接记录.md`
- Modify: `docs/验收规划.md`
- Runtime evidence: `docs/design/screens/runtime/2026-07-16/`
**Interfaces:**
- Consumes: 贴底公共背景组件。
- Produces: 四档 G01 H5 内部候选截图和未验收状态记录。
- [ ] **Step 1: 四档真实截图**
在 320×568、360×640、360×800、412×915 下截取 G01,确认完整画面贴底、上方宣纸区被主要内容覆盖、下方申请区域不再大块空白。
- [ ] **Step 2: 源图与实现同轮对照**
同一比较输入内打开 C 源图与 412×915 实现截图,确认无裁剪、无拉伸、无横向溢出和文字对比度问题。
- [ ] **Step 3: 回归验证**
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/genealogy-shared-background-contract.ps1`
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1`
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/full-page-visual-contract.ps1`
Run: G01、G03、G05、G06、G08-G10、G11-G12 现有运行 smoke。
Run: `git diff --check`
Expected: 所有命令退出码为 0;仍明确缺少 Android/HBuilderX 真机或模拟器复核。
@@ -0,0 +1,70 @@
# G 模块旗舰级连续长背景候选 Implementation Plan
> **For agentic workers:** 当前主代理内联执行;用户明确禁止多代理、worktree、git add、commit、push、reset 和 checkout。
**Goal:** 基于现有 C 方向生成连续长背景候选;用户确认后,将其固化为 1536×3840 母版、生成 1440×3600 运行图并接入共享组件。
**Architecture:** 使用内置 ImageGen 编辑现有 C 母版,生成完整不透明长图。候选先存入 `design-pipeline/generated/g01-background/`;用户确认后保留原稿,以锁定 Pillow/Lanczos 归一化母版并生成版本化运行图,由 `GenealogyPageBackground.vue` 单一接入。
**Tech Stack:** Built-in ImageGen、Pillow 12.3.0、现有 G01 资产流水线。
## Global Constraints
- 候选确认前不替换运行资产或页面引用;用户确认后只切换共享组件,不改 9 个页面业务结构。
- 目标母版 1536×3840,运行方向 1440×3600。
- 无文字、Logo、UI、卡片、红色、接缝和重复图案。
- 不删除、覆盖或清理现有母版、候选、截图和未跟踪文件。
---
### Task 1: 生成长图候选
**Files:**
- Read: `docs/design/assets/g01-background/masters/g01-list-background-direction-c-paper-master.png`
- Create: `design-pipeline/generated/g01-background/genealogy-page-background-long-flagship-candidate.png`
**Interfaces:**
- Consumes: C 母版的宣纸色、竹影、水墨山水、亭台和中央低对比构图。
- Produces: 一张未接入页面的长图候选 PNG。
- [x] **Step 1: 查看 C 母版并作为 ImageGen 编辑目标**
确认输入图无文字、无 UI,保持其暖宣纸和灰金水墨语言。
- [x] **Step 2: 使用内置 ImageGen 生成 2.5:1 候选**
提示中明确 2.5:1 连续纵向构图、顶部安全留白、中部低对比、下部山水、无接缝和禁止元素。
- [x] **Step 3: 将生成结果复制到被忽略的候选路径**
不覆盖现有 A/B/C 母版或 `genealogy-page-background.png`
### Task 2: 候选验证与展示
**Files:**
- Inspect: `design-pipeline/generated/g01-background/genealogy-page-background-long-flagship-candidate.png`
**Interfaces:**
- Consumes: ImageGen 候选。
- Produces: 实际尺寸、文件字节数、SHA-256 和视觉检查结果。
- [x] **Step 1: 用 Pillow 检查尺寸、模式和边缘连续性**
确认不透明 RGB/RGBA、实际像素尺寸及没有异常透明边。
- [x] **Step 2: 打开候选检查视觉**
检查文字/Logo 污染、明显横向色带、重复竹枝、中央过密和亭台位置。
- [x] **Step 3: 向用户展示候选**
只报告候选事实,不宣称已接入、已验收或已完成 Android 验证。
### Task 3: 用户确认后的正式接入
- [x] 保留 793×1983 ImageGen 原稿,并生成 1536×3840 sRGB 归一化母版。
- [x] 先新增失败契约,再扩展 manifest、Python 构建器和 Node 包装器为四候选。
- [x] 生成 1440×3600 版本化运行图,更新共享背景组件;旧 C 文件不覆盖、不删除。
- [x] 完成 G01 五档 H5 截图、G 页面运行 smoke、Python/Node/PowerShell 契约和内部设计 QA。
- [ ] Android/HBuilderX 与 4GB Android 图片解码、切页、回收复核。
- [ ] G01 固定区/独立滚动结构继续与用户讨论,不在本次背景接入中擅自实施。
@@ -0,0 +1,154 @@
# G 类型页面共用 C 背景 Implementation Plan
> **For agentic workers:** 本计划由当前主代理在同一会话内执行;用户明确禁止多代理、worktree、git add、commit、push、reset 和 checkout。
**Goal:** 让 9 个活动 G 页面通过一个公共组件完整显示 C 背景,左右不裁剪、不变形,并用宣纸底色延展剩余页面。
**Architecture:** `components/GenealogyPageBackground.vue` 是背景资产路径和显示规则的唯一所有者。各 G 页面移除旧背景图片与私有背景样式,只保留一个公共组件实例;测试从 `pages.json` 推导路由,防止页面清单漂移。
**Tech Stack:** uni-app、Vue 单文件组件、SCSS、PowerShell 契约测试、Node.js 运行冒烟测试。
## Global Constraints
- 仅修改 G 类型页面背景层,不改变页面内容、结构、交互和接口。
- C 背景按宽度等比显示,顶部对齐,左右不裁剪、不变形。
- 高屏和长页面未覆盖区域使用同色宣纸底色延展。
- 不实施 G01 固定区/列表独立滚动。
- 不使用多代理或 worktree,不执行任何 Git 写操作。
- H5 截图仅作为内部候选,不能替代 Android/HBuilderX 复核。
---
### Task 1: 建立公共背景契约
**Files:**
- Create: `tests/genealogy-shared-background-contract.ps1`
- Read: `pages.json`
**Interfaces:**
- Consumes: `pages.json` 中所有 `pages/genealogy/g*.vue` 活动路由。
- Produces: 每个 G 页面必须渲染一次 `<GenealogyPageBackground />` 的仓库契约。
- [ ] **Step 1: 写失败测试**
测试必须断言:公共组件存在;组件唯一引用 `/static/assets/modules/genealogy/opaque/genealogy-page-background.png`;使用 `mode="widthFix"`;包含固定满屏宣纸底层和宽度 `100%` 的图片;每个实际 G 页面恰好使用一次公共组件;页面不得直接引用旧纸纹、旧页脚或公共背景文件。
- [ ] **Step 2: 运行测试确认失败**
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/genealogy-shared-background-contract.ps1`
Expected: 因公共组件和公共资产尚不存在而失败。
### Task 2: 实现单一公共背景入口
**Files:**
- Create: `components/GenealogyPageBackground.vue`
- Create: `static/assets/modules/genealogy/opaque/genealogy-page-background.png`
- Modify: `design-pipeline/manifests/g01-background-candidates.json`
- Modify: `design-pipeline/tests/g01-background-candidates.test.mjs`
**Interfaces:**
- Consumes: C 母版和可重建生成结果。
- Produces: 无属性、无事件的 `<GenealogyPageBackground />` 视觉组件。
- [ ] **Step 1: 将当前 C 生成结果复制为 G 模块公共运行资产**
源文件为 `design-pipeline/generated/g01-background/g01-list-background-direction-c.png`;目标文件为 `static/assets/modules/genealogy/opaque/genealogy-page-background.png`。复制后验证 SHA-256 仍为 `f14aeed81046d2d5e7ae78b1e62f572689c38261a2cc043142bef9f70200dc5b`
- [ ] **Step 2: 创建最小公共组件**
组件使用固定满屏 `view` 提供宣纸底色,并在顶部放置 `width: 100%``mode="widthFix"` 的 C 背景图片;组件必须 `pointer-events: none` 且位于页面内容下方。
- [ ] **Step 3: 更新流水线清单测试和运行输出所有权**
将 manifest 的 `runtimeOutput` 改为公共资产路径,并让 Node 测试断言新路径,避免 G01 私有资产继续成为正式入口。
### Task 3: 迁移 9 个 G 页面
**Files:**
- Modify: `pages/genealogy/g01-my-genealogies.vue`
- Modify: `pages/genealogy/g03-create-genealogy.vue`
- Modify: `pages/genealogy/g05-genealogy-overview.vue`
- Modify: `pages/genealogy/g06-search-genealogies.vue`
- Modify: `pages/genealogy/g08-join-application.vue`
- Modify: `pages/genealogy/g09-my-applications.vue`
- Modify: `pages/genealogy/g10-application-review.vue`
- Modify: `pages/genealogy/g11-genealogy-settings.vue`
- Modify: `pages/genealogy/g12-generation-poems.vue`
**Interfaces:**
- Consumes: `<GenealogyPageBackground />`
- Produces: 每个 G 页面一个公共背景实例,页面内容和交互保持原样。
- [ ] **Step 1: 替换模板背景层**
删除各页开头的旧纸纹和页脚山水图片,或 G01 的私有 C 背景图片,原位置统一放置 `<GenealogyPageBackground />`
- [ ] **Step 2: 删除仅服务于旧背景的样式**
删除 9 个页面中对应 `__paper``__footer``page-paper-texture``page-footer-landscape``page-background` 规则;不改相邻内容样式。
- [ ] **Step 3: 运行公共背景契约确认通过**
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/genealogy-shared-background-contract.ps1`
Expected: `PASS G genealogy shared background contract`
### Task 4: 更新既有契约与权威资料
**Files:**
- Modify: `tests/g01-visual-contract.ps1`
- Modify: `docs/交接记录.md`
- Modify: `docs/验收规划.md`
- Modify: `docs/design/P00_页面结构与资产清单.md`
- Modify: `docs/design/设计资产生产流水线规范.md`
- Modify: `docs/design/G01_列表背景候选与换机重建.md`
- Modify: `design-qa.md`
**Interfaces:**
- Consumes: 公共组件、公共资产路径和用户本轮决定。
- Produces: 文档与实际代码一致的未验收状态说明。
- [ ] **Step 1: 更新 G01 视觉契约**
契约改为检查公共组件和公共资产 SHA-256,不再要求 G01 私有资产路径。
- [ ] **Step 2: 更新权威资料**
记录 C 已成为 9 个 G 页面公共背景;明确完整显示和宣纸延展规则,同时保留“G01 未整页验收、其他 G 页面未逐页截图复核、Android 复核缺失”。
### Task 5: 验证和截图审核
**Files:**
- Runtime evidence only: `docs/design/screens/runtime/2026-07-16/`
**Interfaces:**
- Consumes: H5 运行页和四个目标视口。
- Produces: 仅供内部审核的运行截图与测试证据。
- [ ] **Step 1: 运行聚焦验证**
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/genealogy-shared-background-contract.ps1`
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1`
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-empty-state-contract.ps1`
Run: `node --test design-pipeline/tests/g01-background-candidates.test.mjs`
Run: `design-pipeline/.venv/Scripts/python.exe -m unittest design-pipeline/tests/test_build_g01_backgrounds.py -v`
Run: `node tests/g01-empty-state-runtime-smoke.js`
Run: `git diff --check`
Expected: 所有测试退出码为 0`git diff --check` 无空白错误。
- [ ] **Step 2: 四档 H5 截图复核 G01**
在 320×568、360×640、360×800、412×915 下确认完整左右边缘、无纵向拉伸、无横向溢出,图片下方自然过渡到宣纸底色。
- [ ] **Step 3: 报告验证边界**
报告 H5 内部候选结果,不宣称 G01 或其他 G 页面正式验收;保留 Android/HBuilderX 真机或模拟器复核缺口。
@@ -0,0 +1,106 @@
# 全模块国风视觉系统 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 以 A 系列已确认控件为全局唯一标准,完成 G、T、F、R、N、M 活动页面的按钮、对话框、提示、返回导航和模块背景统一。
**Architecture:** 新建公共视觉组件持有 A 系列资产,G 页面继续消费现有共享背景,T/F/R/N/M 通过模块背景组件与 `ModulePage` 统一壳消费各自长背景。页面只保留业务状态和模块内容,不再自行定义全局控件外观。
**Tech Stack:** uni-app、Vue 3 `<script setup>`、SCSS、PNG 资产、PowerShell/Node 合同测试。
## Global Constraints
- 不对接接口,不改变路由和数据契约。
- 不使用原生 `uni.showToast``uni.showModal``uni.showLoading``uni.showActionSheet`
- 不生成运行截图;只生成并验证对应视觉资产。
- 不执行任何 Git 写操作,不使用 worktree 或多代理。
- 保留所有已有修改、历史资产、测试和文档。
---
### Task 1: 全局视觉合同
**Files:**
- Create: `tests/global-heritage-visual-system-contract.ps1`
- [ ] 扫描 pages/components,要求无原生提示调用和旧不透明 A01 按钮引用。
- [ ] 约束 PageHeader 返回箭头、公共组件资产路径和六模块背景入口。
- [ ] 运行合同并确认旧代码失败。
### Task 2: A 系列公共控件
**Files:**
- Create: `components/AppButton.vue`
- Create: `components/AppDialog.vue`
- Create: `components/AppToast.vue`
- Create: `components/AppLoading.vue`
- Modify: `components/PageHeader.vue`
- [ ] 实现主/次卷轴按钮和点击状态。
- [ ] 实现单双操作卷轴对话框。
- [ ] 实现卷轴 Toast 与自定义 Loading。
- [ ] 把普通返回文字替换为真实箭头资产。
- [ ] 运行全局视觉合同并确认公共组件部分通过。
### Task 3: 模块长背景资产与页面壳
**Files:**
- Create: `static/assets/modules/tree/opaque/tree-page-background-long.png`
- Create: `static/assets/modules/family/opaque/family-page-background-long.png`
- Create: `static/assets/modules/records/opaque/records-page-background-long.png`
- Create: `static/assets/modules/notification/opaque/notification-page-background-long.png`
- Create: `static/assets/modules/profile/opaque/profile-page-background-long.png`
- Create: `components/ModulePageBackground.vue`
- Modify: `components/ModulePage.vue`
- [ ] 生成五张无文字、无 UI、1440×3600 长背景并验证尺寸。
- [ ] 实现模块到背景资产的单一映射。
- [ ] ModulePage 接入背景、A 系列按钮和自定义 Toast。
- [ ] 删除 ModulePage 原生 Toast 与旧背景路径。
### Task 4: G 系列完整迁移与 G01 指定可读性
**Files:**
- Modify: `pages/genealogy/*.vue`
- Modify: `components/GenealogyCard.vue`
- [ ] 将 G 页面旧按钮替换为 AppButton。
- [ ] 将 G01/G03/G10/G11/G12 页面自制弹窗迁移为 AppDialog。
- [ ] G01 地区、人数、角色、更新时间加深并使用中等字重。
- [ ] 确认 9 个 G 页面仍消费 GenealogyPageBackground。
### Task 5: T 系列完整迁移
**Files:**
- Modify: `components/tree/TreeMemberForm.vue`
- Modify: `pages/tree/*.vue`
- [ ] 接入 T 模块长背景。
- [ ] 迁移全部旧按钮和冲突对话框。
- [ ] 保留世系树、成员详情、表单和目录的现有结构与业务状态。
### Task 6: F、R、N、M 系列完整迁移
**Files:**
- Modify: `pages/family/f01-family-feed.vue`
- Modify: `pages/family/f02-publish-feed.vue`
- Modify: `pages/notification/n01-message-center.vue`
- Modify: `pages/profile/m01-profile-home.vue`
- Modify through ModulePage: remaining F/R/N/M pages
- [ ] 四个自定义根页面接入模块背景和 A 系列控件。
- [ ] F02、N01 原生 Toast 替换为 AppToast。
- [ ] 其余 29 个 ModulePage 消费页面自动获得统一视觉。
### Task 7: 文档与最终验证
**Files:**
- Modify: `docs/交接记录.md`
- Modify: `docs/验收规划.md`
- Modify: `design-qa.md`
- [ ] 运行全局视觉合同、现有 G/T/F/R/N/M 相关合同和运行 smoke。
- [ ] 运行资产尺寸与 SHA-256 清单检查。
- [ ] 运行 `git diff --check`,分别报告通过项和仍缺 Android/HBuilderX 验证。
- [ ] 文档只写成全模块 H5 视觉候选,不写成逐页正式验收。
@@ -0,0 +1,149 @@
# AppLoading 红金印牌重设计 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use `superpowers:executing-plans` to implement this plan task-by-task. 本项目明确禁止多代理、worktree、`git add`、`commit`、`push`、`reset` 和 `checkout`。
**Goal:** 将公共 `AppLoading` 的临时细线方框替换为已批准的红金家谱印牌加载视觉,并保持页面级、区域级调用契约不变。
**Architecture:** `components/AppLoading.vue` 继续作为唯一加载视觉所有者,页面只传入 `variant``text``description`。组件复用 foundation 中的 `brand-seal.png``auth-divider-knot.png`,不让各业务页面重复定义加载资产或动画。
**Tech Stack:** uni-app、Vue 3 `<script setup>`、SCSS、PowerShell 契约测试、Chrome DevTools Protocol 截图脚本。
## Global Constraints
- 当前只做浅色国风主题,不接接口。
- 不修改 G01 状态判断、文案、背景、头部或底部导航。
- 不使用 CSS 绘制印章、SVG、emoji 或占位图形;只使用仓库内真实资产。
- 不使用多代理或 worktree,不执行任何 Git 写操作。
- 复用现有资产,不生成重复资产。
- H5 截图仅为内部候选证据;Android/HBuilderX 仍需复核。
---
### Task 1: 收紧公共加载视觉契约
**Files:**
- Modify: `tests/app-loading-contract.ps1`
- Test: `tests/app-loading-contract.ps1`
**Interfaces:**
- Consumes: `components/AppLoading.vue` 的模板与 scoped SCSS。
- Produces: 红金印牌、如意结、双尺寸和减弱动效的稳定契约。
- [ ] **Step 1: 写入失败契约**
`tests/app-loading-contract.ps1` 中将旧方框尺寸与 `1.35s` 断言替换为以下要求:
```powershell
Assert-Match -Content $component -Pattern 'class="app-loading__seal"\s+src="/static/assets/foundation/transparent/brand-seal\.png"' -Message 'AppLoading must render the approved real red-gold seal asset'
Assert-Match -Content $component -Pattern 'class="app-loading__knot"\s+src="/static/assets/foundation/transparent/auth-divider-knot\.png"' -Message 'AppLoading must render the approved real gold knot asset'
Assert-Match -Content $component -Pattern '(?s)\.app-loading--page\s+\.app-loading__seal\s*\{[^}]*width:\s*132rpx;[^}]*height:\s*136rpx;' -Message 'AppLoading page seal must use the approved size'
Assert-Match -Content $component -Pattern '(?s)\.app-loading--section\s+\.app-loading__seal\s*\{[^}]*width:\s*88rpx;[^}]*height:\s*90rpx;' -Message 'AppLoading section seal must use the approved size'
Assert-Match -Content $component -Pattern 'app-loading-seal-breathe\s+1\.6s' -Message 'AppLoading seal must use the approved restrained breathing rhythm'
Assert-Match -Content $component -Pattern '@media\s*\(prefers-reduced-motion:\s*reduce\)' -Message 'AppLoading must respect reduced-motion preferences'
if ($component -match 'app-loading__mark|border:\s*4rpx\s+double') { throw 'AppLoading must not retain the legacy CSS box mark' }
```
- [ ] **Step 2: 运行失败测试**
Run: `powershell -ExecutionPolicy Bypass -File tests/app-loading-contract.ps1`
Expected: FAIL,首个错误为缺少 `brand-seal.png` 真实印牌。
### Task 2: 实现红金印牌公共加载组件
**Files:**
- Modify: `components/AppLoading.vue`
- Test: `tests/app-loading-contract.ps1`
**Interfaces:**
- Consumes: `/static/assets/foundation/transparent/brand-seal.png``/static/assets/foundation/transparent/auth-divider-knot.png`
- Produces: 调用方式不变的 `AppLoading` 页面级与区域级视觉。
- [ ] **Step 1: 替换模板主体**
将旧 `.app-loading__mark` 替换为:
```vue
<view class="app-loading__emblem" aria-hidden="true">
<image class="app-loading__seal" src="/static/assets/foundation/transparent/brand-seal.png" mode="aspectFit" />
<image class="app-loading__knot" src="/static/assets/foundation/transparent/auth-divider-knot.png" mode="aspectFit" />
</view>
```
- [ ] **Step 2: 写入最小视觉实现**
使用以下边界实现,不改变 props:
```scss
.app-loading__emblem { display: flex; flex-direction: column; align-items: center; }
.app-loading__seal { animation: app-loading-seal-breathe 1.6s ease-in-out infinite; }
.app-loading__knot { margin-top: 8rpx; opacity: .72; animation: app-loading-knot-breathe 1.6s ease-in-out infinite; }
.app-loading--page .app-loading__seal { width: 132rpx; height: 136rpx; }
.app-loading--page .app-loading__knot { width: 56rpx; height: 18rpx; }
.app-loading--section .app-loading__seal { width: 88rpx; height: 90rpx; }
.app-loading--section .app-loading__knot { width: 42rpx; height: 14rpx; margin-top: 5rpx; }
@keyframes app-loading-seal-breathe { 0%, 100% { opacity: .82; transform: scale(.96); } 50% { opacity: 1; transform: scale(1); } }
@keyframes app-loading-knot-breathe { 0%, 100% { opacity: .44; } 50% { opacity: .76; } }
@media (prefers-reduced-motion: reduce) { .app-loading__seal, .app-loading__knot { animation: none; opacity: 1; transform: none; } }
```
- [ ] **Step 3: 调整文字间距**
页面级主文案从印牌组合下方 `22rpx` 开始,区域级从 `14rpx` 开始;保留页面级 `30rpx/24rpx` 与区域级 `24rpx/22rpx` 字号。
- [ ] **Step 4: 运行契约测试**
Run: `powershell -ExecutionPolicy Bypass -File tests/app-loading-contract.ps1`
Expected: `APP-LOADING-CONTRACT PASS`
### Task 3: 回归所有接入页面并完成视觉证据
**Files:**
- Verify: `pages/genealogy/g01-my-genealogies.vue`
- Verify: `pages/genealogy/g06-search-genealogies.vue`
- Verify: `tests/g01-loading-state-contract.ps1`
- Verify: `tests/g-series-app-loading-contract.ps1`
- Verify: `tests/module-app-loading-contract.ps1`
- Create: `docs/design/screens/runtime/2026-07-17/03-g01-loading-red-seal-412x900.png`
**Interfaces:**
- Consumes: 更新后的 `AppLoading` 公共视觉。
- Produces: 同一浏览器中的 G01 页面级与 G06 区域级回归证据。
- [ ] **Step 1: 运行加载契约和编译审计**
Run:
```powershell
powershell -ExecutionPolicy Bypass -File tests/g01-loading-state-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/g-series-app-loading-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/module-app-loading-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/compile-audit.ps1
```
Expected: 四项均输出 `PASS`
- [ ] **Step 2: 在同一个可控 Chrome 标签页截图 G01**
Run:
```powershell
node scripts/capture-chrome-page.js "http://localhost:5173/#/pages/genealogy/g01-my-genealogies?state=loading" ".state-panel--loading" "docs/design/screens/runtime/2026-07-17/03-g01-loading-red-seal-412x900.png" 412 900
```
Expected: 输出 `CAPTURED`,页面只有一个 Chrome 标签并显示红金印牌加载状态。
- [ ] **Step 3: 检查四档响应式尺寸**
分别使用 `320×568``360×640``360×800``412×915` 运行同一截图命令,确认印牌、文字和底栏无裁切、无横向滚动。
- [ ] **Step 4: 运行差异检查**
Run: `git diff --check -- components/AppLoading.vue tests/app-loading-contract.ps1`
Expected: 退出码 `0`;允许 Git 报告现有 LF/CRLF 提示,不允许空白错误。
## Execution Choice
按用户最新授权选择 **Inline Execution**:在当前会话使用 `superpowers:executing-plans` 顺序执行。由于用户明确禁止,不创建 worktree、不使用子代理、不执行提交。
@@ -0,0 +1,66 @@
# G01 Empty Frame Transparency Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 移除 G01 空状态的不透明面板底,并让透明框内的内容尺度与纵向节奏更饱满。
**Architecture:** 设计流水线从已确认的 `g01-empty-panel.png` 精确提取原双金线和四角纹样,输出透明 `g01-empty-panel-frame.png`。空状态只渲染该透明框;错误状态继续使用原不透明资产。
**Tech Stack:** uni-app、Vue 3、SCSS、PowerShell 合同测试、Chrome H5。
## Global Constraints
- 不生成或覆盖现有资产。
- 不改变空状态按钮、文案和跳转行为。
- 不使用多代理、worktree 或 Git 写操作。
- H5 证据不表示 Android/HBuilderX 或 G01 整页正式验收。
---
### Task 1: 空状态透明框
**Files:**
- Modify: `tests/g01-empty-state-contract.ps1`
- Modify: `pages/genealogy/g01-my-genealogies.vue`
**Interfaces:**
- Consumes: `list-slip-frame.png``.empty-panel``.empty-panel__content`
- Produces: 可重建的 `g01-empty-panel-frame.png``.empty-panel__frame` 透明框层和 `26rpx` `.empty-create-note`
- Produces: `1120rpx` 空状态框、垂直居中的内容组、放大的谱印/标题/说明/操作按钮,以及更明显的纵向节奏。
- [ ] **Step 1: 写入失败契约**
锁定空状态模板不再引用不透明面板、使用 `empty-panel__frame`,并设置 `1120rpx` 框高、垂直居中、`560×124rpx` 主操作与 `26rpx` 提示文字。
- [ ] **Step 2: 验证合同失败**
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-empty-state-contract.ps1`
Expected: FAIL,指出空状态仍使用不透明面板或缺少透明框。
- [ ] **Step 3: 实施最小模板与样式修改**
```scss
.empty-panel__frame {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.empty-create-note { font-size: 26rpx; line-height: 38rpx; }
```
- [ ] **Step 4: 验证**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-empty-state-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/compile-audit.ps1
node tests/g01-empty-state-runtime-smoke.js http://localhost:5173
```
Expected: 全部 PASS。
@@ -0,0 +1,49 @@
# G01 读取失败状态重设计 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use `superpowers:executing-plans`. 本项目禁止多代理、worktree 和所有 Git 写操作。
**Goal:** 让 G01 读取失败状态与已通过的空状态、加载状态共享同一红金国风视觉体系。
**Architecture:** G01 页面继续拥有错误状态结构与 `retryLoad` 行为;视觉只消费现有透明金框、foundation 印牌、分隔线和 A 系列按钮资产,不创建新的重复资产。
**Tech Stack:** uni-app、Vue 3、SCSS、PowerShell 契约、Chrome DevTools Protocol 截图。
## Global Constraints
- 只修改 G01 失败状态及其测试。
- 保留状态判断和重试行为。
- 不生成已有资产的副本。
- H5 不是 Android 最终验收。
### Task 1: 建立失败视觉契约
**Files:**
- Create: `tests/g01-error-state-contract.ps1`
- Test: `tests/g01-error-state-contract.ps1`
- [ ] 写入断言:错误态必须引用 `g01-empty-panel-frame.png``brand-seal.png``section-divider.png``a01-scroll-primary-v3.png`,必须保留 `retryLoad`,且错误态片段不得引用 `g01-empty-panel.png`
- [ ] 运行 `powershell -ExecutionPolicy Bypass -File tests/g01-error-state-contract.ps1`,预期因现有旧面板而失败。
### Task 2: 实现透明金框错误态
**Files:**
- Modify: `pages/genealogy/g01-my-genealogies.vue`
- Test: `tests/g01-error-state-contract.ps1`
- [ ]`.state-panel--error` 内部替换为透明框、红金印牌、标题、说明、分隔线和原重试按钮。
- [ ] 为错误态设置 `1120rpx` 高度、居中内容、`132rpx × 136rpx` 印牌、`42rpx` 标题、`27rpx` 说明和 `560rpx × 124rpx` 按钮。
- [ ] 运行契约,预期输出 `G01-ERROR-STATE-CONTRACT PASS`
### Task 3: 运行与视觉回归
**Files:**
- Create: `docs/design/screens/runtime/2026-07-17/04-g01-error-after-412x900.png`
- Verify: `tests/compile-audit.ps1`
- [ ] 运行 G01 失败态契约、空状态契约、加载契约和编译审计。
- [ ] 在同一 Chrome 标签页截图 `320×568``360×640``360×800``412×915`
- [ ] 逐张检查标题、按钮、框线、背景和底栏是否裁切,并运行 `git diff --check`
## Execution Choice
用户已授权自主选择最佳方案,采用当前会话 Inline Execution;不等待额外确认。
@@ -0,0 +1,100 @@
# G01 Meta Legibility Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 让 G01 列表地区与成员图标清楚,并将更新时间放在第二行、地区与成员放在第三行。
**Architecture:** 保持现有模板和资产不变,只修改 `g01-my-genealogies.vue` 的当前卡样式和 `GenealogyCard.vue` 的共享列表卡样式。由 G01 静态合同锁定精确数值,再用同一 Chrome 页面复核 412×915 与 320×568。
**Tech Stack:** uni-app、Vue 3、SCSS、PowerShell 合同测试、Chrome H5。
## Global Constraints
- 不改变卡框、卡高、谱印、背景、快捷入口和业务行为。
- 320px 小屏继续隐藏更新时间。
- 不使用多代理、worktree 或任何 Git 写操作。
- H5 证据不表示 Android/HBuilderX 或 G01 整页正式验收。
---
### Task 1: 锁定并实现元信息可读性
**Files:**
- Modify: `tests/g01-visual-contract.ps1`
- Modify: `pages/genealogy/g01-my-genealogies.vue`
- Modify: `components/GenealogyCard.vue`
**Interfaces:**
- Consumes: G01 当前卡 `.current-meta``.current-meta-icon`;列表卡 `.card-meta``.card-meta-icon``.card-role``.card-updated`
- Produces: 列表地区与成员小图标 `46rpx`、增强赭金对比;更新时间在右对齐第二行,元信息占满第三行,常规卡高 `178rpx`320px 卡高仍为 `148rpx`
- [ ] **Step 1: 写入失败合同**
`tests/g01-visual-contract.ps1` 增加精确断言:更新时间在 DOM 与视觉顺序中先于元信息并占第二行;元信息占第三行;常规卡高 `178rpx`,小屏卡高 `148rpx`
- [ ] **Step 2: 验证合同因旧数值失败**
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1`
Expected: FAIL,指出至少一个新字号或透明度不存在。
- [ ] **Step 3: 实施最小样式调整**
`pages/genealogy/g01-my-genealogies.vue` 设置:
```scss
.current-switch-copy { font-size: 28rpx; }
.current-meta { font-size: 27rpx; }
.current-meta-icon { width: 36rpx; height: 36rpx; opacity: 1; }
@media (max-width: 340px) {
.current-meta-icon { width: 32rpx; height: 32rpx; }
}
```
`components/GenealogyCard.vue` 设置:
```scss
.card-meta-icon {
width: 46rpx;
height: 46rpx;
flex: 0 0 auto;
opacity: 1;
filter: saturate(1.35) brightness(0.82) contrast(1.15);
}
.card-meta-item { margin-right: 0; }
.card-meta-item + .card-meta-item { margin-left: 18rpx; }
.genealogy-card { min-height: 178rpx; }
.card-detail-row { flex-wrap: wrap; }
.card-metas { width: 100%; margin-top: 2rpx; }
.card-updated {
width: 100%;
justify-content: flex-end;
margin-top: 0;
margin-left: 0;
}
.card-meta { font-size: 26rpx; }
.card-updated { font-size: 24rpx; }
.card-role { font-size: 26rpx; }
```
- [ ] **Step 4: 验证合同与编译**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/compile-audit.ps1
```
Expected: 两项均 PASS。
- [ ] **Step 5: 复核真实页面**
在当前 Chrome 中捕获:
```powershell
node scripts/capture-chrome-page.js 'http://localhost:5173/#/pages/genealogy/g01-my-genealogies' '.genealogy-index' 'docs/design/screens/runtime/2026-07-17/G01-meta-legibility-412x915.png' 412 915
node scripts/capture-chrome-page.js 'http://localhost:5173/#/pages/genealogy/g01-my-genealogies' '.genealogy-index' 'docs/design/screens/runtime/2026-07-17/G01-meta-legibility-320x568.png' 320 568
```
Expected: 元信息更清晰,图标更实;无横向溢出,320px 下更新时间仍隐藏。
@@ -0,0 +1,241 @@
# Global Loading System Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:**`AppLoading.vue` 建成页面级/局部级统一加载组件,并接入首批 11 个页面及 G06 搜索结果区域。
**Architecture:** `AppLoading` 单一维护朱砂谱印、呼吸动效、两档尺寸和文案层级;页面只传入 `variant``text``description`,并继续拥有业务状态。按钮提交、列表刷新和上传进度不进入本组件。
**Tech Stack:** uni-app、Vue 3、SCSS、PowerShell 契约测试、Node/Chrome H5 runtime smoke。
## Global Constraints
- `variant` 只允许 `page``section`,默认 `page`
- 页面级尺寸为谱印 `96×96rpx`、印字 `40rpx`、主文案 `30rpx`、说明 `24rpx`、最小高度 `320rpx`
- 局部级尺寸为谱印 `64×64rpx`、印字 `28rpx`、主文案 `24rpx`、说明 `22rpx`、最小高度 `180rpx`
- 不创建全屏遮罩,不接管标题栏、底栏或业务状态。
- 不修改按钮提交、下拉刷新、触底加载和上传流程。
- 不使用多代理、worktree 或 Git 写操作。
- H5 证据不代表 Android/HBuilderX 或页面正式验收。
---
### Task 1: `AppLoading` 双变体合同
**Files:**
- Create: `tests/app-loading-contract.ps1`
- Modify: `components/AppLoading.vue`
- Modify: `tests/g01-loading-state-contract.ps1`
**Interfaces:**
- Consumes: `variant: 'page' | 'section'``text: string``description: string`
- Produces: `.app-loading--page``.app-loading--section``.app-loading__mark``.app-loading__copy``.app-loading__description`
- [ ] **Step 1: 写入失败契约**
契约锁定三个属性、两个变体类、设计尺寸、`1.35s` 动画和可选说明;G01 必须传入 `description`,不再在页面复制辅助说明。
- [ ] **Step 2: 验证失败**
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/app-loading-contract.ps1`
Expected: FAIL,指出 `variant``description` 尚未实现。
- [ ] **Step 3: 实施组件**
```vue
<template>
<view class="app-loading" :class="`app-loading--${variant}`">
<view class="app-loading__mark"><text></text></view>
<text class="app-loading__copy">{{ text }}</text>
<text v-if="description" class="app-loading__description">{{ description }}</text>
</view>
</template>
<script setup>
defineProps({
variant: { type: String, default: 'page', validator: (value) => ['page', 'section'].includes(value) },
text: { type: String, default: '正在展开,请稍候…' },
description: { type: String, default: '' }
})
</script>
```
样式按 Global Constraints 的两档精确尺寸实现,动画继续由 `app-loading-breathe` 唯一维护。
- [ ] **Step 4: 更新 G01 消费方式**
```vue
<AppLoading text="正在整理家谱" description="请稍候,家族记忆正在归卷。" />
```
删除 G01 的 `.state-copy--loading` 独立说明节点。
- [ ] **Step 5: 验证通过**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/app-loading-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-loading-state-contract.ps1
```
Expected: 全部 PASS。
---
### Task 2: G 系列接入
**Files:**
- Create: `tests/g-series-app-loading-contract.ps1`
- Modify: `pages/genealogy/g05-genealogy-overview.vue`
- Modify: `pages/genealogy/g06-search-genealogies.vue`
- Modify: `pages/genealogy/g09-my-applications.vue`
- Modify: `pages/genealogy/g10-application-review.vue`
- Modify: `pages/genealogy/g11-genealogy-settings.vue`
- Modify: `pages/genealogy/g12-generation-poems.vue`
**Interfaces:**
- Consumes: Task 1 的 `AppLoading` 属性合同。
- Produces: G05/G09/G10/G11/G12 页面级 Loading 与 G06 局部 Loading。
- [ ] **Step 1: 写入失败契约**
每页必须导入 `AppLoading`G05、G09、G10、G11、G12 在自身 `loading` 分支渲染页面级组件;G06 搜索区渲染 `variant="section"`
- [ ] **Step 2: 验证失败**
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/g-series-app-loading-contract.ps1`
Expected: FAIL,指出首个尚未接入的 G 页面。
- [ ] **Step 3: 接入页面级分支**
各页在现有成功/空/失败分支之前加入:
```vue
<AppLoading
v-if="pageState === 'loading'"
text="页面对应的已确认文案"
description="页面对应的辅助说明"
/>
```
其中 `pageState` 分别为 `overviewState``applicationState``reviewState``settingsState``poemState`;保留各页其他分支和操作。
- [ ] **Step 4: 接入 G06 局部加载**
```vue
<AppLoading
v-if="searchState === 'loading'"
variant="section"
text="正在检索公开家谱"
description="请稍候,正在整理匹配结果。"
/>
```
搜索框、模式切换、地区筛选和分隔线继续可见。
- [ ] **Step 5: 验证通过**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g-series-app-loading-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1
node tests/module-page-runtime-smoke.js http://localhost:5173
```
Expected: 全部 PASS。
---
### Task 3: T/F/N 页面级接入
**Files:**
- Create: `tests/module-app-loading-contract.ps1`
- Modify: `pages/tree/t01-tree-overview.vue`
- Modify: `pages/tree/t03-member-profile.vue`
- Modify: `pages/tree/t07-member-directory.vue`
- Modify: `pages/family/f01-family-feed.vue`
- Modify: `pages/notification/n01-message-center.vue`
**Interfaces:**
- Consumes: Task 1 的页面级 `AppLoading`
- Produces: 五个页面独立且不会误落入错误卡的 `loading` 分支。
- [ ] **Step 1: 写入失败契约**
锁定五页导入组件并在现有列表/详情/树/错误判断之前单独处理 `loading`;Loading 期间不显示错误操作或发布/审核按钮。
- [ ] **Step 2: 验证失败**
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/module-app-loading-contract.ps1`
Expected: FAIL,指出首个仍把 `loading` 当成错误/空状态的页面。
- [ ] **Step 3: 实施五页分支**
统一结构:
```vue
<AppLoading
v-if="pageState === 'loading'"
text="页面对应的已确认文案"
description="请稍候,正在读取页面数据。"
/>
<template v-else-if="pageState === 'ready-state'"></template>
<view v-else>原空错误状态</view>
```
只调整状态分支,不改变数据、入口、卡片和按钮行为。
- [ ] **Step 4: 验证通过**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/module-app-loading-contract.ps1
node tests/t01-tree-state-runtime-smoke.js http://localhost:5173
node tests/t03-t08-member-flow-runtime-smoke.js http://localhost:5173
node tests/root-pages-runtime-smoke.js http://localhost:5173
```
Expected: 全部 PASS。
---
### Task 4: 全量验证与视觉检查
**Files:**
- Verify only: all modified files.
**Interfaces:**
- Consumes: Tasks 13 的加载组件和页面状态分支。
- Produces: H5 内部候选证据,不改变验收状态。
- [ ] **Step 1: 静态与编译验证**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/app-loading-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-loading-state-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g-series-app-loading-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/module-app-loading-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/compile-audit.ps1
```
- [ ] **Step 2: 运行态验证**
Run G01、G 系列、T/F/N 现有 runtime smoke,任何失败均先定位状态分支,不放宽测试。
- [ ] **Step 3: 代表性截图**
捕获 G01 页面级与 G06 局部级在 320×568、360×640、360×800、412×915 的真实 H5 画面,检查无横向溢出、无错误态闪现、固定底栏不遮挡。
- [ ] **Step 4: 工作区检查**
Run: `git diff --check`
Expected: 无空白错误;现有 LF/CRLF 提示单独报告。
@@ -0,0 +1,160 @@
# AppLoading 必要加载动效实施计划
> **执行要求:** 使用 `superpowers:executing-plans` 在当前会话内逐步执行。用户明确禁止多代理、worktree、`git add`、commit、push、reset 和 checkout。
**目标:** 修复 G01 在 `prefers-reduced-motion: reduce` 下加载态完全静止的问题,使印牌和如意结保留清晰的透明度呼吸,同时不产生缩放、旋转或位移。
**架构:** 继续由 `components/AppLoading.vue` 单一维护加载动效,不在 G01 复制样式。正常模式保持现有动画;减少动态效果模式改用独立的透明度关键帧,并强制 `transform: none`。测试先锁定旧行为必须失败,再验证静态契约和当前 Chrome 运行时证据。
**技术栈:** Vue 3、uni-app、SCSS、PowerShell 契约测试、Chrome DevTools Protocol、Node.js。
## 全局约束
- 只修改 G01 加载态直接依赖的公共 `AppLoading`、聚焦测试和当轮内部证据。
- 不改变 `variant``text``description` 组件契约。
- 不改变 G01 状态逻辑、布局、背景、文案、标题栏或底部导航。
- 不新增图片、CSS 图形、JavaScript 定时器或业务接口。
- `prefers-reduced-motion: reduce` 下只允许透明度变化,`transform` 必须为 `none`
- H5 截图只是内部候选;Android/HBuilderX 仍未验证。
- 不执行任何 Git 写操作。
---
### Task 1:修复并验证减少动态效果模式的必要加载反馈
**文件:**
- 修改:`tests/app-loading-contract.ps1`
- 修改:`components/AppLoading.vue`
- 验证:`tests/g01-loading-state-contract.ps1`
- 验证:`tests/g-series-app-loading-contract.ps1`
- 验证:`tests/module-app-loading-contract.ps1`
- 内部证据:`docs/design/screens/runtime/2026-07-19/g01-approval/03-loading-essential-motion-412x915.png`
**接口:**
- 消费:`AppLoading` 现有 `variant``text``description` 属性。
- 产出:正常模式继续使用 `app-loading-seal-breathe``app-loading-knot-breathe`;减少动态效果模式使用 `app-loading-seal-essential-pulse``app-loading-knot-essential-pulse`
- 不增加新的组件属性、事件或页面状态。
- [ ] **Step 1:先补充会失败的公共契约**
`tests/app-loading-contract.ps1` 的现有动画断言之后加入:
```powershell
Assert-Match -Content $component -Pattern '@keyframes\s+app-loading-seal-essential-pulse' -Message 'Reduced-motion AppLoading must retain an essential seal opacity pulse'
Assert-Match -Content $component -Pattern '@keyframes\s+app-loading-knot-essential-pulse' -Message 'Reduced-motion AppLoading must retain an essential knot opacity pulse'
Assert-Match -Content $component -Pattern '(?s)@media\s*\(prefers-reduced-motion:\s*reduce\).*?\.app-loading__seal\s*\{[^}]*animation:\s*app-loading-seal-essential-pulse\s+1\.2s\s+ease-in-out\s+infinite;[^}]*transform:\s*none;' -Message 'Reduced-motion seal must pulse opacity without transform motion'
Assert-Match -Content $component -Pattern '(?s)@media\s*\(prefers-reduced-motion:\s*reduce\).*?\.app-loading__knot\s*\{[^}]*animation:\s*app-loading-knot-essential-pulse\s+1\.2s\s+ease-in-out\s+\.2s\s+infinite;[^}]*transform:\s*none;' -Message 'Reduced-motion knot must pulse opacity without transform motion'
if ($component -match '(?s)@media\s*\(prefers-reduced-motion:\s*reduce\).*?animation:\s*none') {
throw 'Reduced-motion AppLoading must not become completely static'
}
```
- [ ] **Step 2:运行聚焦契约并确认 RED**
运行:
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/app-loading-contract.ps1
```
预期:退出码非 0,错误首先指向缺少 `app-loading-seal-essential-pulse`,证明测试捕获的是当前完全静止行为,而不是语法或路径错误。
- [ ] **Step 3:实现最小降动效透明度脉冲**
`components/AppLoading.vue` 中保留现有正常模式关键帧,并把当前媒体查询替换为:
```scss
@keyframes app-loading-seal-essential-pulse {
0%, 100% { opacity: .58; }
50% { opacity: 1; }
}
@keyframes app-loading-knot-essential-pulse {
0%, 100% { opacity: .28; }
50% { opacity: .86; }
}
@media (prefers-reduced-motion: reduce) {
.app-loading__seal {
animation: app-loading-seal-essential-pulse 1.2s ease-in-out infinite;
transform: none;
}
.app-loading__knot {
animation: app-loading-knot-essential-pulse 1.2s ease-in-out .2s infinite;
transform: none;
}
}
```
不得修改模板、属性、尺寸、文案或正常模式关键帧。
- [ ] **Step 4:运行聚焦契约并确认 GREEN**
运行:
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/app-loading-contract.ps1
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/g01-loading-state-contract.ps1
```
预期:分别输出 `APP-LOADING-CONTRACT PASS``G01-LOADING-STATE-CONTRACT PASS`,退出码均为 0。
- [ ] **Step 5:在当前唯一 Chrome 标签页验证真实动画**
保持 G01 `state=loading` 和 412×915 视口。通过 9222 CDP 在同一次检查中读取:
```js
const seal = document.querySelector('.app-loading__seal')
const knot = document.querySelector('.app-loading__knot')
const sealStyle = getComputedStyle(seal)
const knotStyle = getComputedStyle(knot)
({
reduced: matchMedia('(prefers-reduced-motion: reduce)').matches,
sealAnimation: sealStyle.animationName,
sealTransform: sealStyle.transform,
sealOpacity: sealStyle.opacity,
sealAnimations: seal.getAnimations().length,
knotAnimation: knotStyle.animationName,
knotTransform: knotStyle.transform,
knotOpacity: knotStyle.opacity,
knotAnimations: knot.getAnimations().length
})
```
等待约 420ms 后再次读取。预期:
- `reduced``true`
- 两个 `animationName` 分别以新的 essential pulse 名称开头;Vue scoped CSS 可在运行时追加哈希后缀;
- 两个 `getAnimations().length` 均大于 0
- 两次读取的透明度不同;
- 两个 `transform` 均为 `none`
- 页面仍为 G01 加载态。
- [ ] **Step 6:捕获并人工检查当前候选帧**
使用当前唯一标签页保存:
```text
docs/design/screens/runtime/2026-07-19/g01-approval/03-loading-essential-motion-412x915.png
```
人工检查:标题栏、背景、印牌、如意结、两行文案和底部导航均完整;没有列表、失败态或原生 Loading 串入。静态截图不作为动画运行证明,动画结论以 Step 5 的多时点数据为准。
- [ ] **Step 7:运行受影响合同与空白检查**
运行:
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/g-series-app-loading-contract.ps1
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/module-app-loading-contract.ps1
git diff --check -- components/AppLoading.vue tests/app-loading-contract.ps1 docs/superpowers/specs/2026-07-19-app-loading-essential-motion-design.md docs/superpowers/plans/2026-07-19-app-loading-essential-motion.md
```
预期:两个合同均输出各自的 `PASS``git diff --check` 退出码为 0。不得把 Android/HBuilderX 写成已验证。
- [ ] **Step 8:回到同一加载态等待用户复核**
保持浏览器停留在修正后的 G01 加载态,不自动切换到失败态。只有用户明确说加载态“通过”后,才继续 G01 下一状态;在此之前 G01 保持 `[!]`
@@ -0,0 +1,200 @@
# F01 Family Feed Baseline Redesign Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. This project explicitly forbids subagents, worktrees, staging, and commits.
**Goal:** Replace F01's application-status cards with a dedicated transparent family-letter content card and make all four shortcuts usable at every supported viewport.
**Architecture:** Keep F01 state and navigation logic unchanged. Add one F01-owned raster card skin under the family module, update only F01 markup/styles, and protect the asset, hierarchy, touch-target, and state contracts with a focused PowerShell test plus existing runtime coverage.
**Tech Stack:** uni-app, Vue 3 `<script setup>`, SCSS, built-in image editing/generation, PowerShell contract tests, Chrome DevTools Protocol runtime smoke.
## Global Constraints
- Modify only F01 and its directly related tests, candidate asset, specs, plan, and screenshots.
- Keep PageHeader, publish routing, family context, module background, AppTabbar, feed states, shortcut labels, and destination routes unchanged.
- Do not use `application-status-card.png` in F01.
- Use a real F01-owned transparent PNG for the family-letter card; do not draw the card with CSS, SVG, text symbols, or placeholders.
- Shortcut and primary-action touch heights must be at least 44 CSS px at 320, 360, and 412 widths.
- Do not run git add, commit, push, reset, or checkout.
- Reuse the existing Chrome project tab and debugging port 9222.
- H5 screenshots are candidate evidence only; Android/HBuilderX remains unverified.
---
### Task 1: Lock the F01 baseline contract
**Files:**
- Create: `tests/f01-module-baseline-contract.ps1`
- Test: `tests/f01-module-baseline-contract.ps1`
**Interfaces:**
- Consumes: UTF-8 source of `pages/family/f01-family-feed.vue`.
- Produces: assertions for the dedicated card asset, no application card, explicit content hierarchy, and 44px shortcut height.
- [ ] **Step 1: Write the failing contract**
Create a test that checks:
```powershell
$ErrorActionPreference = 'Stop'
$root = Split-Path -Parent $PSScriptRoot
$page = Get-Content -LiteralPath (Join-Path $root 'pages/family/f01-family-feed.vue') -Raw -Encoding utf8
function Assert-Match([string]$Pattern, [string]$Message) {
if ($page -notmatch $Pattern) { throw $Message }
}
Assert-Match 'modules/family/transparent/f01-family-letter-card\.png' 'F01 must use its dedicated transparent family-letter card.'
if ($page -match 'application-status-card\.png') { throw 'F01 must not reuse the application status card.' }
Assert-Match 'class="feed-card__title"' 'F01 must expose an explicit feed title hierarchy.'
Assert-Match 'class="feed-card__meta"' 'F01 must expose category and time as secondary metadata.'
Assert-Match 'class="feed-card__summary"' 'F01 must expose feed summary copy.'
Assert-Match 'class="feed-card__author"' 'F01 must expose the author as tertiary information.'
Assert-Match '(?s)\.feed-shortcut\s*\{[^}]*min-height:\s*44px;' 'F01 shortcuts must preserve a 44 CSS px touch height.'
Write-Output 'F01-MODULE-BASELINE-CONTRACT PASS'
```
- [ ] **Step 2: Run and verify RED**
Run:
```powershell
powershell -ExecutionPolicy Bypass -File tests/f01-module-baseline-contract.ps1
```
Expected: FAIL because F01 still uses `application-status-card.png` and has no dedicated class hierarchy.
### Task 2: Create the dedicated family-letter card asset
**Files:**
- Create: `static/assets/modules/family/transparent/f01-family-letter-card.png`
- Preserve: every existing asset under `static/assets/modules/family/` and `static/assets/modules/genealogy/`.
**Interfaces:**
- Consumes: the accepted F01 screenshot and `family-page-background-long.png` as palette/context references.
- Produces: one transparent PNG content-card skin used by list, empty, and error states.
- [ ] **Step 1: Generate one chroma-key candidate with built-in image generation**
Use this exact design intent:
```text
Use case: precise-object-edit / UI asset generation
Asset type: F01 family-feed content-card skin
Primary request: create a wide traditional Chinese family-letter card with a warm ivory rice-paper interior, one restrained thin antique-gold border, subtle family-letter corner details, and no content text.
Composition: wide horizontal card, approximately 3.1:1, designed for a 386×124 CSS px slot.
Palette: match the existing family module background and cinnabar header; keep the card quiet enough for feed text.
Background: perfectly flat #00ff00 chroma key only outside the card.
Constraints: no red vertical line, no top-right status ornament, no buttons, no labels, no icons, no shadows, no white rectangle outside the gold border, no watermark.
```
- [ ] **Step 2: Convert chroma key to alpha and crop transparent bounds**
Use the installed `remove_chroma_key.py` with the real Python launcher at `C:\Users\Rain\AppData\Local\Python\bin\python.exe`, validate transparent corners and visible-card bounds, then save the non-destructive final file at the path above.
### Task 3: Implement F01 content hierarchy and touch targets
**Files:**
- Modify: `pages/family/f01-family-feed.vue`
- Modify: `tests/root-pages-visual-contract.ps1`
- Test: `tests/f01-module-baseline-contract.ps1`
**Interfaces:**
- Consumes: existing `feedState`, `feeds`, `shortcuts`, `toPublish`, `openDetail`, and `openSection` without signature changes.
- Produces: dedicated card markup/classes and 44px shortcut controls.
- [ ] **Step 1: Replace list-card markup**
Each `feed-card` must use the new asset and explicit hierarchy:
```vue
<image class="feed-card__skin" src="/static/assets/modules/family/transparent/f01-family-letter-card.png" mode="scaleToFill" />
<view class="feed-card__copy">
<text class="feed-card__meta">{{ item.tag }} · {{ item.time }}</text>
<text class="feed-card__title">{{ item.title }}</text>
<text class="feed-card__summary">{{ item.content }}</text>
<text class="feed-card__author">发布人{{ item.author }}</text>
</view>
```
- [ ] **Step 2: Replace empty/error panel skin**
Use the same F01 asset for `feed-state-card`, preserving current empty/error copy and retry behavior.
- [ ] **Step 3: Tighten styles**
Set `.feed-shortcut` to `min-height: 44px`, place one shared `a01-scroll-secondary-v3.png` skin behind a four-column equal-width shortcut grid, make the title the largest feed-card text, and keep two equal-height cards between 116 and 132 CSS px at 412px width. Do not add decorative CSS shapes.
- [ ] **Step 4: Update the root-page asset contract**
Replace only F01's required `application-status-card.png` entry with `f01-family-letter-card.png`; leave N01 and M01 requirements unchanged.
- [ ] **Step 5: Run and verify GREEN**
Run:
```powershell
powershell -ExecutionPolicy Bypass -File tests/f01-module-baseline-contract.ps1
```
Expected: `F01-MODULE-BASELINE-CONTRACT PASS`.
### Task 4: Regression and visual verification
**Files:**
- Verify: `pages/family/f01-family-feed.vue`
- Create evidence only under: `docs/design/screens/runtime/2026-07-19/f01-baseline-redesign/`
**Interfaces:**
- Consumes: running H5 service on 5173 and the unique existing Chrome project tab on 9222.
- Produces: regression output, responsive metrics, and accepted F01 screenshots.
- [ ] **Step 1: Run related contracts**
Run:
```powershell
powershell -ExecutionPolicy Bypass -File tests/f01-module-baseline-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/f-series-all-states-visual-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/root-pages-visual-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/module-app-loading-contract.ps1
```
Expected: every command reports PASS.
- [ ] **Step 2: Run runtime coverage**
Run:
```powershell
node tests/root-pages-runtime-smoke.js
node tests/module-series-responsive-runtime-smoke.js
```
Expected: both commands report PASS and only one project tab is used.
- [ ] **Step 3: Capture and inspect F01 states**
Capture list, loading, empty, and error at 412×915. First present only the normal list state for user approval; keep later states hidden until requested.
- [ ] **Step 4: Self-audit responsive sizes**
Capture 320×568, 360×640, 360×800, and 412×915 list state. Verify no overflow, clipped text, card mismatch, shortcut below 44px, or Tab overlap. Restore the tab to 412×915.
- [ ] **Step 5: Run source hygiene checks**
Run:
```powershell
git diff --check
git status --short
```
Expected: no whitespace errors; all pre-existing modified and untracked files remain present. Do not stage or commit anything.
## Self-Review
- Spec coverage: dedicated family card, no white gutter/application semantics, hierarchy, states, 44px shortcuts, responsive sizes, interactions, and evidence limits are covered.
- Placeholder scan: no TBD, TODO, deferred asset decision, or unspecified command remains.
- Interface consistency: F01 state and navigation functions stay unchanged; new class names match the focused contract and implementation steps.
@@ -0,0 +1,156 @@
# G01 添加家谱弹层按钮等宽 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. The user explicitly forbids subagents and worktrees, so execution must remain inline in the current workspace. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 仅在 G01“添加家谱”底部弹层内,让三个现有卷轴按钮以当前红色主按钮的可见宽度为基准左右对齐。
**Architecture:** 保留公共 `AppButton` 及两张现有按钮皮肤不变,在 G01 页面作用域内统一三个按钮根容器的响应式宽高并居中。容器比例按次按钮资产比例设置,使主、次两种 `aspectFit` 皮肤都由宽度约束,从而端点对齐且不横向拉伸。
**Tech Stack:** uni-app、Vue 3 `<script setup>`、SCSS、PowerShell 合同测试、Chrome DevTools Protocol 9222。
## Global Constraints
- 只修改 G01 当前“添加家谱”弹层,不修改公共 `AppButton`、按钮 PNG、其他状态或其他页面。
- 三个按钮使用 `595rpx × 96rpx` 响应式基准,`max-width: 100%`,水平居中。
- 相邻按钮间距保持 `24rpx`;弹层 `780rpx` 最低高度、内容安全居中和最大高度滚动合同保持不变。
- 继续复用 `a01-scroll-primary-v3.png``a01-scroll-secondary-v3.png`,保持 `aspectFit`,不得拉伸、重绘或生成替代资产。
- 复用 9222 上唯一的 `localhost:5173` 项目标签页,不打开第二个浏览器或第二个项目标签页。
- 不使用多代理、worktree;不执行 `git add``commit``push``reset``checkout`;不删除或清理任何现有文件。
- H5 证据仅为内部候选;Android/HBuilderX 仍为未验证项;未经用户明确“通过”不得标记或冻结 G01。
---
### Task 1: 为 G01 局部等宽规则建立合同并最小实现
**Files:**
- Modify: `tests/g01-visual-contract.ps1`
- Modify: `pages/genealogy/g01-my-genealogies.vue`
**Interfaces:**
- Consumes: `AppButton` 根节点已有 `.app-button``.app-button--block` 类;G01 已有 `.add-dialog__actions` 容器。
- Produces: 仅由 `.add-dialog__actions > .app-button` 消费的 `595rpx × 96rpx` 局部尺寸合同。
- [ ] **Step 1: 写入失败合同**
`tests/g01-visual-contract.ps1` 的添加家谱弹层样式断言中加入:
```powershell
if ($page -notmatch '(?s)\.add-dialog__actions\s*>\s*\.app-button\s*\{[^}]*width:\s*595rpx;[^}]*max-width:\s*100%;[^}]*min-height:\s*96rpx;') {
throw 'G-01 add sheet buttons do not keep the approved equal-width geometry.'
}
if ($page -notmatch '(?s)\.add-dialog__actions\s*\{[^}]*align-items:\s*center;') {
throw 'G-01 add sheet buttons are not centered after equal-width sizing.'
}
```
- [ ] **Step 2: 运行合同并确认 RED**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1
```
Expected: FAIL,输出包含 `G-01 add sheet buttons do not keep the approved equal-width geometry.`
- [ ] **Step 3: 写入最小页面级实现**
将 G01 当前动作组样式调整为:
```scss
.add-dialog__actions { display: flex; flex-direction: column; align-items: center; margin: 62rpx -32rpx 0; }
.add-dialog__actions > .app-button { width: 595rpx; max-width: 100%; min-height: 96rpx; }
.add-dialog__actions > .app-button + .app-button { margin-top: 24rpx; }
```
不得修改 `components/AppButton.vue`,不得修改两个按钮 PNG。
- [ ] **Step 4: 运行聚焦合同并确认 GREEN**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1
```
Expected: `PASS G-01 visual contract`
- [ ] **Step 5: 运行相邻 G01 状态合同**
Run each command independently:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-empty-state-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-loading-state-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-error-state-contract.ps1
git diff --check
```
Expected: 三个状态合同均输出 `PASS``git diff --check` 退出码为 0,允许仅出现工作区既有的 LF/CRLF 警告。
### Task 2: 在唯一 Chrome 标签页验证等宽、响应式与压力状态
**Files:**
- Modify: `design-qa.md`
- Create: `docs/design/screens/runtime/2026-07-19/g01-approval/05-add-dialog-equal-width-412x915.png`
- Create: `docs/design/screens/runtime/2026-07-19/g01-approval/05-add-dialog-equal-width-320x568.png`
- Create: `docs/design/screens/runtime/2026-07-19/g01-approval/05-add-dialog-equal-width-six-buttons-412x915.png`
**Interfaces:**
- Consumes: 9222 上唯一的 `localhost:5173` 页面及 G01 已打开的三按钮弹层。
- Produces: 用户可在原标签页审批的 412×915 三按钮状态,以及等宽、响应式和长内容内部证据。
- [ ] **Step 1: 确认服务和唯一项目标签页**
读取 `http://127.0.0.1:9222/json/list`,只选择 URL 以 `http://localhost:5173` 开头且 `type``page` 的项目页。
Expected: 项目页数量严格为 1;若不是 1,停止,不创建新浏览器或标签页。
- [ ] **Step 2: 验证 412×915 正常三按钮状态**
通过当前 CDP 会话将视口保持为 `412×915`,读取三个 `.add-dialog__actions .app-button` 的矩形和相邻间距,并捕获实现截图。
Expected:
```text
buttonCount = 3
每个按钮根容器宽度约 326.8px
三个按钮 left/right 偏差不超过 0.5px
相邻外层间距约 13.17px
dialogHeight 仍约 430.47px
body topSpace 与 bottomSpace 偏差不超过 1px
horizontalOverflow = false
```
同时目视确认红色与米色皮肤左右卷轴端点对齐、图案未横向变形、文字仍居中。
- [ ] **Step 3: 验证 320×568 响应式状态**
在同一标签页临时切换至 `320×568`,保持三个按钮和当前弹层打开。
Expected: 三个按钮左右端点对齐、完整可见、无横向溢出;标题、说明、关闭入口与按钮互不遮挡。
- [ ] **Step 4: 验证六按钮与超高滚动压力状态**
只通过当前页面运行时临时克隆按钮验证布局,不写入生产数据;先检查六按钮自然增高,再检查 18 按钮最大高度滚动。
Expected: 六按钮左右端点一致且间距稳定;18 按钮初始 `scrollTop = 0`、标题可达,滚动到底后末项可见;无横向溢出。验证后移除所有临时克隆。
- [ ] **Step 5: 恢复用户审批状态**
将同一标签页恢复为 `412×915`、三按钮、弹层打开,确认不存在临时克隆或注入样式。
Expected: 项目标签页数量仍为 1,用户只看到本轮等宽候选。
- [ ] **Step 6: 更新设计质检证据**
`design-qa.md` 当前 G01 添加家谱小节记录:源规格、三档截图、同尺寸对比、计算宽度、端点偏差、间距、居中、压力滚动、交互、控制台与证据限制。
Expected: H5 内部候选不存在可执行 P0/P1/P2 时写 `final result: passed`;同时明确“用户尚未通过”和“Android/HBuilderX 未验证”。
- [ ] **Step 7: 运行最终新鲜验证**
重新运行 Task 1 Step 4-5 的四个合同和 `git diff --check`,并重新读取当前浏览器最终状态。
Expected: 所有合同退出码为 0;唯一项目标签页为 `412×915`、三按钮、弹层打开、按钮等宽、无横向溢出。
@@ -0,0 +1,215 @@
# G01 可伸缩完整底板实施计划
> **执行方式:** 仅允许在当前会话内使用 `superpowers:executing-plans` 逐项执行。用户明确禁止多代理、worktree、`git add`、`commit`、`push`、`reset` 和 `checkout`,因此本计划不包含分派、提交或分支步骤。
**目标:** 将 G01“添加家谱”弹层从“矩形宣纸 + 顶部过渡图”拼接结构改为单张完整 PNG,并只伸缩中间宣纸区域,使三按钮状态与未来长内容状态共用同一底板且顶部装饰不变形。
**架构:** `g01-add-sheet-background-v3.png` 是弹层底板的唯一视觉源。G01 本地使用 CSS `border-image` 的纵向三段伸缩:固定源图顶部 `220px` 装饰安全区、固定底部 `1px` 收口、填充并纵向伸缩中间宣纸区域;标题、关闭图标和现有 `AppButton` 保持独立交互节点。本轮不抽取通用组件,也不修改其他页面。
**技术栈:** uni-app、Vue 3 `<script setup>`、SCSS、CSS `border-image`、现有 `AppButton`、PowerShell 契约测试、Chrome DevTools Protocol 9222。
## 全局约束
- 只修改 G01 当前“添加家谱”弹层、对应契约、规格、计划和内部候选证据。
- 保留所有已修改、未跟踪、候选、母版、截图和资产文件,不删除或覆盖历史文件。
- 不使用多代理或 worktree,不执行任何 Git 写操作。
- 三个按钮继续直接复用现有 `AppButton``a01-scroll-primary-v3.png``a01-scroll-secondary-v3.png`
- 不对接接口,不改变 `applyToJoin``joinByInvite``createGenealogy` 跳转逻辑。
- 只复用当前 9222 Chrome 窗口和唯一项目标签页,不打开第二个项目标签页。
- H5 截图只作为内部候选;Android/HBuilderX 继续标记为未验证。
- 未经用户明确“通过”,不得冻结 G01 或更新为 `[x]`
---
### 任务 1:用视觉契约锁定单张底板和伸缩规则
**文件:**
- 修改:`tests/g01-visual-contract.ps1`
- 测试:`tests/g01-visual-contract.ps1`
**接口:**
- 消费:规格中的唯一底板路径 `static/assets/modules/genealogy/transparent/g01-add-sheet-background-v3.png`
- 产出:模板、资产路径、旧拼接禁令和 `border-image` 切片参数的静态合同。
- [ ] **步骤 1:把旧拼接断言改为完整底板断言**
`$addMarkup` 合同中要求:
```powershell
$requiredAddTokens = @(
'class="add-dialog"',
'class="add-dialog__actions"',
'class="add-dialog__close-icon"'
)
if ($addMarkup -match 'add-dialog__paper|add-dialog__edge|page-paper\.jpg|a01-paper-transition-v1\.png') {
throw 'G-01 add sheet still assembles its background from separate paper and edge layers.'
}
if ($page -notmatch [regex]::Escape('/static/assets/modules/genealogy/transparent/g01-add-sheet-background-v3.png')) {
throw 'G-01 add sheet does not use the approved complete background asset.'
}
```
增加伸缩参数合同:
```powershell
if ($page -notmatch '(?s)\.add-dialog\s*\{[^}]*border-image-source:\s*url\("/static/assets/modules/genealogy/transparent/g01-add-sheet-background-v3\.png"\);[^}]*border-image-slice:\s*220\s+0\s+1\s+0\s+fill;[^}]*border-image-width:\s*118rpx\s+0\s+1rpx;') {
throw 'G-01 add sheet does not preserve the complete sheet top while stretching only the paper body.'
}
```
- [ ] **步骤 2:运行契约并确认按预期失败**
运行:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1
```
预期:FAIL,错误明确指出仍存在 `add-dialog__paper` / `add-dialog__edge` 拼接结构或缺少完整底板资产引用;不能因语法、编码或文件缺失以外的原因失败。
---
### 任务 2:最小替换为完整可伸缩底板
**文件:**
- 修改:`pages/genealogy/g01-my-genealogies.vue`
- 使用:`static/assets/modules/genealogy/transparent/g01-add-sheet-background-v3.png`
- 测试:`tests/g01-visual-contract.ps1`
**接口:**
- 消费:任务 1 的资产路径和切片参数合同。
- 产出:`.add-dialog` 单背景伸缩结构;现有关闭和三个按钮交互保持不变。
- [ ] **步骤 1:删除模板中的两个拼接背景节点**
将:
```vue
<image class="add-dialog__paper" src="/static/assets/foundation/opaque/page-paper.jpg" mode="aspectFill" />
<view class="add-dialog__edge" aria-hidden="true">
<image class="add-dialog__edge-image" src="/static/assets/modules/auth/transparent/a01-paper-transition-v1.png" mode="widthFix" />
</view>
```
从当前添加弹层模板移除。不要删除对应静态资产文件;切换家谱弹层保持原样。
- [ ] **步骤 2:让 `.add-dialog` 直接消费完整底板**
用以下本地样式替换 `.add-dialog__paper``.add-dialog__edge``.add-dialog__edge-image`
```scss
.add-dialog {
position: relative;
width: 100%;
max-height: calc(100vh - 80rpx);
box-sizing: border-box;
border: 1px solid transparent;
border-image-source: url("/static/assets/modules/genealogy/transparent/g01-add-sheet-background-v3.png");
border-image-slice: 220 0 1 0 fill;
border-image-width: 118rpx 0 1rpx;
border-image-repeat: stretch;
}
```
保持 `.add-dialog__content``.add-dialog__heading`、关闭热区和 `.add-dialog__actions` 的内容结构;若完整底板使标题压到透明区,只允许微调 `.add-dialog__content` 的顶部内边距,不改变按钮资产或全局 `AppButton`
- [ ] **步骤 3:运行 G01 视觉契约确认转绿**
运行:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1
```
预期:`PASS G-01 visual contract`
- [ ] **步骤 4:运行已通过状态的回归契约**
运行:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-empty-state-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-loading-state-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-error-state-contract.ps1
git diff --check
```
预期:四项均退出码 `0`;前三项分别输出 PASS`git diff --check` 不报告空白错误。不得修改或放宽既有阈值。
---
### 任务 3:验证三按钮高度与长内容压力高度
**文件:**
- 新增内部候选:`docs/design/screens/runtime/2026-07-19/g01-approval/05-add-dialog-complete-sheet-412x915.png`
- 新增内部候选:`docs/design/screens/runtime/2026-07-19/g01-approval/05-add-dialog-complete-sheet-pressure-412x915.png`
- 修改:`design-qa.md`
**接口:**
- 消费:任务 2 的 `.add-dialog``.add-dialog__actions` 和完整底板。
- 产出:同一资产在基准高度和压力高度下的 H5 运行证据;最终恢复正常三按钮状态供用户审批。
- [ ] **步骤 1:只读确认服务和唯一项目标签页**
运行:
```powershell
Invoke-WebRequest -UseBasicParsing 'http://127.0.0.1:5173' | Select-Object StatusCode
Invoke-RestMethod 'http://127.0.0.1:9222/json/list' | Where-Object { $_.type -eq 'page' -and $_.url -like 'http://localhost:5173*' } | Select-Object id,url
```
预期:5173 返回 `200`;项目 page 恰好一个。不启动 Chrome,不创建新标签页。
- [ ] **步骤 2:验证正常三按钮状态**
通过当前 page 的 CDP
```text
Emulation.setDeviceMetricsOverride -> 412×915
若 .add-dialog 不存在,仅点击当前 .create-action
读取 .add-dialog、.add-dialog__content、三个 .app-button 的矩形
读取 borderImageSource、borderImageSlice、borderImageWidth
Page.captureScreenshot
```
预期:弹层贴底、无横向溢出,标题、说明、关闭和三个按钮全部可见;计算样式引用 `g01-add-sheet-background-v3.png`,切片为 `220 0 1 fill`,顶部曲线和纸面无接缝。
- [ ] **步骤 3:验证长内容只扩展中间纸面**
仅在 CDP 当前文档中临时克隆三个 `.app-button``.add-dialog__actions`,不写入源码;等待布局稳定后读取弹层高度并捕获压力图。
预期:弹层高度大于基准高度;背景仍为同一资产;顶部曲线、如意结和圆肩的可见高度与基准图一致;中间纸面扩展;内容超过安全高度时 `.add-dialog__content` 可纵向滚动;无横向溢出。
- [ ] **步骤 4:恢复正常审批状态并复测交互**
通过同一 page 执行 reload 或移除临时克隆节点,重新打开添加弹层,恢复 `412×915`。依次验证关闭图标关闭、重新打开、点击弹层内部不关闭、点击遮罩关闭、重新打开后列表位置不变。
预期:最终唯一项目标签页停留在正常三按钮“添加家谱”弹层,供用户审批;不展示压力态给用户作为当前状态。
- [ ] **步骤 5:完成内部设计 QA 记录**
`design-qa.md` 追加本轮条目,必须记录:
```markdown
- source visual truth path: docs/design/mockups/2026-07-19/g01-add-dialog-paper-sheet-target.png
- implementation screenshot path: docs/design/screens/runtime/2026-07-19/g01-approval/05-add-dialog-complete-sheet-412x915.png
- pressure screenshot path: docs/design/screens/runtime/2026-07-19/g01-approval/05-add-dialog-complete-sheet-pressure-412x915.png
- viewport: 412×915(另查 320×568
- state: G01 添加家谱,正常三按钮与长内容压力态
- final result: passed 或 blocked
```
只有并排对照后不存在可执行 P0/P1/P2 问题时才写 `final result: passed`;否则保持 `blocked` 并继续只返工当前弹层。
---
## 完成条件
- 运行时底板只有 `g01-add-sheet-background-v3.png` 一个视觉源,不再拼接 `page-paper.jpg``a01-paper-transition-v1.png`
- 三按钮和长内容压力态共用同一底板,顶部装饰不随高度拉伸。
- 当前按钮样式、关闭交互、遮罩交互、Android 返回键和列表位置保持合同。
- G01 四项相关契约与 `git diff --check` 通过。
- 唯一 Chrome 标签页最终显示 412×915 正常三按钮添加弹层。
- G01 仍未冻结、未标 `[x]`Android/HBuilderX 仍明确未验证。
@@ -0,0 +1,216 @@
# N01 消息中心基准页 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 将 N01 重做为 N 系列消息中心视觉基准,并完成列表、已读、全部已读、加载、空、失败和审核跳转的 H5 审批状态。
**Architecture:** `pages/notification/n01-message-center.vue` 单独拥有本地演示数据、状态与交互;项目现有 `PageHeader``AppButton``AppLoading``AppToast``ModulePageBackground` 继续作为公共组件。N01 使用本模块独立的透明位图线框,不再引用家谱申请业务卡片。
**Tech Stack:** uni-app、Vue 3 `<script setup>`、SCSS、PowerShell 契约测试、Node CDP 运行时冒烟。
## Global Constraints
- 只处理 N01,不对接接口,不修改 N02 或其他模块页面。
- 不使用子代理或 worktree。
- 不执行 `git add``commit``push``reset``checkout`
- 保留当前全部已修改、未跟踪和忽略文件。
- 所有 Toast、Loading 和按钮使用项目自定义组件。
- 每次只向用户展示一个状态;用户全部明确“通过”后才标记 N01 为 `[x]`
- Android/HBuilderX 仍未验证,H5 截图只作为内部候选证据。
---
### Task 1: 锁定 N01 独立页面契约
**Files:**
- Create: `tests/n01-module-baseline-contract.ps1`
- Modify: `pages/notification/n01-message-center.vue`
**Interfaces:**
- Consumes: `AppButton``AppLoading``AppToast``ModulePageBackground``PageHeader`
- Produces: 可由 `?state=loading|empty|error` 复现的 N01 页面,以及 `.notice-state--list``.notice-state--loading``.notice-state--empty``.notice-state--error` DOM 状态类。
- [ ] **Step 1: 写入失败契约**
```powershell
$source = Get-Content 'pages/notification/n01-message-center.vue' -Raw -Encoding UTF8
$required = @(
'n01-notice-card.png', 'AppLoading', 'AppToast',
'notice-state--loading', 'notice-state--list',
'notice-state--empty', 'notice-state--error',
'未读', '已读', '全部已读', '前往入谱审核'
)
foreach ($token in $required) {
if (-not $source.Contains($token)) { throw "N01 missing contract token: $token" }
}
if ($source.Contains('application-status-card.png')) {
throw 'N01 must not reuse the genealogy application card'
}
Write-Output 'N01-MODULE-BASELINE-CONTRACT PASS'
```
- [ ] **Step 2: 运行契约并确认 RED**
Run: `powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/n01-module-baseline-contract.ps1`
Expected: FAIL,至少指出缺少 `n01-notice-card.png` 或仍引用 `application-status-card.png`
- [ ] **Step 3: 只添加后续实现所需状态类和资产引用,保持测试继续驱动页面实现**
将根节点状态类补齐为:
```vue
<view class="notice-page" :class="`notice-state--${noticeState}`">
```
资产引用统一为:
```vue
<image src="/static/assets/modules/notification/transparent/n01-notice-card.png" mode="scaleToFill" />
```
### Task 2: 制作 N01 透明消息线框资产
**Files:**
- Create: `static/assets/modules/notification/transparent/n01-notice-card.png`
- Preserve: `tmp/imagegen/` 下的生成源图与后处理证据。
**Interfaces:**
- Produces: 约 3:1 比例、四角透明、无文字无底色的古金色消息卡线框 PNG。
- [ ] **Step 1: 用内置 ImageGen 生成可抠色源图**
Prompt:
```text
Use case: ui-mockup
Asset type: scalable message-list card frame for a Chinese genealogy mobile app
Primary request: a restrained traditional Chinese archival card border made only from thin antique-gold linework
Style/medium: refined Song/Yuan inspired ornamental line art, visually consistent with the existing R01 transparent person card
Composition/framing: wide horizontal 3:1 frame, symmetrical corners, quiet center, generous inner text area
Scene/backdrop: perfectly flat solid #00ff00 chroma-key background inside and outside the border
Constraints: no fill panel, no paper texture, no white background, no red marks, no bell icon, no text, no badge, no shadow, no watermark; do not use #00ff00 in the ornament
```
- [ ] **Step 2: 使用 imagegen 技能自带抠色脚本输出透明 PNG**
Run:
```powershell
& 'C:\Users\Rain\AppData\Local\Python\bin\python.exe' 'C:\Users\Rain\.codex\skills\.system\imagegen\scripts\remove_chroma_key.py' --input 'tmp/imagegen/n01-notice-card-chroma.png' --out 'static/assets/modules/notification/transparent/n01-notice-card.png' --auto-key border --soft-matte --transparent-threshold 12 --opaque-threshold 220 --despill
```
- [ ] **Step 3: 检查资产透明度和边缘**
Run:
```powershell
& 'C:\Users\Rain\AppData\Local\Python\bin\python.exe' -c "from PIL import Image; p='static/assets/modules/notification/transparent/n01-notice-card.png'; im=Image.open(p); assert im.mode=='RGBA'; a=im.getchannel('A'); assert a.getpixel((0,0))==0; assert a.getbbox(); print('N01-ASSET-ALPHA PASS', im.size)"
```
Expected: `N01-ASSET-ALPHA PASS`
### Task 3: 实现 N01 列表与审批状态
**Files:**
- Modify: `pages/notification/n01-message-center.vue`
- Test: `tests/n01-module-baseline-contract.ps1`
**Interfaces:**
- `readNotice(item)`:把单条 `item.unread` 设为 `false`
- `markAllRead()`:把全部消息设为已读,并显示“已全部标记为已读”自定义 Toast。
- `restoreList()`:把错误态恢复为列表态。
- `toReview()`:保留 `/pages/genealogy/g10-application-review?genealogyId=...` 路由。
- [ ] **Step 1: 将模板整理为四个明确分支**
```vue
<AppLoading v-if="noticeState === 'loading'" text="正在整理消息" description="请稍候,正在同步家谱申请与家族提醒。" />
<view v-else-if="noticeState === 'list'" class="notice-list">...</view>
<view v-else class="notice-state-card">...</view>
```
列表卡片需使用以下文字层级:
```vue
<text class="notice-card__status" :class="{'is-unread': item.unread}">{{ item.unread ? '未读提醒' : '已读' }} · {{ item.time }}</text>
<text class="notice-card__title">{{ item.title }}</text>
<text class="notice-card__summary">{{ item.content }}</text>
```
- [ ] **Step 2: 统一空态与失败态操作**
```vue
<AppButton
block
:type="noticeState === 'error' ? 'secondary' : 'primary'"
:label="noticeState === 'error' ? '重新查看' : '前往入谱审核'"
@click="noticeState === 'error' ? restoreList() : toReview()"
/>
```
- [ ] **Step 3: 让卡片自适应内容并移除白底来源**
```scss
.notice-content { padding: 24rpx 28rpx 100rpx; }
.notice-list { display: flex; flex-direction: column; gap: 18rpx; }
.notice-card { position: relative; min-height: 220rpx; }
.notice-card__skin { position: absolute; inset: 0; width: 100%; height: 100%; }
.notice-card__copy { position: relative; z-index: 1; padding: 34rpx 44rpx; }
.notice-card__status { color: $ink-muted; }
.notice-card__status.is-unread { color: $brand-red; font-weight: 700; }
.notice-card__title { margin-top: 8rpx; color: $ink; font-family: STKaiti, KaiTi, serif; font-weight: 700; }
.notice-review-action { margin: 30rpx auto 0; }
```
- [ ] **Step 4: 运行聚焦契约并确认 GREEN**
Run: `powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/n01-module-baseline-contract.ps1`
Expected: `N01-MODULE-BASELINE-CONTRACT PASS`
### Task 4: 运行时验证并进入逐状态审批
**Files:**
- Create: `docs/design/screens/runtime/2026-07-19/n01-review/*.png`
- Modify only after all explicit approvals: `docs/验收规划.md`
**Interfaces:**
- Consumes: 单个现有 Chrome 项目标签页和调试端口 9222。
- Produces: 412×915 的逐状态审批画面,以及四档响应式内部证据。
- [ ] **Step 1: 运行静态和运行时检查**
Run:
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/n01-module-baseline-contract.ps1
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/root-pages-visual-contract.ps1
node tests/root-pages-runtime-smoke.js
node tests/module-series-responsive-runtime-smoke.js
git diff --check
```
Expected: 所有测试输出 `PASS``git diff --check` 退出码为 0,允许已有行尾提示。
- [ ] **Step 2: 复用同一标签页显示 412×915 正常列表态**
Run:
```powershell
node scripts/capture-chrome-page.js 'http://localhost:5173/#/pages/notification/n01-message-center' '.notice-state--list' 'docs/design/screens/runtime/2026-07-19/n01-review/01-list-412x915.png' 412 915
```
Inspect: 打开保存的截图,确认没有白底块、裁切、错误页面或半加载内容,再等待用户审批。
- [ ] **Step 3: 按顺序展示其余状态**
顺序:单条已读 → 全部已读 Toast → 加载 → 空 → 失败 → 审核跳转。每次只显示一个状态并等待用户确认。
- [ ] **Step 4: 内部检查四档尺寸**
尺寸:`320×568``360×640``360×800``412×915`。发现问题只返工 N01;未发现问题不逐档打断用户。
- [ ] **Step 5: 所有状态明确通过后更新审批记录**
仅把 `docs/验收规划.md` 的 N01 行从 `[~]` 改为 `[x]`,随后重新运行 Task 4 Step 1 的全部验证。
@@ -0,0 +1,116 @@
# R01 People Directory Baseline Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. This project explicitly forbids subagents, worktrees, staging, and commits.
**Goal:** Replace R01's generic application-style list with a dedicated transparent people-directory page that supports local search, empty, and error review states.
**Architecture:** Keep R01 isolated in `pages/records/r01-people-list.vue` so the shared `ModulePage.vue` and every other R page remain unchanged. Reuse existing project components and controls, add one R01-owned raster card skin, and guard the new ownership and interaction contracts with focused tests.
**Tech Stack:** uni-app, Vue 3 `<script setup>`, SCSS, built-in image generation and alpha post-processing, PowerShell contracts, Chrome DevTools Protocol runtime capture.
## Global Constraints
- Modify only R01 and its directly related test, asset, spec, plan, QA note, and screenshots.
- Do not modify `ModulePage.vue`, other R pages, public components, API code, or routes.
- Do not use `application-status-card.png` or CSS/SVG drawings in R01.
- Keep every touch target at least 44 CSS px.
- Do not use subagents, worktrees, git add, commit, push, reset, or checkout.
- Reuse the existing Chrome project tab on port 9222.
- H5 evidence does not prove Android/HBuilderX behavior.
---
### Task 1: Lock the R01 ownership and visual contract
**Files:**
- Create: `tests/r01-module-baseline-contract.ps1`
- Test: `tests/r01-module-baseline-contract.ps1`
**Interfaces:**
- Consumes: UTF-8 source of `pages/records/r01-people-list.vue`.
- Produces: assertions for R01 ownership, card asset, search, state classes, custom feedback, and 44px targets.
- [ ] **Step 1: Write a failing contract**
Assert that R01 contains `r01-person-name-card.png`, `people-search`, `people-state--empty`, `people-state--error`, `AppButton`, `AppToast`, and a `min-height:44px` search action; reject `ModulePage` and `application-status-card.png`.
- [ ] **Step 2: Verify RED**
Run `powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/r01-module-baseline-contract.ps1`.
Expected: FAIL because the current page only renders `ModulePage`.
### Task 2: Create the R01 transparent name-card asset
**Files:**
- Create: `static/assets/modules/records/transparent/r01-person-name-card.png`
**Interfaces:**
- Consumes: R module background palette and the accepted line-only F01 card restraint as visual context.
- Produces: one wide transparent PNG with restrained antique-gold name-card linework and no paper fill, text, status marks, or white background.
- [ ] **Step 1: Generate the raster candidate**
Use built-in image generation for a wide 3.4:1 traditional Chinese archival name-card line frame on flat green chroma outside and inside the frame.
- [ ] **Step 2: Convert chroma and paper pixels to alpha**
Use the real Python launcher and Pillow to preserve only antique-gold linework, crop transparent bounds, save the final asset, and inspect the original-resolution PNG.
### Task 3: Implement the isolated R01 page
**Files:**
- Modify: `pages/records/r01-people-list.vue`
- Test: `tests/r01-module-baseline-contract.ps1`
**Interfaces:**
- Consumes: `PageHeader`, `ModulePageBackground`, `AppButton`, `AppToast`, and the R01 asset.
- Produces: local ready/empty/error/search-no-result rendering and local search over three people.
- [ ] **Step 1: Replace `ModulePage` with R01-owned markup**
Render the records background, page header, existing search-frame asset, filtered cards, state panel, action button, and custom Toast. Do not render a numbered intro block below the header.
- [ ] **Step 2: Add local state and interactions**
Read `state=empty|error` from the current hash/query; filter by name, role, or generation; clear search to restore all records; card clicks navigate to R02; new-person action opens `AppToast`; error action restores ready.
- [ ] **Step 3: Add scoped responsive styles**
Use transparent overlays, equal card sizes, clear hierarchy, no white wrapper backgrounds, no horizontal overflow, and minimum 44px controls.
- [ ] **Step 4: Verify GREEN**
Run the focused contract and require `R01-MODULE-BASELINE-CONTRACT PASS`.
### Task 4: Regression and visual verification
**Files:**
- Verify: `pages/records/r01-people-list.vue`
- Create evidence under: `docs/design/screens/runtime/2026-07-19/r01-baseline-redesign/`
**Interfaces:**
- Consumes: H5 service on 5173 and the unique existing Chrome project tab on 9222.
- Produces: test output, responsive evidence, and one user-visible state at a time.
- [ ] **Step 1: Run related contracts and runtime smoke**
Run the focused contract, R-series visual contract, root runtime smoke, responsive runtime smoke, and `git diff --check`.
- [ ] **Step 2: Capture and compare normal list**
Capture 412×915 and compare against `r01-baseline-audit/01-list-412x915.png`; fix P0/P1/P2 issues before showing it.
- [ ] **Step 3: Self-audit responsive sizes**
Capture 320×568, 360×640, 360×800, and 412×915; confirm no overflow or clipping and restore 412×915.
- [ ] **Step 4: Present states sequentially**
Present normal list, search no result, empty, failure, and new-person Toast one at a time. Do not mark R01 `[x]` until the user explicitly passes the page.
## Self-Review
- Spec coverage: ownership, asset, white-background removal, search, states, interactions, responsive targets, and evidence limits are covered.
- Placeholder scan: no unresolved design or implementation decision remains.
- Interface consistency: R01 owns its local data and state; shared components and other R pages remain unchanged.
@@ -0,0 +1,159 @@
# T07 Search and Member Card Redesign Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. This project explicitly forbids subagents and git commits.
**Goal:** Remove T07 search/card white gutters and rebuild the member list with approved transparent project assets and clearer information hierarchy.
**Architecture:** Keep all route state and interaction logic inside the existing T07 page. Replace only the two incorrect opaque skins with existing transparent G01-approved assets, then tighten T07-scoped markup and styles. Protect the asset and layout contract with the existing PowerShell contract test and verify behavior in the already-open Chrome tab.
**Tech Stack:** uni-app, Vue 3 `<script setup>`, SCSS, PowerShell contract tests, Chrome DevTools Protocol runtime smoke.
## Global Constraints
- Modify only T07 and its directly related test/evidence files.
- Do not modify page header, current-genealogy context, route states, search behavior, or member navigation behavior.
- Use `t07-search-input-frame.png` for search and `list-slip-frame.png` for cards; do not add a generation seal or draw replacements in CSS/SVG.
- Do not use `g06-search-input-wide.png` or `application-status-card.png` in T07.
- Do not run git add, commit, push, reset, or checkout.
- Reuse the existing Chrome project tab; do not open another browser or project tab.
- H5 evidence is only candidate evidence; Android/HBuilderX remains unverified.
---
### Task 1: Lock the transparent-asset contract
**Files:**
- Modify: `tests/t07-module-baseline-contract.ps1`
- Test: `tests/t07-module-baseline-contract.ps1`
**Interfaces:**
- Consumes: raw source of `pages/tree/t07-member-directory.vue`.
- Produces: assertions that T07 uses the approved transparent skins and no longer references the two opaque skins.
- [ ] **Step 1: Write the failing assertions**
Add assertions equivalent to:
```powershell
Assert-Match 'transparent/list-slip-frame\.png' 'T07 search and cards must use the approved transparent frame.'
if ($page -match 'g06-search-input-wide\.png|application-status-card\.png') {
throw 'T07 must not reuse opaque search or application-status skins.'
}
if ($page -match 'row-seal-frame\.png|directory-card__seal') {
throw 'T07 member cards must not repeat generation information in decorative seals.'
}
Assert-Match 'class="directory-card__status"' 'T07 member identity or profile state must use a dedicated status label.'
```
- [ ] **Step 2: Run the contract and verify RED**
Run:
```powershell
powershell -ExecutionPolicy Bypass -File tests/t07-module-baseline-contract.ps1
```
Expected: FAIL because the current page still references `g06-search-input-wide.png` and `application-status-card.png` and has no seal/status structure.
### Task 2: Implement the approved T07 visual structure
**Files:**
- Modify: `pages/tree/t07-member-directory.vue`
- Test: `tests/t07-module-baseline-contract.ps1`
**Interfaces:**
- Consumes: existing `members`, `filteredMembers`, `searchMembers`, `openMember`, and route-state behavior without signature changes.
- Produces: transparent framed search field and compact transparent member cards.
- [ ] **Step 1: Replace the search skin**
Use the approved transparent frame while retaining the existing input/action bindings:
```vue
<image class="directory-search__frame" src="/static/assets/modules/genealogy/transparent/list-slip-frame.png" mode="scaleToFill" />
```
Set the search field to a 44px-or-greater touch height, strengthen placeholder contrast, and keep the page background visible through the frame.
- [ ] **Step 2: Replace member-card markup**
Each `directory-card` must contain:
```vue
<image class="directory-card__frame" src="/static/assets/modules/genealogy/transparent/list-slip-frame.png" mode="scaleToFill" />
<view class="directory-card__copy">
<text class="directory-card__name">{{ item.name }}</text>
<text class="directory-card__meta"> {{ item.generation }} · {{ item.generationName }} · {{ item.branch }}</text>
<text class="directory-card__status">{{ item.note }}</text>
</view>
```
- [ ] **Step 3: Tighten card layout**
Use one consistent card height between 192rpx and 216rpx at 412px width, vertically center the seal/copy, keep the status visually subordinate, and add a max-width 340px media rule that reduces seal size and spacing without hiding the member name or metadata.
- [ ] **Step 4: Run the focused contract and verify GREEN**
Run:
```powershell
powershell -ExecutionPolicy Bypass -File tests/t07-module-baseline-contract.ps1
```
Expected: `T07-MODULE-BASELINE-CONTRACT PASS`.
### Task 3: Regression and runtime visual verification
**Files:**
- Verify: `pages/tree/t07-member-directory.vue`
- Verify: `tests/t07-module-baseline-runtime-smoke.js`
- Create evidence only under: `docs/design/screens/runtime/2026-07-19/t07-redesign/`
**Interfaces:**
- Consumes: already-running H5 service on 5173 and existing Chrome CDP endpoint on 9222.
- Produces: focused regression output, one-tab runtime results, and current-state screenshots.
- [ ] **Step 1: Run focused and related regression tests**
Run:
```powershell
powershell -ExecutionPolicy Bypass -File tests/t07-module-baseline-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/t07-t08-all-states-visual-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/module-app-loading-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/t03-t08-member-flow-contract.ps1
node tests/t07-module-baseline-runtime-smoke.js
```
Expected: every command reports PASS.
- [ ] **Step 2: Inspect the existing 412×915 tab**
Verify all of the following in the same project tab:
- Search frame has no white band outside its border.
- Member cards have no white rectangle or texture break.
- No red application-status line or top-right status ornament remains.
- Three cards have equal width/height and the name is the primary focus.
- Search restores results and each card retains its click target.
- [ ] **Step 3: Verify responsive sizes**
In the same tab, check 320×568, 360×640, 360×800, and 412×915. Expected: no horizontal overflow, no clipped name/metadata, and natural vertical scrolling.
- [ ] **Step 4: Run source hygiene checks**
Run:
```powershell
git diff --check
git status --short
```
Expected: no whitespace errors; all pre-existing modified/untracked files remain present. Do not stage or commit anything.
## Self-Review
- Spec coverage: transparent search, compact member cards, information hierarchy, responsive sizes, behavior preservation, and evidence limits are covered.
- Placeholder scan: no TBD, TODO, deferred implementation, or unspecified asset choice remains.
- Interface consistency: existing state/search/navigation functions remain unchanged; all new class names are defined in Task 2 and asserted in Task 1.
@@ -0,0 +1,40 @@
# M01 我的首页基准页 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 将 M01 重做为无整页白底、具有个人谱牒册页辨识度且便于后续增加功能的 M 系列视觉基准。
**Architecture:** `pages/profile/m01-profile-home.vue` 继续单独拥有本地状态与路由;复用项目公共页头、底栏、按钮和背景组件。M01 的透明线框资产存放在 profile 模块自己的命名空间。
**Tech Stack:** uni-app、Vue 3、SCSS、PowerShell 契约测试、Node CDP 运行时冒烟。
## Global Constraints
- 只修改 M01 及其聚焦测试、资产和审批文档。
- 不新增个人中心功能,不对接接口。
- 不使用子代理、worktree 或任何 Git 写操作。
- 每次只展示一个审批状态。
### Task 1: 契约 RED
- [ ] 创建 `tests/m01-module-baseline-contract.ps1`,要求 M01 使用 `brand-seal.png``auth-divider-knot.png``chevron-right.png``m01-profile-summary-card.png``AppButton`、ready/error 状态和现有五个目标路由,并禁止重复菜单卡框及三个旧 opaque 业务素材。
- [ ] 运行聚焦测试,确认因缺少新资产引用而失败。
### Task 2: 模块资产
- [ ] 保留一个已经用户审批通过的真实透明线框,专用于失败态;正常册页复用项目真实印章、分隔结与箭头资产。
- [ ] 使用 Pillow 验证失败态线框为 RGBA、透明角且存在非空 alpha 内容。
### Task 3: 页面实现
- [ ] 删除重复卡片结构,改为连续身份区、紧凑提醒栏和“服务与设置”分组列表。
- [ ] 保留资料、提醒及三个菜单路由;失败态增加项目 `AppButton`“重新查看”。
- [ ] 使用内容高度和最小触控高度控制卡片,不固定整页高度。
- [ ] 运行聚焦契约并确认通过。
### Task 4: 验证与审批
- [ ] 运行 M01 聚焦契约、根页面视觉契约、根页面运行时冒烟、模块响应式冒烟和 `git diff --check`
- [ ] 在同一 Chrome 标签页显示 412×915 正常首页,等待明确审批。
- [ ] 正常态通过后显示失败态,再逐一验证资料、提醒和菜单路由。
- [ ] 全部明确通过后才把 `docs/验收规划.md` 的 M01 更新为 `[x]`
@@ -0,0 +1,53 @@
# T01 纵向世系轴基准 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking。
**Goal:** 将 T01 重构为纵向分代、关系线清晰、节点可选择的世系树基准页。
**Architecture:** 页面继续由 `treeState` 管理加载、树、阅读提示、空和失败状态。树态使用固定的三代模拟数据和绝对定位关系线,透明真实资产承载节点、状态卡和成员信息栏,横向滚动只服务同代分支扩展。
**Tech Stack:** uni-app、Vue 3、SCSS、现有 PNG 资产、PowerShell 静态契约、Chrome CDP 运行时验证。
## Global Constraints
- 只修改 T01 及其聚焦测试、设计文档和复制到 tree 命名空间的资产。
- 不接 API,不新增路由,不使用系统弹窗或加载。
- 不执行 Git add、commit、push、reset、checkout,不使用 worktree 或多代理。
- 不删除或覆盖现有修改、测试、文档、截图与资产。
### Task 1: 新视觉契约(RED
**Files:**
- Modify: `tests/t01-tree-state-contract.ps1`
- Modify: `tests/t01-all-states-visual-contract.ps1`
- [ ] 要求 `lineage-connector`、三代横向标签、透明节点/状态/信息栏资产和现有四条路由。
- [ ] 明确禁止 T01 继续引用三个旧不透明表面资产。
- [ ] 运行两个契约,确认因页面尚未实现新结构而失败。
### Task 2: 透明资产与纵向树(GREEN)
**Files:**
- Create: `static/assets/modules/tree/transparent/t01-member-node.png`
- Create: `static/assets/modules/tree/transparent/t01-member-node-selected.png`
- Create: `static/assets/modules/tree/transparent/t01-state-panel.png`
- Create: `static/assets/modules/tree/transparent/t01-member-drawer.png`
- Modify: `pages/tree/t01-tree-overview.vue`
- [ ] 复制经过检查的现有透明资产到 tree 模块命名空间,不改动来源文件。
- [ ] 重排三代节点,加入祖先到子代的垂直/水平关系线和明确世代带。
- [ ] 实现红色选中节点、底部透明成员栏和同代横向阅读提示。
- [ ] 保留 `AppLoading`、查询状态和 T03/T04/T06/T07 导航。
- [ ] 运行聚焦契约并修至通过。
### Task 3: 运行时与视觉复核
**Files:**
- Modify only if necessary: `tests/t01-tree-state-runtime-smoke.js`
- Create/update evidence under: `docs/design/screens/runtime/2026-07-20/t01-baseline/`
- [ ] 运行 T01 运行时 smoke,检查各状态和人物资料跳转。
- [ ] 在既有 Chrome 标签页检查四档响应式尺寸,重点排除节点裁切、断线和底栏遮挡。
- [ ] 对同一 `412×915` 状态做前后视觉对照并修复可见的 P0/P1/P2 问题。
- [ ] 只向用户展示正常树态,等待明确审批后再切下一状态;审批前不标记 `[x]`