/* ============================================================================
   user-page.css —— C 端「配置中心」的**设计层**（手写，不是生成物）
   ============================================================================
   `user.css` 是共享工作台皮肤（深色、给口播线用的，生成物不要手改）。
   这一页是给商家用的配置页，需要自己的样子，所以在这里**覆盖令牌 + 重排结构**。

   ## 这一页的视觉语言（2026-10-09 重做）

   上一版是典型的"SaaS 卡片墙"：左轨列一遍十个入口、顶部 tab 再列一遍同样十个，
   内容切成一张张同样的圆角白卡、同样的浅灰阴影，主色是每个仪表盘都在用的蓝。
   用户的原话是"太垃圾、不优雅、不符合现代审美"。重做时定下四条：

   1. **颜色只表示状态，不表示品牌**。界面本身是墨色（近黑的文字与主按钮），
      唯一的彩色留给"这台机器现在能不能开播"（绿/橙/红）。硬件面板就是这样：
      外壳是中性灰，只有信号灯有颜色。这条把"默认蓝"这个最大众的脸去掉了。
   2. **导航只有一份**（左轨）。顶部那条 tab 栏整条删掉 —— 同一件事说两遍
      不是"信息丰富"，是没想清楚哪个是主。
   3. **结构用细线和留白表达，不用重复的卡片**。所以 `.card` 在这一页被拉平：
      没有边框、没有阴影、没有圆角，只有一条上分隔线；页面是"一张工作表"，
      不是"一堆卡"。
   4. **一屏一个英雄元素**：顶部状态条（`● 可以开播` + 机器/有效期/余额）。
      它是全页最该先看到的一句话，其余地方保持安静。

   另外：数字用等宽数字（`tabular-nums`），中文正文 14.5px/1.7（中文比拉丁字母
   需要更大字号与行高），焦点环可见，`prefers-reduced-motion` 尊重系统设置。
   ========================================================================== */

/* ── 覆盖令牌：**两层都要写** ────────────────────────────────────────────────
   `tokens.primitives.css` 定 `--p-*` 原始色板，`workbench.tokens.css` 里 `--s-*`（语义）
   指向它、`--bg/--panel/…` 又指向 `--s-*`。而别名是**在 `:root` 上算好的**
   （自定义属性的 `var()` 在声明它的元素上就替换掉了），所以只改 `--s-color-*`
   不会让继承下来的 `--bg` 变色；反过来 `studio.css` 里有几处**直接用** `--s-color-primary`
   （按钮渐变），只改 `--bg` 那层又会漏。结论：两层一起写。 */
body.c-end { background: #f4f5f7; }

.studio {
  color-scheme: light;
  /* S 层（语义）—— 主色就是墨色：颜色留给状态，不留给品牌 */
  --s-color-bg: #eef4fb;
  --s-color-surface: #ffffff;
  --s-color-surface-2: #f7faff;
  --s-color-sunken: #e8f0fa;
  --s-color-border: #dbe6f3;
  --s-color-border-strong: #c5d5e8;
  --s-color-text: #1e293b;
  --s-color-text-muted: #64748b;
  --s-color-primary: #4f46e5;
  --s-color-primary-soft: #4338ca;
  --s-color-accent: #4f46e5;
  --s-color-success: #127a5b;
  --s-color-danger: #c0392b;
  --s-color-info: #1d4ed8;      /* 信息蓝：分类标识用（观众页四类弹幕各一个色相）。同值在 Ui.kt 的 INFO */
  /* T 层（兼容别名）：共享皮肤里所有规则的入口 */
  --bg: #eef4fb;
  --panel: #ffffff;
  --panel2: #f7faff;
  --line: #dbe6f3;
  --text: #1e293b;
  --muted: #64748b;
  --primary: #4f46e5;
  --accent: #4f46e5;
  --ok: #127a5b;
  --warn: #b26a00;
  --err: #c0392b;
  --info: #1d4ed8;     /* 信息蓝：分类标识用。同值在 Ui.kt 的 INFO，改一处必改另一处 */
  --r: 10px;          /* 唯一一档圆角：只给"可点/可输入"的东西 */

  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "HarmonyOS Sans SC",
    "Source Han Sans SC", "Microsoft YaHei", "Noto Sans SC", system-ui, sans-serif;
  font-size: 14.5px;
  line-height: 1.7;
  background: var(--bg);
  color: var(--text);
  /* 应用外壳：左轨与顶栏固定，只有内容区滚动（原来是整页一起滚，
     十个 tab 的页面滚到下面就看不到自己在哪一栏了）。 */
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  /* 内容区的宽度**只有这一个数**：顶栏 / 状态条 / 内容三者都按它对齐
     （`.main` 那一条会把左右留白加回去，见下）。 */
  --page-content: 1120px;
  /* ⚠️ 列**和行**都要写死，少写一行就有真故障（2026-10-12 用户：
     「右侧如果超出一个屏幕，会发现没有滚动条，导致右边无法下拉看更多内容，甚至分页都被挡住」）。
     行不写时它是 `auto` —— 按**内容**撑高（实测 900px 高的窗口里，那一行高 2017px），
     `.main` 于是跟着变得和内容一样高（`scrollHeight === clientHeight`）**永远不滚**，
     多出来的部分被外层 `overflow:hidden` 裁掉：分页条就那样没了。行钉成容器高之后，
     `.shell`/`.main` 才有确定的剩余高度可分，滚动条才会出现在 `.main` 上。
     ⚠️ 窄屏那条（`@media max-width: 900px`）本来就写了行、桌面这条漏了 —— 所以这个毛病只在宽屏上出现。
     列从 208 收到 184（用户同日："左侧菜单宽度可以再缩小一点"）：最长的菜单名是 5 个汉字
     （「商品与描述」≈68px），184 下留给文字的宽度还有 117px，够。 */
  grid-template-columns: 184px minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
}

/* 未登录时没有左轨（不给一份点不动的导航）。
   `overflow-y: auto`：登录框在矮窗口里放不下时**要能滚** —— 外层 `.studio` 是 `overflow:hidden`，
   不放开这一条，放不下的部分就是真的看不到（和右边内容区是同一个毛病，同一个修法）。 */
.studio.is-gate {
  display: block; grid-template-columns: none; grid-template-rows: none;
  overflow-y: auto;
}

.mark { width: 22px; height: 22px; flex: 0 0 auto; color: var(--text); }
.mark-txt { font-size: 15px; font-weight: 650; letter-spacing: .01em; white-space: nowrap; }
.mark-txt em { font-style: normal; font-weight: 450; color: var(--muted); margin-left: 7px; }

/* ── 左轨：**唯一一份导航** ─────────────────────────────────────────────── */
.studio .rail {
  display: flex; flex-direction: column; gap: 2px; align-items: stretch;
  padding: 16px 12px 20px; overflow-y: auto;
  background: var(--panel); border-right: 1px solid var(--line);
}
.studio .rail-group {
  padding: 0 8px; margin: 16px 0 6px;
  font-size: 11.5px; font-weight: 500; color: var(--muted); letter-spacing: .04em;
}
.studio .rail-group:empty { height: 4px; margin: 0; padding: 0; }
.studio .rail-btn {
  display: flex; align-items: center; gap: 10px; width: 100%; height: 34px;
  padding: 0 8px; border: 0; border-radius: 7px; cursor: pointer;
  background: transparent; color: var(--text);
  font: inherit; font-size: 13.5px; line-height: 1; text-align: left;
}
.studio .rail-ico { width: 17px; height: 17px; flex: 0 0 auto; color: var(--muted); }
.studio .rail-txt { white-space: nowrap; }
.studio .rail-btn:hover { background: color-mix(in srgb, var(--text) 5%, transparent); }
/* 选中态用**墨色 + 左侧墨条**，不用彩色药丸：选中不是"状态"，不该占用颜色的语义 */
.studio .rail-btn.on {
  background: color-mix(in srgb, var(--text) 7%, transparent);
  font-weight: 600;
  box-shadow: inset 2px 0 0 var(--text);
}
.studio .rail-btn.on .rail-ico { color: var(--text); }

/* ── 右侧：顶栏 + 状态条 + 内容 ─────────────────────────────────────────── */
.studio .shell { display: flex; flex-direction: column; min-width: 0; height: 100%; }
.studio .bar {
  display: flex; align-items: center; flex: 0 0 auto;
  height: 56px; padding: 0 24px;
  background: var(--panel); border-bottom: 1px solid var(--line);
}
/* 顶栏 / 状态条 / 内容三者**左边缘必须对齐**：外壳全宽（背景与分隔线要通到底），
   但里面的内容共用一条 max-width 与居中规则 —— 否则内容会比顶栏缩进几十像素，
   看着像没对齐（实测第一版就是这样）。 */
.studio .bar-in, .studio .strip-in {
  display: flex; align-items: center; gap: 12px;
  width: 100%; max-width: var(--page-content); margin-inline: auto;
}
.studio .bar-brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: inherit; }
.studio .bar-brand:hover .mark-txt { text-decoration: underline; text-underline-offset: 3px; }
.studio .who {
  font-size: 13px; color: var(--muted);
  font-variant-numeric: tabular-nums;   /* 手机号别抖 */
}
.studio .grow { flex: 1; }

