# 命名表

> 这个插件里**每个界面元素只有一个名字**。代码、注释、测试、issue、README、
> 更新日志 —— 以及你和 AI 对话时 —— 都用这张表里的词，不再临时另起一个说法。
>
> 上一版的问题就出在没有这张表：同一个输入框被叫过「选择器字段」「规则名」
> 「面板标题框」，一句「那个框改一下」要来回问三轮才知道是哪一个。
>
> 状态一列的含义：**已实现** = 界面里已经有了；**规划中** = 设计已定、尚未写代码。

---

## 0. 一眼看清：这些名字是叠起来的

```
设置行                                    ← A
├── 行头                                  ← A
│   ├── 行标题「自定义 CSS」 / 行说明
│   └── 动作组                             ← A
│       ├── 拾取入口 [拾取元素]
│       ├── 查找入口 [查找]
│       ├── 文件下拉
│       └── 更多操作菜单
├── 文件栏                                 ← A
│   └── 文件身份区 / 大纲 / 状态点 / 启用开关
└── 编辑容器                               ← A
    ├── 编辑表头（文件名 + CSS 徽章 + 启用开关）
    ├── 编辑正文                           ← A
    │   ├── 代码区                        ← B
    │   │   ├── 行号列 / 代码文本框 / 彩色层 / 补全列表
    │   │   └── 查找栏（查找框 / 替换框 / 命中计数 / 大小写钮 / 替换钮）
    │   ├── 预览块                        ← D   ← 插在这一段
    │   │   ├── 预览头部
    │   │   │   ├── 规则文本
    │   │   │   └── 预览工具组 → [对比按钮] [全屏按钮]
    │   │   ├── 状态芯片组 → 状态芯片 ×N
    │   │   └── 预览视口
    │   │       ├── 单屏预览  ← 默认
    │   │       └── 对比预览  ← 对比模式：原始视口 | 修改后视口
    │   │           （各带视口标签与尺寸读数）
    │   └── 规则面板                       ← C
    │       ├── 选择器字段（内部有面板关闭钮 ×）
    │       ├── 属性网格 → 声明行 → 分量格
    │       ├── 添加属性菜单
    │       └── 插入模板区 → 模板 chip ×N
    └── 状态行

全屏视图                                  ← E（盖在整行之上）
├── 全屏遮罩
└── 全屏卡片
    ├── 全屏顶栏 → 全屏选择器框 + 全屏退出钮
    ├── 全屏预览区 → 原始视口 | 修改后视口
    └── 全屏规则面板（就是上面那个规则面板）
```

> **注意「预览块」的位置**：它在**编辑正文**里、**代码区**与**规则面板**之间。
> 别叫它「编辑器下面那块」——`规则面板`也在编辑器下面，这正是以前会混的地方。

---

## A. 设置行（整行）

