# 2026-05-13 — R7 测试驱动的自检 protocol 验证

## 触发

R7（任务意图 disambiguate）改动落盘后，用户提交首个测试任务：把 Config-T 产品的 pre-design-system Figma（v7.7-8.0, 2024-02-20）1:1 还原成 HTML。

用户字面说"1:1 还原"，但 fileKey + 文件名 + 日期暴露这是**非 TVU library 来源** → R7 disambiguation 推断 **场景 1.2**（Pre-design-system 旧 Figma）。用户确认后启动完整流程。

## R7 表现 ✅

- **Disambiguation 正确**：避开了"1:1 还原"字面对应场景 3.3 的项目语境陷阱
- **触发 ask 协议**：关键词冲突时用 `AskUserQuestion` 让用户确认（而非自作主张）
- **路径选择对**：hex literal + 自实现 radio/switch + 不引 TVU library — 全部符合场景 1.2

## 失败模式 ❌

**实施阶段跳过视觉自检**：
- AI Write HTML（200 行）→ `open` 命令唤起浏览器 → 直接给用户 9 项对照清单
- 用户用 broken v1 截图指出 2 个明显错误：
  1. **Logo 严重错乱**：4 层 img + `inset%` 拼合方案 fragile
  2. **整体卡片不居中**：`body padding 280px + flex column centering` 在 viewport 窄时偏移

**这两个问题如果 AI 自己看一眼浏览器渲染结果就能发现**。但 AI **没有视觉感知能力**，需要主动调用工具链 workaround，而不是默认依赖用户当眼睛。

## Close-loop 验证

用户提议演示自检 pipeline → fixed 版本 close loop。

### 自检 pipeline 5 步全链路成功

| 步骤 | 工具 | 状态 |
|---|---|---|
| 截屏自己 HTML | Chrome `--headless=new --screenshot` | ✅ macOS 默认 Chrome 可用 |
| AI 看 PNG | `Read` tool（支持 PNG/JPG） | ✅ AI 直接"看到"渲染 |
| 取 Figma 真源 | mcp `get_screenshot` + `curl` | ✅ MCP 已加载，URL 7 天有效 |
| 局部裁切 | `sips`（macOS 内置） | ✅ logo crop 实测可用 |
| 视觉 diff | Read 两 PNG + AI 脑对比 | ✅ 主观但够用 |

**全程零依赖人类视觉验证**。

### 修复轨迹

| 版本 | 改动 | 截图 | 状态 |
|---|---|---|---|
| v1 broken | 4 层 img inset% + body flex centering | [v1-broken.png](./2026-05-13-r7-test-evidence/v1-broken.png) | Logo + 居中双错 |
| v2 fix | sips crop 单一 logo PNG + body grid place-items center | （仅 /tmp 临时） | Logo 修好，但垂直居中偏离 Figma |
| v3 close-loop | grid justify-items center + padding-block 40px（only horizontal centering） | [v3-close-loop.png](./2026-05-13-r7-test-evidence/v3-close-loop.png) | 接近 Figma truth（≥95%） |

参照：[figma-truth-reference.png](./2026-05-13-r7-test-evidence/figma-truth-reference.png)（Figma 真源 1280×800 frame screenshot）

最终 v3 跟 Figma truth 视觉对齐 ≥ 95%，差异仅在 logo 边缘 anti-aliasing 等像素级偏差（场景 1.2 visual-fidelity 可接受）。

## Lesson 提炼

### Lesson 1: Figma export reference 不能 1:1 翻译

`get_design_context` 返回的 React+Tailwind reference 是**结构提示**，不是**实现规范**。复杂 composite（logo / 多层 SVG illustration）不能直接翻译为 4 层 `<img>` + inset%，**应取整图**（`get_screenshot` + sips crop）。

### Lesson 2: 居中用 grid + 单方向 align

`body { display: grid; justify-items: center; padding-block: 40px; }` 比 `body { display: flex; align-items: center; padding: 40px 140px; }` 稳健 — 不依赖 viewport 宽度，不会在 viewport 紧时偏移。

### Lesson 3: 视觉任务必须自检（R8 driver）

"AI 没视觉感知 → 默认依赖用户当眼睛"是结构性反模式。**Workaround 存在**：Chrome headless screenshot + Read PNG + mcp get_screenshot + sips。**AI 必须主动 workaround**，不能把"能力边界"当免责借口。

