我已走完 onboarding（L-core 四份 + AGENTS 硬规则/必读链路 + mockup 链的 code 侧 scoped 读：code-conventions 起手必读段 + R0/R2/R3/R6/R7/R13/R14/R15/R16/R19/R-DISCIPLINE、domain-tvu M3/M4/M7/M9/M12/M17、design-process §Scope Handling/M21、figma-component-catalog 相关 entry），并读了这类产物的机检真源 `scripts/audit-mockup-html-conformance.mjs`。

**意图分类**：`intent classified as 场景 2.2（已有页面加新 feature/element）` = US-3 增量；视觉真源 = 宿主页既有惯例 + TVU DS（你显式指定用 TVU 设计系统 = M22 用户意图，覆盖 M21.2 默认的「产品色优先」）。

**R0 Phase 0 element→component mapping**（取数：catalog → canonical → src/components → src/icons）

| Element | Figma component_set（key） | Code 真源 | 状态 |
|---|---|---|---|
| Type of source 三选一 | `radio` (`9f07746f…`, dark theme × status × enable) | `src/canonical/Radio.vue` → `src/components/Radio/Radio.vue` | ✅ sync |
| 顶部 bar | `Top bar` (`918b928e…`) | `src/components/TopBar/TopBar.vue` | ✅ sync |
| 顶部页签（不新增项） | `Tab/Item` (`2267405386…`) + `Tab List` (`47efe04f…`) | `src/components/Tab/TabItem.vue` / `TabList.vue` | ✅ sync |
| 目标接收端 / Discovery / Bandwidth 下拉 | `select box/filled` (`ca2ff89d…`) | `src/components/Select/Select.vue` | ✅ sync |
| Group / Server address 文本框 | `input box/filled` | `src/components/Input/Input.vue` | ✅ sync |
| Apply / Cancel / Rescan | `Button/dark M` (`12b38c8b…`) | `src/components/Button/Button.vue`（PALETTE_SPEC 逐档） | ✅ sync |
| 状态徽标 | `Badge` (`4db5246d…`) / Pill Status | `src/components/Pill/Pill.vue` | ✅ sync |
| 表单行（label+控件+hint） | `Form Item` | `src/components/FormItem/FormItem.vue` | ✅ sync |
| Include audio 开关 | `switch` (`bf16e8f5…`) | `src/components/Switch/Switch.vue` | ✅ sync |
| 空态提示条 | `Message`（设备侧谱系，M12） | 本稿以 DS token 手写 notice | 🟡 单文件无组件链，实装换 `Message` |
| 图标 4 枚 | `navigation/arrow-dropdown` · `action/refresh`(`1202:4182`) · `media/source-unavailable`(`1352:26898`) · `status/info-outline` · `brand/logo-tvu` | `src/icons/raw.ts` 逐字复制 | ✅ sync（零自画 SVG） |
| 分隔线 | — | token `--line-divider-deep` | ✅ |

**四条关键决策**
1. **三选一继续用 `radio`，不改成 Tab/分段控件**：宿主页原本就是互斥表单值（radio 语义），R6/场景 2 禁止借增量把既有控件换平台；且 catalog 的 `Tab/Item` 是导航语义，而你明确说「不新增导航项」。
2. **分隔线**用 `--line-divider-deep`（= `--line-deep`）满宽压边，负 margin 走 `--sp-l`，无裸 px。
3. **NDI 表单**给到 5 个字段（NDI source + Rescan / Discovery / Group / Bandwidth / Include audio / Target receiver）+ 右侧预览元数据卡，与 IP 分支的「预览 + 参数 + Apply」信息架构对齐；`Discovery=Discovery server` 时条件渲染 `Server address`（R14：条件渲染不留尸 DOM）。
4. **多给一帧 3-b「未发现源」**：NDI 发现是网络异步事件，M12 禁止静默 no-op → 空态给出「告知 + 前进路径（Rescan / 改 Discovery server）」，同时顺带展示 disabled 态与条件字段。

**如实登记的两处边界**（不是待办，是本稿能力边界）
- **宿主页范式未 probe**（M17 要求先打开宿主 canonical 帧实测行高/控件宽/对齐）：我没有该页的 Figma/截图/代码，所以几何全部取 DS canonical 实测值（radio 16px/1.2px、Button M 32px/padding 16、Select M 32px、Tab 32px/gap 24、FormItem label 120px/row 32px）。顶部页签标签、卡片示例数据均为占位，**不在改动范围**（Scope Handling：既有区域保持可见、零 mutation）。实装前请拿宿主页核对几何与文案。
- **Logo 之外零自画**：4 枚图标 + TVU logo 均逐字取自 `src/icons/raw.ts`；token 内联自 `src/tokens/variables.css`（单文件无法 `<link>` 真源，实装走 R2.1 的 `copyDesignTokensPlugin`，不手抄色值）。

机检自查（对照 `audit-mockup-html-conformance.mjs`）：`unconstrained-svg` 每个 `<svg>` 带 width/height ✅ · `handrolled-nav` 无 `<nav>`／nav-class `<ul>`，页签走 DS TabList 结构 ✅ · `hardcoded-color` 色值声明全 `var(--…)`，仅舞台底 `#0a0a0a` 属白名单中性底 ✅ · 无 PopupBox/alert ✅。