/* 状态条：全页的"英雄元素"，一行回答"现在能不能开播"。 */
.studio .strip {
  flex: 0 0 auto; padding: 11px 24px;
  background: var(--panel); border-bottom: 1px solid var(--line); font-size: 13px;
}
.studio .strip .dot {
  width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto;
  background: var(--muted); box-shadow: 0 0 0 3px color-mix(in srgb, var(--muted) 18%, transparent);
}
.studio .strip-lead { font-size: 13.5px; font-weight: 620; white-space: nowrap; }
.studio .strip.is-ok .dot { background: var(--ok); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok) 18%, transparent); }
.studio .strip.is-ok .strip-lead { color: var(--ok); }
.studio .strip.is-warn .dot { background: var(--warn); box-shadow: 0 0 0 3px color-mix(in srgb, var(--warn) 20%, transparent); }
.studio .strip.is-warn .strip-lead { color: var(--warn); }
.studio .strip.is-err .dot { background: var(--err); box-shadow: 0 0 0 3px color-mix(in srgb, var(--err) 18%, transparent); }
.studio .strip.is-err .strip-lead { color: var(--err); }
.studio .strip-gap { flex: 1; }
.studio .fact { color: var(--muted); white-space: nowrap; }
.studio .fact b {
  color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums;
  margin-left: 3px;
}
.studio .fact b.err { color: var(--err); }
.studio .unit { color: var(--muted); margin-left: 4px; }

.studio .bar-note {
  display: flex; align-items: center; gap: 10px; flex: 0 0 auto;
  padding: 10px 24px; font-size: 13px;
  background: color-mix(in srgb, var(--ok) 8%, var(--panel));
  border-bottom: 1px solid var(--line);
}
.studio .bar-note.err { background: color-mix(in srgb, var(--err) 7%, var(--panel)); }

/* ── 内容区：一张**工作表**，不是一堆卡片 ──────────────────────────────── */
.studio .main {
  flex: 1; min-height: 0; overflow-y: auto;
  /* 左右 24px 是**内容与分割线之间的间隔**（2026-10-12 用户："左侧的菜单和右边的页面之间应该要有一个间隔…
     右侧页面的内容不要紧挨着菜单右边的分割线。浏览器最大化的时候没有问题，在浏览器宽度不够的情况下就会紧挨着"）。
     真因是原来这里左右**不留 padding**、只靠 `max-width: 1120px` 居中：窗口宽时居中天然余出几十像素，
     窗口一窄余量就归零，内容直接贴在 `border-right` 上；顺带还与顶栏错位 24px
     （顶栏有 padding、这一层没有 —— 原来注释里"三者天然对齐"只在宽屏成立）。实测 1100px：
     内容 x=208、顶栏内容 x=232、距分割线 0px。修法是**把留白补进来、并让 max-width 让出同样 48px**
     —— 内容区仍然是 1120（用户 2026-09 否过"框一层再限制一次"导致可用宽度变小）。 */
  padding: 4px 24px 72px;
  width: 100%; max-width: calc(var(--page-content) + 48px); margin-inline: auto;
}

/* `.card` 在这一页被**拉平**：无边框、无阴影、无圆角，只有一条上分隔线。
   （共享皮肤里它是"深色卡片"；那套在浅色工作表上就是"卡片墙"。） */
.studio .card {
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .04);
  padding: 18px 16px; margin: 0 0 14px;
}
.studio .card:first-child { border-top: 1px solid var(--line); }
/* 概览：两块内容并排，中间一条竖细线（结构用线表达，不用"再来一张卡"） */
.studio .board { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.studio .board > .card { border-top: 0; padding: 22px 0 6px; }
.studio .board > .card + .card { padding-left: 28px; border-left: 1px solid var(--line); }
.studio .board > .card:first-child { padding-right: 28px; }
.studio .sub {
  background: var(--panel2); border: 1px solid var(--line);
  border-radius: var(--r); padding: 14px 16px; margin-top: 12px;
}

/* 章节标题 */
.studio .ch {
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 14px; padding: 0;
}
.studio .ch b, .studio h3 { font-size: 15px; font-weight: 650; letter-spacing: .01em; }
.studio h3 { margin: 0 0 6px; }
/* 章节之间空一行（`.ch.gap` 原来是"分组小标题"，现在只负责上方留白） */
.studio .ch.gap { margin-top: 26px; }

/* ── 键值行 / 字段行 ───────────────────────────────────────────────────── */
.studio .kv {
  display: flex; align-items: baseline; gap: 12px;
  padding: 7px 0; border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
}
.studio .kv:last-child { border-bottom: 0; }
.studio .kv > span:first-child {
  flex: 0 0 auto; min-width: 84px; color: var(--muted); font-size: 13px;
}
.studio .kv b { font-weight: 600; font-variant-numeric: tabular-nums; }
.studio .big { font-size: 20px; font-weight: 650; }

/* 配置概况：一行一项 —— 计数在左（对齐），说明在右（弱） */
/* ⚠️ `.facts` 的列是 `72px / 44px / 1fr` —— **中间那 44px 是给"一个数字"的**（概览页的计数）。
   往里放**长文本**（卖点/优惠/说明）会得到"一个字一行"的竖排（2026-10-10 用户实测）。
   长文本请用 `.kv`（标签 + 值）。 */
.studio .facts { list-style: none; margin: 0; padding: 0; }
.studio .facts li {
  display: grid; grid-template-columns: 72px 44px minmax(0, 1fr);
  align-items: baseline; gap: 12px;
  padding: 9px 0; border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
}
.studio .facts li:last-child { border-bottom: 0; }
.studio .fact-label { font-size: 13.5px; }
.studio .fact-count {
  font-size: 15px; font-weight: 650; font-variant-numeric: tabular-nums;
  text-align: right;
}
.studio .facts li.zero .fact-count { color: var(--muted); font-weight: 500; }
.studio .fact-hint { color: var(--muted); font-size: 12.5px; }

/* ── 表单 ─────────────────────────────────────────────────────────────── */
.studio .srow {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 10px 0;
}
.studio .srow.stack { flex-direction: column; align-items: stretch; gap: 9px; }
/* ⚠️ `:not([type="checkbox"])` 不只是为了排除复选框：共享皮肤里有一条
   `.studio textarea, .studio input, .studio select { font-size: 12px }`（两个类 + 一个元素），
   比裸的 `.studio input`（一个类 + 一个元素）更具体 —— 不加这一级，字号永远被它压住。 */
.studio input:not([type="checkbox"]), .studio select, .studio textarea {
  height: 36px; padding: 0 11px;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--r);
  font: inherit; font-size: 13.5px;
}
/* 竖排（登录那种一行一格的）：**必须解掉上面那条 `flex: 1 1 140px`** ——
   在 `flex-direction: column` 的容器里，那个 basis 是**高度**，输入框会被抻成 140px 高。 */
.studio .srow.stack > input, .studio .srow.stack > select, .studio .srow.stack > textarea {
  flex: 0 0 auto; height: 42px; font-size: 14.5px;
}
.studio textarea { height: auto; padding: 9px 11px; line-height: 1.65; resize: vertical; }
.studio .srow.stack > textarea { height: auto; }
.studio select { padding-right: 8px; }
.studio .srow > input, .studio .srow > select, .studio .srow > textarea { flex: 1 1 140px; min-width: 0; }
/* 数字格子（库存/语速/套数）不该跟文本输入抢宽度：一个三位数占半屏看着很傻 */
.studio .srow > input[type="number"] { flex: 0 1 104px; }
.studio .srow > .primary, .studio .srow > .ghost { flex: 0 0 auto; }
.studio input::placeholder, .studio textarea::placeholder { color: #9aa1ac; }
.studio input:focus, .studio select:focus, .studio textarea:focus {
  outline: none; border-color: var(--text);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--text) 12%, transparent);
}
.studio input:disabled, .studio select:disabled, .studio textarea:disabled {
  background: var(--panel2); color: var(--muted); cursor: not-allowed;
}

.studio button { font: inherit; cursor: pointer; }
.studio button.primary {
  height: 36px; padding: 0 16px; border: 1px solid transparent; border-radius: var(--r);
  background: var(--text); color: #fff; font-size: 13.5px; font-weight: 600;
}
.studio .srow.stack .primary { height: 42px; font-size: 14.5px; }
.studio button.primary:hover:not(:disabled) { background: #000; }
.studio button.primary:disabled { background: #c3c8d0; color: #f4f5f7; cursor: not-allowed; }
/* `ghost` 既是按钮也是链接（顶栏里的"官网"就是个链接）—— 两边的样式必须一样，
   否则同一个位置换个标签就换了长相 */
.studio button.ghost, .studio a.ghost {
  display: inline-flex; align-items: center;
  height: 30px; padding: 0 11px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel); color: var(--text); font-size: 13px; text-decoration: none;
}
.studio button.ghost:hover:not(:disabled), .studio a.ghost:hover {
  border-color: var(--s-color-border-strong); background: var(--panel2);
}
.studio button.ghost:disabled { color: var(--muted); cursor: not-allowed; }
.studio button.link {
  border: 0; background: none; padding: 0; color: var(--text);
  font-size: 13px; text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--text) 30%, transparent);
}
.studio button.link:hover { text-decoration-color: var(--text); }
.studio .chk { display: inline-flex; align-items: center; gap: 7px; font-size: 13.5px; white-space: nowrap; }
.studio .chk input { height: auto; width: 15px; height: 15px; accent-color: var(--text); }