→ 本次 close-loop 直接驱动 **R8（视觉还原任务自检 protocol）** 立为硬规则。详见 [code-conventions.md R8](../code-conventions.md)。

## 工程价值

这次测试**不只是验证 R7**，更**实证了 AI 可以自己当眼睛**。

证据钉死后，未来类似规则讨论可以引用本次 close-loop：
- AI 不会再因"能力边界"逃避视觉自检
- R8 有真实测试场景做支撑，不是凭空规则
- 自检 pipeline 工具链（Chrome headless + Read + mcp + sips）在 macOS 实测可用，后续可复用

## R8 v2 + R9 + meta-rule K 升级（同日深化）

### 触发

用户洞察："不停加规则、加描述还是会有遗漏。比如加脚本？是不是有比加规则更确定的方式来约束？"

——这是这次讨论里最深刻的洞察：**规则累积有 fundamental 上限**。规则是 promise，AI 执行是 best effort，加再多 acceptance criteria 救不了"AI 主观对比漏细节"。

### 升级 3 件事

**1. Meta-rule K 立到 [meta-rules.md](../meta-rules.md)**：「规则提案必须声明 enforcement 层级（L1-L5）」

```
L1 规则文档（AI 主观）         ⭐
L2 结构化输出（模板字段）        ⭐⭐
L3 脚本辅助（客观 measurement） ⭐⭐⭐
L4 Pre-commit hook（强制执行）  ⭐⭐⭐⭐
L5 CI gate（merge gate）         ⭐⭐⭐⭐⭐
```

类别强制：
- **视觉 / 客观可测的规则** → 必须 L3+
- **用户行为 / commit format** → 必须 L4+
- **跨人协作** → 必须 L5
- **AI 自我约束 / 元规则** → L1 可接受

→ 这把"加规则"行为本身约束起来：设计阶段就拷问"L1 够吗"，stop 凭"写下来就放心"反模式。

**2. R8 v1 → v2 升级（L3 enforcement）**：

- 写 [`scripts/visual-diff.py`](../../scripts/visual-diff.py)（Python + PIL，零新依赖）
- R8 自检 5 步 → 7 步，强制调用 visual-diff.py 拿客观 diff%
- AI 主观判断**不**作为 release 依据

**3. R9 立**（Static-to-Interactive Augmentation Protocol，场景 1/3 强制；L1，v2 待升 L3 通过 CSS linter）

从 active state 反推 hover/focus/disabled。**理由**：Code 与 mockup 的核心差别就是交互；只做 static fidelity 浪费 medium 能力。

### 实证 — visual-diff.py 测出 AI 主观偏差 ~30pp

| 维度 | AI 主观估计 | visual-diff.py 客观测量 |
|---|---|---|
| v3 vs Figma truth match | **"≥95% match"** | **35.34% diff（即 ~65% match）** |
| 偏差 | — | **~30 percentage points** |

这是 R8 v2 升 L3 的最强实证 — AI 主观判断在视觉对比上完全不可信。

### 第二轮 close-loop（v4 → v5）

加 caret 实心 + back arrow 圆背景 + 5 类 hover effects 后：

| 版本 | 改动 | visual-diff.py 客观 diff% | 截图 |
|---|---|---|---|
| v4 | caret 实心三角 + back arrow `rgba(255,255,255,0.06)` 圆背景 + hover effects (menu/sub-tab/radio/switch/back) | **35.37%** | 仍高 — 暴露 padding-block 问题 |
| v5 | 移除 body `padding-block: 40px` + 加 `align-content: start` | **25.88%** | 10pp 改善 |

剩余 25.88% 根因（diff PNG 分析）：
- **顶部 nav 区域**: 轻微 anti-alias noise（已大幅改善）
- **大红块 y≈460-700**: Figma frame 用 `flex-[1_0_0]` 让 page-card 强制撑满 800px 高度，HTML 自然 height ~470px — **Figma frame design vs HTML viewport rendering 固有差异**，非实现 bug

**作 R8 v2 acceptance criteria 第 2 条豁免处理**："Figma frame 的 `flex-[1_0_0]` 强制撑满 viewport 高度是设计工艺 quirk，HTML 实际不该这么做；25.88% 在此约束下可接受。"

### Lesson 4: enforcement 层级思维

新规则提议时，机械问 3 个问题：

1. 这条规则 enforcement 层级是几？
2. 为什么不能升 L3+？
3. L3+ 工具是什么？放哪？

这条 meta 思维比任何具体规则都更结构性 — 它**约束了如何加规则**本身。