| 名字 | 标识（代码 / 选择器） | 说明 | 状态 |
| --- | --- | --- | --- |
| **设置行** | `CustomCssRow` · `.dshCc_row` | 设置 → 通用 里这一整行 | 已实现 |
| **行头** | `.dshCc_head` | 设置行顶部：标题在左，动作组在右 | 已实现 |
| **行标题** | `.dshCc_title` | 行头左侧的「自定义 CSS」 | 已实现 |
| **行说明** | `.dshCc_desc` | 标题下方那行说明文字 | 已实现 |
| **动作组** | `.dshCc_actions` | 行头右侧那排入口 | 已实现 |
| **拾取入口** | `.dshCc_pickBtn` | [拾取元素]，武装期间变成 [取消拾取] | 已实现 |
| **查找入口** | `.dshCc_findBtn` | [查找]，栏打开时变 [关闭查找] | 已实现 |
| **文件下拉** | `.dshCc_trigger` `.dshUi_menu` | DSH 原生样式的样式表下拉 | 已实现 |
| **更多操作菜单** | `.dshCc_menuBtn` | [更多操作]：打开文件 / 导入 / 导出 / 格式化 / 历史版本 / 重置 | 已实现 |
| **文件栏** | `.dshCc_fileBar` | [图标 + 文件名 + 徽章] [大纲] [状态点] [启用开关] | 已实现 |
| **文件身份区** | `.dshCc_fileIdentity` | 文件栏左侧：图标 + 文件名 + `CSS` 徽章 | 已实现 |
| **大纲** | `.dshCc_outline` | 规则清单下拉，每条带「命中 N 个」 | 已实现 |
| **状态点** | `.dshCc_statusDot` | 文件栏里那个小圆点 | 已实现 |
| **启用开关** | `.dshUi_switch` | 临时停用当前样式表的胶囊 | 已实现 |
| **编辑容器** | `.dshCc_shell` | 圆角 12px 的大框：表头 / 正文 / 状态行三段同框 | 已实现 |
| **编辑表头** | — | 容器顶部：文件名 + 徽章 + 开关 | 已实现 |
| **编辑正文** | `.dshCc_main` | 容器中间那一块 | 已实现 |
| **状态行** | `.dshCc_foot` `.dshCc_status` | 容器底部：保存状态、校验问题 | 已实现 |

---

## A2. 壁纸（插件详情页里的那一节）

壁纸的**控件本体**挂在**插件详情页**（插件管理器 → `dsh-custom-css`）里，是**一节**
（`.dshUi_section`）里的一块面板（`.dshWp_root`）。**设置行里只有一行链接**
（`.dshCc_wallpaperLinkRow`），点它跳到这一节 —— 见文末「设置行里的入口」。

> 它曾经在设置行里挂过**整份面板**（`.dshCc_wallpaperBlock`），**已删除**。下面这张表里
> 也没有那一块的名字了；别再往设置行里加第二份控件。

| 名字 | 标识（代码 / 选择器） | 说明 | 状态 |
| --- | --- | --- | --- |
| **壁纸节** | `WallpaperSection` · `.dshUi_section` | 插件详情页里这一整节（标题 + 说明 + 面板 + 事实） | 已实现 |
| **壁纸标题** | `.dshUi_sectionTitle` | 节标题「自定义壁纸」（14px/500，跟插件管理器自己的 section 同规格） | 已实现 |
| **壁纸说明** | `.dshUi_desc` | 标题下那一句（讲图片存在哪、浓度是干什么的） | 已实现 |
| **壁纸事实** | `.dshUi_facts` | 节底部的 `dl`：图片与记录 / 上限 / 与皮肤的关系 | 已实现 |
| **壁纸面板** | `WallpaperPanel` · `.dshWp_root` | 控件本体：预览列 + 四行控件 | 已实现 |
| **壁纸预览** | `.dshWp_preview`（在 `.dshWp_previewCol` 里） | 左（窄时在上）那块 16:9 的图，底下盖一层界面浓度 | 已实现 |
| **预览说明** | `.dshWp_previewNote` | 预览下面那行小字：预览里压着的那层就是「界面浓度」 | 已实现 |
| **选择图片钮** | `.dshUi_button`（`ui.button`） | `选择图片…`；已有图时写 `更换图片`，旁边多一个 `移除` | 已实现 |
| **填充下拉** | `.dshUi_choice`（`ui.choice`） | 铺满 / 完整 · 留边 / 拉伸 · 填满 / 平铺 | 已实现 |
| **界面浓度滑块** | `.dshUi_slider`（`aria-label` 为「界面底色浓度…」） | 0–60%，0 = 完全遮住壁纸；越大壁纸越明显 | 已实现 |
| **明暗滑块** | `.dshUi_slider`（`aria-label` 为「壁纸明暗」） | −60%…+60% 的 `filter: brightness()` | 已实现 |
| **用过的** | `.dshWp_gallery` · `.dshWp_thumb` | 宿主上还留着的图，每个叫**壁纸缩略图** | 已实现 |
| **图片文件夹** | `.dshWp_path` + 「重新读取」钮 | 显示 `.wallpapers/` 目录，并可重新列出「用过的」 | 已实现 |
| **壁纸状态行** | `.dshUi_status` | 「已保存」/「正在保存…」/ 错误；皮肤覆盖令牌时的说明另起一行 `.dshUi_hint` | 已实现 |

