# Plan B Figma Mockup — Handoff (2026-05-14)

## TL;DR

Plan B 完整效果图 + UX 标注已交付到 Figma 文件 `Micro-Apps-20250923` 内，section `Plan B: Pagination Support`（node `3668:84170`）。

- **6 frames** (1920 宽)：All Sessions Overview / App Detail / My Sessions Overview / App Detail / SCTE Empty A-my / SCTE Empty A-admin
- **8 新 file-local 组件**（前缀 `MicroApp PlanB`）+ 复用 6 个 Plan A file-local + 多个 TVU library 组件
- **9 M23 UX 标注**（navy chip + 双语 + accent stroke + 规则卡）+ **14 VECTOR connectors** + **2 state-group GROUPs** (`_flow-state-1/2`) + **3 condition label GROUPs** (`_`) + **reconnect map JSON** (page sharedPluginData)
- **整体 layout (v3 final)**：**Plan A 风格 horizontal 配对** — 3 rows × 2 cols，左列 Admin (F1/F2/F6) / 右列 User (F3/F4/F5)；annotations 在 frames **上下左右** 摆放（参考 Plan A）：#1 header 左上；#2/#6/#9 ABOVE F1；#4 + state group LEFT of F1；#3/#5 BETWEEN F1↔F3 (top row gap)；#7 BETWEEN F2↔F4 (mid row gap)；#8 BETWEEN F6↔F5 (bottom row gap)。Section 6080×5340，canvas (-839, 8389) → (5241, 13729)。**No overlap** with sibling sections (Plan A bottom y=6861 gap=1528 / PlanB Local Components top y=15463 gap=1734)。

> **2026-05-14 layout refactor v2 闭环**：first retrofit 把 connectors 全建完后用户反馈"连线全是穿越 section 的长对角线，可读性差，annotation 应贴效果图旁边用短直线/折线"。第二轮重构：6 frames 从横向 1 行（13332 wide）改为**纵向 stack**（3280 wide × 9806 tall）；9 annotations 全部移到右栏 (sec x=2080)，每个紧贴对应 frame；14 VECTORs 全部短水平或 L 形（vertical-first L 用于跨行：垂直段走右栏 margin，水平段进入 target frame）；删除 #3 → F1 admin chip 长跨行连线（在 card 文本描述）+ #5 → F1 absence 连线（同理）；4 condition labels → 3（删 orphan cond-#5-F1）。Pickup: [`docs/2026-05-14-plan-b-figma-connectors-pickup.md`](2026-05-14-plan-b-figma-connectors-pickup.md)。

### Layout 对照（v1 → v2 → v3）

| 维度 | v1（horizontal row + 列分配） | v2（vertical stack + right column） | **v3（Plan A horizontal pair, final）** |
|---|---|---|---|
| Section 尺寸 | 13332 × 5417（极宽） | 3280 × 9806（极高，压到 Local Components） | **6080 × 5340（balanced）** |
| Frames 排列 | 1 行 6 frames | 6 frames 纵向 stack | **3 rows × 2 cols pair**（Admin/User 对比） |
| 配对方式 | 无明显配对 | 按 frame 类型顺序 | **按 view 配对**：Overview / AppDetail / Empty |
| Annotation 位置 | 散布在 frames 下方 + 跨 frame 带 | 全部右栏 sec x=2080 | **上 / 下 / 左 / 中** (Plan A 风格 4 边) |
| Connector 形态 | 4 vertical + 14 diagonal（穿越整个 section） | 14 L 形（vertical-first 走右栏 margin） | **14 短直线 + L 形**（无跨 section 长线） |
| 最长连线 | #3 → F1 Admin chip ~9000 px | #3 → F3 User chip ~1900 px | **#5 → F3/F4 buttons ~2000 px** (在右列中横穿 sub-header 带) |
| Overlap 风险 | 无 | **有！** 纵向拉到 y=18195 压到 PlanB Local Components (y=15463-17663) | **无** Gap 1734 px 到 PlanB Local Components |
| 配对叙事 | 弱 | 弱 | **强** — Admin/User 同 view 横向对比，#3/#8 跨 persona annotation 自然在列间 |
| 用户验收 | ❌ "到处看" | ❌ "纵向而非横向，且压到其他 section" | ✅ Plan A 风格对齐 |