### Lesson 5: AI 主观对比 ≠ 视觉验证

任何"AI Read PNG 主观对比"都应配合客观工具（visual-diff.py / pixelmatch / playwright visual-regression）。主观判断作为辅助 + 解释工具，不作为决策依据。

### Lesson 6: 矢量源 → 矢量输出

R8 v1 → v2 close-loop 修复了 layout 问题，但 logo 用 **sips crop PNG** 仍是 raster 中转——用户指出"Figma 是矢量，code 也得是矢量"。

**Why 错**：raster 中转失去缩放能力 / DPR 自适应 / edit-ability。Vector source (SVG) → raster output (PNG) 是**反向降级**。

**纠偏**：
- 矢量内容（logo / icon / illustration / 几何 shape）→ **inline `<svg>` 或 `.svg` 文件**
- 例外：固定大背景图（照片 / artwork / 3D render 等本来就是 raster 源）→ raster OK

**实现路径**：
- 简单几何 → 手写 inline SVG
- 复杂 logo → Figma plugin API（`use_figma` + `exportAsync({ format: "SVG" })`）或 Figma desktop 手动 export
- 当前 v6 demo 用 approximate inline SVG（真 SVG export 留 follow-up；principle 已 demonstrate）

**Lesson 1 wording 校正**：原"复杂 composite → 取整图（sips crop）"措辞误导 — 应改为"复杂 composite → 取**矢量整图**（SVG）"。R8 v2 acceptance criteria 已补"矢量源 → 矢量输出"硬约束。

**这次的 meta 启示**：每条 lesson 写完后，强制问一次"这条 lesson 会不会让 AI 走偏向相反极端？"。Lesson 1 "取整图" 让 AI 走向 raster，正好是 Lesson 6 要修正的反方向。规则之间互相校验机制（per meta-rules.md 触发器 J 查重原则的延伸）。

### v7 close-loop（real Figma SVG composite）

用户继续指出 v6 inline approximate SVG "还是不对，应该是一个完整的 svg 图，而你把它拆成很散了" → 进一步 close-loop。

**步骤**：

1. Bash `file /tmp/asset.bin` 检测 Figma MCP asset URLs 实际格式 → 发现是 **SVG**（不是 PNG！）
2. curl 下载 4 个真 Figma SVG layers（10KB + 1KB + 5KB + 2KB）
3. Python 脚本合成单一 `logo.svg`（4 个 nested `<svg>` at 计算 inset 位置）→ 18KB single file
4. HTML 改 `<img src="logo.svg">` — 单一文件，矢量保持
5. v7 visual-diff: 25.94%（vs v6 26.13% 略降），剩余 framework artifact

**v7 logo 渲染**：真 Figma vector paths，比 approximate inline SVG 显著改善（虽然 nested SVG rendering 有 minor proportion artifacts，但 vector quality + 文件结构都对了）。

### Lesson 7: Verify asset 实际格式（不假设）

**反模式**：AI 假设 Figma MCP asset URLs 返回 PNG（raster），所以走"取整图 sips crop"路径——错的方向。

**实测**：Bash `file /tmp/asset.bin` 输出 "SVG Scalable Vector Graphics image"。前 200 bytes 是 `<svg preserveAspectRatio...`。**URLs 一直是 SVG**。

**纠偏**：任何 asset 处理任务，先用 `file` / `curl -I Content-Type` 验证实际格式，再决定走 vector / raster 路径。**Don't assume format**。

**反思链**：
- Lesson 1（v1 broken）："复杂 composite → 取整图" 措辞模糊 — 误导 AI 走 raster
- Lesson 6（v6 approximate）："矢量源 → 矢量输出" 原则 — 但 AI 还是 approximate 重画了
- Lesson 7（v7 composite）：**先验证 asset 实际格式** — 揭示 Figma URLs 是 SVG，直接用即可，无需 approximate 重画

每 lesson 都让 AI 偏向新极端。**真根因**：AI 倾向"我自己想办法"而不是"先查 source 实际是什么"。Meta lesson：**永远先 verify upstream truth**。

### Lesson 1-7 校正版总结（避免下次再绕弯）