> 面板里的**壁纸记录**指宿主上那份 `wallpaper.json.css`（一张普通样式表文件，内容恰好是 JSON），
> 不是界面元素的名字，但代码与文档里都用这个词，不再叫它「配置文件」或「设置文件」。
> **插件设置**则是另一份 `settings.json.css`，见下面的 A3。

### A3. 插件设置（插件详情页里独立的一节）

| 名字 | 标识（代码 / 选择器） | 说明 | 状态 |
| --- | --- | --- | --- |
| **设置节** | `SettingsSection` · `section[data-dsh-wallpaper="settings-section"]` | 插件详情页里「壁纸设置」这一整节（order 21，排在壁纸节之后） | 已实现 |
| **设置面板** | `SettingsPanel` · `div[data-dsh-wallpaper="settings"]` | 八行控件本体，分「壁纸」与「编辑器」两组 | 已实现 |
| **分组标题** | `.dshUi_group` | 面板里的分组标题（目前只有「编辑器」一条） | 已实现 |
| **轮换下拉** | `.dshUi_choice`（`ui.choice`，`aria-label` 为「壁纸轮换间隔」） | 关 / 5 分钟 / 30 分钟 / 每小时 / 每天 | 已实现 |
| **遮罩滑块** | `.dshUi_slider`（`aria-label` 为「壁纸遮罩浓度」） | 0–80%，压在图片上的暗色层 | 已实现 |
| **模糊滑块** | `.dshUi_slider`（`aria-label` 为「壁纸模糊半径」） | 0–24px 的 `blur()` | 已实现 |
| **角落时间开关** | `.dshUi_switch`（`ui.switch`，`aria-label` 为「在壁纸上显示时间」） | 右下角时钟；`.dshWp_clock` 是它落在页面上的那个元素 | 已实现 |
| **保存延迟下拉** | `.dshUi_choice`（`ui.choice`，`aria-label` 为「样式表保存延迟」） | 200ms / 400ms / 1s / 3s | 已实现 |
| **校验下拉** | `.dshUi_choice`（`ui.choice`，`aria-label` 为「格式校验严格度」） | 语法 + 变量体检 / 只查语法 / 关闭校验 | 已实现 |
| **行号开关** | `.dshUi_switch`（`ui.switch`，`aria-label` 为「显示编辑器行号」） | 关掉时给 `.dshCc_row` 加 `.dshCc_noGutter`（**隐藏**，不卸载） | 已实现 |
| **Tab 宽度下拉** | `.dshUi_choice`（`ui.choice`，`aria-label` 为「Tab 宽度（空格数）」） | 2 / 4 / 8 空格；Tab 键与「格式化」都用它 | 已实现 |
| **数据分组** | `.dshUi_group`「数据」 | 「导出全部」「重置插件」两个动作 | 已实现 |
| **导出全部** | `.dshUi_button`（`ui.button`） | `GET /export` → 下载一个带时间戳的 JSON | 已实现 |
| **重置插件** | `.dshUi_button`（`ui.button`，两步确认） | `POST /archive-and-reset` → 归档到 `.backup/<时间戳>/` | 已实现 |
| **关于分组** | `.dshUi_group`「关于」 + `.dshUi_facts` | 版本 / 目录 / 宿主 / 链接四行事实（`dt`+`dd`，与壁纸节同一形状） | 已实现 |
| **文档链接** | `.dshUi_link` | 「仓库」「文档」两个外链（`--dsw-alias-state-business-primary`） | 已实现 |

