/* 青蔓 QingMan · 软光设计层（Soft UI / Neomorphism）—— **基础层，默认生效**
 * ---------------------------------------------------------------------------
 * 来源：设计稿 prototype.html 的 `<style id="qmSoftSkin">`，2026-10-13/14 定稿并入。
 *
 * 定位（V0.0.45 起）—— 本层是**唯一的设计语言**（即用户裁定的「新默认」），不再是
 *   一个可选的皮肤层。配色一律来自 tokens.css 的 :root 与 15 款皮肤；本层只统一「语法」：
 *     ① 光源固定左上、两侧镜像对称；② 模糊 = 位移 × 2。
 *   15 款皮肤**只提供配色与影色**，形态（位移 / 模糊 / 内陷 / 外凸）由本层唯一提供 ——
 *   即「UI 设计风格统一，切换皮肤仅是切换配色」。皮肤中原本各自复制的形态表达式
 *   （--qm-shadow-raise / --qm-inset）实测 15 份**取值完全一致**（纯冗余），已全部剥离，
 *   其唯一来源上移到 tokens.css（引用皮肤影色变量，故仍随皮肤明暗自动适配）。
 *
 * 挂载（V0.0.45 变更）—— **无属性开关，直接生效**。
 *   旧版靠 `<html data-soft>` 属性 + 本文件全部规则带 `html[data-soft]` 前缀，属「可整块
 *   摘除的独立层」。现正式化为基础层：三页 `<html>` 上的 data-soft 已删除；选择器统一写
 *   `html X`（**保留 html 元素选择器是刻意的** —— 它给本层 +1 元素级特异性，使去属性后
 *   仍能压住 base / layout 中的同名**常态**规则）。
 *   ⚠ 去属性会让本层特异性**整体降一档**（`html[data-soft] .x` (0,2,1) → `html .x` (0,1,1)），
 *     故凡「其它文件里**带伪类**的高特异性规则」都可能反超本层。已用无头探针
 *     （564 元素 × 静态 + hover/active/focus 三交互态，:hover 经「重写为等价类 + 全域施加」
 *      逼出）**定位到且仅有**两处，均已在本文件显式修补：
 *       ① `.tpl-item:hover`（layout.css）→ 见第 7 节的压制规则；
 *       ② `input / select:focus`（base.css）→ 见第 9 节的显式描边规则。
 *     改本层的选择器形态或样式表加载顺序时，务必重跑那套探针（方法见《错误笔记》第 67 条）。
 *
 * 变量 —— --qm-soft-dark / --qm-raise / --qm-raise-hi / --qm-sink / --qm-tap /
 *         --qm-tap-hi / --qm-tap-in / --qm-scrim，以及 V0.0.45 新增的形态语法变量
 *         （--qm-card-edge / --qm-topbar-shadow / --qm-layer-shadow / --qm-pop-shadow /
 *          --qm-qr-shadow / --qm-btn-edge）均定义在 tokens.css 的 :root。
 *
 * 三条硬化规则（来自实测教训，不是审美偏好）：
 *   ① 有底才有影 —— 透明底元素配 box-shadow 会投出一个方形影框。
 *   ② 父子不能都浮起 —— 父层浅底+柔光、子按钮再浮起，两层影会叠成一圈白晕。
 *   ③ 小控件的光影必须比大区块短 —— 偏移 2–4px、模糊 5–10px。
 *
 * ⚠ 本节选择器对应元素的实现状态（2026-10-14 实测，扫 `src/web/**` 的 `.html` + `.js`；
 *    **2026-10-17 复核更新**，见 `.tpl-more` 一行）：
 *   · **已实现、规则已命中**：
 *       `.icon-btn` / `.tb-status`  —— 顶栏图标钮与状态组（V0.0.40）
 *       `.layer.*`                  —— 应用内弹层 / 浮层（V0.0.40，`ui/layer.js`）
 *       `.sup-qr-img`               —— 支持页赞赏码
 *       `.tpl-badge`                —— 模板行**来源层**徽标（内置 / 用户，`templates.js`
 *                                      动态创建，非静态 HTML）。⚠ 原记「格式徽标」系史实
 *                                      偏差，据实更正：格式（json / md）V0.3.6 起归 `.tpl-fmt`
 *       `.tpl-fmt`                  —— 模板行**文件格式**徽标（V0.3.6，`templates.js` 动态创建）
 *       `.tpl-more`                 —— 模板行行尾 ⋮（V0.0.51@r11 装回；`templates.js`
 *                                      动态创建）。⚠ 原记「⋮ 已于 V0.0.38 随右键菜单改造
 *                                      移除、下方规则已成死码」系**史实错误**，据实更正：
 *                                      V0.0.38 移除的是 `.tpl-ops` **文字**按钮，而 ⋮
 *                                      **从未装过**（`git log --all -S "tpl-more"` 在
 *                                      `src/web/js/` 命中 0）—— 故本节这两条规则自
 *                                      V0.0.40 起一直是**无消费者的死码**，装回 ⋮ 后**当场生效**
 *   · **未实现、规则暂不命中**：
 *       `.ob-group`                 —— v4–v7 设计提案的按钮组，主界面未落地
 */