---

## F1 Walkthrough Audit (2026-05-14, post-v3) — Findings + Disposition

> Audit via subagent invoking `design-walkthrough` skill (Sonnet, ~$0.22)。完整报告：[`docs/audits/2026-05-14-plan-b-f1-walkthrough.md`](audits/2026-05-14-plan-b-f1-walkthrough.md)
>
> **Overall: 6.2/10 — Fix before ship**

### Fixed in this session ✅

| Audit finding | Action taken |
|---|---|
| P1-5 M25 hover token silent-reverted | `MicroApp PlanB Sidebar Item` hover variants (`3705:5021` / `3705:5032`) opacity 1 → **0.10** via Q2 two-step (setBoundVariableForPaint + spread + opacity)。验证：跨 use_figma context 重 probe 后 opacity 仍为 0.10 ✓ (Master COMPONENT 层 paint.opacity 持久；Q7 只影响 nested instance internal frame) |
| Frame count typo (2 处 "5 frames") | 全改 "6 frames" (line 102 + 233) |
| **Connector accuracy (v3.1)** | F1 walkthrough 漏检 — 3 个 tip 错位（#6 偏 58px / #8-F5 偏 89px / #8-F6 偏 68px）+ #5 两条横段穿 F3/F4 frame 内容。全部重建：3 个 tip 重对位 + #5 两条改用 U-3seg routing 绕开 frame 内容。详 reconnect map `v31FixLog` |
| **P0-1 缺失 empty / variant states** | Row 4 加 6 个 mini-frames：Empty B (Filter-empty) / Empty C (Overview my 0) / Empty D (Overview all 0) — 用现成 `MicroApp PlanB Empty State` 3 个 variants instance + Loading skeleton (spec §10.1 简化版) + Sort-active demo + 全部带 navy 双语 label chip |
| **P0-2 缺失 App Picker mid-state** | Row 4 加 App Picker dropdown mini (400×480)，列 8 个 MicroApps + 流程注（per spec §4.3）|
| **M2 violations V1-V5** (5 处 Library-first 违例) | V1: 12 hand-drawn count Frame → TVU `Badge` instance (3 Sidebar Item master + 9 Sidebar Expanded master 行); V2: 8 App Picker placeholder rect → file-local `APP Icons` Green variants; V3: TEXT "↑" → TVU `icon/Arrow/Sorting`; V4→V5: Unicode ‹/› TEXT × 6 → TVU `icon/Arrow/Previous` (sidebar collapse + 4 breadcrumb) + `icon/Arrow/Next` (sidebar expand). 用户实证 user F1 sidebar 12 个 Badge 渲染正常 (Green Rectangle 52 / Neutral Circle 7/5/4/9/6/0 / Neutral Rectangle 10/11)。**架构修正**：原方案 Badge 嵌入 19×15 旧 Frame → 视觉撑爆；重做后删旧 Frame，Badge 直接作 row 子节点 (224×24 right-aligned 12px margin)。**回流**：[mockup-conventions.md M0 scope](../../../tvu-design-system/docs/internal/mockup-conventions.md) + [design-process.md M15.1](../../../tvu-design-system/docs/internal/design-process.md) |
| **Copyable columns + Copy icon (v6 → v6.1 refine)** | 用户反馈两轮：(1) F2/F4 session table 4 列支持复制，仿 Plan A 在文本后加 `icon/Edit/Copy`；(2) 图标应**紧跟文本** (hug content) 不是 cell 右边固定位置，颜色用 `Color Type/Icon/Default` token。Import TVU `icon/Edit/Copy` (key `75d48adc...`) — 共 **44 instance** (F2 24 + F4 20)。Event Owner col 跳过 (mailto/tel)，F4 my-sessions col x 偏移 (68/343/618/893)。**v6.1 refine**：text autoresize 改 `WIDTH_AND_HEIGHT` + force re-flow (`t.characters = t.characters`)，icon `x = text.x + text.width + 4` hug content；icon fills bind to `Color Type/Icon/Default` variable (key `e8580f8f...`) per M10 + Q2 two-step (setBoundVariableForPaint + spread)。**文字 overflow spec (dev)**：center-ellipsis (如 `udp://237.0...0:1234`)，Figma 无 native 支持，dev CSS/JS impl |