/* 焦点可见（键盘用户）：所有可点/可输入的东西统一墨色环 */
.studio :focus-visible, .gate :focus-visible {
  outline: 2px solid var(--text); outline-offset: 2px;
}

/* ── 表格：细线，不要斑马纹与重边框 ───────────────────────────────────────
   2026-10-10 用户口径："所有的列表，尤其是话术列表为例，不应该提供横向滚动，列头要收缩，
   文字要写了固定几个后就省略，鼠标移动停留后显示 hint。"
   ⇒ 三条落点（**四条口径一处落地**，各表只声明列宽与"哪一列在窄屏隐藏"）：
   ① `table-layout: fixed` + 每个表自己的 `<colgroup>` ⇒ 列宽是我们定的，表格**永远等于容器宽**，
      **不出现横向滚动条**（原来窄屏是 `.tblwrap { overflow-x: auto }` + `min-width: 620px`，
      也就是"要拖才能看全"，用户明确不要）；
   ② 单元格 `overflow:hidden + text-overflow:ellipsis + white-space:nowrap` ⇒ 溢出不换行、
      不撑宽列（真撑了 fixed 也会压回列宽）。**列头同样处理**：列头文字过长在 fixed 布局下
      不会撑宽，只会被挤出省略号；
   ③ 省略是**两段**：模板里按字数 `clip(...)`（"写了固定几个后就省略"，省略位置稳定，
      不随窗口宽窄改变）+ 这里的宽度兜底；全文一律走 `:title`（鼠标停留就是浏览器原生 hint，
      不自绘 tooltip —— 自绘的要处理定位/层级/触屏，而这里只需要"看得见全文"）。 */
.studio .tbl { width: 100%; border-collapse: collapse; font-size: 13.5px; table-layout: fixed; }
.studio .tbl th, .studio .tbl td {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.studio .tbl th {
  text-align: left; font-weight: 500; font-size: 12.5px; color: var(--muted);
  padding: 0 12px 8px 0; border-bottom: 1px solid var(--line);
}
.studio .tbl td {
  padding: 11px 12px 11px 0; border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
  vertical-align: middle;
}
.studio .tbl tr:last-child td { border-bottom: 0; }
/* 未支持的平台整行压暗（"看起来都能配"是最坏的一类绿） */
.studio .tbl tr.off td { color: var(--muted); }
.studio .tbl tr.off .chip { opacity: .8; }
.studio .tbl tr.off input { cursor: not-allowed; }

/* ── 标签 / 提示 / 错误 ────────────────────────────────────────────────── */
.studio .chip {
  display: inline-flex; align-items: center; height: 21px; padding: 0 8px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel); color: var(--muted);
  font-size: 12px; font-weight: 500; white-space: nowrap;
}
.studio .chip.ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 35%, transparent); background: transparent; }
.studio .chip.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 35%, transparent); background: transparent; }
.studio .muted { color: var(--muted); }
.studio .hint { margin: 5px 0; color: var(--muted); font-size: 13px; line-height: 1.7; }
.studio .err, .studio .hint.err { color: var(--err); }
/* 「要重新训练」用的橙色（2026-10-12）：三张表的状态格与矩阵格子共用 `packStatusCls`，
   与 `.err` 同一形状 —— 绿=能用 / 橙=要你动手 / 红=失败。 */
.studio .warn, .studio .hint.warn { color: var(--warn); }
.studio .tag {
  display: inline-flex; align-items: center; height: 19px; padding: 0 7px;
  border-radius: 5px; background: var(--panel2); color: var(--muted); font-size: 11.5px;
}
.studio .link, .studio a { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }

/* ── 「?」：长说明收进折叠，点开才看 ───────────────────────────────────── */
.studio .hint-row { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin: 5px 0; }
.studio .hint-row > p.hint { margin: 0; }
.studio .hint-row > details.why { margin: 0; }
.studio .hint-row > details.why[open] { flex-basis: 100%; }
.studio details.why { margin: 6px 0; }
.studio details.why > summary {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%; cursor: pointer; list-style: none;
  border: 1px solid var(--line); color: var(--muted); font-size: 11.5px;
}
.studio details.why > summary::-webkit-details-marker { display: none; }
.studio details.why > summary:hover { border-color: var(--s-color-border-strong); color: var(--text); }
.studio details.why[open] > summary { color: var(--text); border-color: var(--text); }
.studio details.why > p {
  margin: 8px 0 0; padding-left: 11px; border-left: 2px solid var(--line);
  color: var(--muted); font-size: 13px; line-height: 1.75;
}

/* ── 常见问题：细线列表，不要卡片套卡片 ─────────────────────────────────── */
.studio details.faq { border-bottom: 1px solid color-mix(in srgb, var(--line) 60%, transparent); }
.studio details.faq:last-of-type { border-bottom: 0; }
.studio details.faq > summary {
  display: flex; align-items: center; gap: 9px; cursor: pointer; list-style: none;
  padding: 11px 0; font-size: 13.5px; font-weight: 550;
}
.studio details.faq > summary::-webkit-details-marker { display: none; }
.studio details.faq > summary::before {
  content: "+"; flex: 0 0 auto; width: 15px; color: var(--muted);
  font-weight: 400; font-size: 15px; line-height: 1; text-align: center;
}
.studio details.faq[open] > summary::before { content: "–"; color: var(--text); }
.studio details.faq > p {
  margin: 0 0 14px 24px; color: var(--muted); font-size: 13px; line-height: 1.8;
  max-width: 68ch;                       /* 一行别太长（中文 68 字以内还能读） */
}

/* ── 未登录 / 窗口不对：居中的单一动作区 ──────────────────────────────── */
.gate {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 100vh; min-height: 100dvh; padding: 48px 20px;
  position: relative;
}
/* 回官网的路放**左上角**（登录页的通用位置），而不是塞进表单里 —— 它不是这一步的动作，
   是"走错页了"的退路。做成实心可点的链接，不靠"品牌 logo 能不能点"让人猜。 */
.gate .back {
  position: absolute; top: 22px; left: 24px;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 6px 12px; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--panel); color: var(--text); font-size: 13px; text-decoration: none;
}
.gate .back:hover { border-color: var(--s-color-border-strong); background: var(--panel2); }
/* ⚠️ 选择器要带 `.gate`（两个类）：共享皮肤里那条 `.studio a { text-decoration: underline }`
   是一个类 + 一个元素，单个 `.gate-brand` 压不过它 —— 品牌字下面会凭空多一条下划线。 */
.gate .gate-brand {
  display: flex; align-items: center; gap: 10px; margin-bottom: 26px;
  text-decoration: none; color: inherit;
}
.gate .gate-brand:hover .mark-txt { text-decoration: underline; text-underline-offset: 3px; }
/* ⚠️ 用 `.studio .panel.login` 这个选择器：共享皮肤里有一条
   `.studio .panel.login { max-width: 620px }`（三个类），比 `.gate .login`（两个类）更具体 ——
   不改这一级，登录框永远宽 620。 */
.studio .panel.login {
  width: 100%; max-width: 380px; margin: 0; padding: 0;
  background: transparent; border: 0; border-radius: 0; box-shadow: none;
  display: block;
}
.studio .panel.login h3 { font-size: 19px; font-weight: 650; margin: 0 0 7px; }
.studio .panel.login .hint { font-size: 13.5px; }
.studio .panel.login .srow { margin: 16px 0 10px; }
.studio .panel.login button.primary { margin-top: 4px; }
.studio .panel.login .err { margin: 8px 0 0; font-size: 13px; }

/* 图形验证码（2026-10-22）：输入框 + 服务端自产 SVG，点图换一张。 */
.studio .panel.login .captcha-row {
  display: flex; gap: 8px; align-items: stretch; width: 100%;
}
.studio .panel.login .captcha-row input { flex: 1 1 auto; min-width: 0; }
.studio .panel.login .captcha-img {
  flex: 0 0 118px; height: 44px; overflow: hidden; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r);
  background: #fff; display: flex; align-items: center; justify-content: center;
}
.studio .panel.login .captcha-img svg { width: 108px; height: 40px; display: block; }

/* ── v-cloak / noscript ────────────────────────────────────────────────── */
[v-cloak] { display: none !important; }
.noscript {
  margin: 40px auto; max-width: 520px; padding: 18px 20px;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  font-size: 13.5px;
}