> 这一节的标签与滑块的 `aria-label` 都在 `WALLPAPER_SETTING_LABELS` 里，一处定义、两处使用
> （看得见的字与读屏器听到的字不是同一句，所以两个都要写）。
>
> **控件全是设置行那一套自绘的**：`.dshUi_button`（`ui.button`）、`.dshUi_switch`（`ui.switch`）、
> `.dshUi_choice`（`ui.choice`，底层是行里的 `Dropdown`）、`.dshUi_badge`（`ui.badge`）、
> `.dshUi_field`（URL 文本框）。组件库那一路已在 0.3.8 撤回，见 [开发](./development.md) 的
> 「控件只有一套」。`.dshWp_btn` / `.dshWp_select` / `.dshWp_text` / `.dshWp_switch*` 都已不存在。

### 设置行里的入口

| 名字 | 标识（代码 / 选择器） | 说明 | 状态 |
| --- | --- | --- | --- |
| **壁纸链接行** | `.dshCc_wallpaperLinkRow` | 设置行最下面那一行，只有链接 + 一句说明 | 已实现 |
| **壁纸链接** | `.dshCc_linkBtn` | 「自定义壁纸…」，跳到插件详情页那一节（`pluginNavigation.openBundle`） | 已实现 |
| **链接说明** | `.dshCc_linkNote` | 链接右边那句「在插件详情页里设置」 | 已实现 |

**这一行里不放控件。** 它是**入口**，不是设置 —— 设置那一套控件只属于上面那一节。


---

## A4. 令牌管理（新增）

入口：设置行「更多操作 → 令牌」。版面与历史版本 / 选择器体检同一套分页版式。

| 名字 | 标识 | 说明 | 状态 |
| --- | --- | --- | --- |
| **令牌页** | `.dshCc_tokens` | 那一页的整体 | 已实现 |
| **令牌行** | `.dshCc_tokenRow` | 一条令牌，两行：名字 + 用量 / 值 + 来源 | 已实现 |
| **令牌名** | `.dshCc_tokenName` | `--dsw-alias-bg-base`（等宽字体） | 已实现 |
| **令牌值** | `.dshCc_tokenValue` / `.dshCc_tokenInput` | 解析值（解析不到时显示定义值）；接管后变成输入框 | 已实现 |
| **令牌来源** | `.dshCc_tokenSource` | 哪张样式表定义的（如 `ext/theme.css`） | 已实现 |
| **令牌用量** | `.dshCc_tokenMeta` | `· 31 条规则`；警告色与明细待做 | 已实现 |
| **接管开关** | `.dshCc_hlToggle` | 开 = 写进 `tokens.css`（「接管」）；关 = 删掉那一条（「撤销」，`aria-pressed`）—— **复用强调显示那个胶囊按钮** | 已实现 |
| **重置钮** | `.dshCc_hlToggle` | 就是「撤销」：删掉覆盖，回到来源值（与接管同一个类） | 已实现 |
| **令牌搜索框** | `.dshUi_field` + `.dshCc_tokenSearch` | 按名字 / 值 / 来源过滤（**共享字段组件**，本地类只管布局） | 已实现 |
| **令牌列表** | `.dshCc_tokenList` | 限高 260px 自己滚的那一列 | 已实现 |
| **材质区** | `.dshCc_materialTokens` | 置顶那一块：`--dsh-material-*`（云母 / 亚克力 / 毛玻璃） | 规划中 |
| **材质令牌** | `--dsh-material-{acrylic,frost,mica}-{bg,blur,saturate,border,grain}` | 预设引用的材质参数 | 规划中 |

> **接管 = 一份插件自己的 `tokens.css`**，注入在**用户 `custom.css` 之前**、在 DSH 与其它扩展之后：
> 覆盖它们，但用户自己的表仍然最后、仍然赢。写盘顺序见 [令牌管理](./token-manager.md)。

---

## B. 编辑器