/* ---------- 1. 板块：三栏 / 顶栏 —— 结构线保留，投影换成柔性 ---------- */
html #sidebar,
html #center,
html #inspector {
  background: var(--qm-surface);
  border-color: var(--qm-line);
  box-shadow: var(--qm-raise), var(--qm-card-edge);
}
html #topbar {
  background: var(--qm-surface);
  border-bottom-color: transparent;
  box-shadow: var(--qm-topbar-shadow);
}
html #statusBar { box-shadow: none; }
html .opband { border-bottom-color: var(--qm-line-soft); }

/* ---------- 2. 通用按钮：柔性凸起（全站统一语言） ---------- */
html .btn {
  background: var(--qm-surface-2);
  border-color: var(--qm-line-soft);
  box-shadow: var(--qm-tap);
}
html .btn:hover:not(:disabled) { box-shadow: var(--qm-tap-hi); }
html .btn:active:not(:disabled) { box-shadow: var(--qm-tap-in); }
html .btn:disabled {
  background: transparent; border-color: transparent; box-shadow: none;
}

/* ---------- 3. 图标钮族：浅底 + 淡边 + **单向落影**（V0.3.8） ----------
   ⚠ `:not(.tpl-more)` 必须要有：左栏模板行右端的 ⋮ 类名正是
     `.btn.btn-ghost.btn-mini.btn-ic`，不加排除会被本组规则退回「外挂描边方块」。

   **V0.3.8 为什么不再用 `--qm-tap`（双向 neumorphism）**：它是
   「左上 -2px 亮 rgba(255,255,255,.06) + 右下 2px 暗 rgba(0,0,0,.62)」——
   深浅两侧强度差近 10 倍。深色皮肤上亮侧基本看不见、暗侧糊成按钮下方的一圈，
   视觉上读成「按钮塌进底板」的**凹槽**，而不是凸起（用户实测反馈：截图里每个
   图标钮下面都有一道凹边）。改成**单向落影**（只向下、不留左上高光）后，
   方向唯一、不再有"凹"的二义性；立体感与悬停动画由 `transform` 承担 ——
   这正是本文件里 `.chip-btn` / `.btn-primary` 一直以来的做法。
   位移 / 模糊 / 时长**全部**在 tokens.css 的 `--qm-drop-*` / `--qm-mo-*` 里，
   本节只做 `var()` 引用（守卫 7d-6：本文件不得出现 px 字面量）。 */