### Deferred to next sprint (with disposition) 📋

| # | Severity | Finding | Disposition |
|---|---|---|---|
| ~~**P0-1**~~ ✅ | P0 | PRD §10.4 定义 5 个 empty states，现仅画了 A-admin / A-my（**~43% PRD 覆盖**）。缺 Overview Empty-C (my-sessions 0 sessions) / Overview Empty-D (all-sessions 0 sessions) / Filter-Empty-B / Loading skeleton / Sort-active state | **闭环（v4）**：Row 4 加 6 个 mini-frames 覆盖全部 5 个 missing variant states。Empty B/C/D 用现成 `MicroApp PlanB Empty State` 3 个 variants instance（spec 4 variants 完整使用）；Loading 简化骨架 + Sort-active demo 从零建。**Deferred**：完整 1920×1460 Overview Empty C/D 主视图（含 sidebar/topbar 全套）可在 sprint+2 补，当前 mini 已覆盖核心信息差 |
| ~~**P0-2**~~ ✅ | P0 | #5 New Session 3-state flow 缺中间态：**App Picker dropdown** mid-state 无 frame | **闭环（v4）**：Row 4 加 App Picker dropdown mini (400×480)，列 8 个 MicroApps + 流程注（per spec §4.3 openMicroAppPlaceholder + toast）|
| **P1-3** | P1 | A11y annotations 完全缺失：`aria-sort` (5 个排序列) / `aria-disabled` (URL 缺失态) / `data-tooltip` patterns / collapsed sidebar tooltip 反向 | **Next sprint 补 annotation**：可新建 #10 "A11y Spec" card，列各组件 ARIA 属性。或在现有 annotations 加 a11y 子段 |
| **P1-4** | P1 | Action Cluster state matrix (Bidirectional / Analyzer / Generator × inactive/preview/on-air/analyzing) **零 annotation** | **Next sprint 补 annotation**：新建 #11 "Action Cluster State Matrix" card，至少表格化呈现 |
| **Misc** | P2 | F1 (1080) vs F3 (1460) 高度不对称，配对 layout 视觉错位 | **设计判断**：F1 是 Overview cards (无 pagination)，F3 是 my-sessions overview (有 pagination + 自身 my 信息)，高度差有功能原因。不修，加 annotation 说明即可 |
| **Misc** | P2 | Tooltip 方向 exception (collapsed sidebar 弹右) 零 annotation | **Next sprint 加到 #4 Sidebar Collapse card body** |

### Audit Process meta-收获

1. **`design-walkthrough` as subagent 真的能抓 anchoring bias 漏的东西** — $0.22 换 5 个 P0/P1 finding，ROI 高
2. **本 session 缺 audit gate** — 上 session retrofit 没跑 walkthrough → 本 session 多次 layout 返工。建议回流到 `tvu-design-mockup` skill 协议加 step 8.5 mandatory post-design F1 audit
3. **Self-review 系统偏宽松** — 我自己 self-review 时点了 surface 问题，但漏了 PRD §10.4 系统覆盖率检查 / Action Cluster 这类交互复杂区 / 自己立的 M25 规则没 verify follow-up

---

## Figma 产物索引

### Section
- `Plan B: Pagination Support` — `3668:84170`（Page `Monitor for all of Micro Apps 20260430`）

### Frames（6 个，1920×1460）
| Frame | Node ID | 说明 |
|---|---|---|
| Plan B · All Sessions · Overview / 1920 | `3709:5152` | admin 默认态，8 App Overview Cards |
| Plan B · All Sessions · App Detail (AV Sync) / 1920 | `3766:5776` | AV Sync session table，6 rows |
| Plan B · My Sessions · Overview / 1920 | `3772:6270` | john.doe view，my-sessions 数据 |
| Plan B · My Sessions · App Detail (AV Sync) / 1920 | `3776:6867` | my-sessions AV Sync detail，5 rows |
| Plan B · My Sessions · SCTE Insertion (Empty A-my) / 1920 | `3778:7322` | Empty State A-my |
| Plan B · All Sessions · SCTE Insertion (Empty A-admin) / 1920 | `3797:7520` | Empty State A-admin（admin readonly，无 + New Session）|