| 名字 | 标识 | 说明 | 状态 |
| --- | --- | --- | --- |
| **代码区** | `.dshCc_editorWrap` `.dshCc_code` | 行号列 + 代码文本框所在的那一块 | 已实现 |
| **行号列** | `.dshCc_gutter` | 左边那排行号 | 已实现 |
| **代码文本框** | `.dshCc_editor` | 打字的地方（透明 textarea） | 已实现 |
| **彩色层** | `.dshCc_highlight` | 语法高亮那层，盖在文本框下面 | 已实现 |
| **补全列表** | `.dshCc_suggest` | 打字时弹出，里面每一项叫**补全项** `.dshCc_suggestItem` | 已实现 |
| **查找栏** | `.dshCc_findBar` | 代码区上方那条 | 已实现 |
| **查找框 / 替换框** | `.dshCc_findField` | 栏里那两个输入框 | 已实现 |
| **命中计数** | `.dshCc_findCount` | `3 / 12` | 已实现 |
| **大小写钮** | `.dshCc_findIcon` + `aria-pressed` | `Aa` | 已实现 |
| **替换钮 / 全部替换钮** | `.dshCc_findWide` | `↦` / `⇉` | 已实现 |

---

## C. 规则面板

| 名字 | 标识 | 说明 | 状态 |
| --- | --- | --- | --- |
| **规则面板** | `.dshCc_panel` | 代码下方那块：选择器字段 + 属性网格 + 插入模板 | 已实现 |
| **选择器字段** | `.dshCc_panelField` `.dshCc_panelName` | 面板顶部可改名的输入框 | 已实现 |
| **面板关闭钮** | `.dshCc_panelClose` | 选择器字段**内部**靠右的 `×` | 已实现 |
| **属性网格** | `.dshCc_propGrid` | 面板中间声明铺开的那片 | 已实现 |
| **声明行** | `.dshCc_prop` | 网格里的一条（`上外边距 4px`） | 已实现 |
| **分量格** | `.dshCc_partCell` | 简写属性拆出来的小格（上 / 右 / 下 / 左） | 已实现 |
| **属性值输入框** | `.dshCc_propText` | 声明行里填值的地方 | 已实现 |
| **添加属性菜单** | `.dshCc_addPropWrap` | 「＋ 添加属性…」展开的菜单 | 已实现 |
| **插入模板区** | `.dshCc_tplGrid` | 面板最下面那排模板，每个叫**模板 chip** `.dshCc_tpl` | 已实现 |

---

## D. 预览块（新增）

**右上角三个按钮，按这个顺序**：全屏 → 对比 → 列表。