html .icon-btn,
html .btn.btn-ghost.btn-ic:not(.tpl-more),
html .btn.btn-ghost.btn-mini.btn-ic:not(.tpl-more) {
  background: var(--qm-surface-2);
  border-color: var(--qm-line-soft);
  box-shadow: var(--qm-drop);
  /* **只过渡 transform / box-shadow**（V0.3.8 实测修正）。
     早先把 background-color / border-color / color 也列进来，想让「换肤」也渐变过去 ——
     代价是**颜色变成了随时间变化的值**：换肤瞬间 `getComputedStyle().color` 返回
     插值中间态，页面冒烟 D-P3-2（图标色须等于 `--qm-text-dim`）当场读到
     `rgb(93,102,115)` 而变量是 `rgb(93,88,79)` → 判定「图标色未随皮肤」。
     这不是判据太严：颜色即时切换才是可复现的；「立体 + 动画」也不靠颜色渐变，
     它靠 translateY / scale 与落影深浅。故颜色类属性一律不进过渡。 */
  transition: transform var(--qm-mo-fast) var(--qm-mo-ease),
              box-shadow var(--qm-mo-fast) var(--qm-mo-ease);
}
html .icon-btn:hover:not(:disabled),
html .btn.btn-ghost.btn-ic:not(.tpl-more):hover:not(:disabled),
html .btn.btn-ghost.btn-mini.btn-ic:not(.tpl-more):hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: var(--qm-drop-hover);
}
html .icon-btn:active:not(:disabled),
html .btn.btn-ghost.btn-ic:not(.tpl-more):active:not(:disabled),
html .btn.btn-ghost.btn-mini.btn-ic:not(.tpl-more):active:not(:disabled) {
  transform: translateY(0) scale(.96);
  box-shadow: var(--qm-drop-active);
}
/* 展开态（弹层已开）：靠强调底色 + 描边区分，**不再用 inset** ——
   否则一点开就"按进去"，与悬停时的"抬起来"方向相反，手感是断的。 */
html .icon-btn[aria-expanded="true"] {
  background: var(--qm-accent-soft); color: var(--qm-accent-ink);
  border-color: var(--qm-accent);
  box-shadow: var(--qm-drop-expanded);
}
/* 动效可关断：系统设了"减少动态效果"就不位移，只留阴影变化 */
@media (prefers-reduced-motion: reduce) {
  html .icon-btn,
  html .btn.btn-ghost.btn-ic:not(.tpl-more),
  html .btn.btn-ghost.btn-mini.btn-ic:not(.tpl-more) {
    transition: box-shadow .01ms linear;
  }
  html .icon-btn:hover:not(:disabled),
  html .btn.btn-ghost.btn-ic:not(.tpl-more):hover:not(:disabled),
  html .btn.btn-ghost.btn-mini.btn-ic:not(.tpl-more):hover:not(:disabled) {
    transform: none;
  }
}

/* ---------- 4. 顶栏状态组：被动槽凹陷，组内可点 chip 反向凸起 ---------- */
html .tb-status {
  background: var(--qm-bg);
  border-color: var(--qm-line-soft);
  box-shadow: var(--qm-sink);
}
html .tb-status .chip-btn {
  background: var(--qm-surface-2);
  border-color: var(--qm-line-soft);
  box-shadow: var(--qm-tap);
}

/* ---------- 5. 主操作「一键生成」：父层完全退场，主色块一次性塑形 ----------
   （旧结构 = 父层浅底 + 大柔光 ⇒ 子块再浮起 ⇒ 两层影叠成一圈白晕） */