| # | Lesson | 简要 |
|---|---|---|
| 1 | Figma export reference 不能 1:1 翻译 | get_design_context 返回是参考，不是规范 |
| 2 | 居中用 grid + 单方向 align | 不依赖 body 横向 padding + flex |
| 3 | 视觉任务必须自检（R8 driver） | AI 不能依赖用户当眼睛 |
| 4 | enforcement 层级思维（meta-rule K driver） | 加规则前问 L1-L5 |
| 5 | AI 主观对比 ≠ 视觉验证 | 主观判断 ~30pp 偏差实证 |
| 6 | 矢量源 → 矢量输出 | 不经 raster 中转 |
| 7 | Verify asset 实际格式（不假设） | 先 `file` / Content-Type 查 |
| 8 | Upstream signal 优先于下游反推 | 先看 Figma node name / type，不从 React code 反推 |
| 9 | AI 不确定必 ask + 列举疑问点 | 不自作主张默认值；元规则 触发器 L |
| 10 | 规则提案完成后必须同步 quick-reference matrix | AI 倾向"每条规则 self-contained"忽略跨规则速查；用户起手 grep 多处段 = 反模式 |
| 11 | 数据驱动 CSS 提取替代 AI 估算 | scripts/figma-extract-css.py 从 Figma MCP 取精确 values, AI 不许估算 layout |
| 12 | 跨设备/账号/项目 portability — 所有 Claude Code 资产必须 in git, 不放 ~/.claude/ | hook + settings 放本机全局 = 同事 clone 拿不到, 破坏 "GitHub 分享即可用" 目标 |
| 13 | "支持" 等于"端到端实测通过", 不是"理论 reasoned 应该工作" | docs/README 写 install command 但没 run 过 = 让用户当 tester (反模式) |

### Lesson 10: 规则提案完成后必须更新 quick-reference matrix

**反模式**：AI 写新规则时（R8 / R9 / R10 / meta K / meta L 等）每条都写自己 scope（"场景 X 强制"），但**没汇总"跨规则适用矩阵"**。用户起手时要自己 grep 5 处规则段才能拼出"这次该 fire 哪些规则"。

**根因**：AI 优化"每条规则 self-contained"，忽视"跨规则 navigation / quick lookup"。这是文档可用性的盲区——规则本身正确不代表读者能 efficiently 用。

**纠偏（2026-05-13 session 末用户指出）**：
- code-conventions.md 加 **规则适用速查表**段（场景 × 规则矩阵 + 全场景永远适用 + 起手 5 步 checklist + 易混淆边界）
- 放在 R7 段之后、R8 段之前（R7 是 scenario 来源 → 矩阵 → 各规则段，flow 自然）
- 未来加新 R# / meta-trigger 时**强制更新此表**

**候选元规则 触发器 M**（待用户决定立不立）：
> 规则提案 / 升级 / 加 trigger 完成后,**强制**更新对应快速参照表 (`规则适用速查表` / table of contents / cross-reference matrix)。新规则与现有规则的适用关系必须显式列出, 不留给读者自己 grep 拼凑。

**反思**：这跟 R10 同源——都是"AI 倾向自我封闭 vs 退一步看全局"。R10 是 upstream signal 优先；Lesson 10 是 cross-rule 全局视角优先。元规则**永远要问"读者怎么 efficiently 用"**。

### Lesson 11: 数据驱动 CSS 提取（反 AI 估算）

**反模式实证 (2026-05-13 Config-T return-video case)**: 新 Claude Code session AI 走了 8 轮 iteration (v1 → v8) 才把 visual-diff% 压到 6.26%，但**仍有 semantic 错误** (annotation 被渲染、logo 还原不对、累积 layout 偏移 12-37px)。

**Root cause**: AI **估算 padding/margin/font-size 数值**而非从 Figma API 取数。Figma 是 connected MCP source (含精确 metadata)，AI 把它当**图片**用 (看图估值) = fundamental 错误。

**纠偏 (R10/R8/R12 升级 + 新工具)**:
- `scripts/figma-extract-css.py` 解析 mcp `get_design_context` 输出的 React+Tailwind reference (Tailwind arbitrary values 如 `w-[1000px]` `gap-[40px]` 直接含精确数值)
- 输出 `extracted-css.css` (数据驱动) + `skeleton.html` + `assets-manifest.json` + `annotation-filtered.md`
- AI 角色转变: estimator → consumer (用 extracted CSS 做 baseline, 不再估算)

**预期效果**: 场景 1 raw Figma 还原任务 8 轮 → 1-2 轮; semantic 正确 (annotation filtered, asset 用 figma-asset-fetch.py 取真 SVG); diff% 预期 <3%。