| 名字 | 标识 | 说明 | 状态 |
| --- | --- | --- | --- |
| **预览块** | `.dshCc_preview` | 插在声明区上方（代码区与规则面板之间），只在打开某条规则时出现 | 已实现 |
| **预览工具条** | `.dshCc_previewBar`（28px 一行，全高 `ui.*` 控件） | 视图分段 / 状态芯片 / 命中菜单 / 背景 / 适应 / 全屏 | 已实现 |
| **规则文本** | `.dshCc_previewRule` | **全屏顶栏**左侧：当前规则的原文（只读、省略号）；行内不再重复一份（选择器框就在上面） | 已实现 |
| **视图分段** | `.dshUi_segments`（`aria-label` = 预览视图） | 单屏 / 对比，二选一 | 已实现 |
| **画布背景** | `.dshUi_choice.dshUi_choiceSm`（`aria-label` = 画布背景） | 换画布背景：页面（默认）/ 棋盘 / 方格 / 斜纹 / 点阵 / 渐变 / 纯色 | 已实现 |
| **画布** | `.dshCc_canvas`（`data-canvas` = 预设 id） | 样本坐着的那块**可拖动**的画布；**一份**平移量写进每个 `[data-pane]`，行内与全屏一起走；夹取保证样本至少露 48px | 已实现 |
| **窗格** | `.dshCc_previewBox`（`overflow:hidden`，带描边与「当前/修改后」标签） | **窗口**：组件在它里面按原始尺寸排版，装不下的部分裁掉 | 已实现 |
| **样本层** | `.dshCc_previewAfter[data-pane="modified"]` / `.dshCc_previewCurrent[data-pane="current"]` | 拖动实际作用在它身上（`transform` 写在这层，不是窗格或舞台上）；宽度由实测值写死，不压缩 | 已实现 |
| **归位** | `.dshCc_canvasReset`（里面是 `ui.button({ size:'sm', icon:true })`） | 画布右下角：所有样本层平移量清零（双击画布同效） | 已实现 |
| **全屏按钮** | `.dshUi_button.dshUi_buttonSm` | 打开全屏视图 | 已实现 |
| **对比段** | `.dshUi_segment`（视图分段里的第二段） | 开**对比模式** | 已实现 |
| **命中菜单** | `.dshUi_choice.dshUi_choiceSm`（`aria-label` = 预览第几个命中元素） | 命中多于一个时选看哪个（`div · 2/5`）；替代了「列表 + 卡片导航」 | 已实现 |
| **预览视口** | `.dshCc_previewStage` | 装样本的框（**不是 iframe**） | 已实现 |
| **单屏预览** | — | 默认：只有一块「修改后」 | 已实现 |
| **对比模式** | — | **左侧多出一块「当前」**，右侧「修改后」 | 已实现 |
| **当前面板** | `.dshCc_previewCurrent`（带 `data-dshcc-owned`） | 对比模式左边那块：**打开这条规则时**的文本；标记为插件界面，不参与匹配 | 已实现 |
| **修改后面板** | `.dshCc_previewAfter`（带 `data-dshcc-owned`） | 一直有：现在的文本；同上，不参与匹配 | 已实现 |
| ~~卡片导航~~ | — | 已去掉：命中切换改由「命中菜单」承担 | 已移除（v4） |
| ~~样本卡片~~ | — | 同上，已移除（v4） | 已移除（v4） |
| **样本** | `.dshCc_sample` | 克隆元素 + **冻结的计算样式**（内联），一个面板里一个 | 规划中 |
| **伪元素样本** | `.dshCc_samplePseudo` | `::before` / `::after` 合成出来的那个 span（近似，见 [预览块](./preview.md)） | 已实现 |
| **演示中标记** | `.dshUi_status[data-state=warn]`（`ui.status`） | 强制态生效时那一行警告色小字 | 已实现 |
| **视口标签** | — | 面板左上角小字：`当前` / `修改后` | 已实现 |
| **尺寸读数** | — | 面板角上的 `320×180` | 规划中 |
| **冻结口径说明** | `.dshUi_hint`（在 `.dshCc_previewFoot` 里） | 底部那行小字：样本冻结了什么、没冻结什么 | 已实现 |
| **合成样本** | `.dshCc_sampleSynthetic` | 命中 0 个时用规则自己的声明拼的方框，标注「不是页面上的元素」 | 已实现 |
| ~~状态芯片组~~ | — | 芯片直接排在工具条里（对比 / 全屏时隐藏） | 已移除（v4） |
| **状态芯片** | `.dshUi_button.dshUi_buttonSm`（`aria-pressed`） | 悬停 / 聚焦 / 占位符（真页面强制）+ `::before` / `::after`（样本里合成）；**只列选择器里真有的状态** | 已实现 |

> **为什么不用 iframe**：`--dsw-*` 令牌在宿主 `body` 上，iframe 里没有；更要紧的是
> `backdrop-filter` 在 iframe 里模糊的是 iframe 自己的内容 —— 玻璃预览会变成一块空盒子。
> 详见 [预览块](./preview.md)。

---

## D2. 预设（新增）

位置：**规则面板上面**一排。点一个 = 往**当前规则**写入一组声明（一次编辑、一次 `Ctrl+Z` 可撤回）。