html .ob-group.ob-gen {
  background: transparent; border: 0; border-radius: 0; padding: 0; box-shadow: none;
}
html .ob-group.ob-gen .btn-ic { width: 38px; height: 36px; padding: 0; }   /* V0.0.51：随 .btn-ic 同批 34×32→38×36，保持「主操作更大」层级 */
html .btn.btn-primary {
  /* v14：底色交回 --qm-btn-bg（各皮肤自带主色，已按 WCAG 配 --qm-on-accent），
     不再写死黄色渐变 —— 否则切任何皮肤它都是黄块，等于「切了没反应」。
     立体感由「对称柔光 + 顶部内高光」承担，不依赖渐变。 */
  background: var(--qm-btn-bg);
  border-color: var(--qm-btn-bg);
  color: var(--qm-on-accent);
  border-radius: var(--qm-r-sm);
  /* V0.0.45：位移 / 模糊收敛到语法变量；**V0.3.8**：不再叠双向 `--qm-tap`，
     改为「单向落影 + 顶部内高光（--qm-btn-edge）」。理由同第 3 节 ——
     双向投影在深色皮肤上会在按钮下方糊出一圈凹边，而内高光才是真正的"顶面反光"。
     三态阴影（常态 / 悬停 / 按下）已合成为 `--qm-drop-primary*`，本节只做引用。 */
  box-shadow: var(--qm-drop-primary);
  /* 同第 3 节：颜色类属性不进过渡（换肤须即时可复现，否则计算色变成时间函数）。 */
  transition: transform var(--qm-mo-fast) var(--qm-mo-ease),
              box-shadow var(--qm-mo-fast) var(--qm-mo-ease);
}
html .btn.btn-primary:hover:not(:disabled) {
  background: var(--qm-btn-bg-hi);
  border-color: var(--qm-btn-bg-hi);
  transform: translateY(-1px);
  box-shadow: var(--qm-drop-primary-hover);
}
html .btn.btn-primary:active:not(:disabled) {
  transform: translateY(0) scale(.97);
  box-shadow: var(--qm-drop-primary-active);
}

/* ---------- 6. 操作带分组：凹陷胶囊（分段控件语言） ---------- */
html .ob-group {
  background: transparent; border: 0;
  box-shadow: var(--qm-sink);
}
html .ob-group.ob-edit { box-shadow: none; }
html .obband-sep { background: var(--qm-line-soft); }

/* ---------- 7. 左栏模板行（卡片已上移到 .tpl-row） ---------- */
html .tpl-row {
  background: var(--qm-surface);
  border-color: var(--qm-line-soft);
  box-shadow: var(--qm-tap);
}
html .tpl-row:hover { box-shadow: var(--qm-tap-hi); }
html .tpl-row.is-active,
html .tpl-row.is-checked {
  background: var(--qm-accent-soft); border-color: var(--qm-accent);
  box-shadow: var(--qm-tap-hi);
}
html .tpl-item { background: transparent; border-color: transparent; box-shadow: none; }
html .tpl-row .tpl-item:active { box-shadow: var(--qm-tap-in); }
/* V0.0.45「去属性 · 转基础层」的**实测补丁**：去掉 [data-soft] 后本节特异性由
   (0,2,1) 降到 (0,1,1)，于是 layout.css 的 `.tpl-item:hover` (0,2,0) **反超** ——
   无头实测表现为「hover 时旧设计的灰底高亮 + 强调描边泄漏」（34 处，**仅交互态**）。
   soft 体系里模板行卡片由 `.tpl-row` 承担、行内容恒透明；且 hover 若也用 accent-soft
   会与「选中态」(`.tpl-row.is-active`) 视觉混淆。故显式压制（(0,3,1) > (0,2,0)）。 */
html .tpl-row .tpl-item:hover { background: transparent; border-color: transparent; }
/* ⋮ 的**透明复位** —— 两处都得挡：本组 `:not(.tpl-more)` 排除不了第 2 节的
   通用 `.btn` 规则（⋮ 本身是 `.btn.btn-ghost.btn-mini.btn-ic`），故此处再给一条
   (0,3,1) 的复位，高于 `.btn` 的 (0,2,1)。
   ⚠ 形态取**我方按钮族**（`.btn-mini.btn-ic` ⇒ 27×27、圆角 `--qm-r-sm` = 12px 的
   **方块**），**不是**设计稿 v7.1 的 22×22 圆形 —— 本批（V0.0.51@r11）采纳的是
   「丙-1」：与既有图标钮同形，不为此单独引入一套外观。半透明常驻与点亮见
   `layout.css` 的 `.tpl-row` 节（那是**交互态**，不属本层的柔光职责）。 */