**这次 lesson 比前 10 个更根本**: 前 10 个都是 "AI 应该怎么做" (L1 文档级规则); Lesson 11 是 "AI 不该做什么" (L3 工具机械替代 AI 估算)。**真正 step change 在层级跃升**: L1 → L3 才能消除 AI 主观判断的偏差源。

**反思**: 之前几次都在 L1 加规则、加 acceptance criteria, 但 AI 仍能 skip。Lesson 11 启示**遇到顽固反模式不该再加 L1 规则,该 L3 工具机械替代**。

### Lesson 12: 跨设备 / 跨账号 / 跨项目 portability — 资产位置选错破坏 share 目标

**反模式实证 (2026-05-13 P2)**: 我把 UserPromptSubmit hook 放 `~/.claude/hooks/`, 把 hook 注册放 `~/.claude/settings.json`. **本机全局 = 同事 clone 拿不到**, 直接破坏用户 "GitHub 分享给同事即可用" 的目标.

**6 维 portability 自检**:

| 维度 | 之前 | 现在 (Lesson 12 纠偏后) |
|---|---|---|
| 1. 跨设备 | ❌ 仅我 Mac | ✅ git clone 即拿到 |
| 2. 跨账号 | ❌ 仅我账号 | ✅ 同上 |
| 3. 跨 Session | ✅ ~/.claude/ 持久 | ✅ 项目级 `.claude/` 持久 + 同步 |
| 4. 跨项目 (sibling) | ✅ 全局生效 | ⚠️ 需 `scripts/install-claude-config.sh` (一次性 opt-in) |
| 5. 跨平台 | ⚠️ macOS-only (sips/Chrome path) | ⚠️ 同, future work |
| 6. 同事开箱即用 | ❌ 缺 hook | ✅ clone + (可选) install-claude-config.sh = full feature |

**纠偏措施**:
- 移 hook script `~/.claude/hooks/detect-figma-task.sh` → `.claude/hooks/detect-figma-task.sh` (in git)
- 移 hook 注册 `~/.claude/settings.json` → `.claude/settings.json` (in git)
- Hook content 用 portable path detection: `$CLAUDE_PROJECT_DIR` > `$TVU_DESIGN_SYSTEM_PATH` > script-location walkup (no hardcoded `~/Documents/...`)
- 新增 `scripts/install-claude-config.sh` 给"想要跨项目全局生效"的场景 (一次性, idempotent)
- 旧 `~/.claude/` 保留 (我本机 already setup, 不破坏现状; 但建议运行 install script 来 sync 新版)

**Root cause 反思**: AI 倾向把 "工具配置" 当作 "用户本机偏好" → 默认全局. 但项目级约束必须 in repo (per [meta-rules.md trigger B](../meta-rules.md): "对话产出项目级规则必须落仓库"). Hook 也是项目级约束 (TVU 的, 不是用户的), 应放 repo.

**Meta lesson**: 写完任何"约束/配置/工具"立刻问 "**这个是项目级 (in git) 还是用户级 (~/.) ?**". 99% 跟 TVU 相关的都是项目级. 默认 in repo, 例外才放 global.