### 新建 file-local 组件（8 个 · 前缀 `MicroApp PlanB`）
位置：sibling section `MicroApps PlanB — Local Components` (`3694:5002`)

| 组件 | Node ID | Variants |
|---|---|---|
| MicroApp PlanB Persona Chip | `3695:5006` | Type=Admin / User |
| MicroApp PlanB Aggregate Counter Chip | `3696:5034` | Status × Active=True/False (8 variants) |
| ~~MicroApp PlanB Pagination~~ | 已删除 | 改用 library `Pagination` |
| MicroApp PlanB AutoRefresh Widget | `3698:5037` | State=Running / Paused / Off |
| MicroApp PlanB Empty State | `3699:5033` | Kind=No-sessions / Filtered-empty / Platform-empty / User-no-own |
| MicroApp PlanB Sidebar Item | `3705:5060` | State × Collapsed (6 variants) |
| MicroApp PlanB Sidebar | `3706:5241` | State=Expanded / Collapsed |
| MicroApp PlanB Overview Card | `3708:5195` | State=Has-sessions / Empty |

### 复用的 Plan A file-local 组件
- `APP Icons` (`3:14402`) — 8 Tag variants × Color=Green
- `State Pill` (`3261:1480`) — 4 status
- `Counter Pill` (`3264:1484`) — 4 status（用于 Overview aggregate chips）
- `Action Cluster (Bidirectional)` (`3267:1510`) — 3 state
- `Action Cluster (Analyzer)` (`3268:1517`) — 2 state
- `Action Cluster (Generator)` (`3268:1528`) — 2 state

### 复用的 TVU UX Design System library 组件
- `Top bar` (`918b928e...`) — After Login variant
- `Pagination` (`dd76ae53...`) — Classic / Small / Simple variants
- `input box/line` (`fb1c1b49...`)
- `Button/dark M` (`12b38c8b...`)
- icons: Sorting / Search / Play / Record stop / Live / Copy / Open link / Edit/Add / Edit/Copy / Arrow/Dropdown / load/refresh / logo/TVU / Message/Success / warning / Error

### M23 UX Annotations（9 张 navy bilingual chip card）
位置：3 行 × 3 张，y=10289 / y=10720 / y=11200

| # | 主题 | 形态 |
|---|---|---|
| 1 | Plan A vs Plan B — When to Use Which | 对比型 navy card |
| 2 | Page Structure — 4 Layers | 说明型 navy card |
| 3 | Persona Differentiation — 5 Visual Differences | 矩阵 navy card |
| 4 | Sidebar Collapse — Multi-State Flow | 状态流 navy card |
| 5 | + New Session — Scope by View | 3-case 状态流 |
| 6 | AutoRefresh Widget — Plan A vs Plan B | 对比型 navy card |
| 7 | Pagination Replaces Internal Scroll | 对比型 navy card |
| 8 | Empty States — 5 Scenarios Matrix | 矩阵 navy card |
| 9 | Aggregate Status Counters in Overview | 说明型 navy card |

每张 chip 遵循 M23 完整规范：
- bg `#2B2D42` navy + accent stroke `#33A4FD` 3px left border
- header chip `#33A4FD` Medium 14px
- body `Roboto Regular 12px` 白色 + 中文 `Noto Sans SC` 比 EN 小 2px + opacity 0.45
- 中英双语逐行内联（Layout A-逐行 + 2-space 分隔）

---

## 应用的硬规则 ✅