| 名字 | 标识 | 说明 | 状态 |
| --- | --- | --- | --- |
| **预设栏** | `.dshCc_panelSection` + `.dshCc_tplGrid` | 规则面板顶部、声明区上方（**复用声明模板那排**） | 已实现 |
| **预设按钮** | `.dshCc_tpl` | 一个效果：亚克力 / 毛玻璃 / 云母 / 细描边卡片 | 已实现 |
| **预设检查** | `.dshCc_presetCheck` | 应用前对目标元素的检查（结果三种：可应用 / 有提醒 / 拒绝） | 规划中 |
| **预设说明** | `.dshCc_versionsNote` | 拒绝或提醒时那一行原因（**复用历史版本页的说明样式**） | 已实现 |

> 预设**合并**而不是覆盖：只写它负责的那几个属性；**不写 `!important`**、**不动几何**、
> **不覆盖 `--dsw-*` 令牌**。详见 [预设](./presets.md)。

---

## E. 全屏视图（已实现，0.10.0）

| 名字 | 标识 | 说明 | 状态 |
| --- | --- | --- | --- |
| **全屏视图** | `dialog.dshCc_full` | 铺满的那个视图；**原生 `<dialog>` + `showModal()`**，`Esc` 或 × 退出 | 已实现 |
| **全屏遮罩** | `.dshCc_full::backdrop` | 铺满的**毛玻璃**：`--dsw-alias-bg-overlay` 混 55% 透明 + `blur(18px) saturate(1.15)`；关掉透明效果时退回不透明 | 已实现 |
| **全屏卡片** | `.dshCc_full` 自身 | 设置卡片面 + 唤起阴影；尺寸 `min(1280px,96vw)` × `min(94vh,960px)`，内边距 20 | 已实现 |
| **全屏顶栏** | `.dshCc_fullHead` | 卡片最上面一行 | 已实现 |
| **全屏选择器框** | `.dshCc_previewRule`（在顶栏里） | **只显示**该规则的选择器（只读） | 已实现 |
| **全屏命中读数** | `.dshCc_fullMeta` | 顶栏里的 `N 个命中 · 第 i 个`（行内面板有它，全屏也要有） | 已实现 |
| **全屏命中菜单** | `.dshUi_choice.dshUi_choiceSm`（顶栏里） | 命中多于一个时选看哪个；与行内那枚是同一个控件 | 已实现 |
| **全屏退出提示** | `.dshCc_fullEsc` | 顶栏里的 `Esc 退出`；≤900px 时隐藏 | 已实现 |
| **全屏退出钮** | `.dshCc_panelClose`（顶栏里） | 顶栏右侧的 `×` | 已实现 |
| **全屏预览区** | `.dshCc_fullStage` | 顶栏下方：**左「当前」/ 右「修改后」**（强制并排），外面包一层 `.dshCc_canvas` | 已实现 |
| **全屏正文** | `.dshCc_fullBody` | 预览区下方：**同一份面板正文**（预设 / 声明 / 加属性 / 模板），自己滚 | 已实现 |

> **为什么是原生 `<dialog>` 而不是 `position:fixed` 的浮层**：浮层会被任何带 `transform` 的祖先变成
> 「相对该祖先定位」—— 设置对话框就是一例，于是「全屏」实际上只有对话框那么大。`showModal()` 进
> top layer，不受祖先影响。
>
> **这一版是强制的两块**：进了全屏就等于同时开了对比。
>
> **正文是同一份，不是副本**：`RulePanel` 里的正文抽成了 `renderBody()`，内联面板与全屏共用 ——
> 在那边改一条属性，两块一起动。

---

## F. 「这两边到底差什么」的口径

对比模式不是在比「两张样式表」，是在比**你打开这条规则之后改了什么**：

| 面板 | 里面是什么 |
| --- | --- |
| **当前** | **打开这条规则那一刻**的样式表文本，应用在这个元素上的计算样式 |
| **修改后** | **现在的**样式表文本，应用在这个元素上的计算样式 |