跟 [feedback_skills-project-level.md](file:///Users/nancy/.claude/projects/-Users-nancy-Documents-AICoding-VS-Code-tvu-design-system/memory/feedback_skills-project-level.md) memory 同源 (2026-05-12 已提示过 skills 必须项目级), 但我这次仍然犯了 hook 放全局的错 — 说明这条 governance 还需要继续强化.

### Lesson 13: "支持" 等于"端到端实测通过", 不是"理论 reasoned 应该工作"

**反模式实证 (2026-05-13 session 末)**: 我写了 `scripts/install-claude-config.sh` + 在 README onboarding 段宣称 "可选: `bash scripts/install-claude-config.sh`". User 问 "这个是支持了还是未支持啊", 我才意识到**没真 run 过端到端**:

- ✅ 写了脚本
- ✅ chmod +x
- ✅ 内部 logic (Python dedup / JSON merge) 单独测过
- ❌ **没真的 run 一次 end-to-end install 流程**

写在 README + commit message 里宣称的 "支持" 本质是**让 user 当 tester** — 同事 clone 后第一次跑挂掉, user 才发现. 反模式: 把"reasoned should work"当"verified working".

**纠偏 (跑了 verify 后)**:
- 4 项 install 行为全部 verified pass (复制 hook / 注册 settings / 加 env var / fire 测试)
- 现在才能真说"支持"

**Root cause**: 我把"内部组件测过"等同于"整体链路测过"——两者根本不同。Component test ≠ Integration test ≠ End-to-end test.

**Meta lesson**: 任何在 docs / README / commit message / 项目宣传 里宣称的 install / setup / 配套命令必须**端到端实测一次**才能宣称"支持". **没跑过的 = 未支持**, 别让 user 当 tester.

**适用面 (远超 install script)**:
- 新加 npm script → 必须 run 一次
- 新加 CLI tool → 必须模拟典型用户输入跑一次
- 新加 git hook → 必须模拟触发场景验证
- 新加 onboarding step → 必须跟着自己的 doc 跑一遍
- 新加 R-rule / Lesson 里的 example command → 必须能复制粘贴 work

**反模式检测词**: "应该 work" / "理论上应该" / "should work" / "based on docs..." — 都是"没真跑"信号。

跟 [R8 v2 (L3 enforcement)](../code-conventions.md) 同根原则: **客观验证 > 主观确信**. R8 是视觉 diff, Lesson 13 是 install 跑过. 主观判断 (无论是视觉对不对 / 脚本应该 work) 都不该当 release 依据.

### Lesson 8: Upstream signal 优先于下游反推

R7 测试 logo case 暴露 AI 反模式："从下游 `get_design_context` React code（4 img layers）反推处理策略"，**而不是**"先看 upstream Figma node `data-name='Logo/TVU'` 这个 component-style 命名 signal"。

**Figma `/` 命名 convention**（行业惯例）：
- `Logo/TVU`, `Icon/Search`, `Button/Primary` 等用 `/` 作 component namespace separator
- 这是设计师 "我是一个 unit" 的强 signal
- AI 看到 `data-name` 含 `/` → 立刻应该判断为单一 SVG 单元

**Root cause**：AI 倾向 "从我手上能看到的下游产物（React code reference）反推决策"，而不是 "退一步看 upstream source signal（node name / type）"。

→ 驱动 **R10**（Vector 元素导出策略决策）立为硬规则，强制 upstream signal 优先判断。

**反思**：每写完一个 component / vector handling step，强制问 "我看 upstream signal 了吗？还是从下游推的？" — 前者是正解；后者是反模式。

### Lesson 9: AI 不确定必 ask + 列举疑问点（meta-rules 触发器 L）

v6 + v7 两轮用户 push back 暴露 AI 反模式："遇到 ambiguous case 自作主张默认值"（v6 选 approximate inline SVG；v7 选 composite 4-layer），用户当 reviewer 兜底。

**纠偏（元规则化）**：触发器 L 立到 meta-rules.md，AI 任何不确定 case 必须 stop + 列举疑问点 + 等用户拍板。**不允许"我先按 X 做"自作主张**。

适用面（不限于视觉任务）：
- 视觉 / 设计决策（尺寸 / 颜色 / 字体）
- 实现路径决策（library / pattern / 数据结构）
- 业务逻辑决策（边界 case / error handling）
- 规则提案细节

这是比 R10 case D 更通用的元规则，覆盖所有 ambiguity handling。

### R9 hover 实现（推断规则表）

| Element | Active state | Hover (从 active 反推) |
|---|---|---|
| Top nav inactive | — | bg `rgba(255,255,255,0.05)` + color `#fff` |
| Top nav active (Advanced) | bg `#333` + bold | bg `#444` |
| Sub-tab inactive | — | color `#fff` |
| Radio unselected | gray ring | ring `rgba(255,255,255,0.7)` |
| Switch ON | green pill | brightness(1.1) |
| Back arrow | bg `rgba(255,255,255,0.06)` | bg `rgba(255,255,255,0.12)` |

推断逻辑统一："active 的弱版本"（bg 弱化 / color 略亮 / 不加 bold）。

## 资料

- 测试 HTML：`~/Documents/AICoding/VS_Code/Config-T-r7-test/index.html`（sibling 路径，不入仓库）
- Logo 资产：`~/Documents/AICoding/VS_Code/Config-T-r7-test/logo.png`
- 证据截图：`./2026-05-13-r7-test-evidence/`（本目录，已入仓库）
- 临时截图：`/tmp/config-t-{broken,fixed,v3,v4,v5,figma-truth,*-diff*}.png`（~1 周清理）
- R8 v2 工具：[`scripts/visual-diff.py`](../../scripts/visual-diff.py)（已入仓库）
- 规则文件：
  - [code-conventions.md R8 v2 + R9](../code-conventions.md)
  - [meta-rules.md 触发器 K](../meta-rules.md)