| 规则 | 实现 |
|---|---|
| **M0 Phase 0 element-to-component mapping** | 动手前生成完整 table 给 user review |
| **M1 Top bar 公共基建必 instance** | 6 frames 全部用 library `Top bar` After Login variant |
| **M2 Library-First** | 复用 Plan A file-local + TVU library，新组件均经 search_design_system 实证后才自建 |
| **M3 状态色按 ON AIR 惯例** | On-air 红 / Preview 绿 / Analyzing 蓝 / Inactive 灰 |
| **M4 Monitoring dark theme only** | 全 Layer_1 / Layer_2 / Layer_3 dark tokens |
| **M10 颜色绑 Color Variable，禁 hex literal** | 唯一例外：Card bg `#1f1f1f` mirror Plan A 选择（Layer_2 token 未发布，登记 backlog）|
| **M11 probe-based self-audit** | 关键属性（fills opacity / variant matches / icon swap）全部 probe 验证 |
| **M21 sibling visual contract** | probe Plan A MC/1920，21 个 library variables / 2 text styles / Card 样式合同全部 mirror |
| **M23 UX 交付注释规则** | 9 张 navy chip card + 双语 + accent stroke |
| **Q2 (M18) 两步法 paint opacity** | 所有 `bf()` 函数遵循 bind-then-mutate 模式 |
| **Q3 (M19) Master 改完 instance force-sync** | 改组件后批量 sync instance fills/strokes |

---

## 根因分析 — 为什么 code 都用对了，AI 还原效果图时反而错？

3 个连环 bug（all 2026-05-14 sessions 内出现，全部由 user 抓出）：

| Bug | Code 正确做法 | AI 错误做法 | 根因 |
|---|---|---|---|
| Sidebar hover bg | `var(--brand-hover)` | `UX/Background/Layer_3` 生灰 | 没读 Vue CSS，凭"hover 都用 layer_3"通用直觉 |
| Status bar inactive 段 | `var(--bg-layer4)` | `UX/Grey/grey-7` (text color!) | 凭"inactive 是灰的就用 grey-7"，没区分 BG vs Text 灰系 |
| Card translucent badge | `rgba(brand, 0.18)` | `paint.opacity = 0.18` 单步合并 | 没读 Q2 两步法 + 嵌套 instance edge case |

**共同根因**：**AI 没有把"源码 CSS 变量名"显式映射到"TVU library variable name"再绑 paint**。spec.md 里写的是工程师的术语（`--brand-hover` / `--bg-layer4`），TVU library 里是设计师的术语（`UX/Brand/Hover` / `Color Type/Background/Layer_4`）。**这两套术语不会自动对齐，需要前置一张映射表**。

AI 跳过映射表，凭"看上去像哪个 token 就用哪个" → 系统性错误。

## 写入 TVU 设计系统的范式（避免后续产品踩同样的坑）

已 commit 到 `tvu-design-system` repo：

### 新增 3 个 M-rule（`docs/internal/mockup-conventions.md`）

| Rule | 内容 |
|---|---|
| **M24** Code→Token Mapping Table（**仅** "已有 code 还原效果图" 场景，严格触发条件 AND）| **触发**：任务明确说"根据 code 还原 / match the running impl" **且** 提供 source file 定义视觉 token。**不触发**：greenfield（US-1/2）、纯 UX 探索、增量改既有 mockup（走 M21）、设计先行场景。触发后才必产 mapping table |
| **M25** State Color Discipline | hover ≠ brand：每个状态色都有专门 Hover/Disable variant token（`UX/Brand/Hover` / `UX/Red/Hover 1` 等）。Brand-colored interactive element 的 hover 必须用 brand-hover，绝不可用 Layer_3 |
| **M26** BG vs Text Grey Discipline | `Layer_{1,2,3,4}` 是 BG fill token；`UX/Grey/grey-N` + `Color Type/Text/*` 是 text/border token。两套不可混用。Status bar inactive 段是 BG = Layer_4，不是 Grey-7 |

### 新增 1 个 Q-rule（`docs/internal/figma-technical-reference.md`）

| Rule | 内容 |
|---|---|
| **Q7** 嵌套 instance `paint.opacity` 不持久（强化 Q3）| 顶层 instance 可 paint.opacity override；**嵌套 instance 内 frame children paint.opacity override 在下次 probe 时被 Figma 重置回 master 默认**。解药：用 child Rectangle + `node.opacity` 替代 paint.opacity（node 级属性可继承嵌套 instance） |

### 反模式实证（catalog 已写入警示）

> **规则**：hover = brand-hover @ low alpha / active = brand pure / inactive bg = Layer_4 (NOT grey-7)

后续任何消费 TVU 设计系统的产品设计 → 起手必读 M24 + 必产 Code→Token mapping table，**这一步省了就会重蹈这次的覆辙**。