/* ── 窄屏：左轨变成顶部横向滚动条 ─────────────────────────────────────── */
@media (max-width: 900px) {
  .studio { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  .studio .rail {
    flex-direction: row; align-items: center; gap: 4px;
    padding: 8px 10px; overflow-x: auto; overflow-y: hidden;
    border-right: 0; border-bottom: 1px solid var(--line);
  }
  .studio .rail-group { display: none; }
  .studio .rail-btn { width: auto; flex: 0 0 auto; padding: 0 10px; }
  .studio .bar { height: 48px; padding: 11px 14px; flex-wrap: wrap; gap: 8px; }
  /* 窄屏省一行：品牌在顶栏里是重复信息（左轨就在上面），只留身份与退出 */
  .studio .bar-brand { display: none; }
  /* 状态条**换行**，不要横向滚动：`nowrap` 的项会把"可以开播"挤成一列一个字 */
  .studio .strip { padding: 10px 14px; overflow: visible; }
  .studio .strip-in { flex-wrap: wrap; gap: 4px 12px; }
  .studio .strip-gap { display: none; }
  .studio .fact { font-size: 12.5px; }
  .studio .main { padding: 2px 14px 56px; }
  .studio .board { grid-template-columns: minmax(0, 1fr); }
  .studio .board > .card + .card {
    padding-left: 0; border-left: 0; border-top: 1px solid var(--line);
  }
  .studio .board > .card:first-child { padding-right: 0; }
  .studio .facts li { grid-template-columns: 64px 36px minmax(0, 1fr); gap: 8px; }
  /* 表格在窄屏**不横向滚动**（用户 2026-10-10 明确不要），而是**按列的轻重隐藏**：
     `t-sm` = 到这一档（≤900px）就隐藏的次要列；`t-xs` = 更窄（≤640px）才隐藏的再次要列。
     两档都在模板里逐列标好（见各表的 `<colgroup>` / `<th>`）。
     七列挤进 390px 的结果只可能是"每列一个字"，那比少看一列更糟。 */
  .studio .tbl .t-sm { display: none; }
  /* 兜底：`display:none` 在 <col> 上的支持按规范应移除整列，这里再把宽度压成 0 ——
     两重保险的成本是一次声明，而"少看一列"与"整表横向滚动"的差别就在这里。 */
  .studio .tbl col.t-sm { width: 0; }
  /* 抽屉在窄屏占满整屏（半屏抽屉在手机上只剩一条缝） */
  .studio .drawer { width: 100%; }
}

/* 新建/编辑话术的**按需表单**（2026-10-09：列表才是主体，表单点了才出现）。
   用左侧一道细线 + 稍暗的底表示"这是从列表里长出来的一块"，不再另起一张卡片
   （卡片套卡片会让"哪一层是页面、哪一层是表单"变得看不出来）。 */
.studio .subform {
  margin: 4px 0 14px; padding: 12px 14px;
  border-left: 2px solid var(--s-color-primary);
  background: var(--panel2); border-radius: var(--w-r-sm);
}
.studio .subform .ch { margin-bottom: 8px; }

/* ── 商品 / 套餐 那一栏：操作列 / 空态 / 分页 / 抽屉（2026-10-10）───────────────
   用户口径（逐条）："1、缺少删除按钮 2、缺少修改按钮 3、没有数据的时候也要显示列头
   4、没有数据的时候也要显示分页 5、一页最多20笔 6、编辑区域考虑采用抽屉交互"。
   样式口径沿用这一页的四条（颜色只表示状态 / 细线与留白 / 一屏一个英雄元素 /
   动效只回应用户动作）：所以分页与抽屉都是**细线 + 墨色**，没有彩色装饰。 */

/* 操作列：宽度由各表的 `<colgroup>` 定（不再写死 208px —— 宽屏时那一列会白占一大块，
   窄屏时又把别的列挤没）。这里只管对齐与不折行。 */
.studio .tbl th.act, .studio .tbl td.act { text-align: right; white-space: nowrap; }
.studio .tbl td.act button + button { margin-left: 12px; }
/* 删除是**破坏性**动作：唯一的彩色留给它（这一页的规则是"颜色只表示状态"，
   而"这条会被删掉"正是一种状态）。hover 才变色，平时仍是墨色链接。 */
.studio .tbl button.link.danger:hover { color: var(--err); text-decoration-color: var(--err); }

/* 空态：表头**留着**（用户口径 3），所以这里只是一行说明，不是"整块消失" */
.studio .tbl td.empty {
  padding: 22px 0; color: var(--muted); font-size: 13.5px; text-align: center;
  border-bottom: 0;
}

/* 分页条：**常驻**（用户口径 4）——没有数据时显示「共 0 条 · 第 1/1 页」且两个按钮禁用 */
.studio .pager {
  display: flex; align-items: center; gap: 14px;
  margin-top: 12px; padding-top: 10px;
  border-top: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
  font-size: 13px;
}
.studio .pager .muted { margin-right: auto; }   /* 「共 N 条 · 第 x/y 页」在左，翻页在右 */
.studio .pager button.link:disabled { color: #c3c8d0; cursor: not-allowed; text-decoration: none; }

/* ── 列表筛选行（2026-10-10 用户："外面列表也没有看到筛选条件"）───────────────
   所有列表同一形状：关键词框 + 各列表自己的下拉 + 「清除筛选」+ 右边「筛选后/全部」。
   细线 + 墨色，与这一页的四条视觉口径一致（颜色只表示状态）。 */
.studio .filterbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 10px 0 12px; padding: 0 0 10px;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
}
/* ⚠️ 必须显式把 `width` 从 base 的 `select{width:100%}` 里抢回来 —— 否则每个控件各占一整行，
   筛选行会立成三行（实测截图：关键词一行、分组一行、状态一行，列表被推到屏幕外）。 */
.studio .filterbar input {
  flex: 0 0 auto; width: 220px; height: 32px; font-size: 13.5px;
}
.studio .filterbar select {
  flex: 0 0 auto; width: auto; min-width: 120px; max-width: 220px;
  height: 32px; font-size: 13.5px;
}
.studio .filterbar .muted { margin-left: auto; font-size: 12.5px; white-space: nowrap; }

/* 分组多选（抽屉里）：一行 chip，选中的加粗 —— 不用 select multiple（那东西在中文上很难点） */
.studio .chips { display: flex; flex-wrap: wrap; gap: 10px 14px; }
.studio .chips .chk { font-size: 13.5px; }

/* 管理分组面板：一行一个分组（名字 + 来源 chip + 右侧动作） */
.studio .group-list { margin: 4px 0 10px; }
.studio .group-row {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 0; border-bottom: 1px solid color-mix(in srgb, var(--line) 45%, transparent);
  font-size: 13.5px;
}
.studio .group-row:last-child { border-bottom: 0; }
.studio .group-row .grow { flex: 1; }

/* ── 抽屉（新增 / 修改商品共用）────────────────────────────────────────────
   `position: fixed` + 右侧滑入：它盖在当前页上，但不改变页面本身的布局
   （用整页跳转/弹窗都会把"我刚才在看哪一行"丢掉）。宽度在窄屏退成整屏。 */
.studio .drawer-mask {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(16, 18, 22, .28);
}
.studio .drawer {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 41;
  /* 2026-10-21 用户口径：默认抽屉宽度**加倍**（460 → 920）—— 表单字段多，
     460 里「参考文本 / 规格 / 多选」都要来回滚；窄屏仍退成整屏（见 @media 900px）。 */
  width: min(920px, 100%); display: flex; flex-direction: column;
  background: var(--panel); border-left: 1px solid var(--line);
  box-shadow: -18px 0 40px rgba(16, 18, 22, .12);
}
.studio .drawer-hd {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 16px 18px; border-bottom: 1px solid var(--line);
}
.studio .drawer-hd b { font-size: 15px; font-weight: 650; }
.studio .drawer-bd { flex: 1; overflow-y: auto; padding: 16px 18px; }
.studio .drawer-ft {
  display: flex; justify-content: flex-end; gap: 10px;
  padding: 14px 18px; border-top: 1px solid var(--line);
}
/* 抽屉里的字段：一行一个（标签在上、控件在下）——这里比表格宽，不需要再挤成两列 */
.studio .drawer .field { display: block; margin: 0 0 14px; }
.studio .drawer .field > span { display: block; margin-bottom: 5px; color: var(--muted); font-size: 12.5px; }
.studio .drawer .field input { width: 100%; }
.studio .drawer .frow { display: flex; gap: 12px; }
.studio .drawer .frow .field { flex: 1; min-width: 0; }
.studio .drawer .chk { margin: 4px 0 10px; }
.studio .drawer .hint { margin: 0; }

/* 关键词规则的「匹配方式」：两档竖排，每档名后面跟一句人话解释。
   ⚠️ 下面四条覆盖**每一条都是必须的**，少一条就回到"挤成一行、读不断"：
   1) `.drawer .field input` 是 `width: 100%`（那是给输入框的）—— 不覆盖，单选钮会被撑满整行；
   2) `.chk` 默认 `white-space: nowrap`（给"开关"那种两三个字用的）—— 不覆盖，解释会被截掉；
   3) 名字与解释要**分两行**：解释是 `display: block` 顶到下一行，不然跟名字连成一句；
   4) 名字用正文色、解释用灰色：两块同色同字重时，眼睛分不出哪是选项、哪是注解。 */
.studio .drawer .field.match-mode input[type="radio"] {
  width: 15px; height: 15px; flex: 0 0 auto; margin-top: 2px;
}
.studio .drawer .field.match-mode .chk {
  margin: 0; white-space: normal; align-items: flex-start;
  font-size: 13.5px; color: var(--text);
}
.studio .drawer .field.match-mode .chk em {
  display: block; margin-top: 1px; font-style: normal;
  color: var(--muted); font-size: 12.5px; line-height: 1.5;
}

/* 渲染预览（商品信息提示词）：这是**要交给 AI 的原文**，所以用等宽字体 + 原样换行 ——
   排版成好看的正文反而会让人看不出"到底塞进去了什么"。限高滚动：提示词可以很长，
   但抽屉里不能让它把保存按钮顶出屏幕。 */
.studio .preview-box {
  margin: 6px 0 0; padding: 10px 12px; max-height: 260px; overflow: auto;
  background: var(--panel2); border: 1px solid var(--line); border-radius: var(--r);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; line-height: 1.55; white-space: pre-wrap; word-break: break-word;
  color: var(--text);
}

/* 动效只有"回应用户动作"这一种，且尊重系统设置 */
@media (prefers-reduced-motion: reduce) {
  .studio *, .gate * { transition: none !important; animation: none !important; }
}

/* ── 训练页的选择区与只读正文（2026-10-10）───────────────────────────────
   选择区：话术可能几十条，所以限高滚动（不把"训练参数/预估/按钮"顶到屏幕外）；
   只读正文：**只是看**，所以用与预览同一套等宽块，且**不放任何编辑入口**。 */
.studio .picklist {
  max-height: 220px; overflow-y: auto; margin: 4px 0 10px;
  border: 1px solid var(--line); border-radius: var(--r); background: var(--panel2);
}
.studio .pickrow {
  display: flex; align-items: center; gap: 10px; padding: 7px 12px;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
  cursor: pointer; font-size: 13px;
}
.studio .pickrow:last-child { border-bottom: 0; }
.studio .pickrow:hover { background: color-mix(in srgb, var(--panel2) 70%, var(--line)); }
.studio .pickrow .nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.studio .picklist .muted { padding: 10px 12px; display: block; }
.studio .readonly-box {
  max-height: 260px; overflow-y: auto; margin: 4px 0 10px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--r); background: var(--panel2);
}
.studio .readonly-box .ro-hd { margin: 0 0 2px; font-size: 13px; }
.studio .readonly-box .ro-text {
  margin: 0 0 10px; font-size: 12.5px; line-height: 1.6; color: var(--text);
  white-space: pre-wrap; word-break: break-word;
}
.studio .readonly-box .ro-text:last-child { margin-bottom: 0; }