html .tpl-row .tpl-more {
  background: transparent; border-color: transparent; box-shadow: none;
}
html .tpl-row .tpl-more:hover:not(:disabled) {
  background: var(--qm-surface-2); border-color: transparent; box-shadow: var(--qm-tap);
}
html .tpl-row .tpl-badge { background: var(--qm-surface-2); border-color: transparent; }
/* V0.3.6 新增：名称右侧的**文件格式**徽标。与 `.tpl-badge` 同族（都是有底无描边的
   小方块），只改底色/描边以对齐柔光风格 —— 否则同一行两个徽标一个浮一个平，很扎眼。 */
html .tpl-row .tpl-fmt { background: var(--qm-surface-2); border-color: transparent; }

/* ---------- 8. 目录树 ---------- */
html .tree-row:hover { background: transparent; box-shadow: var(--qm-tap-in); }
/* 选中态 = 强调底色（识别度）+ 向外凸起（触感）+ 强调描边（钉边界）。
   实测：纯凸起在 ~24px 真实行高下光影铺不开、几乎看不出选中；纯内陷方向与
   参考图相反（参考图里所有「激活」都是凸的）。 */
html .tree-row.is-selected {
  background: var(--qm-accent-soft); color: var(--qm-accent-ink);
  border-color: var(--qm-accent); border-radius: 10px;
  box-shadow: var(--qm-tap);
}

/* ---------- 9. 表单 / 文本域 ---------- */
html input[type="text"],
html select,
html .prop-input {
  background: var(--qm-surface-2);
  border-color: var(--qm-line);
  box-shadow: var(--qm-tap-in);
}
/* V0.0.45：输入类的 focus 描边**显式声明**，不再依赖 layout.css 的 `:focus` 反超 ——
   去属性后那层反超不再发生，若不显式写会退回「focus 无色变」（实测 A/B 各 4 处差异）。
   取色与下方 `.prop-note:focus` 一致（--qm-accent），符合 soft 的既有意图。 */
html input[type="text"]:focus,
html select:focus,
html .prop-input:focus { border-color: var(--qm-accent); }
html .prop-note {
  background: var(--qm-surface-2);
  border-color: var(--qm-line);
  box-shadow: var(--qm-tap-in);
}
html .prop-note:focus { box-shadow: none; border-color: var(--qm-accent); }

/* ---------- 10. 浮层：暗影 + 外圈 ring ----------
   浮层不套白高光柔光 —— 实测：弱白高光就把弹窗左缘梯度从 84.8 打到 42.9，
   完整对称双影只剩 20.0（并在遮罩上留 +68.9 外亮晕）。白高光属于「内嵌元素」的
   语言（按钮/卡片），浮层与背景是**不同材质的分离关系**，靠暗影 + 描边区分。
   影色引用皮肤 --qm-shadow-dark 并**叠层**以累积浓度（浅色皮肤 α.15 ×3 ≈ .386；
   深色皮肤 α.62 ×3 ≈ .945）；ring 用皮肤描边色 --qm-line（深色皮肤下为白 α.14）。 */
html #scrim { background: var(--qm-scrim); }
html .layer.modal {
  box-shadow: var(--qm-layer-shadow);
}
html .layer.popover,
html #ctxMenu {
  box-shadow: var(--qm-pop-shadow);
}
html .sup-qr-img { box-shadow: var(--qm-qr-shadow); }
html .toast {
  box-shadow: var(--qm-pop-shadow);
}

/* ---------- 11. 皮肤色块 ----------
   皮肤色块**刻意不在此处写样式**：verify.py §P0-3 L5 规定组件 CSS 不得出现
   `.skin-` 前缀的选择器（换肤只靠覆盖变量），故其外观由色块自身与其容器承担。 */