---

## 反哺到 TVU 设计系统（2026-05-14 update）

### 新登记/补充的库知识（已写入 `tvu-design-system/docs/internal/figma-component-catalog.md`）

| 项 | 内容 |
|---|---|
| `icon/Preview/4` (key `b2cb6ce9...`) | **新登记**：2×2 grid icon = Overview / Dashboard / All Apps 入口的**标准图标**。MicroApps Console Plan B sidebar Overview row 实证后采纳。建议未来任何"看全部应用 / 所有 dashboard"类入口都直接 import 此 icon，禁止自画 grid |
| `icon/Preview/{1, 6, 9, 25}` | 同 namespace 的 N-tile grid 系列补登记，对应不同密度的 multiviewer 选择 |
| `icon/Preview/{List, grid view, Layout, sidebar}` | 视图切换类同 namespace 补登记 |
| `UX/Brand/Hover` (key `eab4ef3b...`) | **新登记**：hover 状态专用品牌色变量。**Hover ≠ Brand**：hover state 必须用此 token，绝不可直接用 `UX/Brand/Brand`（后者是 active/primary 身份色）|
| `UX/Brand/Disable` (key `9166c747...`) | 禁用态品牌色 |
| `UX/Red/Hover 1` / `UX/Blue/Hover 1` / `UX/Orange/Hover 1` | 状态色的 hover 变体（同套规则） |
| `Color Type/Icon/Active & Hover` | icon 专用的 active+hover 共用色 |
| `Color Type/Background/Hover Grey Button` / `Text/Hover Grey button` | grey button hover token 套件 |

### 实证教训（已写入 catalog 警示）

> **规则：hover = brand-hover @ low alpha / active = brand pure**
> 
> Plan B Sidebar Item Hover 初版误用 `Layer_3` 灰 bg，没有品牌色 hover affordance。修正为 `UX/Brand/Hover @ 0.10`。Active 状态仍用 `UX/Brand/Brand`（pure brand）作主身份。

---

## 已知库债 & v2 候选（待 TVU library 发布）