/* ── 话术历史版本的**逐段对照**（2026-10-12）─────────────────────────────────
   用户："修改话术是否需要考虑提供历史版本对比功能？就像 project-video 的 writer
   的提示词一样？" —— 左边是版本清单，右边是「选中的那一版 vs 现在」。
   容器直接用 `.readonly-box`（同一件事：在框里读一段长正文，超了就在框里滚）——
   另起一个框只会多一套边距要对齐。
   颜色只表示状态（与其它地方同一口径，不新增装饰）：绿 = 新加的一段、
   橙 = 改过的一段、红 = 删掉的一段；没变的那些行**不靠颜色**，只压浅 ——
   它们多数时候被「只看改动」滤掉了，剩下的时候要一眼看出"这些不用看"。 */
.studio .diff-row {
  display: flex; align-items: flex-start; gap: 7px;
  padding: 3px 0 3px 7px; border-left: 2px solid transparent;
}
.studio .diff-row .mk { flex: 0 0 auto; width: 1em; color: var(--muted); font-weight: 650; }
.studio .diff-row .tx { flex: 1 1 auto; min-width: 0; }
.studio .diff-row .tx p {
  margin: 0 0 2px; font-size: 12.5px; line-height: 1.6;
  white-space: pre-wrap; word-break: break-word;
}
.studio .diff-row .tx p:last-child { margin-bottom: 0; }
/* 旧的那一句划掉（"这句没了"）—— 但仍然是用户照着改回去的**依据**，所以只压灰、不隐去 */
.studio .diff-row .tx p.old { color: var(--muted); text-decoration: line-through; }
/* 改到的是哪几样（文字 / 停顿 / 情绪 / 段落类型）：右侧窄条，不跟正文抢宽度 */
.studio .diff-row .fd { flex: 0 0 auto; font-size: 12px; color: var(--muted); white-space: nowrap; }
.studio .diff-row.d-edit { border-left-color: var(--s-color-primary); }
.studio .diff-row.d-add { border-left-color: var(--ok); }
.studio .diff-row.d-add .mk { color: var(--ok); }
.studio .diff-row.d-del { border-left-color: var(--err); }
.studio .diff-row.d-del .mk { color: var(--err); }
/* 整段删掉的行没有"新"的一侧，划掉反而像"还没删干净"—— 直接用删除色 */
.studio .diff-row.d-del .tx p.old { color: var(--err); text-decoration: none; }
.studio .diff-row.d-same { opacity: .6; }

/* ── 商品页的**左树 + 右详情**（2026-10-10 用户）───────────────────────────────
   用户原话："不对，商品信息看起来是商品的补充。不能这样做，要采用左右树的方式，
   明确哪些提示词属于哪个商品"。

   为什么用网格而不是两张卡片：这一页的样式口径是"结构用细线和留白表达，不用重复的卡片"，
   左右两块之间只留一条竖细线（与 `.board` 同一口径）—— 卡片套卡片会让"哪一层是页面、
   哪一层是内容"变得看不出来。
   左树的每一行是**两段**：名称（含「主推」小标）+ 徽标（这一档的说法是自己在生效、
   还是在吃通用）。徽标必须存在：它正是"我配了怎么没生效"的答案。 */
/* ── 左右 + 右上下：三块区域的边界（2026-10-10 用户："边界不够明显"）────────────
   原来只有一条 `--line` 的细线（#e5e7eb，2 倍屏上几乎看不见），左栏和右栏糊在一起，
   右侧上下两块也只是同一条淡线 —— 用户看不出"哪里是选、哪里是内容、哪里是结果"。

   **一个视觉装置就够**（不再加框、不加阴影，符合这一页"细线 + 留白"的口径）：

   | 区域 | 样子 | 含义 |
   |---|---|---|
   | 左（选择器） | 浅底面板 `--panel2` + 圆角 | "从这里挑" |
   | 右上（要动手/正在看的那一块） | 同样浅底面板 | "就在这里操作" |
   | 右下（列表 / 记录 / 覆盖矩阵） | **白底**，无边框 | "这是结果" |

   两块浅底之间夹着白底列表 —— 边界靠**底色反差**表达，比加粗线条安静，也更清楚。 */
.studio .master {
  display: grid; grid-template-columns: minmax(220px, 280px) minmax(0, 1fr);
  gap: 0 24px; align-items: start;
}
.studio .tree {
  min-width: 0; padding: 12px 12px 10px;
  background: var(--panel2); border: 1px solid var(--line); border-radius: var(--r);
}
/* 左栏的小标题（"这是什么"）：商品 / 分组 —— 面板里没有标题会像一块空框 */
.studio .tree-hd {
  margin: 0 2px 8px; font-size: 12.5px; font-weight: 600; color: var(--muted);
  letter-spacing: .04em;
}
/* ⚠️ 筛选行在**窄栏**里要**竖排**：全局 `.filterbar input` 是固定 220px、下拉最小 120px，
   并排塞进 220–280px 的树栏会折成三行（列表被推到屏幕外）。 */