```html
<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Device Local Settings · Video Source — NDI increment (TVU Design System)</title>
<style>
/* ==========================================================================
   1 · TVU DESIGN SYSTEM TOKENS
   逐字复制自 tvu-design-system/src/tokens/variables.css（dark 默认档）。
   单文件交付物无法 <link> 真源；实装请按 code-conventions §R2.1 用
   vite copyDesignTokensPlugin 输出 tvu-tokens.css 并 <link>，不要手抄色值。
   ========================================================================== */
:root{
  /* Neutrals */
  --color-white:#ffffff;--color-grey-2:#f8f8f8;--color-grey-3:#f0f0f0;--color-grey-4:#dbdbdb;
  --color-grey-5:#cccccc;--color-grey-6:#9e9e9e;--color-grey-7:#7b7b7b;--color-grey-8:#595959;
  --color-grey-9:#434343;--color-grey-10:#353535;--color-grey-11:#262626;--color-grey-12:#1f1f1f;
  --color-grey-13:#141414;--color-grey-14:#000000;
  /* Brand & status */
  --brand:#2fb54e;--brand-hover:#41c760;--brand-match:#0b2b13;--brand-disable:#1a652c;
  --red:#ea4233;--red-hover:#ed5b4e;--red-bg:#fff1f0;
  --orange:#f68512;--orange-hover:#f89c3e;--orange-bg:#fff3db;--orange-tz:#d39f39;
  --blue:#3892f3;--blue-hover:#62a9f6;--blue-bg:#e1eefd;
  /* Message soft backgrounds */
  --msg-bg-red:#3b1c1a;--msg-bg-brand:#19311e;--msg-bg-blue:#1a2b3c;--msg-bg-grey:#353535;
  /* Text */
  --text-heading:#ffffff;--text-body:#f8f8f8;--text-2:#cccccc;--text-tips:#9e9e9e;
  --text-placeholder:#7b7b7b;--text-disabled:#595959;--text-primary-btn:#f8f8f8;
  /* Icon */
  --icon-active:#f8f8f8;--icon-default:#9e9e9e;--icon-disabled:#595959;--icon-placeholder:#7b7b7b;
  /* Surface */
  --bg-layer1:#141414;--bg-layer2:#1f1f1f;--bg-layer3:#262626;--bg-layer4:#353535;
  --bg-topbar:#000000;--bg-grey-btn-hv:#595959;--bg-grey-btn-en:#434343;--bg-grey-btn-dis:#434343;
  /* Line */
  --line-border:#595959;--line-deep:#353535;--line-light:#434343;
  /* Input / select aliases */
  --input-line-border:var(--color-grey-8);--input-disabled-border:var(--color-grey-8);
  --select-line-border:var(--color-grey-8);--select-disabled-border:var(--color-grey-8);
}
/* Spacing */
:root{--sp-xxs:4px;--sp-xs:8px;--sp-s:12px;--sp-m:16px;--sp-l:24px;--sp-xl:32px;--sp-xxl:40px;--sp-xxxl:56px}
/* Radius */
:root{--r-xs:2px;--r-s:4px;--r-m:8px;--r-l:12px;--r-xl:16px;--r-xxl:20px}
/* Layout breakpoints / containers */
:root{--bp-sm:640px;--bp-md:960px;--bp-lg:1100px;--bp-xl:1280px;
      --container-narrow:720px;--container-prose:840px;--container-page:1600px;--container-wide:1800px}
/* Typography */
:root{
  --font-family-en:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,'Fira Sans','Droid Sans','Helvetica Neue',sans-serif;
  --font-family-zh:'PingFang SC','Microsoft YaHei',Helvetica,Arial,sans-serif;
  --font-family-base:var(--font-family-en),var(--font-family-zh);
  --text-style-tips:400 12px/16px var(--font-family-base);
  --text-style-body:400 14px/21px var(--font-family-base);
  --text-style-pop-title:600 16px/24px var(--font-family-base);
  --text-style-headline-2:600 18px/27px var(--font-family-base);
  --text-style-headline-1:600 20px/30px var(--font-family-base);
  --font-size-tips:12px;--font-size-body:14px;--font-size-pop-title:16px;--font-size-headline-2:18px;
  --line-height-tips:16px;--line-height-body:21px;
  --font-weight-regular:400;--font-weight-semibold:600;
}
/* Component-variant / structural tokens */
:root{
  --topbar-height:64px;--topbar-section-gap:80px;
  --radio-circle-size:16px;--radio-circle-border-width:1.2px;--radio-selected-dot-size:6px;
  --switch-track-w:40px;--switch-track-h:20px;--switch-thumb-size:16px;--switch-thumb-inset:2px;--switch-thumb-travel:20px;
  --switch-bg-off-dark:var(--color-grey-8);--switch-bg-disabled-off-dark:var(--color-grey-9);--switch-thumb-disabled-dark:var(--color-grey-7);
  --form-item-row-height:32px;--form-item-label-width-120:120px;--form-item-label-width-200:200px;
  --control-height-xxs:32px;
}
/* Effects */
:root{
  --shadow-l1:0 5px 12px 4px #00000017,0 3px 6px 0 #0000001f,0 1px 2px -2px #00000029;
  --shadow-l2:0 9px 28px 8px #0000000d,0 6px 16px 0 #00000014,0 3px 6px -4px #0000001f;
}
/* Derived aliases */
:root{
  --input-filled-bg:var(--bg-layer4);--green-bg:var(--brand-match);
  --line-divider-deep:var(--line-deep);--line-divider-light:var(--line-light);
  --control-default-border:var(--icon-placeholder);--control-disabled-bg:var(--line-deep);
  --control-disabled-border:var(--line-border);--control-disabled-text:var(--text-disabled);
  --radio-default-border:var(--text-tips);--radio-selected-dot:var(--bg-layer1);
  --radio-disabled-off-bg:var(--text-disabled);--radio-disabled-off-border:var(--bg-layer4);
  --radio-disabled-selected-bg:var(--brand-disable);
}

/* ==========================================================================
   2 · DS element base layer（同 variables.css 末段：语义 HTML 兜底）
   ========================================================================== */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
body{font:var(--text-style-body);font-family:var(--font-family-base)}
h1{font:var(--text-style-headline-1);color:var(--text-body)}
h2{font:var(--text-style-headline-2);color:var(--text-body)}
h3{font:var(--text-style-pop-title);color:var(--text-body)}
label{font:var(--text-style-body);color:var(--text-body)}
a{color:var(--brand)}
button{font:var(--text-style-body);color:inherit;border-radius:var(--r-s)}
input,select{font:var(--text-style-body);color:var(--text-body);background:var(--input-filled-bg);
  border:1px solid var(--line-border);border-radius:var(--r-s);padding:var(--sp-xs) var(--sp-s)}
input::placeholder{color:var(--text-placeholder)}
table{font:var(--text-style-body);color:var(--text-body);border-collapse:collapse}
th{font-weight:600;color:var(--text-body);text-align:left;padding:var(--sp-xs) var(--sp-s)}
td{padding:var(--sp-xs) var(--sp-s);border-top:1px solid var(--line-border)}

/* ==========================================================================
   3 · 说明层（frame 外，非产品 UI —— code-conventions §R12：批注不进界面）
   ========================================================================== */
html,body{background:#0a0a0a}
body{color:var(--text-body);-webkit-font-smoothing:antialiased}
.stage{padding:var(--sp-xl) var(--sp-l) var(--sp-xxxl)}
.wrap{max-width:var(--bp-xl);margin:0 auto}
.doc-head{margin-bottom:var(--sp-xl)}
.doc-head h1{color:var(--text-heading)}
.doc-sub{margin-top:var(--sp-xs);color:var(--text-tips);font:var(--text-style-body)}
.doc-cols{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-m);margin-top:var(--sp-m)}
.doc-card{background:var(--bg-layer2);border:1px solid var(--line-deep);border-radius:var(--r-m);padding:var(--sp-m)}
.doc-card h3{margin-bottom:var(--sp-xs)}
.doc-card ol,.doc-card ul{margin:0;padding-left:18px;color:var(--text-2);font:var(--text-style-body)}
.doc-card li{margin:var(--sp-xxs) 0}
.doc-card li b{color:var(--text-heading);font-weight:var(--font-weight-semibold)}
.new-tag{display:inline-block;padding:0 var(--sp-xxs);border-radius:var(--r-xs);
  background:var(--msg-bg-brand);color:var(--brand);font:var(--text-style-tips);font-weight:var(--font-weight-semibold)}
.frame-cap{display:flex;align-items:baseline;gap:var(--sp-s);margin:var(--sp-xl) 0 var(--sp-s);flex-wrap:wrap}
.frame-chip{padding:var(--sp-xxs) var(--sp-xs);border:1px solid var(--line-light);border-radius:var(--r-s);
  background:var(--bg-layer3);color:var(--text-2);font:var(--text-style-tips);font-weight:var(--font-weight-semibold);white-space:nowrap}
.frame-title{color:var(--text-heading);font:var(--text-style-pop-title)}
.frame-note{color:var(--text-tips);font:var(--text-style-tips)}
.doc-foot{margin-top:var(--sp-xxl)}
.doc-foot table{width:100%;background:var(--bg-layer2);border:1px solid var(--line-deep);border-radius:var(--r-m)}
.doc-foot th{color:var(--text-tips);font:var(--text-style-tips);font-weight:var(--font-weight-semibold);
  text-transform:uppercase;letter-spacing:.6px;border-bottom:1px solid var(--line-deep)}
.doc-foot td{border-top:1px solid var(--line-deep);font:var(--text-style-tips);color:var(--text-2);vertical-align:top}
.doc-foot td:first-child{color:var(--text-body)}
.mono-ish{font-variant-numeric:tabular-nums}

/* ==========================================================================
   4 · DS 组件镜像（class 名沿用各组件真源，便于逐条回溯）
   Radio / Button / Tab / Select / Input / Pill / FormItem / Switch
   ========================================================================== */
/* — Radio（src/components/Radio/Radio.vue）— */
.radio{display:inline-flex;align-items:center;gap:var(--sp-xs);height:21px;cursor:pointer;
  font:var(--text-style-body);color:var(--text-body);user-select:none}
.radio-circle{flex-shrink:0;width:var(--radio-circle-size);height:var(--radio-circle-size);box-sizing:border-box;
  border-radius:50%;border:var(--radio-circle-border-width) solid var(--radio-default-border);background:transparent;
  display:flex;align-items:center;justify-content:center;transition:border-color .15s,background .15s}
.radio-dot{width:var(--radio-selected-dot-size);height:var(--radio-selected-dot-size);border-radius:50%;
  background:var(--radio-selected-dot);display:none}
.radio:hover .radio-circle{border-color:var(--brand)}
.radio:focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:var(--r-xs)}
.radio[aria-checked="true"] .radio-circle{background:var(--brand);border-color:var(--brand)}
.radio[aria-checked="true"] .radio-dot{display:block}

/* — Button（src/components/Button/Button.vue · size M）— */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:0;height:32px;padding-inline:var(--sp-m);
  border:1px solid transparent;border-radius:var(--r-s);background:transparent;color:var(--text-2);
  font-family:var(--font-family-base);font-size:var(--font-size-body);font-weight:var(--font-weight-regular);
  line-height:var(--line-height-body);cursor:pointer;white-space:nowrap;outline:none;user-select:none;
  transition:background .15s,color .15s,border-color .15s}
.btn:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.btn--icon-left{gap:var(--sp-xxs)}
.btn--icon-left svg{flex-shrink:0}
.btn--fill-green{background:var(--brand);color:var(--text-primary-btn)}
.btn--fill-green:hover{background:var(--brand-hover)}
.btn--ghost-green{border-width:1.2px;border-color:var(--brand);color:var(--brand)}
.btn--ghost-green:hover{background:var(--green-bg)}
.btn--ghost-gray{border-width:1.2px;border-color:var(--bg-grey-btn-en);color:var(--text-2)}
.btn--ghost-gray:hover{background:var(--bg-grey-btn-en)}
.btn[disabled]{cursor:not-allowed}
.btn--fill-green[disabled]{background:var(--brand-disable);color:var(--text-tips)}
.btn--ghost-green[disabled]{border-color:var(--brand-disable);color:var(--brand-disable);background:transparent}
.btn--ghost-gray[disabled]{color:var(--text-placeholder);background:transparent}

/* — Tab（src/components/Tab/TabList.vue + TabItem.vue · type=line）— */
.tab-list{display:flex;align-items:stretch;border-bottom:1px solid var(--line-deep);padding:0 var(--sp-m);background:var(--bg-layer1)}
.tab-list__items{display:inline-flex;align-items:center;gap:var(--sp-l)}
.tab-item{display:inline-flex;align-items:center;gap:var(--sp-xs);height:32px;padding:0 var(--sp-m);
  font:var(--text-style-body);color:var(--text-tips);cursor:pointer;white-space:nowrap;user-select:none;
  border-bottom:1px solid transparent;margin-bottom:-1px;transition:color .15s,border-color .15s}
.tab-item:hover{color:var(--text-2)}
.tab-item--active{color:var(--text-body);border-bottom-color:var(--line-light);font-weight:700}

/* — Select（src/components/Select/Select.vue · variant=filled, size=M）— */
.select-wrap{position:relative;display:block;width:100%}
.select{display:block;width:100%;height:32px;background:var(--bg-layer4);border:1px solid transparent;
  border-radius:var(--r-s);color:var(--text-body);font-size:13px;font-family:var(--font-family-base);
  outline:none;appearance:none;-webkit-appearance:none;cursor:pointer;padding:0 36px 0 var(--sp-s);transition:border-color .15s}
.select:hover:not(:disabled),.select:focus:not(:disabled){border-color:var(--brand)}
.select:disabled{color:var(--text-tips);background:var(--control-disabled-bg);cursor:not-allowed}
.select--placeholder{color:var(--text-placeholder)}
/* overlay: 下拉箭头锚在 select 右内缘（R14 例外条款 — 浮层/装饰无 layout 语义） */
.select-arrow{position:absolute;right:var(--sp-s);top:50%;transform:translateY(-50%);pointer-events:none;
  color:var(--text-tips);display:flex;align-items:center}
.select:disabled ~ .select-arrow{color:var(--icon-disabled)}

/* — Input（src/components/Input/Input.vue · variant=filled, size=M）— */
.tvu-input{display:block;width:100%;height:32px;padding:var(--sp-xs) var(--sp-s);background:var(--input-filled-bg);
  border:1px solid transparent;border-radius:var(--r-s);color:var(--text-body);font-size:var(--font-size-body);
  font-family:var(--font-family-base);outline:none;transition:border-color .15s}
.tvu-input:hover:not(:disabled),.tvu-input:focus:not(:disabled){border-color:var(--brand)}
.tvu-input:disabled{background:var(--control-disabled-bg);color:var(--text-disabled);cursor:not-allowed}

/* — Pill Status（src/components/Pill/Pill.vue）— */
.pill{display:inline-flex;align-items:center;box-sizing:border-box;min-height:28px;gap:var(--sp-xs);
  padding:var(--sp-xxs) var(--sp-s) var(--sp-xxs) 10px;border-radius:999px;background:var(--pill-bg,var(--msg-bg-grey));
  border:1px solid transparent;color:var(--text-body);font-size:var(--font-size-tips);font-weight:500;
  line-height:1.4;font-family:var(--font-family-base);white-space:nowrap}
.pill__dot{flex-shrink:0;width:6px;height:6px;border-radius:50%;background:var(--pill-dot,var(--text-tips))}
.pill--live{--pill-bg:var(--msg-bg-red);--pill-dot:var(--red)}
.pill--ok{--pill-bg:var(--msg-bg-brand);--pill-dot:var(--brand)}
.pill--idle{--pill-bg:var(--msg-bg-grey);--pill-dot:var(--text-tips)}
.pill--sm{min-height:20px;padding:0 var(--sp-xs) 0 6px}

/* — FormItem（src/components/FormItem/FormItem.vue · dark）— */
.form-item{color:var(--text-body)}
.form-item__main{display:flex;gap:var(--sp-xs);align-items:flex-start}
.form-item__label{display:inline-flex;align-items:center;gap:var(--sp-xxs);box-sizing:border-box;
  min-height:var(--form-item-row-height);width:var(--form-item-label-width-120);padding:var(--sp-xxs) 0;
  font:var(--text-style-body);color:var(--text-tips);flex-shrink:0}
.form-item__content{display:flex;flex:1 1 auto;min-width:0;flex-direction:column;gap:var(--sp-xxs)}
.form-item__message{font:var(--text-style-tips);color:var(--text-tips)}
.form-item--two-lines .form-item__main{flex-direction:column;gap:0}
.form-item--two-lines .form-item__label{width:auto;min-height:auto;padding-bottom:var(--sp-xxs)}
.form-item--two-lines .form-item__content{width:100%}

/* — Switch（src/components/Switch/Switch.vue · dark）— */
.switch{display:inline-flex;align-items:center;width:var(--switch-track-w);height:var(--switch-track-h);
  border-radius:var(--r-xxl);padding:var(--switch-thumb-inset);background:var(--switch-bg-off-dark);
  border:none;cursor:pointer;transition:background .2s;outline:none;flex-shrink:0}
.switch:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.switch--on{background:var(--brand)}
.switch--disabled{cursor:not-allowed;background:var(--switch-bg-disabled-off-dark)}
.switch-thumb{width:var(--switch-thumb-size);height:var(--switch-thumb-size);border-radius:50%;
  background:var(--color-white);transition:transform .2s;flex-shrink:0}
.switch--on .switch-thumb{transform:translateX(var(--switch-thumb-travel))}
.switch--disabled .switch-thumb{background:var(--switch-thumb-disabled-dark)}

/* ==========================================================================
   5 · 页面合成层（设备本地设置页）
   ========================================================================== */
.device{width:100%;background:var(--bg-layer1);border:1px solid var(--line-deep);border-radius:var(--r-m);
  overflow:hidden;box-shadow:var(--shadow-l1)}
/* TopBar — src/components/TopBar/TopBar.vue（Tag=After Login，height 64） */
.topbar{display:flex;align-items:center;gap:var(--sp-m);height:var(--topbar-height);
  padding:var(--sp-xs) var(--sp-m);background:var(--bg-topbar);border-bottom:1px solid var(--line-deep)}
.topbar-brand{display:flex;align-items:center;gap:var(--sp-m);flex-shrink:0}
.topbar-logo{width:28px;height:28px;display:block}
.topbar-title{font:var(--text-style-pop-title);color:var(--text-heading);white-space:nowrap}
.topbar-right{display:flex;align-items:center;gap:var(--sp-s);margin-left:auto;flex-shrink:0}
.topbar-dev{font:var(--text-style-body);color:var(--text-2);font-variant-numeric:tabular-nums}

.page{padding:var(--sp-l)}
.panel{background:var(--bg-layer2);border:1px solid var(--line-deep);border-radius:var(--r-m);padding:var(--sp-l)}

/* 选择行 —— 三选一互斥（本次从二选一扩为三） */
.src-row{display:flex;align-items:center;gap:var(--sp-l);flex-wrap:wrap}
.src-row__label{font:var(--text-style-body);color:var(--text-tips);flex-shrink:0}
.src-choice{display:flex;align-items:center;gap:var(--sp-l);flex-wrap:wrap}
/* 需求 ③：选择行与内容区之间的视觉分隔（满宽压边，用 divider token） */
.src-divider{border:0;border-top:1px solid var(--line-divider-deep);
  margin:var(--sp-m) calc(-1 * var(--sp-l)) var(--sp-l)}

.branch-head{display:flex;align-items:baseline;gap:var(--sp-xs);margin-bottom:var(--sp-s)}
.branch-title{font:var(--text-style-body);font-weight:var(--font-weight-semibold);color:var(--text-heading)}
.branch-meta{font:var(--text-style-tips);color:var(--text-tips);font-variant-numeric:tabular-nums}
.branch-sp{flex:1}

/* — 分支 A：本地物理输入（既有内容，本轮零改动） — */
.li-list{border:1px solid var(--line-deep);border-radius:var(--r-s);overflow:hidden}
.li-row{display:grid;grid-template-columns:140px 1fr auto;align-items:center;gap:var(--sp-m);
  min-height:44px;padding:var(--sp-xs) var(--sp-s);background:var(--bg-layer3);border-bottom:1px solid var(--line-deep)}
.li-row:last-child{border-bottom:none}
.li-name{display:flex;align-items:center;gap:var(--sp-xs);font:var(--text-style-body);color:var(--text-body);font-weight:var(--font-weight-semibold)}
.li-fmt{font:var(--text-style-body);color:var(--text-2);font-variant-numeric:tabular-nums}
.li-fmt--none{color:var(--text-placeholder)}
.branch-foot{display:flex;align-items:flex-end;gap:var(--sp-m);margin-top:var(--sp-m);flex-wrap:wrap}
.branch-foot .form-item{min-width:280px}
.branch-foot__actions{display:flex;gap:var(--sp-xs);margin-left:auto}

/* — 分支 B：IP Source 来源卡片网格（既有内容，本轮零改动） — */
.card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:var(--sp-m)}
.src-card{display:flex;flex-direction:column;background:var(--bg-layer3);border:1px solid var(--line-deep);
  border-radius:var(--r-m);overflow:hidden}
.preview{position:relative;aspect-ratio:16/9;background:var(--bg-layer1);display:flex;align-items:center;
  justify-content:center;border-bottom:1px solid var(--line-deep)}
/* overlay: 状态标与格式标锚在预览面内缘（R14 例外条款 — overlay 无 layout 语义） */
.pv-tag{position:absolute;top:var(--sp-xs);right:var(--sp-xs)}
.pv-fmt{position:absolute;left:var(--sp-xs);bottom:var(--sp-xs);padding:2px var(--sp-xxs);border-radius:var(--r-xs);
  background:var(--msg-bg-grey);color:var(--text-2);font:var(--text-style-tips);font-variant-numeric:tabular-nums}
.pv-empty{display:flex;flex-direction:column;align-items:center;gap:var(--sp-xxs);color:var(--text-placeholder);
  font:var(--text-style-tips)}
.card-body{display:flex;flex-direction:column;gap:var(--sp-xs);padding:var(--sp-s)}
.card-name{font:var(--text-style-body);font-weight:var(--font-weight-semibold);color:var(--text-heading);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.card-ip{font:var(--text-style-tips);color:var(--text-tips);font-variant-numeric:tabular-nums}
.card-foot{display:flex;justify-content:flex-end;padding:0 var(--sp-s) var(--sp-s)}

/* — 分支 C：NDI 专属表单（本次新增） — */
.ndi-grid{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:var(--sp-l)}
.ndi-form{display:flex;flex-direction:column;gap:var(--sp-s)}
.ndi-inline{display:flex;align-items:center;gap:var(--sp-xs)}
.ndi-inline .select-wrap{flex:1}
.ndi-side{display:flex;flex-direction:column;gap:var(--sp-s);background:var(--bg-layer3);
  border:1px solid var(--line-deep);border-radius:var(--r-m);padding:var(--sp-s)}
.kv{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-m);
  padding:var(--sp-xs) 0;border-bottom:1px solid var(--line-deep)}
.kv:last-child{border-bottom:none}
.kv__k{font:var(--text-style-tips);color:var(--text-tips)}
.kv__v{font:var(--text-style-body);color:var(--text-body);font-variant-numeric:tabular-nums;text-align:right}
.kv__v--none{color:var(--text-placeholder)}
.notice{display:flex;align-items:flex-start;gap:var(--sp-xs);padding:var(--sp-s);border-radius:var(--r-s);
  background:var(--msg-bg-grey);color:var(--text-body);font:var(--text-style-body)}
.notice svg{flex-shrink:0;margin-top:2px;color:var(--icon-default)}
.notice b{font-weight:var(--font-weight-semibold);color:var(--text-heading)}
.ndi-foot{display:flex;align-items:center;gap:var(--sp-xs);justify-content:flex-end;
  margin-top:var(--sp-m);padding-top:var(--sp-m);border-top:1px solid var(--line-divider-light)}

@media (max-width:960px){
  .doc-cols{grid-template-columns:1fr}
  .ndi-grid{grid-template-columns:1fr}
}
</style>
</head>
<body>
<div class="stage"><div class="wrap">

  <!-- ============ 说明层：本轮增量说明（frame 外，非产品 UI） ============ -->
  <div class="doc-head">
    <h1>Device Local Settings · Video Source — NDI 增量设计</h1>
    <p class="doc-sub">
      TVU 设计系统（dark 默认档 · token 逐字取自 <span class="mono-ish">src/tokens/variables.css</span>）·
      三个选中态同页并置 · 静态高保真帧
    </p>
    <div class="doc-cols">
      <div class="doc-card">
        <h3>本轮改动（4 项，逐条对应需求）</h3>
        <ol>
          <li><b>「Type of source:」二选一 → 三选一互斥</b>，新增第三项 <span class="new-tag">NDI</span>；控件仍是 DS <b>radio</b>（互斥表单值语义），不改成 Tab/分段控件。</li>
          <li><b>选中项决定下方内容区</b>：<b>IP Source</b> 保持既有来源卡片网格（预览 / IP / 目标接收端 / Apply 一项未动）；<b>NDI</b> 切换为 NDI 专属表单。</li>
          <li><b>选择行与内容区之间加视觉分隔</b>：满宽 1px 分隔线，绑 <span class="mono-ish">--line-divider-deep</span>。</li>
          <li><b>顶部导航零新增</b>：NDI 不是导航项，页签集合与既有页逐字一致。</li>
        </ol>
      </div>
      <div class="doc-card">
        <h3>未改动 / 如实边界</h3>
        <ul>
          <li><b>宿主页几何未 probe</b>（无该页 Figma / 截图 / 代码）：行高、控件宽、对齐全部取 DS canonical 实测值；顶部页签标签与卡片示例数据为<b>占位</b>，不在改动范围。实装前请按宿主页核对（domain-tvu §M17）。</li>
          <li><b>HDMI/SDI/USB 分支</b>按结构示意保留、零 mutation（design-process §Scope Handling：作用域收窄 ≠ 可见范围收窄）。</li>
          <li>图标 5 枚（含 logo）逐字取自 <span class="mono-ish">src/icons/raw.ts</span>，<b>零自画 SVG</b>；颜色全部 <span class="mono-ish">var(--…)</span>，零裸 hex。</li>
          <li>产品 UI 文案单语英文（code-conventions §R16）；中文只出现在本说明层。</li>
        </ul>
      </div>
    </div>
  </div>

  <!-- ================= FRAME 1 · HDMI/SDI/USB ================= -->
  <div class="frame-cap">
    <span class="frame-chip">STATE 1 / 3</span>
    <span class="frame-title">Type of source = HDMI/SDI/USB</span>
    <span class="frame-note">既有分支 · 选择行多出第三项后本分支内容零改动</span>
  </div>

  <div class="device">
    <div class="topbar">
      <div class="topbar-brand">
        <!-- icon: brand/logo-tvu — 逐字取自 src/icons/raw.ts (LogoTVU) -->
        <svg class="topbar-logo" width="28" height="28" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.9933 8.68971V8.6898V8.6899V8.69001C15.9962 8.96317 16 9.31582 16 9.81499V13.9033C16 13.9033 16 16 13.6733 15.9997H7.99586L7.98791 15.9998L7.97996 16H7.97102H7.93922C7.93922 16 7.94419 16 7.9538 15.9997C3.55876 15.9857 0 12.4098 0 8.00017C0 3.5819 3.573 0 7.97996 0C12.1057 0 15.5005 3.13931 15.9165 7.16512L15.9182 7.16545L15.9185 7.18106C15.946 7.45033 15.99 7.97375 15.99 8.25C15.99 8.37606 15.9915 8.51693 15.9933 8.68953L15.9933 8.68971ZM1.19653 7.97028C1.19653 11.7388 4.24392 14.7937 8.00305 14.7937C11.7622 14.7937 14.8096 11.7388 14.8096 7.97028C14.8096 4.20178 11.7622 1.14681 8.00305 1.14681C4.24392 1.14681 1.19653 4.20178 1.19653 7.97028ZM13.4204 15.2121V13.212L15.0122 14.2386L13.4204 15.2121ZM12.6575 12.0533C12.7649 12.0533 12.8543 12.0186 12.926 11.9492C12.9973 11.8798 13.0333 11.7951 13.033 11.6953C13.033 11.6246 13.0119 11.5608 12.9701 11.5041C12.9273 11.448 12.8468 11.39 12.7279 11.3296C12.6304 11.2805 12.5665 11.2378 12.5359 11.2011C12.5057 11.1651 12.4904 11.1274 12.4904 11.088C12.4904 11.0433 12.5087 11.0042 12.5457 10.9705C12.5828 10.9368 12.627 10.9201 12.6789 10.9201C12.7605 10.9201 12.8441 10.9605 12.9293 11.0419L13.032 10.9378C12.9161 10.8281 12.8013 10.7733 12.6871 10.7733C12.5889 10.7733 12.5077 10.804 12.4435 10.8651C12.3793 10.9265 12.347 11.0032 12.347 11.0957C12.347 11.1667 12.367 11.2298 12.4075 11.2849C12.4476 11.3399 12.5237 11.396 12.6358 11.4527C12.7401 11.5051 12.8074 11.5481 12.8369 11.5825C12.8665 11.6175 12.8814 11.6576 12.8814 11.7023C12.8814 11.7567 12.859 11.8041 12.8142 11.8444C12.7693 11.8848 12.7146 11.9048 12.6507 11.9048C12.5593 11.9048 12.473 11.8595 12.3915 11.7694L12.2913 11.8812C12.3337 11.9349 12.3874 11.9769 12.4527 12.0076C12.5175 12.038 12.5858 12.0533 12.6575 12.0533ZM11.9733 12.0533L11.3829 11.4987V12.0533H11.2319V10.3467H11.3829V11.3188L11.9264 10.8219H12.148L11.5037 11.4093L12.1856 12.0533H11.9733ZM10.6556 10.9878C10.7049 10.916 10.7569 10.8623 10.8117 10.8267C10.8665 10.7911 10.9234 10.7733 10.9826 10.7733C11.0274 10.7733 11.075 10.7874 11.126 10.8157L11.0416 10.9512C11.0078 10.9365 10.9792 10.9293 10.9561 10.9293C10.902 10.9293 10.85 10.9512 10.8 10.9953C10.7501 11.0391 10.7118 11.1075 10.6856 11.1999C10.6656 11.271 10.6556 11.4147 10.6556 11.6312V12.0533H10.4902V10.8055H10.6556V10.9878ZM9.64269 10.7733C9.83034 10.7733 9.98595 10.8411 10.1095 10.9769C10.2217 11.1007 10.2778 11.2472 10.2781 11.4167C10.2781 11.5868 10.2187 11.7353 10.1001 11.8625C9.9816 11.9896 9.82934 12.0533 9.64302 12.0533C9.45603 12.0533 9.3031 11.9896 9.18456 11.8625C9.06569 11.7353 9.00659 11.5868 9.00659 11.4167C9.00659 11.2482 9.06269 11.102 9.17488 10.9782C9.29809 10.8417 9.45403 10.7733 9.64269 10.7733ZM9.88152 11.8421C9.95431 11.8007 10.0121 11.742 10.0548 11.6659C10.0976 11.5899 10.1189 11.5081 10.1186 11.4197C10.1186 11.2832 10.0718 11.1667 9.97768 11.0706C9.88352 10.9742 9.77166 10.9262 9.6421 10.9262C9.51155 10.9262 9.39969 10.9745 9.30586 11.0706C9.21203 11.1667 9.16528 11.2832 9.16528 11.4197C9.16528 11.5078 9.18665 11.5899 9.22939 11.6659C9.27213 11.742 9.3299 11.8007 9.40269 11.8421C9.47548 11.8835 9.55529 11.9042 9.6421 11.9042C9.72892 11.9042 9.80872 11.8835 9.88152 11.8421ZM8.33623 12.0533H8.36592L8.90069 10.7733H8.73604L8.35108 11.7025L7.95565 10.7733H7.92698L7.53391 11.7025L7.15637 10.7733H6.99341L7.5194 12.0533H7.5491L7.9425 11.1368L8.33623 12.0533ZM6.88747 10.9474H6.63214V12.0533H6.4714V10.9474H6.25171V10.8089H6.4714V10.3467H6.63214V10.8089H6.88747V10.9474ZM5.83626 11.7904C5.79475 11.8261 5.74412 11.8548 5.68505 11.8761C5.62564 11.8978 5.56454 11.9085 5.5021 11.9085C5.37214 11.9085 5.26278 11.8635 5.17434 11.773C5.08591 11.6826 5.04034 11.5668 5.0373 11.4253H6.14579C6.1441 11.2592 6.09887 11.1204 6.00976 11.0092C5.8842 10.8517 5.71644 10.7733 5.50648 10.7733C5.30261 10.7733 5.13958 10.8501 5.01806 11.0039C4.9222 11.1247 4.87427 11.2622 4.87427 11.4167C4.87427 11.5808 4.93097 11.728 5.04439 11.8581C5.1578 11.9883 5.31476 12.0533 5.51594 12.0533C5.60674 12.0533 5.68775 12.0396 5.75964 12.0126C5.83154 11.9853 5.89601 11.9456 5.95339 11.8935C6.01077 11.8414 6.06141 11.7727 6.10529 11.6876L5.97162 11.6182C5.92301 11.697 5.87778 11.7547 5.83626 11.7904ZM5.19687 11.0383C5.28395 10.9615 5.38758 10.9232 5.50875 10.9232C5.582 10.9232 5.65187 10.9385 5.71837 10.9689C5.78486 10.9996 5.8382 11.0396 5.8787 11.0897C5.91921 11.1397 5.94992 11.2065 5.97119 11.2899H5.05273C5.08548 11.1781 5.13341 11.094 5.19687 11.0383ZM4.45639 10.8445C4.38617 10.7969 4.30564 10.7733 4.21478 10.7733C4.1256 10.7733 4.04273 10.7945 3.96686 10.8369C3.89098 10.8793 3.82176 10.9433 3.75919 11.0291V10.8055H3.60278V12.053H3.75919V11.5954C3.75919 11.4309 3.76652 11.3181 3.78149 11.2562C3.80545 11.1615 3.85471 11.0818 3.92958 11.0178C4.00446 10.9535 4.08899 10.9214 4.1835 10.9214C4.26603 10.9214 4.33326 10.9423 4.38451 10.984C4.43576 11.0257 4.4707 11.0876 4.48867 11.1704C4.50032 11.2186 4.50597 11.3143 4.50597 11.4583V12.0533H4.66239V11.4114C4.66239 11.2418 4.64575 11.1167 4.61213 11.0366C4.57852 10.9556 4.52661 10.8917 4.45639 10.8445ZM12.8146 8.39867V5.86667H13.669V8.41467C13.669 8.90067 13.6164 9.27267 13.3229 9.53167C13.0294 9.79067 12.5968 9.92 12.0253 9.92C11.4538 9.92 11.022 9.79034 10.7291 9.53167C10.4366 9.273 10.3843 8.90134 10.3843 8.41734V5.86667H11.2394V8.39867C11.2394 8.67167 11.2963 8.875 11.4098 9.00867C11.5233 9.14233 11.7705 9.20934 12.0257 9.20934C12.2772 9.20934 12.524 9.14534 12.6402 9.01667C12.7564 8.888 12.8146 8.682 12.8146 8.39867ZM9.02194 5.86667L8.01441 8.853L7.00721 5.86667H6.03979L7.53984 9.92H8.46061L9.96033 5.86667H9.02194ZM3.48276 6.554H2.2251V5.86667H5.61583V6.554H4.35817V9.92H3.48276V6.554Z" fill="#56AF31"/></svg>
        <span class="topbar-title">Local Settings</span>
      </div>
      <div class="topbar-right">
        <span class="topbar-dev">TVU-ONE-04517</span>
        <span class="pill pill--ok"><span class="pill__dot"></span>Online</span>
      </div>
    </div>

    <!-- 顶部导航：既有页签集合，本轮零新增（NDI 不是导航项） -->
    <div class="tab-list">
      <div class="tab-list__items" role="tablist" aria-label="Device settings sections">
        <div class="tab-item" role="tab" aria-selected="false" tabindex="-1">Status</div>
        <div class="tab-item tab-item--active" role="tab" aria-selected="true" tabindex="0">Video Source</div>
        <div class="tab-item" role="tab" aria-selected="false" tabindex="-1">Network</div>
        <div class="tab-item" role="tab" aria-selected="false" tabindex="-1">Streaming</div>
        <div class="tab-item" role="tab" aria-selected="false" tabindex="-1">System</div>
      </div>
    </div>

    <div class="page">
      <div class="panel">
        <div class="src-row">
          <span class="src-row__label">Type of source:</span>
          <div class="src-choice" role="radiogroup" aria-label="Type of source">
            <span class="radio" role="radio" aria-checked="true" tabindex="0">
              <span class="radio-circle"><span class="radio-dot"></span></span>HDMI/SDI/USB
            </span>
            <span class="radio" role="radio" aria-checked="false" tabindex="-1">
              <span class="radio-circle"><span class="radio-dot"></span></span>IP Source
            </span>
            <span class="radio" role="radio" aria-checked="false" tabindex="-1">
              <span class="radio-circle"><span class="radio-dot"></span></span>NDI
            </span>
          </div>
        </div>

        <hr class="src-divider">

        <div class="branch-head">
          <span class="branch-title">Local inputs</span>
          <span class="branch-sp"></span>
          <span class="branch-meta">2 of 3 connectors detected</span>
        </div>

        <div class="li-list">
          <div class="li-row">
            <span class="li-name">HDMI</span>
            <span class="li-fmt">1920×1080p59.94</span>
            <span class="pill pill--ok"><span class="pill__dot"></span>Signal detected</span>
          </div>
          <div class="li-row">
            <span class="li-name">SDI</span>
            <span class="li-fmt li-fmt--none">No signal</span>
            <span class="pill pill--idle"><span class="pill__dot"></span>Idle</span>
          </div>
          <div class="li-row">
            <span class="li-name">USB</span>
            <span class="li-fmt">1280×720p30</span>
            <span class="pill pill--ok"><span class="pill__dot"></span>Signal detected</span>
          </div>
        </div>

        <div class="branch-foot">
          <div class="form-item">
            <div class="form-item__main">
              <label class="form-item__label" for="f1-recv">Target receiver</label>
              <div class="form-item__content">
                <div class="select-wrap">
                  <select class="select" id="f1-recv" aria-label="Target receiver">
                    <option selected>R-Studio-01</option>
                    <option>R-Studio-02</option>
                    <option>R-Truck-02</option>
                  </select>
                  <!-- icon: navigation/arrow-dropdown -->
                  <span class="select-arrow"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M3.05146 6.20128C3.27161 5.95374 3.65086 5.93145 3.89853 6.15148L7.86707 9.67727C7.94284 9.74458 8.05698 9.74458 8.13274 9.67727L12.1013 6.15148C12.349 5.93145 12.7282 5.95374 12.9484 6.20128C13.1685 6.44883 13.1462 6.82788 12.8985 7.04791L8.39841 11.046C8.17112 11.2479 7.8287 11.2479 7.60141 11.046L3.10129 7.04791C2.85362 6.82788 2.83131 6.44883 3.05146 6.20128Z" fill="currentColor"/></svg></span>
                </div>
              </div>
            </div>
          </div>
          <div class="branch-foot__actions">
            <button type="button" class="btn btn--ghost-green">Apply</button>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- ================= FRAME 2 · IP Source ================= -->
  <div class="frame-cap">
    <span class="frame-chip">STATE 2 / 3</span>
    <span class="frame-title">Type of source = IP Source</span>
    <span class="frame-note">既有来源卡片网格逐项保留：预览 · IP · 目标接收端 · Apply（含无信号卡的 disabled 态）</span>
  </div>

  <div class="device">
    <div class="topbar">
      <div class="topbar-brand">
        <!-- icon: brand/logo-tvu -->
        <svg class="topbar-logo" width="28" height="28" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.9933 8.68971V8.6898V8.6899V8.69001C15.9962 8.96317 16 9.31582 16 9.81499V13.9033C16 13.9033 16 16 13.6733 15.9997H7.99586L7.98791 15.9998L7.97996 16H7.97102H7.93922C7.93922 16 7.94419 16 7.9538 15.9997C3.55876 15.9857 0 12.4098 0 8.00017C0 3.5819 3.573 0 7.97996 0C12.1057 0 15.5005 3.13931 15.9165 7.16512L15.9182 7.16545L15.9185 7.18106C15.946 7.45033 15.99 7.97375 15.99 8.25C15.99 8.37606 15.9915 8.51693 15.9933 8.68953L15.9933 8.68971ZM1.19653 7.97028C1.19653 11.7388 4.24392 14.7937 8.00305 14.7937C11.7622 14.7937 14.8096 11.7388 14.8096 7.97028C14.8096 4.20178 11.7622 1.14681 8.00305 1.14681C4.24392 1.14681 1.19653 4.20178 1.19653 7.97028ZM13.4204 15.2121V13.212L15.0122 14.2386L13.4204 15.2121ZM12.8146 8.39867V5.86667H13.669V8.41467C13.669 8.90067 13.6164 9.27267 13.3229 9.53167C13.0294 9.79067 12.5968 9.92 12.0253 9.92C11.4538 9.92 11.022 9.79034 10.7291 9.53167C10.4366 9.273 10.3843 8.90134 10.3843 8.41734V5.86667H11.2394V8.39867C11.2394 8.67167 11.2963 8.875 11.4098 9.00867C11.5233 9.14233 11.7705 9.20934 12.0257 9.20934C12.2772 9.20934 12.524 9.14534 12.6402 9.01667C12.7564 8.888 12.8146 8.682 12.8146 8.39867ZM9.02194 5.86667L8.01441 8.853L7.00721 5.86667H6.03979L7.53984 9.92H8.46061L9.96033 5.86667H9.02194ZM3.48276 6.554H2.2251V5.86667H5.61583V6.554H4.35817V9.92H3.48276V6.554Z" fill="#56AF31"/></svg>
        <span class="topbar-title">Local Settings</span>
      </div>
      <div class="topbar-right">
        <span class="topbar-dev">TVU-ONE-04517</span>
        <span class="pill pill--ok"><span class="pill__dot"></span>Online</span>
      </div>
    </div>

    <div class="tab-list">
      <div class="tab-list__items" role="tablist" aria-label="Device settings sections">
        <div class="tab-item" role="tab" aria-selected="false" tabindex="-1">Status</div>
        <div class="tab-item tab-item--active" role="tab" aria-selected="true" tabindex="0">Video Source</div>
        <div class="tab-item" role="tab" aria-selected="false" tabindex="-1">Network</div>
        <div class="tab-item" role="tab" aria-selected="false" tabindex="-1">Streaming</div>
        <div class="tab-item" role="tab" aria-selected="false" tabindex="-1">System</div>
      </div>
    </div>

    <div class="page">
      <div class="panel">
        <div class="src-row">
          <span class="src-row__label">Type of source:</span>
          <div class="src-choice" role="radiogroup" aria-label="Type of source">
            <span class="radio" role="radio" aria-checked="false" tabindex="-1">
              <span class="radio-circle"><span class="radio-dot"></span></span>HDMI/SDI/USB
            </span>
            <span class="radio" role="radio" aria-checked="true" tabindex="0">
              <span class="radio-circle"><span class="radio-dot"></span></span>IP Source
            </span>
            <span class="radio" role="radio" aria-checked="false" tabindex="-1">
              <span class="radio-circle"><span class="radio-dot"></span></span>NDI
            </span>
          </div>
        </div>

        <hr class="src-divider">

        <div class="branch-head">
          <span class="branch-title">IP sources</span>
          <span class="branch-sp"></span>
          <span class="branch-meta">4 sources · 1 live</span>
        </div>

        <div class="card-grid">
          <!-- card 1 · live -->
          <div class="src-card">
            <div class="preview">
              <span class="pv-tag"><span class="pill pill--live pill--sm"><span class="pill__dot"></span>LIVE</span></span>
              <span class="pv-fmt">1080p59.94</span>
            </div>
            <div class="card-body">
              <span class="card-name">CAM-A · Studio Front</span>
              <span class="card-ip">10.20.34.11 : 5004</span>
              <div class="form-item form-item--two-lines">
                <div class="form-item__main">
                  <label class="form-item__label" for="f2-r1">Target receiver</label>
                  <div class="form-item__content">
                    <div class="select-wrap">
                      <select class="select" id="f2-r1" aria-label="Target receiver">
                        <option selected>R-Studio-01</option>
                        <option>R-Studio-02</option>
                      </select>
                      <!-- icon: navigation/arrow-dropdown -->
                      <span class="select-arrow"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M3.05146 6.20128C3.27161 5.95374 3.65086 5.93145 3.89853 6.15148L7.86707 9.67727C7.94284 9.74458 8.05698 9.74458 8.13274 9.67727L12.1013 6.15148C12.349 5.93145 12.7282 5.95374 12.9484 6.20128C13.1685 6.44883 13.1462 6.82788 12.8985 7.04791L8.39841 11.046C8.17112 11.2479 7.8287 11.2479 7.60141 11.046L3.10129 7.04791C2.85362 6.82788 2.83131 6.44883 3.05146 6.20128Z" fill="currentColor"/></svg></span>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div class="card-foot"><button type="button" class="btn btn--ghost-green">Apply</button></div>
          </div>

          <!-- card 2 · idle -->
          <div class="src-card">
            <div class="preview">
              <span class="pv-tag"><span class="pill pill--idle pill--sm"><span class="pill__dot"></span>Idle</span></span>
              <span class="pv-fmt">1080p29.97</span>
            </div>
            <div class="card-body">
              <span class="card-name">CAM-B · Sideline</span>
              <span class="card-ip">10.20.34.12 : 5004</span>
              <div class="form-item form-item--two-lines">
                <div class="form-item__main">
                  <label class="form-item__label" for="f2-r2">Target receiver</label>
                  <div class="form-item__content">
                    <div class="select-wrap">
                      <select class="select select--placeholder" id="f2-r2" aria-label="Target receiver">
                        <option selected>Select receiver</option>
                        <option>R-Studio-02</option>
                        <option>R-Truck-02</option>
                      </select>
                      <!-- icon: navigation/arrow-dropdown -->
                      <span class="select-arrow"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M3.05146 6.20128C3.27161 5.95374 3.65086 5.93145 3.89853 6.15148L7.86707 9.67727C7.94284 9.74458 8.05698 9.74458 8.13274 9.67727L12.1013 6.15148C12.349 5.93145 12.7282 5.95374 12.9484 6.20128C13.1685 6.44883 13.1462 6.82788 12.8985 7.04791L8.39841 11.046C8.17112 11.2479 7.8287 11.2479 7.60141 11.046L3.10129 7.04791C2.85362 6.82788 2.83131 6.44883 3.05146 6.20128Z" fill="currentColor"/></svg></span>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div class="card-foot"><button type="button" class="btn btn--ghost-green">Apply</button></div>
          </div>

          <!-- card 3 · idle -->
          <div class="src-card">
            <div class="preview">
              <span class="pv-tag"><span class="pill pill--idle pill--sm"><span class="pill__dot"></span>Idle</span></span>
              <span class="pv-fmt">720p59.94</span>
            </div>
            <div class="card-body">
              <span class="card-name">ENC-Truck-2</span>
              <span class="card-ip">10.20.34.31 : 5004</span>
              <div class="form-item form-item--two-lines">
                <div class="form-item__main">
                  <label class="form-item__label" for="f2-r3">Target receiver</label>
                  <div class="form-item__content">
                    <div class="select-wrap">
                      <select class="select" id="f2-r3" aria-label="Target receiver">
                        <option selected>R-Truck-02</option>
                        <option>R-Studio-01</option>
                      </select>
                      <!-- icon: navigation/arrow-dropdown -->
                      <span class="select-arrow"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M3.05146 6.20128C3.27161 5.95374 3.65086 5.93145 3.89853 6.15148L7.86707 9.67727C7.94284 9.74458 8.05698 9.74458 8.13274 9.67727L12.1013 6.15148C12.349 5.93145 12.7282 5.95374 12.9484 6.20128C13.1685 6.44883 13.1462 6.82788 12.8985 7.04791L8.39841 11.046C8.17112 11.2479 7.8287 11.2479 7.60141 11.046L3.10129 7.04791C2.85362 6.82788 2.83131 6.44883 3.05146 6.20128Z" fill="currentColor"/></svg></span>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div class="card-foot"><button type="button" class="btn btn--ghost-green">Apply</button></div>
          </div>

          <!-- card 4 · no signal（disabled 态） -->
          <div class="src-card">
            <div class="preview">
              <span class="pv-empty">
                <!-- icon: media/source-unavailable (figmaNodeId 1352:26898) -->
                <svg width="24" height="24" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M1 2.2C1 1.53726 1.53726 1 2.2 1H13.8C14.4627 1 15 1.53726 15 2.2V13.8C15 14.4627 14.4627 15 13.8 15H2.2C1.53726 15 1 14.4627 1 13.8V2.2ZM2.20001 2.39922V3.9C2.20001 3.95523 2.24478 4 2.30001 4H4.25819C4.33806 4 4.3857 3.91099 4.3414 3.84453L3.27421 2.24375C3.25566 2.21593 3.22444 2.19922 3.19101 2.19922H2.40001C2.28956 2.19922 2.20001 2.28876 2.20001 2.39922ZM5.94078 4H7.75819C7.83806 4 7.8857 3.91099 7.8414 3.84453L6.77421 2.24375C6.75566 2.21593 6.72444 2.19922 6.69101 2.19922H4.8736C4.79373 2.19922 4.74609 2.28823 4.79039 2.35469L5.85758 3.95547C5.87613 3.98329 5.90735 4 5.94078 4ZM9.44078 4H11.2583C11.3381 4 11.3858 3.91098 11.3415 3.84453L10.2742 2.24375C10.2557 2.21593 10.2245 2.19922 10.191 2.19922H8.3736C8.29373 2.19922 8.24609 2.28823 8.29039 2.35469L9.35758 3.95547C9.37613 3.98329 9.40735 4 9.44078 4ZM12.9409 4H13.7C13.7552 4 13.8 3.95523 13.8 3.9V2.39922C13.8 2.28876 13.7105 2.19922 13.6 2.19922H11.8736C11.7938 2.19922 11.7461 2.28824 11.7904 2.35469L12.8577 3.95547C12.8762 3.98329 12.9075 4 12.9409 4ZM2.30001 5.2C2.24478 5.2 2.20001 5.24477 2.20001 5.3V13.5992C2.20001 13.7097 2.28956 13.7992 2.40001 13.7992H13.6C13.7105 13.7992 13.8 13.7097 13.8 13.5992V5.3C13.8 5.24477 13.7552 5.2 13.7 5.2H2.30001ZM9.26989 11.5179C9.5042 11.7522 9.8841 11.7522 10.1184 11.5179C10.3527 11.2836 10.3527 10.9037 10.1184 10.6694L8.91678 9.46776C8.87773 9.42871 8.87773 9.36539 8.91678 9.32634L10.1184 8.12468C10.3528 7.89037 10.3528 7.51047 10.1184 7.27615C9.88413 7.04184 9.50423 7.04184 9.26991 7.27615L8.06826 8.47781C8.0292 8.51687 7.96589 8.51687 7.92683 8.47781L6.7243 7.27528C6.48999 7.04097 6.11009 7.04097 5.87578 7.27528C5.64146 7.5096 5.64146 7.8895 5.87578 8.12381L7.07831 9.32634C7.11736 9.36539 7.11736 9.42871 7.07831 9.46776L5.8758 10.6703C5.64149 10.9046 5.64149 11.2845 5.8758 11.5188C6.11012 11.7531 6.49002 11.7531 6.72433 11.5188L7.92683 10.3163C7.96589 10.2772 8.0292 10.2772 8.06826 10.3163L9.26989 11.5179Z" fill="currentColor"/></svg>
                No signal
              </span>
            </div>
            <div class="card-body">
              <span class="card-name">ENC-Roof-1</span>
              <span class="card-ip">10.20.34.44 : 5004</span>
              <div class="form-item form-item--two-lines">
                <div class="form-item__main">
                  <label class="form-item__label" for="f2-r4">Target receiver</label>
                  <div class="form-item__content">
                    <div class="select-wrap">
                      <select class="select" id="f2-r4" aria-label="Target receiver" disabled>
                        <option selected>Select receiver</option>
                      </select>
                      <!-- icon: navigation/arrow-dropdown -->
                      <span class="select-arrow"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M3.05146 6.20128C3.27161 5.95374 3.65086 5.93145 3.89853 6.15148L7.86707 9.67727C7.94284 9.74458 8.05698 9.74458 8.13274 9.67727L12.1013 6.15148C12.349 5.93145 12.7282 5.95374 12.9484 6.20128C13.1685 6.44883 13.1462 6.82788 12.8985 7.04791L8.39841 11.046C8.17112 11.2479 7.8287 11.2479 7.60141 11.046L3.10129 7.04791C2.85362 6.82788 2.83131 6.44883 3.05146 6.20128Z" fill="currentColor"/></svg></span>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div class="card-foot"><button type="button" class="btn btn--ghost-green" disabled>Apply</button></div>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- ================= FRAME 3 · NDI（新增） ================= -->
  <div class="frame-cap">
    <span class="frame-chip">STATE 3 / 3 · NEW</span>
    <span class="frame-title">Type of source = NDI</span>
    <span class="frame-note">内容区切换为 NDI 专属表单；右侧沿用页面既有的「预览 + 元数据」信息架构</span>
  </div>

  <div class="device">
    <div class="topbar">
      <div class="topbar-brand">
        <!-- icon: brand/logo-tvu -->
        <svg class="topbar-logo" width="28" height="28" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.9933 8.68971V8.6898V8.6899V8.69001C15.9962 8.96317 16 9.31582 16 9.81499V13.9033C16 13.9033 16 16 13.6733 15.9997H7.99586L7.98791 15.9998L7.97996 16H7.97102H7.93922C7.93922 16 7.94419 16 7.9538 15.9997C3.55876 15.9857 0 12.4098 0 8.00017C0 3.5819 3.573 0 7.97996 0C12.1057 0 15.5005 3.13931 15.9165 7.16512L15.9182 7.16545L15.9185 7.18106C15.946 7.45033 15.99 7.97375 15.99 8.25C15.99 8.37606 15.9915 8.51693 15.9933 8.68953L15.9933 8.68971ZM1.19653 7.97028C1.19653 11.7388 4.24392 14.7937 8.00305 14.7937C11.7622 14.7937 14.8096 11.7388 14.8096 7.97028C14.8096 4.20178 11.7622 1.14681 8.00305 1.14681C4.24392 1.14681 1.19653 4.20178 1.19653 7.97028ZM13.4204 15.2121V13.212L15.0122 14.2386L13.4204 15.2121ZM12.8146 8.39867V5.86667H13.669V8.41467C13.669 8.90067 13.6164 9.27267 13.3229 9.53167C13.0294 9.79067 12.5968 9.92 12.0253 9.92C11.4538 9.92 11.022 9.79034 10.7291 9.53167C10.4366 9.273 10.3843 8.90134 10.3843 8.41734V5.86667H11.2394V8.39867C11.2394 8.67167 11.2963 8.875 11.4098 9.00867C11.5233 9.14233 11.7705 9.20934 12.0257 9.20934C12.2772 9.20934 12.524 9.14534 12.6402 9.01667C12.7564 8.888 12.8146 8.682 12.8146 8.39867ZM9.02194 5.86667L8.01441 8.853L7.00721 5.86667H6.03979L7.53984 9.92H8.46061L9.96033 5.86667H9.02194ZM3.48276 6.554H2.2251V5.86667H5.61583V6.554H4.35817V9.92H3.48276V6.554Z" fill="#56AF31"/></svg>
        <span class="topbar-title">Local Settings</span>
      </div>
      <div class="topbar-right">
        <span class="topbar-dev">TVU-ONE-04517</span>
        <span class="pill pill--ok"><span class="pill__dot"></span>Online</span>
      </div>
    </div>

    <div class="tab-list">
      <div class="tab-list__items" role="tablist" aria-label="Device settings sections">
        <div class="tab-item" role="tab" aria-selected="false" tabindex="-1">Status</div>
        <div class="tab-item tab-item--active" role="tab" aria-selected="true" tabindex="0">Video Source</div>
        <div class="tab-item" role="tab" aria-selected="false" tabindex="-1">Network</div>
        <div class="tab-item" role="tab" aria-selected="false" tabindex="-1">Streaming</div>
        <div class="tab-item" role="tab" aria-selected="false" tabindex="-1">System</div>
      </div>
    </div>

    <div class="page">
      <div class="panel">
        <div class="src-row">
          <span class="src-row__label">Type of source:</span>
          <div class="src-choice" role="radiogroup" aria-label="Type of source">
            <span class="radio" role="radio" aria-checked="false" tabindex="-1">
              <span class="radio-circle"><span class="radio-dot"></span></span>HDMI/SDI/USB
            </span>
            <span class="radio" role="radio" aria-checked="false" tabindex="-1">
              <span class="radio-circle"><span class="radio-dot"></span></span>IP Source
            </span>
            <span class="radio" role="radio" aria-checked="true" tabindex="0">
              <span class="radio-circle"><span class="radio-dot"></span></span>NDI
            </span>
          </div>
        </div>

        <hr class="src-divider">

        <div class="branch-head">
          <span class="branch-title">NDI source</span>
          <span class="branch-sp"></span>
          <span class="branch-meta">6 sources found · last scan 12:04:31</span>
        </div>

        <div class="ndi-grid">
          <div class="ndi-form">
            <div class="form-item">
              <div class="form-item__main">
                <label class="form-item__label" for="f3-src">NDI source</label>
                <div class="form-item__content">
                  <div class="ndi-inline">
                    <div class="select-wrap">
                      <select class="select" id="f3-src" aria-label="NDI source">
                        <option selected>TVU-STUDIO-A (Camera 1)</option>
                        <option>TVU-STUDIO-A (Camera 2)</option>
                        <option>OB-TRUCK-02 (Program)</option>
                        <option>GFX-01 (Fill)</option>
                      </select>
                      <!-- icon: navigation/arrow-dropdown -->
                      <span class="select-arrow"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M3.05146 6.20128C3.27161 5.95374 3.65086 5.93145 3.89853 6.15148L7.86707 9.67727C7.94284 9.74458 8.05698 9.74458 8.13274 9.67727L12.1013 6.15148C12.349 5.93145 12.7282 5.95374 12.9484 6.20128C13.1685 6.44883 13.1462 6.82788 12.8985 7.04791L8.39841 11.046C8.17112 11.2479 7.8287 11.2479 7.60141 11.046L3.10129 7.04791C2.85362 6.82788 2.83131 6.44883 3.05146 6.20128Z" fill="currentColor"/></svg></span>
                    </div>
                    <button type="button" class="btn btn--ghost-gray btn--icon-left">
                      <!-- icon: action/refresh (figmaNodeId 1202:4182) -->
                      <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M10.8367 1.60055C9.46757 0.993637 7.93986 0.84184 6.47805 1.16746C5.01623 1.49308 3.69739 2.27896 2.71528 3.40962C1.73317 4.54028 1.13958 5.95612 1.02172 7.44912C0.903855 8.94211 1.26794 10.4336 2.06047 11.7043C2.853 12.9751 4.0322 13.9581 5.42481 14.5091C6.81743 15.0601 8.35004 15.1499 9.79746 14.7653C11.2449 14.3807 12.5308 13.5421 13.4663 12.3726C13.6733 12.1138 13.6313 11.7362 13.3726 11.5292C13.1138 11.3222 12.7362 11.3642 12.5292 11.623C11.7541 12.592 10.6886 13.2869 9.48933 13.6055C8.29003 13.9242 7.02016 13.8498 5.86628 13.3933C4.71239 12.9367 3.73534 12.1222 3.07867 11.0693C2.422 10.0164 2.12034 8.78061 2.21799 7.54355C2.31565 6.3065 2.80748 5.13338 3.62123 4.19654C4.43498 3.25971 5.52773 2.60856 6.73895 2.33876C7.95017 2.06895 9.21599 2.19473 10.3504 2.6976C11.3659 3.14773 12.2282 3.87877 12.8379 4.80078H11.6C11.2686 4.80078 11 5.06941 11 5.40078C11 5.73215 11.2686 6.00078 11.6 6.00078H14.4C14.7314 6.00078 15 5.73215 15 5.40078L15 5.39692V2.6C15 2.26863 14.7314 2 14.4 2C14.0686 2 13.8 2.26863 13.8 2.6V4.08078C13.0666 2.99539 12.0409 2.13433 10.8367 1.60055Z" fill="currentColor"/></svg>
                      Rescan
                    </button>
                  </div>
                  <span class="form-item__message">Sources on this subnet, discovered automatically.</span>
                </div>
              </div>
            </div>

            <div class="form-item">
              <div class="form-item__main">
                <label class="form-item__label" for="f3-disc">Discovery</label>
                <div class="form-item__content">
                  <div class="select-wrap">
                    <select class="select" id="f3-disc" aria-label="Discovery">
                      <option selected>Auto (mDNS)</option>
                      <option>Discovery server</option>
                    </select>
                    <!-- icon: navigation/arrow-dropdown -->
                    <span class="select-arrow"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M3.05146 6.20128C3.27161 5.95374 3.65086 5.93145 3.89853 6.15148L7.86707 9.67727C7.94284 9.74458 8.05698 9.74458 8.13274 9.67727L12.1013 6.15148C12.349 5.93145 12.7282 5.95374 12.9484 6.20128C13.1685 6.44883 13.1462 6.82788 12.8985 7.04791L8.39841 11.046C8.17112 11.2479 7.8287 11.2479 7.60141 11.046L3.10129 7.04791C2.85362 6.82788 2.83131 6.44883 3.05146 6.20128Z" fill="currentColor"/></svg></span>
                  </div>
                </div>
              </div>
            </div>

            <div class="form-item">
              <div class="form-item__main">
                <label class="form-item__label" for="f3-group">Group</label>
                <div class="form-item__content">
                  <input class="tvu-input" id="f3-group" type="text" value="public" aria-label="Group">
                  <span class="form-item__message">Comma-separated. Leave as “public” unless the sender uses groups.</span>
                </div>
              </div>
            </div>

            <div class="form-item">
              <div class="form-item__main">
                <label class="form-item__label" for="f3-bw">Bandwidth</label>
                <div class="form-item__content">
                  <div class="select-wrap">
                    <select class="select" id="f3-bw" aria-label="Bandwidth">
                      <option selected>Full — highest quality</option>
                      <option>Proxy — low bandwidth</option>
                    </select>
                    <!-- icon: navigation/arrow-dropdown -->
                    <span class="select-arrow"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M3.05146 6.20128C3.27161 5.95374 3.65086 5.93145 3.89853 6.15148L7.86707 9.67727C7.94284 9.74458 8.05698 9.74458 8.13274 9.67727L12.1013 6.15148C12.349 5.93145 12.7282 5.95374 12.9484 6.20128C13.1685 6.44883 13.1462 6.82788 12.8985 7.04791L8.39841 11.046C8.17112 11.2479 7.8287 11.2479 7.60141 11.046L3.10129 7.04791C2.85362 6.82788 2.83131 6.44883 3.05146 6.20128Z" fill="currentColor"/></svg></span>
                  </div>
                </div>
              </div>
            </div>

            <div class="form-item">
              <div class="form-item__main">
                <span class="form-item__label" id="f3-audio-lbl">Include audio</span>
                <div class="form-item__content">
                  <button type="button" class="switch switch--on" role="switch" aria-checked="true" aria-labelledby="f3-audio-lbl">
                    <span class="switch-thumb"></span>
                  </button>
                </div>
              </div>
            </div>

            <div class="form-item">
              <div class="form-item__main">
                <label class="form-item__label" for="f3-recv">Target receiver</label>
                <div class="form-item__content">
                  <div class="select-wrap">
                    <select class="select" id="f3-recv" aria-label="Target receiver">
                      <option selected>R-Studio-01</option>
                      <option>R-Studio-02</option>
                      <option>R-Truck-02</option>
                    </select>
                    <!-- icon: navigation/arrow-dropdown -->
                    <span class="select-arrow"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M3.05146 6.20128C3.27161 5.95374 3.65086 5.93145 3.89853 6.15148L7.86707 9.67727C7.94284 9.74458 8.05698 9.74458 8.13274 9.67727L12.1013 6.15148C12.349 5.93145 12.7282 5.95374 12.9484 6.20128C13.1685 6.44883 13.1462 6.82788 12.8985 7.04791L8.39841 11.046C8.17112 11.2479 7.8287 11.2479 7.60141 11.046L3.10129 7.04791C2.85362 6.82788 2.83131 6.44883 3.05146 6.20128Z" fill="currentColor"/></svg></span>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <div class="ndi-side">
            <div class="preview">
              <span class="pv-tag"><span class="pill pill--ok pill--sm"><span class="pill__dot"></span>Ready</span></span>
              <span class="pv-fmt">1080p59.94</span>
            </div>
            <div>
              <div class="kv"><span class="kv__k">Source</span><span class="kv__v">TVU-STUDIO-A (Camera 1)</span></div>
              <div class="kv"><span class="kv__k">Sender IP</span><span class="kv__v">10.20.34.58</span></div>
              <div class="kv"><span class="kv__k">Video</span><span class="kv__v">1920×1080p59.94</span></div>
              <div class="kv"><span class="kv__k">Audio</span><span class="kv__v">2 ch · 48 kHz</span></div>
              <div class="kv"><span class="kv__k">Bitrate</span><span class="kv__v">128 Mbps</span></div>
            </div>
          </div>
        </div>

        <div class="ndi-foot">
          <button type="button" class="btn btn--ghost-gray">Cancel</button>
          <button type="button" class="btn btn--fill-green">Apply</button>
        </div>
      </div>
    </div>
  </div>

  <!-- ================= FRAME 3-b · NDI 空态 + Discovery server 分支 ================= -->
  <div class="frame-cap">
    <span class="frame-chip">STATE 3-b · NEW</span>
    <span class="frame-title">NDI · no sources found + Discovery server</span>
    <span class="frame-note">
      网络侧异步事件不做静默 no-op（domain-tvu §M12：检测 → 告知 → 前进路径）；同时展示条件字段 Server address 与 disabled 态
    </span>
  </div>

  <div class="device">
    <div class="topbar">
      <div class="topbar-brand">
        <!-- icon: brand/logo-tvu -->
        <svg class="topbar-logo" width="28" height="28" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.9933 8.68971V8.6898V8.6899V8.69001C15.9962 8.96317 16 9.31582 16 9.81499V13.9033C16 13.9033 16 16 13.6733 15.9997H7.99586L7.98791 15.9998L7.97996 16H7.97102H7.93922C7.93922 16 7.94419 16 7.9538 15.9997C3.55876 15.9857 0 12.4098 0 8.00017C0 3.5819 3.573 0 7.97996 0C12.1057 0 15.5005 3.13931 15.9165 7.16512L15.9182 7.16545L15.9185 7.18106C15.946 7.45033 15.99 7.97375 15.99 8.25C15.99 8.37606 15.9915 8.51693 15.9933 8.68953L15.9933 8.68971ZM1.19653 7.97028C1.19653 11.7388 4.24392 14.7937 8.00305 14.7937C11.7622 14.7937 14.8096 11.7388 14.8096 7.97028C14.8096 4.20178 11.7622 1.14681 8.00305 1.14681C4.24392 1.14681 1.19653 4.20178 1.19653 7.97028ZM13.4204 15.2121V13.212L15.0122 14.2386L13.4204 15.2121ZM12.8146 8.39867V5.86667H13.669V8.41467C13.669 8.90067 13.6164 9.27267 13.3229 9.53167C13.0294 9.79067 12.5968 9.92 12.0253 9.92C11.4538 9.92 11.022 9.79034 10.7291 9.53167C10.4366 9.273 10.3843 8.90134 10.3843 8.41734V5.86667H11.2394V8.39867C11.2394 8.67167 11.2963 8.875 11.4098 9.00867C11.5233 9.14233 11.7705 9.20934 12.0257 9.20934C12.2772 9.20934 12.524 9.14534 12.6402 9.01667C12.7564 8.888 12.8146 8.682 12.8146 8.39867ZM9.02194 5.86667L8.01441 8.853L7.00721 5.86667H6.03979L7.53984 9.92H8.46061L9.96033 5.86667H9.02194ZM3.48276 6.554H2.2251V5.86667H5.61583V6.554H4.35817V9.92H3.48276V6.554Z" fill="#56AF31"/></svg>
        <span class="topbar-title">Local Settings</span>
      </div>
      <div class="topbar-right">
        <span class="topbar-dev">TVU-ONE-04517</span>
        <span class="pill pill--ok"><span class="pill__dot"></span>Online</span>
      </div>
    </div>

    <div class="tab-list">
      <div class="tab-list__items" role="tablist" aria-label="Device settings sections">
        <div class="tab-item" role="tab" aria-selected="false" tabindex="-1">Status</div>
        <div class="tab-item tab-item--active" role="tab" aria-selected="true" tabindex="0">Video Source</div>
        <div class="tab-item" role="tab" aria-selected="false" tabindex="-1">Network</div>
        <div class="tab-item" role="tab" aria-selected="false" tabindex="-1">Streaming</div>
        <div class="tab-item" role="tab" aria-selected="false" tabindex="-1">System</div>
      </div>
    </div>

    <div class="page">
      <div class="panel">
        <div class="src-row">
          <span class="src-row__label">Type of source:</span>
          <div class="src-choice" role="radiogroup" aria-label="Type of source">
            <span class="radio" role="radio" aria-checked="false" tabindex="-1">
              <span class="radio-circle"><span class="radio-dot"></span></span>HDMI/SDI/USB
            </span>
            <span class="radio" role="radio" aria-checked="false" tabindex="-1">
              <span class="radio-circle"><span class="radio-dot"></span></span>IP Source
            </span>
            <span class="radio" role="radio" aria-checked="true" tabindex="0">
              <span class="radio-circle"><span class="radio-dot"></span></span>NDI
            </span>
          </div>
        </div>

        <hr class="src-divider">

        <div class="branch-head">
          <span class="branch-title">NDI source</span>
          <span class="branch-sp"></span>
          <span class="branch-meta">0 sources found · last scan 12:07:02</span>
        </div>

        <div class="ndi-grid">
          <div class="ndi-form">
            <div class="notice">
              <!-- icon: status/info-outline -->
              <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M15 8C15 11.866 11.866 15 8 15C4.13401 15 1 11.866 1 8C1 4.13401 4.13401 1 8 1C11.866 1 15 4.13401 15 8ZM13.8 7.99922C13.8 4.79597 11.2033 2.19922 8.00001 2.19922C4.79676 2.19922 2.20001 4.79597 2.20001 7.99922C2.20001 11.2025 4.79676 13.7992 8.00001 13.7992C11.2033 13.7992 13.8 11.2025 13.8 7.99922ZM8.60002 4.6C8.60002 4.93137 8.3314 5.2 8.00002 5.2C7.66865 5.2 7.40002 4.93137 7.40002 4.6C7.40002 4.26863 7.66865 4 8.00002 4C8.3314 4 8.60002 4.26863 8.60002 4.6ZM7.40002 7C7.40002 6.66863 7.66865 6.4 8.00002 6.4C8.3314 6.4 8.60002 6.66863 8.60002 7V11.4C8.60002 11.7314 8.3314 12 8.00002 12C7.66865 12 7.40002 11.7314 7.40002 11.4V7Z" fill="currentColor"/></svg>
              <span><b>No NDI sources on this network.</b> Auto discovery (mDNS) does not cross subnets — rescan, or point the device at a Discovery server.</span>
            </div>

            <div class="form-item">
              <div class="form-item__main">
                <label class="form-item__label" for="f4-src">NDI source</label>
                <div class="form-item__content">
                  <div class="ndi-inline">
                    <div class="select-wrap">
                      <select class="select" id="f4-src" aria-label="NDI source" disabled>
                        <option selected>No sources found</option>
                      </select>
                      <!-- icon: navigation/arrow-dropdown -->
                      <span class="select-arrow"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M3.05146 6.20128C3.27161 5.95374 3.65086 5.93145 3.89853 6.15148L7.86707 9.67727C7.94284 9.74458 8.05698 9.74458 8.13274 9.67727L12.1013 6.15148C12.349 5.93145 12.7282 5.95374 12.9484 6.20128C13.1685 6.44883 13.1462 6.82788 12.8985 7.04791L8.39841 11.046C8.17112 11.2479 7.8287 11.2479 7.60141 11.046L3.10129 7.04791C2.85362 6.82788 2.83131 6.44883 3.05146 6.20128Z" fill="currentColor"/></svg></span>
                    </div>
                    <button type="button" class="btn btn--ghost-green btn--icon-left">
                      <!-- icon: action/refresh -->
                      <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M10.8367 1.60055C9.46757 0.993637 7.93986 0.84184 6.47805 1.16746C5.01623 1.49308 3.69739 2.27896 2.71528 3.40962C1.73317 4.54028 1.13958 5.95612 1.02172 7.44912C0.903855 8.94211 1.26794 10.4336 2.06047 11.7043C2.853 12.9751 4.0322 13.9581 5.42481 14.5091C6.81743 15.0601 8.35004 15.1499 9.79746 14.7653C11.2449 14.3807 12.5308 13.5421 13.4663 12.3726C13.6733 12.1138 13.6313 11.7362 13.3726 11.5292C13.1138 11.3222 12.7362 11.3642 12.5292 11.623C11.7541 12.592 10.6886 13.2869 9.48933 13.6055C8.29003 13.9242 7.02016 13.8498 5.86628 13.3933C4.71239 12.9367 3.73534 12.1222 3.07867 11.0693C2.422 10.0164 2.12034 8.78061 2.21799 7.54355C2.31565 6.3065 2.80748 5.13338 3.62123 4.19654C4.43498 3.25971 5.52773 2.60856 6.73895 2.33876C7.95017 2.06895 9.21599 2.19473 10.3504 2.6976C11.3659 3.14773 12.2282 3.87877 12.8379 4.80078H11.6C11.2686 4.80078 11 5.06941 11 5.40078C11 5.73215 11.2686 6.00078 11.6 6.00078H14.4C14.7314 6.00078 15 5.73215 15 5.40078L15 5.39692V2.6C15 2.26863 14.7314 2 14.4 2C14.0686 2 13.8 2.26863 13.8 2.6V4.08078C13.0666 2.99539 12.0409 2.13433 10.8367 1.60055Z" fill="currentColor"/></svg>
                      Rescan
                    </button>
                  </div>
                </div>
              </div>
            </div>

            <div class="form-item">
              <div class="form-item__main">
                <label class="form-item__label" for="f4-disc">Discovery</label>
                <div class="form-item__content">
                  <div class="select-wrap">
                    <select class="select" id="f4-disc" aria-label="Discovery">
                      <option>Auto (mDNS)</option>
                      <option selected>Discovery server</option>
                    </select>
                    <!-- icon: navigation/arrow-dropdown -->
                    <span class="select-arrow"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M3.05146 6.20128C3.27161 5.95374 3.65086 5.93145 3.89853 6.15148L7.86707 9.67727C7.94284 9.74458 8.05698 9.74458 8.13274 9.67727L12.1013 6.15148C12.349 5.93145 12.7282 5.95374 12.9484 6.20128C13.1685 6.44883 13.1462 6.82788 12.8985 7.04791L8.39841 11.046C8.17112 11.2479 7.8287 11.2479 7.60141 11.046L3.10129 7.04791C2.85362 6.82788 2.83131 6.44883 3.05146 6.20128Z" fill="currentColor"/></svg></span>
                  </div>
                </div>
              </div>
            </div>

            <!-- 条件字段：仅在 Discovery = Discovery server 时渲染（R14：条件渲染，不留隐藏尸 DOM） -->
            <div class="form-item">
              <div class="form-item__main">
                <label class="form-item__label" for="f4-server">Server address</label>
                <div class="form-item__content">
                  <input class="tvu-input" id="f4-server" type="text" value="10.20.30.5:5959" aria-label="Server address">
                  <span class="form-item__message">Shown only when Discovery is set to “Discovery server”.</span>
                </div>
              </div>
            </div>

            <div class="form-item">
              <div class="form-item__main">
                <label class="form-item__label" for="f4-group">Group</label>
                <div class="form-item__content">
                  <input class="tvu-input" id="f4-group" type="text" value="public" aria-label="Group" disabled>
                </div>
              </div>
            </div>

            <div class="form-item">
              <div class="form-item__main">
                <label class="form-item__label" for="f4-recv">Target receiver</label>
                <div class="form-item__content">
                  <div class="select-wrap">
                    <select class="select" id="f4-recv" aria-label="Target receiver" disabled>
                      <option selected>Select receiver</option>
                    </select>
                    <!-- icon: navigation/arrow-dropdown -->
                    <span class="select-arrow"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M3.05146 6.20128C3.27161 5.95374 3.65086 5.93145 3.89853 6.15148L7.86707 9.67727C7.94284 9.74458 8.05698 9.74458 8.13274 9.67727L12.1013 6.15148C12.349 5.93145 12.7282 5.95374 12.9484 6.20128C13.1685 6.44883 13.1462 6.82788 12.8985 7.04791L8.39841 11.046C8.17112 11.2479 7.8287 11.2479 7.60141 11.046L3.10129 7.04791C2.85362 6.82788 2.83131 6.44883 3.05146 6.20128Z" fill="currentColor"/></svg></span>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <div class="ndi-side">
            <div class="preview">
              <span class="pv-empty">
                <!-- icon: media/source-unavailable -->
                <svg width="24" height="24" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M1 2.2C1 1.53726 1.53726 1 2.2 1H13.8C14.4627 1 15 1.53726 15 2.2V13.8C15 14.4627 14.4627 15 13.8 15H2.2C1.53726 15 1 14.4627 1 13.8V2.2ZM2.20001 2.39922V3.9C2.20001 3.95523 2.24478 4 2.30001 4H4.25819C4.33806 4 4.3857 3.91099 4.3414 3.84453L3.27421 2.24375C3.25566 2.21593 3.22444 2.19922 3.19101 2.19922H2.40001C2.28956 2.19922 2.20001 2.28876 2.20001 2.39922ZM5.94078 4H7.75819C7.83806 4 7.8857 3.91099 7.8414 3.84453L6.77421 2.24375C6.75566 2.21593 6.72444 2.19922 6.69101 2.19922H4.8736C4.79373 2.19922 4.74609 2.28823 4.79039 2.35469L5.85758 3.95547C5.87613 3.98329 5.90735 4 5.94078 4ZM9.44078 4H11.2583C11.3381 4 11.3858 3.91098 11.3415 3.84453L10.2742 2.24375C10.2557 2.21593 10.2245 2.19922 10.191 2.19922H8.3736C8.29373 2.19922 8.24609 2.28823 8.29039 2.35469L9.35758 3.95547C9.37613 3.98329 9.40735 4 9.44078 4ZM12.9409 4H13.7C13.7552 4 13.8 3.95523 13.8 3.9V2.39922C13.8 2.28876 13.7105 2.19922 13.6 2.19922H11.8736C11.7938 2.19922 11.7461 2.28824 11.7904 2.35469L12.8577 3.95547C12.8762 3.98329 12.9075 4 12.9409 4ZM2.30001 5.2C2.24478 5.2 2.20001 5.24477 2.20001 5.3V13.5992C2.20001 13.7097 2.28956 13.7992 2.40001 13.7992H13.6C13.7105 13.7992 13.8 13.7097 13.8 13.5992V5.3C13.8 5.24477 13.7552 5.2 13.7 5.2H2.30001ZM9.26989 11.5179C9.5042 11.7522 9.8841 11.7522 10.1184 11.5179C10.3527 11.2836 10.3527 10.9037 10.1184 10.6694L8.91678 9.46776C8.87773 9.42871 8.87773 9.36539 8.91678 9.32634L10.1184 8.12468C10.3528 7.89037 10.3528 7.51047 10.1184 7.27615C9.88413 7.04184 9.50423 7.04184 9.26991 7.27615L8.06826 8.47781C8.0292 8.51687 7.96589 8.51687 7.92683 8.47781L6.7243 7.27528C6.48999 7.04097 6.11009 7.04097 5.87578 7.27528C5.64146 7.5096 5.64146 7.8895 5.87578 8.12381L7.07831 9.32634C7.11736 9.36539 7.11736 9.42871 7.07831 9.46776L5.8758 10.6703C5.64149 10.9046 5.64149 11.2845 5.8758 11.5188C6.11012 11.7531 6.49002 11.7531 6.72433 11.5188L7.92683 10.3163C7.96589 10.2772 8.0292 10.2772 8.06826 10.3163L9.26989 11.5179Z" fill="currentColor"/></svg>
                No source selected
              </span>
            </div>
            <div>
              <div class="kv"><span class="kv__k">Source</span><span class="kv__v kv__v--none">—</span></div>
              <div class="kv"><span class="kv__k">Sender IP</span><span class="kv__v kv__v--none">—</span></div>
              <div class="kv"><span class="kv__k">Video</span><span class="kv__v kv__v--none">—</span></div>
              <div class="kv"><span class="kv__k">Audio</span><span class="kv__v kv__v--none">—</span></div>
            </div>
          </div>
        </div>

        <div class="ndi-foot">
          <button type="button" class="btn btn--ghost-gray">Cancel</button>
          <button type="button" class="btn btn--fill-green" disabled>Apply</button>
        </div>
      </div>
    </div>
  </div>

  <!-- ============ 说明层：组件映射 + 交付边界 ============ -->
  <div class="doc-foot">
    <div class="frame-cap">
      <span class="frame-chip">HANDOFF</span>
      <span class="frame-title">组件映射 · UI primitives used</span>
      <span class="frame-note">Radio · TopBar · TabList/TabItem · SelectBoxFilled · InputBoxFilled · Button(M) · PillStatus · FormItem · Switch</span>
    </div>
    <table>
      <thead>
        <tr><th>页面元素</th><th>Figma component_set（library key）</th><th>Code 真源</th><th>本轮</th></tr>
      </thead>
      <tbody>
        <tr><td>Type of source 三选一</td><td>radio · 9f07746f19d962fe8b0ac31e6697a5b8f242d8b0</td><td>src/canonical/Radio.vue → src/components/Radio/Radio.vue</td><td>扩为 3 项</td></tr>
        <tr><td>顶部 bar</td><td>Top bar · 918b928e4541f1573de5c98c32b408af663d7f2f</td><td>src/components/TopBar/TopBar.vue</td><td>未动</td></tr>
        <tr><td>页签导航</td><td>Tab List · 47efe04ff35b46602f0827f24c87af9dca3bae4b · Tab/Item · 2267405386cb3186ba920b0d0b790d54e65a1529</td><td>src/components/Tab/TabList.vue · TabItem.vue</td><td>未动（零新增页签）</td></tr>
        <tr><td>下拉（receiver / discovery / bandwidth）</td><td>select box/filled · ca2ff89d2fc24bad4cb29c8512d8102c04a2c352（展开面板另用 Drop down List/Select · 12602e73b9682f9a9c45ec1e9373e8ac80bb489a）</td><td>src/components/Select/Select.vue</td><td>NDI 分支新增</td></tr>
        <tr><td>文本框（group / server address）</td><td>input box/filled</td><td>src/components/Input/Input.vue</td><td>NDI 分支新增</td></tr>
        <tr><td>Apply / Cancel / Rescan</td><td>Button/dark M · 12b38c8b68cd67dd3978e0d68712bc646f1e97c1</td><td>src/components/Button/Button.vue（PALETTE_SPEC 逐档取色）</td><td>NDI 分支新增</td></tr>
        <tr><td>状态徽标</td><td>Badge · 4db5246d0782fe13bcc01747a7a2578c2da77b2a / Pill Status</td><td>src/components/Pill/Pill.vue</td><td>未动</td></tr>
        <tr><td>表单行</td><td>Form Item</td><td>src/components/FormItem/FormItem.vue（label 120px · row 32px）</td><td>NDI 分支新增</td></tr>
        <tr><td>Include audio 开关</td><td>switch · bf16e8f5ba6b8bd85a0b75961d19589a08a5c3a5</td><td>src/components/Switch/Switch.vue</td><td>NDI 分支新增</td></tr>
        <tr><td>空态提示条</td><td>Message（设备侧谱系；需按钮时升级 Notification）</td><td>本稿以 token 手写，实装换组件</td><td>NDI 分支新增</td></tr>
        <tr><td>图标</td><td>navigation/arrow-dropdown · action/refresh (1202:4182) · media/source-unavailable (1352:26898) · status/info-outline · brand/logo-tvu</td><td>src/icons/raw.ts（逐字复制，零自画）</td><td>—</td></tr>
        <tr><td>颜色 / 间距 / 圆角 / 字阶</td><td>—</td><td>src/tokens/variables.css（本页内联 dark 档，零裸 hex）</td><td>—</td></tr>
      </tbody>
    </table>
    <div class="doc-cols">
      <div class="doc-card">
        <h3>实装时需要补的三件</h3>
        <ul>
          <li><b>宿主页几何核对</b>：本稿几何取 DS canonical，宿主页真值（行高 / 控件宽 / 右缘对齐）需按 §M17 打开该页范式帧实测后覆盖。</li>
          <li><b>Message 组件替换</b>：空态提示条改用设备侧 <span class="mono-ish">Message</span> set（需一键动作时升级到 <span class="mono-ish">Notification</span>）。</li>
          <li><b>交互接线</b>：本稿为静态帧，radio 切换内容区、Rescan 轮询、条件字段显隐由 dev 实装（hover / focus / disabled 三态样式已按 DS 给全）。</li>
        </ul>
      </div>
      <div class="doc-card">
        <h3>刻意没做的</h3>
        <ul>
          <li>没新增顶部导航项 —— NDI 是 source 类型不是导航层级。</li>
          <li>没把三选一改成 Tab / 分段控件 —— 既有控件是互斥表单值，增量任务不换控件平台（§R6 / 场景 2）。</li>
          <li>没顺手修 HDMI/SDI/USB 与 IP 分支的既有实现 —— pre-design-system 合规债不在本次 scope（§R6 澄清条）。</li>
          <li>没出浅色稿 —— 设备操控类界面默认只交 dark（§M4）。</li>
        </ul>
      </div>
    </div>
  </div>

</div></div>
</body>
</html>
```

**Rule checklist**：R7 ✅（场景 2.2 显式声明）· R0 ✅（mapping table 上表）· R6 ✅（增量不换控件平台、不修既有合规债）· R2 ✅（零裸 hex，token 内联真源）· R3/R15 ✅（9 个复合/原子组件全 mirror canonical，零从零自写）· R13/R1 ✅（5 枚图标全库内实证 + 逐字复制）· R14 ✅（全 flex/grid，3 处 `position:absolute` 均是 overlay 且带理由注释）· R16 ✅（产品 UI 单语英文，中文只在说明层）· R19 —（本稿无 selected 列表项 / 卡片选中态，故 3 层信号不适用）· R9 ✅（hover / focus-visible / disabled 三态按 DS 给全）· M3/M7/M9 ✅（红=Live、pill 最安静、action 用正规 32px M 且 label 为动词）· M12 ✅（3-b 帧给检测→告知→前进路径）· 机检五条自查见上。

一个需要你拍的点：**帧内的顶部页签标签、设备名、示例 IP/源名全是占位**。如果你能给我宿主页的 Figma 链接或一张截图，我可以把几何与文案换成真值（这是本稿唯一一处「未取到真源就先按 DS 兜底」的地方）。