| Backlog ID | 项 | 影响 | Workaround |
|---|---|---|---|
| **BRIDGE-MOCKUP-001** | TVU library 缺预混合 alpha 的 bg token（`--brand-bg-18` / `--blue-bg-18` 等）| Persona chip / Aggregate filter / Card "N active" badge 都需要 18% alpha | **Overview Card badge**：用 child Rectangle + `node.opacity=0.18`（可传 instance）。**其他 chip**：直接 set instance fills opacity（top-level instance 可工作） |
| **BRIDGE-MOCKUP-002** | `--bg-layer2` (#1f1f1f) 未发布 Variable | Card bg | Plan A 也用 hex literal — mirror 此做法 |
| **BRIDGE-TOPBAR-BELL** | library `Top bar / After Login` 默认 Right_content 无通知铃铛 | Frame 1-5 topbar 右侧 cluster 无 bell | Plan A 也无 — 等 library 添加或在产品代码层注入 slot 内容 |
| ~~**BRIDGE-MOCKUP-003**~~ ❌ **stale, void** | ~~`icon/Arrow/Left` / `Right` 未发布~~ | 经 2026-05-14 re-verify (M15.1)，库**一直有** `icon/Arrow/Left` (key `503af6b686d3ff869c5c2c48cd9ee438cd05f83e`) + `icon/Arrow/Right` (key `a135a5138dda4900963d0c6c69823c5523d96f80`)。上一 session 0-search 即断言未发布，违 M15。条目 void，sidebar toggle 应 instance 库 chevron icon |
| **BRIDGE-MOCKUP-004 (待编号)** | `icon/empty-tray` / `icon/Video/Pause` 未发布 | Empty State / AutoRefresh widget 用占位 shape + 自画 | 等 library 补 |

---

## Figma 平台技术 quirks 实证

本次 session 实证两个 Q-rule（来自 `figma-technical-reference.md`）：

### Q2 — 绑 Color Variable 与设 opacity 必须分两步
- 复现：`setBoundVariableForPaint(paint, 'color', v)` 返回的新 paint **不带 opacity 字段**（输入 paint 的 opacity 被丢弃）
- 修复：先 bind 再 spread + mutation 强制 opacity 字段

### Q3 — Master 改完后 instance 需 force-sync
- 复现：Master 组件 fills opacity 0.18，instance 创建后 fills opacity 仍为 1.0（不自动继承）
- 修复 path 1（顶级 instance）：直接 `inst.fills = inst.fills.map(p => ({...p, opacity: 0.18}))` — 持久
- 修复 path 2（嵌套 instance 内部 frame children）：**path 1 不持久**，下次 probe 又变 1.0。改架构：child Rectangle 用 `node.opacity` 替代 `paint.opacity`，node opacity 可传嵌套 instance

**Plan B 独家发现**（建议回流到 figma-technical-reference.md）：

> **Q2 / Q3 edge case：嵌套 instance 内部 frame 的 paint.opacity 不可 override。**
> 
> 复现：top-level instance `setOpacity` 通过；nested instance child 的 same operation 立即 probe = 0.18，但下次 script 中 probe 回 1.0（Figma 在 plugin 上下文重新 evaluate paint properties 时重置）。
> 
> 解药：把 alpha 效果实现为**单独的 child Rectangle + node-level opacity**，不依赖 paint.opacity。node.opacity 可正常传递嵌套 instance children。具体 patterns：
> 1. Master 内 badge frame fills=[] strokes=[]，第一个子节点 Rectangle 绝对定位 STRETCH/STRETCH + node.opacity=0.18 + 状态色 fills
> 2. Instance 内的 outer badge fills 也需要清空（instance creation 时 stale data 不会自动 sync 到 master 的 fills=[]）

---

## 关键交互 spec 锚定（per `2026-05-13-plan-b-spec.md`）

- Sidebar collapse: localStorage `microapps-sidebar-collapsed` 持久化；折叠态 tooltip 弹右
- AutoRefresh: 30s 默认 + 倒计时数字主信息 + 底部 2px progress line
- Pagination: 默认 15/页（选 10/15/20/50）；filter 后自动 clamp 当前页
- Empty States 5 场景图标语义：`i-empty-tray`（被动）/ `i-search`（过滤后空）/ `i-add`（可创建，仅按钮内）
- Persona chip 颜色：Admin 蓝 (UX/Blue/Default) / User 绿 (UX/Brand/Brand)
- + New Session 作用域：Overview 视图 sub-header 按钮 / App Detail 视图 filter bar 按钮 / All Sessions 完全不显示
- Event Owner 列：admin 显示（hyperlink mailto/tel）/ my-sessions 隐藏 / 不支持排序
- 排序：Event Name / Object ID / Input URL / Output URL / State 4+1 列支持（图标 `icon/Arrow/Sorting`）；Event Owner 不支持

---

## 后续 Next Steps（建议）

1. **设计师 review**：在 Figma 内逐 frame review，特别看 Plan A 视觉合同是否 100% 对齐
2. **PM 视角**：从对比叙事（📌#1）开始 → Overview → App Detail → Empty 场景串讲
3. **TVU library 团队**：登记 5 个 backlog 库债项目（BRIDGE-MOCKUP-001 至 004 + BRIDGE-TOPBAR-BELL）
4. **Figma file 维护**：把 6 frames + 9 annotations 移到 production review section 后命名固化
5. **回流 figma-technical-reference.md**：把"嵌套 instance paint.opacity 失效"作为 Q-rule 新增条目

---

## 文件改动总结

无项目源码改动；本次工作完全在 Figma 文件层面。文档新增：
- 本 handoff doc：`docs/2026-05-14-plan-b-figma-handoff.md`
- 触发的库债登记建议项（写入 tvu-design-system backlog 由用户/AI 后续操作）

---

## Session 元数据

- 启动指令：`@TVU mockup`（route to tvu-design-mockup skill）
- 真源：`docs/2026-05-13-plan-b-spec.md`（spec）+ vue-app 实现（reference code）+ Plan A frames（visual contract）
- Skill 加载：`tvu-design-mockup` (route) → `figma:figma-generate-design` + `figma:figma-use` + `figma-technical-reference.md` Q-rules
- 工具：`use_figma` 大量 calls + `search_design_system`（找 Pagination）+ `get_screenshot` 验证