两块都是**同一个元素的克隆**，样式**冻结成内联**（见 [预览块](./preview.md)）—— 所以左右只差
你打开之后的改动。**同一选择器有多条规则时不用特殊处理**：两份文本各自完整应用，差别天然覆盖它们。

另一种口径（左边 = 整表**去掉**这条规则）回答的是另一个问题（「这条规则本身有什么用」），
留作以后的可选切换，第一版不做。

---

## G. 令牌对照：新 UI 全部取自 DSH 自身

这几条都在 DSH 自己的产物里逐个查过（`--dsw-*` 共 418 个），不是照现有代码猜的。

| 用在哪 | 取哪个令牌 |
| --- | --- |
| 预览块描边 / 视口描边 | `--dsw-alias-border-l2`（0.5px 分隔用 `--dsw-alias-border-l1`） |
| 预览块底 / 视口底 | `--dsw-alias-bg-module-platform` / `--dsw-alias-bg-layer-1` |
| 原始视口 点缀 | `--dsw-alias-code-diff-deleted` |
| 修改后视口 点缀 | `--dsw-alias-code-diff-added` |
| 状态芯片：选中 / 未选中 | `--dsw-alias-interactive-bg-active` / `--dsw-alias-bg-module-platform` |
| 全屏遮罩 | `--dsw-alias-bg-overlay` **混成 55% 透明**（它本身不透明，直接铺会盖死页面）+ `backdrop-filter:blur(18px) saturate(1.15)` |
| 全屏卡片 | `--dsw-alias-settings-card-fill` + `--dsw-alias-settings-card-stroke` |
| 全屏卡片阴影 | `--dsw-elevation-prominent` |
| 聚焦环 | `--dsw-alias-brand-primary` |
| 尺寸读数 / 视口标签 | `--dsw-alias-label-caption` |

---

## H. 怎么用这套名字

1. **提需求**：说名字就够 —— 「预览头部右上角加第三个按钮」比「上面那块右边再加个东西」少三轮确认。
2. **写代码**：类名用标识那一列的前缀（`.dshCc_preview…`），组件名用同一套词。
3. **记日志**：`info` 级别的日志要能说出是**哪个名字**做了**什么**（如「预览视口：重绘，命中 3 个样本」），你点了一个按钮没反应时，日志能告诉你是哪个。
4. **改名字**：先改这张表，再改代码 —— 表是口径，不是代码的摘抄。

### 这张表不覆盖已发布的名字

`dsh.client` / `dsh.bundle` / `compat.json` / `cordis.patch.yml` 里的**类名与文件**是已经
发到 npm 的东西，改它们会让别的插件、别人写的样式表、以及 `docs/` 下那四张架构图一起
对不上。所以：

- 这张表是**给人说话用**的 —— 它规定的是「这块东西叫什么」，不是「这个 class 要改成什么」。
- 表里「标识」一列是**现状的对照**；新加的东西（D/E 两节）才由这张表指定标识。
- 架构图与 README 里旧的说法，按位置能对上的以**本表**为准。

---

## 附：待定的

| 项 | 选项 | 当前取值 |
| --- | --- | --- |
| 开发实例端口 | 3081 / 3082 | 3081 |
| 窄行（约 440px）下的对比模式 | 上下堆叠 / 提示「先全屏」 | 上下堆叠 |
| 预览样本的保真度口径 | 冻结计算样式（**已定**）/ iframe 克隆 / 真页面切换 | 冻结计算样式 |
| 对比左边的口径 | **当前（打开时的文本，已定）** / 去掉这条规则 | 当前 |
| 状态芯片的机制 | 真页面 + 临时表（**已定**）/ 冻结样式 | 真页面 + 临时表 |
| 预设第一批做几个 | 4 个（亚克力 / 毛玻璃 / 云母 / 细描边）/ 先做 2 个 | 4 个 |