.studio .tree .filterbar { flex-direction: column; align-items: stretch; gap: 6px; }
.studio .tree .filterbar input,
.studio .tree .filterbar select { width: 100%; max-width: none; }
.studio .tree .filterbar .muted { margin-left: 0; }
/* 分页条同理：窄栏里允许折行，不要把「共 N 条」压成一列一个字 */
.studio .tree .pager { border-top: 0; padding: 8px 0 0; flex-wrap: wrap; gap: 4px 10px; }
.studio .tree-list { display: flex; flex-direction: column; }
.studio .node {
  display: flex; flex-direction: column; gap: 2px;
  width: 100%; text-align: left; cursor: pointer;
  padding: 8px 10px; border: 0; border-left: 2px solid transparent;
  border-radius: 0; background: transparent; color: inherit; font: inherit;
}
.studio .node:hover { background: color-mix(in srgb, var(--panel2) 60%, transparent); }
.studio .node.on { border-left-color: var(--s-color-primary); background: var(--panel); }
.studio .node .nm {
  display: flex; align-items: center; gap: 6px; min-width: 0;
  font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.studio .node .bd { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.studio .node .bd.self { color: var(--ok); }
.studio .node .bd.warn { color: var(--warn); }
.studio .tree-empty { margin: 8px 2px; font-size: 12.5px; color: var(--muted); }
.studio .detail { min-width: 0; display: flex; flex-direction: column; gap: 16px; }
.studio .pane { min-width: 0; padding: 0; }
/* 右上那一块（要操作/正在看）：浅底面板 —— 与左栏同一种"可以动手"的底色 */
.studio .pane.act {
  background: var(--panel2); border: 1px solid var(--line); border-radius: var(--r);
  padding: 14px 16px;
}
/* 右下（列表/记录）保持白底：与上面那块面板之间**不需要**再画线，底色已经分开了 */
.studio .pane + .pane:not(.act) { border-top: 0; padding-top: 0; }
/* 2026-10-21 用户口径：「同级功能都用卡片样式包裹」——
   两块卡片之间要留出间距（否则描边贴在一起像一张表被切开）。 */
.studio .pane.act + .pane.act { margin-top: 16px; }
/* 每张卡片与上方内容之间留一口气（否则第一张卡贴着说明文字） */
.studio section.card > .pane.act { margin-top: 14px; }
/* 详情区的表头（标题 + 状态片 + 一串动作）。
   ⚠️ 三条**必须**，否则窄屏/长标题下中文会被压成"一个字一行"（2026-10-10 用户实测：
   "字都被压倒非常窄的3个字符宽度，导致文字竖排"）：
   ① `flex-wrap: wrap` —— 一行放不下就换行，而不是把每一项都挤瘦；
   ② 标题可省略（`min-width` + `nowrap` + `ellipsis`）：它是最长的那个，
      不设 `min-width` 会被压到 min-content（中文的 min-content = **一个汉字宽**）；
   ③ 动作/状态片 `flex: 0 0 auto` + `nowrap`：按钮文字永远不该被折行；
      说明文字给 `min-width: 12ch`（可以折行，但不会折成一根竖条）。 */
.studio .pane-hd { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  row-gap: 6px; margin: 0 0 10px; }
.studio .pane-hd > b { font-size: 14px; font-weight: 650; flex: 0 1 auto;
  min-width: 8ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.studio .pane-hd > .chip, .studio .pane-hd > .tag,
.studio .pane-hd > button, .studio .pane-hd > .link { flex: 0 0 auto; white-space: nowrap; }
.studio .pane-hd > .muted, .studio .pane-hd > span:not(.chip):not(.tag):not(.grow) {
  flex: 1 1 12ch; min-width: 12ch;
}
.studio .pane-hd > .grow { flex: 1 1 auto; }

@media (max-width: 640px) {
  /* 手机：再收一档列（`t-xs`）—— 剩下的列才有地方放正文（而不是每列一个字） */
  .studio .tbl .t-xs { display: none; }
  .studio .tbl col.t-xs { width: 0; }
  /* 手机上表格字号略收，配合截断让一屏能看全一行 */
  .studio .tbl { font-size: 13px; }
  /* ⚠️ 手机上**操作列只有 ~50px**（列宽是按百分比申明的），而「修改 / 删除」两个按钮
     并排要 76px。`.tbl td` 的 `overflow:hidden + white-space:nowrap` 不会报错、也不会
     出横向滚动条 —— 它把「删除」**裁在单元格外面**（DOM 里有、点不到），
     实测 390px 下 `scripts-delete` / `rules-delete` 的右边界 386px 越过了单元格的 376px。
     手机上删不掉配置 = 这一页在手机浏览器上不可用（用户就是从 App「去网页配置」点进来的）。
     所以窄屏让操作列**允许换行、允许超出**：行高多几像素，换来"每个按钮都点得到"。 */
  .studio .tbl td.act { white-space: normal; overflow: visible; }
  /* 空态那一行横跨整表，而说明又必须写清"点哪里"（超过一行的长度）——
     同样被 nowrap 裁掉的话，新账号在手机上看到的就只剩半句话。 */
  .studio .tbl td.empty { white-space: normal; overflow: visible; }
  /* 右内边距收 4px：窄屏下每列多出一点文字宽度（7 列累计 ~28px），
     让状态片（`开启` / `已检查`）不再被裁成半个。 */
  .studio .tbl th, .studio .tbl td { padding-right: 8px; }
}

@media (max-width: 1000px) {
  /* 窄屏：树与详情**上下摞**（并排时只有一条缝）；竖线改成横线，含义不变。
     ⚠️ 选择器必须**并列写 `.master.narrow`**：训练页用的是 `class="master narrow"`
     （3 个类的选择器），而这条媒体查询里原来只写 `.studio .master`（2 个类）——
     同源顺序下**特异性更高者胜**，于是 1000px 以下训练页仍然是 `200px + 1fr`：
     实测 390px 手机上右详情只剩 **138px**（`gridTemplateColumns: "200px 138px"`），
     筛选框被挤到屏幕外（右边界 458px）、「上线到我的直播机」被压成竖排（28×204px）。
     右详情一旦比左树还窄，这一页在手机上就等于不可用 —— 所以两档都要摞。 */
  .studio .master, .studio .master.narrow { grid-template-columns: minmax(0, 1fr); }
  .studio .tree, .studio .master.narrow .tree {
    padding: 0 0 12px; border-right: 0; border-bottom: 1px solid var(--line);
  }
  .studio .detail { padding-top: 14px; }
}

/* ── 训练向导（2026-10-10 用户："要补充向导方式方便用户理解"）──────────────────
   向导 = **把同一份状态讲一遍**（点"下一步"不改任何东西），真正的动作仍只有右上那一块。
   所以它的样式很轻：一条上边线 + 三个步骤点 + 一句人话；被讲到的那一块加 `.spot`
   （虚线圈）—— 用"这里"指路，而不是把用户拽到一个新页面上。 */
.studio .wizard {
  margin: 0 0 16px; padding: 12px 14px;
  border-left: 2px solid var(--s-color-primary);
  background: var(--panel2); border-radius: var(--w-r-sm);
}
.studio .wz-hd { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.studio .wz-hd b { font-size: 14px; font-weight: 650; }
.studio .wz-dots {
  display: flex; flex-wrap: wrap; gap: 8px; list-style: none;
  margin: 0 0 8px; padding: 0; font-size: 12.5px; color: var(--muted);
}
.studio .wz-dots li {
  padding: 3px 10px; border: 1px solid var(--line); border-radius: 999px;
}
.studio .wz-dots li.on { color: var(--text); border-color: var(--s-color-primary); font-weight: 600; }
.studio .wz-dots li.done { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 35%, transparent); }
.studio .wz-txt { margin: 0 0 10px; font-size: 13.5px; line-height: 1.7; }
/* 被向导指到的那一块：虚线框（`outline` 不占布局、不引起抖动） */
.studio .spot { outline: 2px dashed color-mix(in srgb, var(--s-color-primary) 55%, transparent);
  outline-offset: 4px; border-radius: var(--w-r-sm); }

/* 训练页的左树：只有分组名 + 「N 条 · 已训 M」徽标，比商品树窄一档就够 ——
   多出来的宽度应该给右边的覆盖矩阵与预估明细（它们是这一页的主角）。
   ⚠️ 这条**必须放在下面的媒体查询之前**：它与媒体查询里的
   `.studio .master.narrow` 特异性相同（都是 3 个类），靠**源顺序**决胜 ——
   放在文件末尾时，窄屏那条会被它反压回去（训练页在手机上保持 200px + 1fr，
   右详情只剩 138px）。这里显式写成"只在宽屏生效"，顺序就不再有歧义。 */
@media (min-width: 1001px) {
  .studio .master.narrow { grid-template-columns: minmax(160px, 200px) minmax(0, 1fr); }
  .studio .master.narrow .tree { padding: 10px 9px 8px; }
}

/* ── 话术历史：**大抽屉 + 左右对照（git diff 形状）**（2026-10-21 用户口径）─────
   「历史功能应该也放到功能列表，而且是开比较大的抽屉来做左右对比」。
   左侧版本清单 / 右侧逐段左右并排：左边旧版、右边现在；颜色仍只表示状态。 */
.studio .drawer.wide { width: min(1100px, 100%); }
.studio .diff-wrap { display: flex; gap: 16px; min-height: 0; height: 100%; }
.studio .diff-versions {
  flex: 0 0 240px; overflow: auto; padding-right: 12px;
  border-right: 1px solid var(--line);
}
.studio .diff-main { flex: 1 1 auto; min-width: 0; display: flex;
  flex-direction: column; overflow: hidden; }
.studio .diff-head { display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap; margin: 0 0 8px; }
.studio .diff-cols {
  display: grid; grid-template-columns: 16px 1fr 1fr; gap: 10px;
  padding: 0 10px 4px; font-size: 11.5px; color: var(--muted);
}
.studio .diff-box { flex: 1 1 auto; overflow: auto; }
.studio .diff-wrap .diff-row {
  display: grid; grid-template-columns: 16px 1fr 1fr; gap: 10px;
  align-items: start; padding: 6px 10px; border-left: 0;
  border-top: 1px dashed var(--line);
}
.studio .diff-wrap .diff-row .mk { width: auto; font-family: ui-monospace, monospace; }
.studio .diff-wrap .diff-cell {
  white-space: pre-wrap; word-break: break-word; font-size: 12.5px; line-height: 1.6;
}
.studio .diff-wrap .diff-row.d-add .new { background: rgba(46, 160, 67, .12); }
.studio .diff-wrap .diff-row.d-del .old { background: rgba(248, 81, 73, .12); }
.studio .diff-wrap .diff-row.d-del .mk { color: var(--err); }
.studio .diff-wrap .diff-row.d-add .mk { color: var(--ok); }
.studio .diff-wrap .diff-row.d-edit .old,
.studio .diff-wrap .diff-row.d-edit .new { background: rgba(210, 153, 34, .10); }
.studio .diff-wrap .diff-row .fd {
  grid-column: 2 / -1; font-size: 11.5px; color: var(--muted); white-space: normal;
}
.studio .scards .pane.act + .pane.act { margin-top: 14px; }

/* ── 页面级 `.field`（2026-10-21 用户：「label 和输入框之间 margin 不对、看不出关系」）──
   根因：`.field > label` 是**行内元素**，`margin-bottom` 对行内盒子**不生效** ——
   标签和输入框贴在同一行，看不出谁是谁的。`.field` 的样式此前只写在
   `.studio .drawer .field` 里，页面上的字段（账号默认口吻与禁区）根本没被覆盖到。
   这里给页面级字段同一套：标签块级 + 与控件留 6px + 次要色；控件占满整行；
   整组字段之间 14px。语义上也把 `<div><label>…</label><input></div>` 换成
   `<label class="field"><span>…</span><input></label>`（隐式关联，点标签就能聚焦输入框）。 */
.studio .field { min-width: 0; margin: 0 0 14px; }
.studio .field > span,
.studio .field > label {
  display: block; margin: 0 0 6px;
  font-size: 12.5px; font-weight: 500; color: var(--muted); line-height: 1.5;
}
.studio .field > input,
.studio .field > textarea,
.studio .field > select { width: 100%; box-sizing: border-box; }
.studio .field > em { display: block; margin: 5px 0 0; font-style: normal;
  font-size: 11.5px; color: var(--muted); line-height: 1.6; }
.studio .field-grid { row-gap: 4px; }
.studio .field-grid > .field { margin-bottom: 10px; }

/* ── 列表卡：把"表格区域"画成一眼能认出来的一块（2026-10-21 用户口径）────────
   「凡事列表的，都要用浮动卡片包裹起来，明确区分表格区域」。
   口径：
   · 列表卡 = 现有 `.pane.act` 卡片 + 更明确的表格面板；
   · 表格本体自带 1px 边、10px 圆角、表头浅底、行 hover、最后一行与卡片圆角对齐；
   · 筛选条与分页留在卡内：筛选在上、分页在下（分页上方一条虚线分隔）；
   · 窄屏不横向滚动（沿用按列轻重隐藏的既有口径）。 */
.studio .list-card { padding: 14px 16px 12px; }
.studio .list-card > .filter-bar { margin-bottom: 10px; }
.studio .list-card .tbl,
.studio .pane.act .tbl,
.studio .table-panel .tbl {
  border-collapse: separate; border-spacing: 0;
  width: 100%; border: 1px solid var(--line); border-radius: 10px;
  overflow: hidden; background: var(--panel);
}
.studio .list-card .tbl th,
.studio .pane.act .tbl th,
.studio .table-panel .tbl th {
  background: var(--panel2); color: var(--muted); font-weight: 600;
  padding: 9px 10px; border-bottom: 1px solid var(--line);
}
.studio .list-card .tbl th:first-child,
.studio .pane.act .tbl th:first-child,
.studio .table-panel .tbl th:first-child { border-top-left-radius: 9px; }
.studio .list-card .tbl th:last-child,
.studio .pane.act .tbl th:last-child,
.studio .table-panel .tbl th:last-child { border-top-right-radius: 9px; }
.studio .list-card .tbl td,
.studio .pane.act .tbl td,
.studio .table-panel .tbl td {
  padding: 10px; border-top: 1px solid var(--line); vertical-align: top;
}
.studio .list-card .tbl tbody tr:first-child td,
.studio .pane.act .tbl tbody tr:first-child td { border-top: 0; }
.studio .list-card .tbl tbody tr:hover td,
.studio .pane.act .tbl tbody tr:hover td,
.studio .table-panel .tbl tbody tr:hover td {
  background: color-mix(in srgb, var(--panel2) 60%, transparent);
}
.studio .list-card .tbl tbody tr:last-child td:first-child,
.studio .pane.act .tbl tbody tr:last-child td:first-child,
.studio .table-panel .tbl tbody tr:last-child td:first-child {
  border-bottom-left-radius: 9px;
}
.studio .list-card .tbl tbody tr:last-child td:last-child,
.studio .pane.act .tbl tbody tr:last-child td:last-child,
.studio .table-panel .tbl tbody tr:last-child td:last-child {
  border-bottom-right-radius: 9px;
}
/* 空态：表体里一句话，不要像"没加载完" */
.studio .list-card .tbl td.empty,
.studio .pane.act .tbl td.empty { padding: 22px 12px; text-align: center; color: var(--muted); }
/* 分页：卡内底部，与表体用虚线分开；卡外分页（老页面）保持原样 */
.studio .list-card .pager {
  margin: 10px 2px 0; padding-top: 9px; border-top: 1px dashed var(--line);
}

/* 话术修改抽屉：比默认更宽，正文给足高度（2026-10-21 用户口径） */
.studio .drawer[data-testid="scripts-drawer"] { width: min(1100px, 100%); }
.studio .drawer[data-testid="scripts-drawer"] textarea[data-testid="scripts-f-text"] {
  min-height: 460px;
}

/* 话术流式生成预览：边写边看，不等整篇 */
.studio .stream-preview { margin: 10px 0; }
.studio .stream-preview pre {
  margin: 6px 0 0; max-height: 260px; overflow: auto; white-space: pre-wrap;
  background: var(--panel, #141416); border: 1px solid var(--line, #2a2a30);
  border-radius: 8px; padding: 10px 12px; font-size: 13px; line-height: 1.7;
}

/* 生效任务列表：只给状态/进度，不展示变体与成本细节 */
.studio .jobs-list { display: grid; gap: 8px; margin: 10px 0; }
.studio .jobs-row { display: flex; gap: 14px; align-items: center; padding: 8px 10px;
  border: 1px solid var(--line, #2a2a30); border-radius: 8px; font-size: 13px; }
.studio .jobs-row b { min-width: 180px; }

/* 历史对比：左旧 / 右新，两个版本选择器（对齐 writer 的 git 式双栏） */
.studio .diff-pickers { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.studio .diff-pickers label { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; }
.studio .diff-pickers select { max-width: 140px; }
.studio .diff-wrap .diff-cell .ln { display: inline-block; width: 22px; color: var(--muted);
  font-family: ui-monospace, monospace; font-size: 11px; user-select: none; }

/* ── 历史版本：复刻 writer-prompt-history（admin_prompts）的 git 式双栏 ── */
.studio .history-drawer { width: 85%; max-width: 1800px; }
.studio .history-bd { display: flex; flex-direction: row; gap: 16px;
  min-height: 60vh; overflow: hidden; }
.studio .wph-list { flex: 0 0 172px; overflow-y: auto; padding-right: 8px;
  border-right: 1px solid var(--line); }
.studio .wph-list-hd { font-size: 12px; color: var(--muted); margin-bottom: 6px; }
.studio .wph-ver-card { border: 1px solid var(--line); border-radius: 8px;
  padding: 6px 8px; margin-bottom: 6px; cursor: pointer; }
.studio .wph-ver-card:hover { border-color: #93c5fd; }
.studio .wph-ver-card.wph-ver-active { border-color: #2563eb;
  box-shadow: inset 0 0 0 1px #2563eb; }
.studio .wph-ver-top { display: flex; justify-content: space-between; align-items: center; gap: 4px; }
.studio .wph-cur { font-size: 11px; color: #059669; border: 1px solid #059669;
  border-radius: 10px; padding: 0 6px; white-space: nowrap; }
.studio .wph-meta { font-size: 12px; color: var(--muted); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.studio .wph-note { color: var(--muted); }
.studio .wph-actions { margin-top: 6px; display: flex; gap: 4px; flex-wrap: nowrap; }
.studio .wph-actions .btn { padding: 2px 6px; font-size: 12px; white-space: nowrap; }
.studio .wph-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.studio .wph-toolbar { display: flex; gap: 10px; align-items: center;
  margin-bottom: 8px; flex-wrap: wrap; font-size: 13px; }
.studio .wph-hint { font-size: 12px; color: var(--muted); }
.studio .wph-summary { font-size: 12px; color: var(--muted); }
.studio .wph-body { display: flex; border: 1px solid var(--line); border-radius: 6px;
  height: calc(100vh - 320px); min-height: 320px; flex: 1; overflow: hidden; }
.studio .wph-pane { width: 50%; overflow: auto; }
.studio .wph-pane + .wph-pane { border-left: 1px solid var(--line); }
.studio .wph-line { display: flex; width: 100%; box-sizing: border-box;
  align-items: flex-start; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; line-height: 18px; min-height: 18px; }
.studio .wph-no { flex: 0 0 48px; text-align: right; padding-right: 8px;
  color: #9ca3af; user-select: none; }
.studio .wph-txt { flex: 1 1 auto; min-width: 0; white-space: pre-wrap;
  word-break: break-word; overflow-wrap: anywhere; padding: 0 6px 2px; }
.studio .wph-del { background: #fee2e2; }
.studio .wph-ins { background: #dcfce7; }
.studio .wph-empty { background: #f3f4f6; }
.studio .wph-collapsed { font-size: 12px; color: #6b7280; background: #f3f4f6;
  padding: 2px 8px; box-sizing: border-box; min-width: 100%; }

/* ── AI 回复自检：按用户截图复刻（深色卡 / 蓝说明条 / 绿商品条 / 紫色提问按钮）── */
.studio .selfcheck-panel {
  background: #0b111c; border: 1px solid #263244; border-radius: 10px;
  padding: 16px; color: #e5e7eb;
}
.studio .selfcheck-panel .sc-banner {
  background: #0b1f3a; border: 1px solid #1d4ed8; border-radius: 8px;
  color: #a8c7ff; font-size: 13px; line-height: 1.7; padding: 12px 16px;
}
.studio .selfcheck-panel .sc-product {
  margin-top: 10px; background: #06251c; border: 1px solid #166534;
  border-radius: 8px; color: #86efac; font-size: 13px; padding: 11px 16px;
}
.studio .selfcheck-panel .sc-product span { margin-left: 12px; color: #4ade80; }
.studio .selfcheck-panel .sc-form {
  margin-top: 10px; padding: 16px; border: 1px solid #263244;
  border-radius: 8px; background: #0e1522;
}
.studio .selfcheck-panel .sc-field { display: block; margin: 0 0 14px; }
.studio .selfcheck-panel .sc-field > span {
  display: block; margin-bottom: 7px; color: #cbd5e1; font-size: 12.5px;
}
.studio .selfcheck-panel .sc-field select,
.studio .selfcheck-panel .sc-field input {
  width: 100%; box-sizing: border-box; height: 38px; padding: 0 10px;
  border: 1px solid #334155; border-radius: 8px;
  background: #1e293b; color: #e5e7eb; font-size: 13px;
}
.studio .selfcheck-panel .sc-help {
  margin: -8px 0 14px; color: #94a3b8; font-size: 12px;
}
.studio .selfcheck-panel .sc-help .link { color: #cbd5e1; margin-left: 6px; }
.studio .selfcheck-panel .sc-ask { display: flex; align-items: center; gap: 12px; }
.studio .selfcheck-panel .sc-ask input { flex: 1 1 auto; }
.studio .selfcheck-panel .sc-ask .primary {
  flex: 0 0 104px; height: 38px; border-radius: 8px;
  background: #6366f1; border-color: #6366f1; color: #fff;
}
.studio .selfcheck-panel .sc-quick {
  display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px;
}
.studio .selfcheck-panel .sc-quick .ghost {
  background: #1e293b; border: 1px solid #334155; color: #cbd5e1;
  border-radius: 8px; padding: 7px 12px; font-size: 12.5px;
}
.studio .selfcheck-panel .hint,
.studio .selfcheck-panel .muted { color: #94a3b8; }

/* ── 音色克隆：按截图复刻（蓝色说明条 / 余额卡 / 我的音色卡 / 公共音色卡）── */
.studio .voice-clone {
  background: #0b111c; border: 1px solid #263244; border-radius: 10px;
  padding: 16px; color: #e5e7eb;
}
.studio .voice-clone .vc-banner {
  background: #0b1f3a; border: 1px solid #1d4ed8; border-radius: 8px;
  color: #a8c7ff; font-size: 13px; line-height: 1.7; padding: 12px 16px;
}
.studio .voice-clone .vc-balance {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 10px; padding: 14px 16px; background: #0e1522;
  border: 1px solid #263244; border-radius: 8px;
}
.studio .voice-clone .vc-balance b { font-size: 15px; color: #e5e7eb; }
.studio .voice-clone .vc-balance p { margin: 5px 0 0; color: #cbd5e1; font-size: 13px; }
.studio .voice-clone .vc-head {
  display: flex; align-items: center; justify-content: space-between;
  margin: 22px 0 10px;
}
.studio .voice-clone .vc-head b { font-size: 15px; }
.studio .voice-clone .vc-head .primary {
  background: #6366f1; border-color: #6366f1; color: #fff; border-radius: 8px;
}
.studio .voice-clone .vc-list { display: flex; flex-direction: column; gap: 10px; }
.studio .voice-clone .vc-card {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px 16px; background: #0e1522; border: 1px solid #263244;
  border-radius: 8px;
}
.studio .voice-clone .vc-main { min-width: 0; }
.studio .voice-clone .vc-main b { font-size: 14px; color: #e5e7eb; }
.studio .voice-clone .vc-tags { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 8px; }
.studio .voice-clone .vc-tags .tag {
  background: #1e293b; border: 1px solid #334155; color: #cbd5e1;
  border-radius: 6px; padding: 2px 8px; font-size: 12px;
}
.studio .voice-clone .vc-tags .tag.ok { color: #86efac; border-color: #166534; background: #06251c; }
.studio .voice-clone .vc-actions { display: flex; flex: 0 0 auto; gap: 8px; flex-wrap: wrap; }
.studio .voice-clone .vc-actions .ghost,
.studio .voice-clone .vc-actions .danger-outline {
  background: #1e293b; border: 1px solid #475569; color: #e5e7eb;
  border-radius: 8px; padding: 6px 12px; font-size: 12.5px;
}
.studio .voice-clone .vc-actions .danger-outline {
  color: #fca5a5; border-color: #7f1d1d;
}
.studio .voice-clone .vc-empty { color: #94a3b8; font-size: 13px; padding: 18px 4px; }
.studio .voice-clone .vc-error { color: #fca5a5; font-size: 12px; margin: 7px 0 0; }
.studio .voice-clone .hint { color: #94a3b8; }


/* ── 全局浅色化：与音色/自检截图同一风格，换成更浅的蓝灰配色 ───────────── */
.studio .card {
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  padding: 20px; margin: 12px 0;
  box-shadow: 0 4px 16px rgba(37, 99, 235, .05);
}
.studio .card:first-child { border-top: 1px solid var(--line); }
.studio .board > .card { border: 1px solid var(--line); }
.studio .board > .card + .card { padding-left: 20px; border-left: 1px solid var(--line); }
.studio .board > .card:first-child { padding-right: 20px; }
.studio .sub { background: var(--panel2); color: var(--text); }
.studio .kv { color: var(--text); }
.studio .tbl th { color: var(--muted); }
.studio .preview-box { color: var(--text); }

/* 自检：浅色版（蓝说明条 / 绿商品条 / 白表单卡） */
.studio .selfcheck-panel {
  background: var(--panel); border: 1px solid var(--line); color: var(--text);
}
.studio .selfcheck-panel .sc-banner {
  background: #eaf2ff; border: 1px solid #bfd4ff; color: #1e40af;
}
.studio .selfcheck-panel .sc-product {
  background: #ecfdf5; border: 1px solid #a7f3d0; color: #166534;
}
.studio .selfcheck-panel .sc-product span { color: #047857; }
.studio .selfcheck-panel .sc-form {
  background: var(--panel2); border: 1px solid var(--line);
}
.studio .selfcheck-panel .sc-field > span { color: var(--text); }
.studio .selfcheck-panel .sc-field select,
.studio .selfcheck-panel .sc-field input {
  background: var(--panel); color: var(--text); border: 1px solid var(--line);
}
.studio .selfcheck-panel .sc-help { color: var(--muted); }
.studio .selfcheck-panel .sc-help .link { color: var(--primary); }
.studio .selfcheck-panel .sc-ask .primary {
  background: var(--primary); border-color: var(--primary); color: #fff;
}
.studio .selfcheck-panel .sc-quick .ghost {
  background: var(--panel); border: 1px solid var(--line); color: var(--text);
}
.studio .selfcheck-panel .hint,
.studio .selfcheck-panel .muted { color: var(--muted); }

/* 音色克隆：浅色版 */
.studio .voice-clone {
  background: var(--panel); border: 1px solid var(--line); color: var(--text);
}
.studio .voice-clone .vc-banner {
  background: #eaf2ff; border: 1px solid #bfd4ff; color: #1e40af;
}
.studio .voice-clone .vc-balance { background: var(--panel2); border: 1px solid var(--line); }
.studio .voice-clone .vc-balance b { color: var(--text); }
.studio .voice-clone .vc-balance p { color: var(--muted); }
.studio .voice-clone .vc-head .primary { background: var(--primary); border-color: var(--primary); color: #fff; }
.studio .voice-clone .vc-card { background: var(--panel); border: 1px solid var(--line); }
.studio .voice-clone .vc-main b { color: var(--text); }
.studio .voice-clone .vc-tags .tag {
  background: var(--panel2); border: 1px solid var(--line); color: var(--muted);
}
.studio .voice-clone .vc-tags .tag.ok {
  background: #ecfdf5; border-color: #a7f3d0; color: #166534;
}
.studio .voice-clone .vc-actions .ghost,
.studio .voice-clone .vc-actions .danger-outline {
  background: var(--panel); border: 1px solid var(--line); color: var(--text);
}
.studio .voice-clone .vc-actions .danger-outline { color: var(--err); border-color: #fecaca; }
.studio .voice-clone .vc-empty { color: var(--muted); }
.studio .voice-clone .vc-error { color: var(--err); }
.studio .voice-clone .hint { color: var(--muted); }
