/* =============================================================
   单向 WebRTC 网页工作系统 — 全局样式
   风格：简约干净商务风。无花哨动画、无闪烁特效。
   （重要：查看页会被OBS 捕获软件抓取，任何闪烁都会进工作间）
   ============================================================= */

:root {
  /* ---- VI 配色（按要求固定） ---- */
  --primary: #2563eb;
  --primary-hover: #1d4ed8;
  --primary-active: #1e40af;
  --primary-soft: #eff6ff;
  --primary-border: #bfdbfe;

  --secondary: #64748b;
  --secondary-soft: #f1f5f9;

  --text: #1e293b;
  --text-sub: #475569;
  --text-muted: #94a3b8;

  --bg: #f8fafc;
  --card: #ffffff;
  --border: #e2e8f0;
  --border-strong: #cbd5e1;

  --danger: #dc2626;
  --danger-hover: #b91c1c;
  --danger-soft: #fef2f2;
  --success: #16a34a;
  --success-soft: #f0fdf4;
  --warning: #d97706;
  --warning-soft: #fffbeb;

  --disabled-bg: #cbd5e1;
  --disabled-text: #f1f5f9;

  --radius-sm: 6px;
  --radius: 10px;
  --radius-lg: 14px;

  --shadow-xs: 0 1px 2px rgba(15, 23, 42, 0.05);
  --shadow-sm: 0 1px 3px rgba(15, 23, 42, 0.08), 0 1px 2px rgba(15, 23, 42, 0.04);
  --shadow: 0 4px 14px rgba(15, 23, 42, 0.07);

  /* ---- iOS 安全区（刘海 / 圆角 / Home 指示条）----
     ⚠️ 前提：页面 <meta viewport> 必须带 viewport-fit=cover，否则 env() 恒为 0（规范如此）。
     先给 0px 兜底、再用 @supports 探测 env() 支持后覆盖：在不认 env() 的老浏览器里
     --sat 仍是合法值，不会因为「变量无效」把依赖它的 --header-h 一起拖垮。 */
  --sat: 0px;
  --sab: 0px;
  --sal: 0px;
  --sar: 0px;

  --header-h: calc(60px + var(--sat));

  /* ---- 全局基础字体：阿里妈妈数黑体 ----
     优先调用系统已安装的「阿里妈妈数黑体 / Alimama ShuHeiTi」；
     本机未安装时自动回退到系统自带无衬线黑体（PingFang SC / 微软雅黑 / 思源黑体 …）。
     不内置字体文件（零下载、不拖慢加载），字重与字号层级完全由 CSS 控制。 */
  --font: "Alimama ShuHeiTi", "AlimamaShuHeiTi", "阿里妈妈数黑体",
    "PingFang SC", "Microsoft YaHei", "微软雅黑", "HarmonyOS Sans SC",
    "Source Han Sans SC", "Noto Sans SC", "Hiragino Sans GB",
    "Helvetica Neue", Arial, sans-serif;
  /* 数字/等宽场景沿用同一基础字体，另用 font-variant-numeric: tabular-nums 保证数字列对齐 */
  --font-mono: var(--font);
  /* 等宽专用（仅代码/诊断详情等语义化技术内容保留等宽） */
  --font-code: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;

  /* ---- 字重层级（规范） ----
     bold    加粗：页面大标题 / 模块标题 / 关键数据 / 主按钮文字
     regular 常规：正文内容 / 辅助说明 / 次要标签 */
  --fw-bold: 700;
  --fw-regular: 400;
}

* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  font-family: var(--font);
  font-weight: var(--fw-regular);
  font-size: 15px;
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* 表单控件默认不继承字体，这里统一为主字体（含输入框、下拉、按钮、文本域） */
input,
select,
textarea,
button,
optgroup,
option,
output {
  font-family: var(--font);
  font-weight: var(--fw-regular);
}

/* 禁用会分散注意力的动画 */
@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
  }
}

@supports (padding-top: env(safe-area-inset-top, 0px)) {
  :root {
    --sat: env(safe-area-inset-top, 0px);
    --sab: env(safe-area-inset-bottom, 0px);
    --sal: env(safe-area-inset-left, 0px);
    --sar: env(safe-area-inset-right, 0px);
  }
}

/* ============================ 顶部栏 ============================ */

.topbar {
  height: var(--header-h);
  background: var(--card);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 20px;
  /* 顶栏自己铺到刘海下面，但把内容（LOGO/标题/按钮）推回安全区。
     高度已由 --header-h 自动加上 --sat，这里只补内边距，两者保持一致。 */
  padding-top: var(--sat);
  padding-left: calc(20px + var(--sal));
  padding-right: calc(20px + var(--sar));
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 50;
  flex: 0 0 auto;
}

/* 品牌 Logo 占位区 —— 后续把自己的图片链接填到后台「站点设置」里即可 */
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  flex: 0 0 auto;
}

.brand-logo {
  height: 34px;
  width: auto;
  max-width: 160px;
  object-fit: contain;
  display: block;
}

/* 没配 logo 时显示的方块占位 */
.brand-logo-placeholder {
  height: 34px;
  min-width: 100px;
  padding: 0 12px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  background: var(--secondary-soft);
  white-space: nowrap;
}

.brand-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.topbar-divider {
  width: 1px;
  height: 22px;
  background: var(--border);
  flex: 0 0 auto;
}

.topbar-title {
  font-size: 14px;
  color: var(--text-sub);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.topbar-spacer {
  flex: 1 1 auto;
  min-width: 8px;
}

/* ============================ 状态徽标 ============================ */

.status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-sub);
  padding: 5px 11px;
  border-radius: 999px;
  background: var(--secondary-soft);
  border: 1px solid var(--border);
  white-space: nowrap;
  flex: 0 0 auto;
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-muted);
  flex: 0 0 auto;
}

.status.is-live {
  color: #15803d;
  background: var(--success-soft);
  border-color: #bbf7d0;
}
.status.is-live .status-dot {
  background: var(--success);
}

.status.is-warn {
  color: #b45309;
  background: var(--warning-soft);
  border-color: #fde68a;
}
.status.is-warn .status-dot {
  background: var(--warning);
}

.status.is-error {
  color: var(--danger);
  background: var(--danger-soft);
  border-color: #fecaca;
}
.status.is-error .status-dot {
  background: var(--danger);
}

.status.is-ok {
  color: #15803d;
  background: var(--success-soft);
  border-color: #bbf7d0;
}
.status.is-ok .status-dot {
  background: var(--success);
}

/* ============================= 按钮 ============================= */

.btn {
  -webkit-appearance: none;
  appearance: none;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.2;
  padding: 10px 18px;
  cursor: pointer;
  background: var(--secondary-soft);
  color: var(--text);
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
  white-space: nowrap;
  -webkit-user-select: none;
  user-select: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
}

.btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* 主按钮：蓝色圆角，悬浮变色 */
.btn-primary {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.btn-primary:hover:not(:disabled) {
  background: var(--primary-hover);
  border-color: var(--primary-hover);
}
.btn-primary:active:not(:disabled) {
  background: var(--primary-active);
  border-color: var(--primary-active);
}

.btn-outline {
  background: #fff;
  border-color: var(--border-strong);
  color: var(--text-sub);
}
.btn-outline:hover:not(:disabled) {
  background: var(--secondary-soft);
  border-color: var(--secondary);
  color: var(--text);
}

.btn-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--secondary);
}
.btn-ghost:hover:not(:disabled) {
  background: var(--secondary-soft);
  color: var(--text);
}

.btn-danger {
  background: #fff;
  border-color: #fecaca;
  color: var(--danger);
}
.btn-danger:hover:not(:disabled) {
  background: var(--danger-soft);
  border-color: var(--danger);
  color: var(--danger-hover);
}

.btn-sm {
  font-size: 13px;
  padding: 7px 12px;
  border-radius: var(--radius-sm);
}

.btn-lg {
  font-size: 15px;
  padding: 13px 26px;
}

/* 不可点击时置灰 */
.btn:disabled,
.btn[disabled] {
  background: var(--disabled-bg) !important;
  border-color: var(--disabled-bg) !important;
  color: var(--disabled-text) !important;
  cursor: not-allowed !important;
  opacity: 1;
}

/* ============================= 卡片 ============================= */

.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.card-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
  flex: 0 0 auto;
}

.card-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.card-title .dot {
  width: 4px;
  height: 16px;
  border-radius: 2px;
  background: var(--primary);
  flex: 0 0 auto;
}

.card-sub {
  font-size: 13px;
  color: var(--text-muted);
  font-weight: 400;
}

.card-body {
  padding: 18px 20px;
}

/* =========================== 话术区域 =========================== */

.script-scroll {
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}

.script-scroll::-webkit-scrollbar {
  width: 10px;
}
.script-scroll::-webkit-scrollbar-track {
  background: transparent;
}
.script-scroll::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 999px;
  border: 2px solid var(--card);
}
.script-scroll::-webkit-scrollbar-thumb:hover {
  background: var(--secondary);
}

/* 话术正文：员工端观看比例 —— 大字号档 + 紧行距，同屏能看到的行数更多 */
.script-content {
  font-size: 17px;
  line-height: 1.4;
  color: var(--text);
  letter-spacing: 0.01em;
  word-break: break-word;
  white-space: pre-wrap;
  padding: 4px 4px 24px 4px;
  margin: 0;
  font-family: var(--font);
}

/* 观看比例统一：不管BOSS端那边把字号/字体写成什么，员工端一律按本端字号档渲染；
   颜色、加粗、高亮、删除线等格式全部保留（标红标绿不受影响）。
   编辑模式豁免（:not contenteditable）：通配符 + !important 在几千个 WPS span 上
   每敲一个字都触发全子树样式重算 → 打字卡顿；编辑时交还给 execCommand，退出即恢复 */
.script-content:not([contenteditable="true"]) * {
  font-size: inherit !important;
  line-height: inherit !important;
  font-family: inherit !important;
}
/* 标题档（正文/标题1-3 全文切换后）保持层级：em 相对值，随阅读字号一起缩放 */
.script-content h1 { font-size: 1.5em !important; }
.script-content h2 { font-size: 1.3em !important; }
.script-content h3 { font-size: 1.15em !important; }

/* 富文本/本机草稿视图：换行只认 <p>/<br>，HTML 源码里的 \n 一律折叠
   （BOSS端 WPS 粘贴的 span 里带 \n，pre-wrap 会把它们渲染成断行 → 格式错乱） */
.script-content.is-rich {
  white-space: normal;
}

.script-content.is-empty {
  color: var(--text-muted);
  font-style: normal;
}

/* ========================= 摄像头预览窗口 ========================= */

/* 16:9 容器 + 黑底 + 比例保持（加黑边，绝不拉伸） */
.video-frame {
  position: relative;
  /* 宽度上限 = 54vh × 画面宽高比：竖屏(9:16)时预览高不超过 54vh，
     不再撑出巨框霸屏挡住下方内容；横向比例时仍占满栏宽。窄了自动居中。 */
  width: min(100%, calc(54vh * var(--ar, 1.7778)));
  margin: 0 auto;
  aspect-ratio: 16 / 9;
  background: #0b1220;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow);
}

.video-frame video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* contain = 保持原始比例，四周补黑边，不裁切不变形 */
  object-fit: contain;
  background: #0b1220;
  display: block;
}

/* 员工端本地预览做镜像（照镜子）。发给查看端的流不受影响 —— 这里只改 CSS。 */
.video-frame video.is-mirrored {
  transform: scaleX(-1);
}

.video-frame.is-flat {
  box-shadow: none;
}

/* ---------- 视频参数：上行带宽 + 清晰度档位（OBS 捕获软件同款，融入设备与画质卡） ---------- */
.vq-band-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  font-size: 13px;
}
.vq-band-label { color: var(--text-muted); }
.vq-band-val {
  color: var(--primary);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.vq-band-tip {
  color: #94a3b8;
  cursor: help;
  font-size: 12px;
}
.vq-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin-bottom: 6px;
}
.vq-preset {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 13px;
  cursor: pointer;
  color: var(--text);
  white-space: nowrap;
}
.vq-preset input { accent-color: var(--primary); margin: 0; }
.vq-hint {
  font-size: 12px;
  color: #94a3b8;
  margin-bottom: 12px;
  line-height: 1.5;
}

/* ---------- 画布选择 / 画布对齐（OBS 捕获软件同款卡片组） ---------- */
.cv-block {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}
.cv-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 6px;
}
.cv-label-sub { font-weight: 400; font-size: 11px; }
.cv-ratio-row {
  display: flex;
  gap: 8px;
  margin-bottom: 10px;
}
.cv-ratio-btn {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: 8px 4px;
  font-size: 11.5px;
  color: var(--text-muted);
  background: #f8fafc;
  border: 1px solid var(--border);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
}
.cv-ratio-btn:hover { border-color: #93b4f0; }
.cv-ratio-btn.is-active {
  border-color: var(--primary);
  color: var(--primary);
  font-weight: 600;
  box-shadow: inset 0 0 0 1px var(--primary);
  background: #eff4ff;
}
.cv-shape {
  display: block;
  background: #cbd5e1;
  border-radius: 3px;
}
.cv-ratio-btn.is-active .cv-shape { background: var(--primary); }
.cv-169 { width: 26px; height: 15px; }
.cv-43 { width: 22px; height: 16px; }
.cv-916 { width: 13px; height: 23px; }
.cv-auto { width: 20px; height: 20px; border-radius: 50%; }

/* ---------- 预览吸顶（滑动下方调节面板时标题+画面整体固定不动） ---------- */
/* sticky 要求祖先不裁剪：预览卡取消 overflow:hidden（卡内无需要裁剪的背景，圆角不受影响） */
.host-side-col .side-card.preview-card {
  overflow: visible;
}
/* 吸顶单元 = 卡片标题栏 + 预览画面：标题与边框都不动，始终停在右栏顶部 */
.preview-pin {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 8;
  background: var(--card);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  transition: box-shadow 0.18s;
}
/* 已吸顶：加投影 + 1px 下边线（用 shadow 画，不产生 1px 抖动） */
.preview-pin.is-stuck {
  box-shadow: 0 14px 30px rgba(15, 23, 42, 0.3), 0 1px 0 0 var(--border);
}

/* 常驻操作条：开始采集/停止/开始工作放进吸顶单元，滚到调节面板最底也一直在眼前 */
.pin-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  padding: 10px 12px;
  border-top: 1px solid var(--border);
  background: var(--card);
}
.pin-actions .pin-span {
  grid-column: 1 / -1;
}

.video-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background: rgba(11, 18, 32, 0.88);
  color: #cbd5e1;
  font-size: 14px;
  text-align: center;
  padding: 20px;
}

.video-overlay .icon {
  font-size: 26px;
  opacity: 0.7;
}

.video-badge {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 5;
  font-size: 12px;
  font-weight: 500;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(15, 23, 42, 0.72);
  color: #e2e8f0;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  gap: 6px;
}

.video-badge .live-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #ef4444;
}

/* ============================= 布局 ============================= */

/* 上岗页（电脑端）：左侧 70% 话术 + 右侧 30% 预览 */
.host-layout {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 3fr);
  gap: 18px;
  padding: 18px 20px 24px;
  height: calc(100vh - var(--header-h));
  height: calc(100dvh - var(--header-h));
  align-items: stretch;
}

.host-script-col {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

/* 话术卡：固定在视口内，话术区内置滚动条（「滚屏」在该框内循环，不再整页滚） */
.script-card {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.script-card .card-head,
.script-card .script-legend {
  flex-shrink: 0;
}
.script-card .script-scroll {
  flex: 1 1 auto;
  min-height: 0;
  max-height: none;
}

.host-side-col {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: thin;
}

/* ---------- 右栏紧凑排版：预览+控制+设备+外部平台画面 控制在一屏内 ---------- */
.host-side-col {
  gap: 10px;
  overscroll-behavior: contain;
}
.host-side-col .side-card .card-head {
  padding: 8px 12px;
  gap: 8px;
}
.host-side-col .side-card .card-title {
  font-size: 14px;
}
.host-side-col .side-card .card-body {
  padding: 10px 12px;
}
.host-side-col .side-card .kv {
  padding: 3px 0;
  font-size: 12.5px;
}
.host-side-col .side-card .field {
  margin-bottom: 8px;
}
.host-side-col .side-card .field-label {
  font-size: 11.5px;
  margin-bottom: 3px;
}
.host-side-col .side-card .select {
  padding: 6px 30px 6px 10px;
  font-size: 13px;
}
.host-side-col .side-card .btn-lg {
  font-size: 15px;
  padding: 10px 18px;
}
.host-side-col .side-card .mt-12 {
  margin-top: 8px;
}
.host-side-col .side-tip {
  font-size: 11.5px;
  line-height: 1.5;
}
/* 上岗自动开小窗 勾选框（窄栏里压缩成一行小字） */
.douyin-card .card-head {
  flex-wrap: wrap; /* 右栏窄时让勾选框/按钮换行，不挤破标题 */
  row-gap: 6px;
}
.douyin-card .card-head .dy-auto-pop {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
  margin-right: 6px;
  font-size: 11.5px;
  color: var(--text-secondary, #64748b);
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  white-space: nowrap;
}
.douyin-card .card-head .dy-auto-pop input {
  width: 13px;
  height: 13px;
  margin: 0;
  accent-color: var(--primary, #2563eb);
  cursor: pointer;
}
.douyin-card .card-head .dy-auto-pop:hover {
  color: var(--primary, #2563eb);
}

/* 外部平台工作间画面区：占右栏剩余高度 */
.douyin-card {
  flex: 1 1 auto;
  min-height: 160px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.douyin-card .douyin-side-body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 8px 12px 10px;
}
.douyin-card .side-douyin-frame {
  flex: 1 1 auto;
  width: 100%;
  min-height: 0;
  border: 0;
  border-radius: 8px;
  background: #0b1220;
}
.douyin-card .douyin-side-note {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-align: center;
  color: var(--text-secondary, #64748b);
  font-size: 12.5px;
  line-height: 1.6;
  border: 1px dashed var(--border-strong, #cbd5e1);
  border-radius: 8px;
  padding: 10px;
}
.douyin-card .douyin-hint-icon {
  font-size: 22px;
}

/* ---------- 外部平台工作间实时画面（服务端代理取流，16:9 画面框） ----------
   画面比例严格保持原始比例：竖屏流在 16:9 框内左右留黑边，绝不拉伸变形。 */
.dy-live-box {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1 1 auto;
  min-height: 0;
}
/* 手机竖屏造型（用户指定 9:16 + iPhone 外观）：
   深色金属中框 + 大圆角 + 顶部灵动岛；高度不超过视口 68vh，超宽面板时水平居中 */
.dy-live-frame {
  position: relative;
  width: min(100%, calc(68vh * 9 / 16), 320px);
  aspect-ratio: 9 / 16;           /* 用户指定：按 9:16 手机竖屏显示 */
  margin: 0 auto;
  background: #05070c;
  border-radius: 38px;
  overflow: hidden;
  border: 7px solid #16181d;      /* iPhone 深色中框 */
  outline: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 14px 34px rgba(15, 23, 42, 0.28), inset 0 0 0 2px rgba(255, 255, 255, 0.05);
}
/* 灵动岛（顶部居中黑胶囊，叠在画面上，不挡操作） */
.dy-live-frame::before {
  content: '';
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  width: 30%;
  height: 15px;
  background: #000;
  border-radius: 999px;
  z-index: 6;
  box-shadow: inset 0 0 2px rgba(255, 255, 255, 0.08);
  pointer-events: none;
}
.dy-live-video {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: contain;           /* 加黑边、不拉伸 */
  background: #05070c;
}
.dy-live-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 10px;
  text-align: center;
  background: linear-gradient(180deg, rgba(6, 10, 18, 0.72), rgba(6, 10, 18, 0.9));
  color: #e6eefb;
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  transition: opacity 0.2s ease;
}
.dy-live-overlay.is-hidden { opacity: 0; pointer-events: none; }
.dy-live-state { font-size: 13px; font-weight: 600; letter-spacing: 0.2px; }
.dy-live-sub { font-size: 11.5px; opacity: 0.72; line-height: 1.5; }
.dy-live-badge {
  position: absolute;
  top: 7px;
  left: 8px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
  background: rgba(229, 48, 61, 0.92);
  box-shadow: 0 2px 10px rgba(229, 48, 61, 0.45);
}
.dy-live-badge::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #fff;
  animation: dy-live-dot 1.2s ease-in-out infinite;
}
@keyframes dy-live-dot {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}
/* 控制条悬浮在画面内部底部（用户指定：不占画面外的空间） */
.dy-live-ctl {
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 8px;
  z-index: 7;
  display: flex;
  align-items: center;
  gap: 5px;
  flex-wrap: wrap;
  padding: 5px 6px;
  border-radius: 14px;
  background: rgba(8, 12, 20, 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.dy-live-ctl .btn {
  padding: 3px 9px;
  font-size: 11.5px;
  white-space: nowrap;
  box-shadow: none;
}
.dy-live-ctl .btn-outline {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.22);
  color: #e6eefb;
}
.dy-live-ctl .btn-outline:hover {
  background: rgba(255, 255, 255, 0.16);
}
.dy-live-ctl a {
  text-decoration: none;
}
.dy-live-ctl-gap { flex: 1 1 auto; }
.dy-live-sel {
  width: auto;
  min-width: 70px;
  padding: 3px 6px;
  font-size: 11.5px;
  height: 26px;
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.22);
  color: #e6eefb;
}
.dy-live-meta {
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--text-secondary, #64748b);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- 右栏二次压缩（按用户标注） ---------- */
/* 镜像切换按钮：悬浮在预览画面右上角 */
.video-mirror-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 6;
  border: none;
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 12px;
  color: #fff;
  background: rgba(15, 23, 42, 0.55);
  cursor: pointer;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  transition: background 0.15s ease;
}
.video-mirror-btn:hover {
  background: rgba(15, 23, 42, 0.8);
}
.video-mirror-btn.is-off {
  opacity: 0.65;
}

/* ---------- 画面快捷工具（并入底部音频条一行，节约空间） ---------- */
.video-tools {
  display: flex;
  gap: 4px;
  flex: 0 0 auto;
}
.video-tool-btn {
  border: none;
  border-radius: 999px;
  padding: 3px 8px;
  font-size: 11.5px;
  color: #fff;
  background: rgba(255, 255, 255, 0.18);
  cursor: pointer;
  transition: background 0.15s ease;
  white-space: nowrap;
}
.video-tool-btn:hover { background: rgba(255, 255, 255, 0.32); }
.video-tool-btn.is-on {
  background: var(--primary);
}
.video-tool-btn.is-on:hover { background: #1d4ed8; }

/* ---------- 构图参考线：头顶留白线 + 头部区 + 肩线弧（仅本机预览叠加） ---------- */
.compose-guide {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
}
.compose-guide.hidden { display: none; }
/* 预览框恒定 4:3，viewBox 400×300 正好铺满不变形 */
.compose-guide .cg-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
/* 构图参考线：沿用开屏姿势插画风格 —— 细白柔线、低干扰、干净标签 */
.compose-guide .cg-dash {
  fill: none;
  stroke: rgba(255, 255, 255, 0.8);
  stroke-width: 2;
  stroke-dasharray: 1 7;
  stroke-linecap: round;
  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));
}
.compose-guide .cg-ell {
  fill: rgba(255, 255, 255, 0.07);
  stroke: rgba(255, 255, 255, 0.8);
  stroke-width: 2;
  stroke-dasharray: 1 7;
  stroke-linecap: round;
  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));
}
.compose-guide .cg-label {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  font-size: 11px;
  font-weight: 600;
  color: #3a4a5c;
  background: rgba(255, 255, 255, 0.92);
  border-radius: 999px;
  padding: 2.5px 10px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
  white-space: nowrap;
}

/* ---------- 自动检测：结果大字直接显示在画面上，5 秒后消失 ---------- */
.video-diag {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 8;
  pointer-events: none;
  max-width: 88%;
  text-align: center;
  background: rgba(0, 0, 0, 0.45);
  border-radius: 12px;
  padding: 12px 18px;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
.video-diag.hidden { display: none; }
.video-diag .vd-row {
  font-size: 17px;
  font-weight: 600;
  color: #fff;
  line-height: 1.6;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.8);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.video-diag .vd-tip {
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.92);
  line-height: 1.5;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
}

/* ---------- 预览全屏展示（⛶ 按钮 / 双击进入，Esc 退出） ---------- */
.video-frame:fullscreen {
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  border-radius: 0;
  background: #000;
}
.video-frame:fullscreen video {
  object-fit: contain;
}
/* 麦克风音量条：悬浮在预览画面底部 */
.video-mic-strip {
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 8px;
  z-index: 6;
  display: flex;
  align-items: center;
  gap: 8px;
  background: rgba(15, 23, 42, 0.55);
  border-radius: 999px;
  padding: 5px 12px;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
.video-mic-strip .vm-icon {
  font-size: 12px;
}
.video-mic-strip .vm-meter {
  flex: 1 1 auto;
  height: 6px;
  background: rgba(255, 255, 255, 0.25);
  border-color: transparent;
}
.video-mic-strip .vm-val {
  font-size: 11.5px;
  color: #fff;
  min-width: 42px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
/* 工作控制数据：两栏网格 */
.kv-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 12px;
}
.kv-grid .kv-span {
  grid-column: 1 / -1;
}
/* 设备设置：画质+码率并排 */
.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-top: 8px;
}

/* 移动端提示条（仅手机竖屏显示） */
.portrait-hint {
  display: none;
  align-items: center;
  gap: 8px;
  background: var(--primary-soft);
  border: 1px solid var(--primary-border);
  color: #1e40af;
  border-radius: var(--radius);
  padding: 10px 14px;
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.5;
}

.portrait-hint .hint-icon {
  flex: 0 0 auto;
  font-size: 15px;
}

/* ============================ 表单控件 ============================ */

.field {
  margin-bottom: 14px;
}

.field-label {
  display: block;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-sub);
  margin-bottom: 6px;
}

.input,
.select,
.textarea {
  width: 100%;
  font-family: inherit;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
  background: #fff;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  padding: 9px 12px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.input:focus,
.select:focus,
.textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}

.input::placeholder,
.textarea::placeholder {
  color: var(--text-muted);
}

.textarea {
  resize: vertical;
  min-height: 120px;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.6;
}

.select {
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2364748b' d='M6 8L0 0h12z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 34px;
}

/* 麦克风音量条 */
.meter {
  height: 6px;
  border-radius: 999px;
  background: var(--secondary-soft);
  overflow: hidden;
  border: 1px solid var(--border);
}

.meter-fill {
  height: 100%;
  width: 0%;
  background: var(--success);
  border-radius: 999px;
  transition: width 0.1s linear, background-color 0.2s ease;
}

/* 信息行 */
.kv {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 0;
  font-size: 13px;
  border-bottom: 1px dashed var(--border);
}
.kv:last-child {
  border-bottom: none;
}
.kv .k {
  color: var(--text-muted);
  flex: 0 0 auto;
}
.kv .v {
  color: var(--text-sub);
  font-weight: 500;
  text-align: right;
  word-break: break-all;
  min-width: 0;
}
.kv .v.mono {
  font-family: var(--font-mono);
  font-size: 12.5px;
}

/* ============================= 提示条 ============================= */

.alert {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border-radius: var(--radius);
  font-size: 13.5px;
  line-height: 1.6;
  border: 1px solid var(--border);
  background: var(--secondary-soft);
  color: var(--text-sub);
}
.alert .alert-icon {
  flex: 0 0 auto;
  font-size: 15px;
  line-height: 1.4;
}
.alert-danger {
  background: var(--danger-soft);
  border-color: #fecaca;
  color: #991b1b;
}
.alert-warn {
  background: var(--warning-soft);
  border-color: #fde68a;
  color: #92400e;
}
.alert-info {
  background: var(--primary-soft);
  border-color: var(--primary-border);
  color: #1e40af;
}
.alert-success {
  background: var(--success-soft);
  border-color: #bbf7d0;
  color: #166534;
}

/* ============================ 查看页 ============================ */

.watch-main {
  /* 固定为可视区高度，让里面的画面区可以撑满（主画面越大越好） */
  height: calc(100vh - var(--header-h));
  height: calc(100dvh - var(--header-h));
  display: flex;
  flex-direction: column;
  padding: 12px 16px 8px;
  gap: 8px;
}

.watch-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
}

.watch-stage {
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
  min-height: 0;
}

/* 主画面占满顶栏和状态行以外的全部空间。
   视频本身用 object-fit: contain 保持原始 16:9，
   多出来的区域是黑色底（.video-frame 背景），不裁切不变形。 */
.watch-stage .video-frame {
  height: 100%;
  aspect-ratio: auto;
}

.watch-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
  font-size: 13px;
  color: var(--text-muted);
  min-height: 24px;
}

/* --------------------- 交接班侧栏 --------------------- */

/* 有侧栏时改为横向布局：左边大画面（占满剩余宽度），右边待播员工端 */
.watch-main.has-side {
  flex-direction: row;
  align-items: stretch;
  gap: 12px;
}
.watch-main:not(.has-side) .watch-side {
  display: none;
}

.watch-side {
  flex: 0 0 200px;
  width: 200px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
  overflow: hidden;
}

.side-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 2px;
}
.side-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-sub);
  letter-spacing: 0.5px;
}

.side-list {
  flex: 1 1 auto;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 2px;
  min-height: 0;
}

/* 单个待播员工端卡片 */
.side-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s;
  flex: 0 0 auto;
}
.side-card:hover {
  border-color: var(--primary);
}
/* 当前正在大画面展示的员工端：蓝色描边 */
.side-card.is-active {
  border-color: var(--primary);
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.18);
}
.side-card.is-offline {
  cursor: default;
  opacity: 0.72;
}

.side-thumb {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #0b1220;
  overflow: hidden;
}
.side-thumb video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}
/* 无画面时的占位 */
.side-placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #64748b;
  font-size: 12px;
  background: linear-gradient(180deg, #1e293b 0%, #0b1220 100%);
}
.side-placeholder .cam {
  font-size: 22px;
  opacity: 0.85;
}

/* 角标：工作中 / 待播 */
.side-flag {
  position: absolute;
  left: 6px;
  top: 6px;
  font-size: 11px;
  line-height: 1;
  padding: 3px 7px;
  border-radius: 999px;
  color: #fff;
  background: rgba(15, 23, 42, 0.72);
}
.side-flag.is-live {
  background: #16a34a;
}
.side-flag.is-ready {
  background: #2563eb;
}

.side-info {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  padding: 6px 9px 7px;
}
.side-name {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.side-devices {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 11px;
  line-height: 1;
}
/* 摄像头/麦克风图标：开着的高亮，关着的灰暗（emoji 不吃 color，用透明度+灰度） */
.side-devices .dev {
  transition: opacity 0.15s, filter 0.15s;
}
.side-devices .dev.on {
  opacity: 1;
  filter: none;
}
.side-devices .dev.off {
  opacity: 0.3;
  filter: grayscale(1);
}

/* ---------------------------------------------------------------------
   纯净模式（?bare=1）：只留一个画面，方便OBS 捕获软件抓取窗口

   交接班侧栏在纯净模式下隐藏 —— 否则待播员工端的小窗会被一起抓进外部平台工作间。
   但「自动切换大画面」的逻辑照常运行，所以交接班依然是自动完成的：
   一号员工端停播、二号员工端上岗后，大画面会自己切过去，抓到的一直是当前员工端。
   --------------------------------------------------------------------- */
body.bare {
  background: #000;
}
body.bare .topbar,
body.bare .watch-meta,
body.bare .watch-side {
  display: none !important;
}
body.bare .watch-main {
  height: 100vh;
  height: 100dvh;
  padding: 0;
  gap: 0;
}
body.bare .watch-stage {
  width: 100vw;
  min-width: 0;
}
body.bare .video-frame {
  border-radius: 0;
  box-shadow: none;
  height: 100vh;
  height: 100dvh;
}

/* 巨幕/全屏按钮，鼠标离开自动淡化，避免被OBS 捕获软件抓进画面 */
.float-btn {
  position: fixed;
  right: 16px;
  bottom: 16px;
  /* iOS 安全区：横屏刘海在右、Home 指示条在下 */
  right: calc(16px + var(--sar));
  bottom: calc(16px + var(--sab));
  z-index: 80;
  opacity: 0;
  transition: opacity 0.2s ease;
}
body:hover .float-btn,
.float-btn:focus-visible {
  opacity: 1;
}

/* ============================ 全屏错误页 ============================ */

.fullscreen-block {
  position: fixed;
  inset: 0;
  z-index: 999;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.block-card {
  max-width: 460px;
  width: 100%;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 32px 28px;
  text-align: center;
}

.block-card .block-icon {
  font-size: 40px;
  line-height: 1;
  margin-bottom: 16px;
}

.block-card h2 {
  margin: 0 0 10px;
  font-size: 19px;
  font-weight: 600;
  color: var(--text);
}

.block-card p {
  margin: 0 0 8px;
  font-size: 14px;
  line-height: 1.7;
  color: var(--text-sub);
}

.block-card .block-tip {
  margin-top: 18px;
  padding: 12px 14px;
  background: var(--secondary-soft);
  border-radius: var(--radius);
  font-size: 13px;
  color: var(--text-muted);
  text-align: left;
  line-height: 1.7;
}

/* ============================= 后台 ============================= */

.admin-wrap {
  max-width: var(--tk-container);
  margin: 0 auto;
  padding: 20px 20px 60px;
}

.admin-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 18px;
}

.toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.table-wrap {
  overflow-x: auto;
  border-radius: var(--radius);
  border: 1px solid var(--border);
}

table.tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
  background: #fff;
  min-width: 900px;
}

table.tbl th {
  text-align: left;
  font-weight: 600;
  color: var(--text-sub);
  background: var(--secondary-soft);
  padding: 10px 12px;
  white-space: nowrap;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
}

table.tbl td {
  padding: 12px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  color: var(--text);
}

table.tbl tr:last-child td {
  border-bottom: none;
}

table.tbl tr:hover td {
  background: #fbfdff;
}

.tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 500;
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
  border: 1px solid var(--border);
  background: var(--secondary-soft);
  color: var(--text-sub);
}
.tag-ok {
  background: var(--success-soft);
  border-color: #bbf7d0;
  color: #15803d;
}
.tag-off {
  background: var(--danger-soft);
  border-color: #fecaca;
  color: #b91c1c;
}
.tag-live {
  background: #eff6ff;
  border-color: var(--primary-border);
  color: var(--primary);
}

.row-actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

/* 老板端房间卡：把「作废 / 重置上岗链接」这类**不可逆**的键推到最后，
   并用一条细线隔开，降低"手抖就点到"的概率。
   ⚠️ 这不是二次确认的替代品 —— 那两个操作在 revokeRoom()/rotateRoom() 里本来就有 confirm()。
      这里只解决"危险键紧挨日常键"的布局问题。
   ⚠️ 窄屏下按钮本来就会换行，分隔线反而会打断阅读，所以 <560px 直接隐藏。 */
.row-actions-sep {
  flex: 1 1 auto;
  min-width: 10px;
  height: 22px;
  align-self: center;
  margin-left: 4px;
  border-left: 1px solid var(--line);
}
@media (max-width: 560px) {
  .row-actions-sep { display: none; }
}

.link-box {
  display: flex;
  align-items: center;
  gap: 6px;
}
.link-box input {
  font-family: var(--font-mono);
  font-size: 12px;
  padding: 5px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--secondary-soft);
  color: var(--text-sub);
  width: 100%;
  min-width: 0;
}

/* 弹窗 */
.modal-mask {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.42);
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.modal {
  background: #fff;
  border-radius: var(--radius-lg);
  width: 100%;
  max-width: 680px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 18px 48px rgba(15, 23, 42, 0.22);
  overflow: hidden;
}

.modal-head {
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex: 0 0 auto;
}

.modal-head h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

.modal-body {
  padding: 20px;
  overflow-y: auto;
  flex: 1 1 auto;
}

.modal-foot {
  padding: 14px 20px;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  flex: 0 0 auto;
}

.hidden {
  display: none !important;
}

/* 文本工具类 */
.mono {
  font-family: var(--font-mono);
  font-size: 12.5px;
}
.muted {
  color: var(--text-muted);
}
.text-sm {
  font-size: 13px;
}
.mb-0 {
  margin-bottom: 0;
}
.mb-12 {
  margin-bottom: 12px;
}
.mt-12 {
  margin-top: 12px;
}

/* 预览浮层里的诊断入口（仅在采集失败时出现）：醒目按钮行，不再是不起眼的文字链接 */
.overlay-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}
.overlay-actions .btn {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
}
/* 环境自检面板：失败时列出页面地址/安全上下文/脚本版本/设备数/抛错位置 */
.overlay-env {
  margin-top: 10px;
  padding: 8px 10px;
  max-width: 92%;
  text-align: left;
  font-family: var(--font-code, Consolas, monospace);
  font-size: 10.5px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.82);
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 8px;
  white-space: pre-wrap;
  word-break: break-all;
}

/* =====================================================================
   摄像头诊断页
   ===================================================================== */

.diag-wrap {
  max-width: 880px;
  margin: 0 auto;
  padding: 22px 20px 60px;
}

.diag-head {
  margin-bottom: 18px;
}
.diag-head h1 {
  font-size: 22px;
  font-weight: 600;
  color: var(--text);
  margin: 0 0 6px;
}
.diag-head p {
  margin: 0;
  color: var(--text-muted);
  font-size: 13.5px;
}

/* 单条检查项 */
.diag-item {
  display: flex;
  gap: 12px;
  padding: 13px 0;
  border-bottom: 1px solid var(--border);
}
.diag-item:last-child {
  border-bottom: none;
}
.diag-item .diag-mark {
  flex: 0 0 22px;
  height: 22px;
  line-height: 22px;
  text-align: center;
  border-radius: 50%;
  font-size: 12px;
  background: #e2e8f0;
  color: #64748b;
}
.diag-item.is-run .diag-mark {
  background: #dbeafe;
  color: #2563eb;
}
.diag-item.is-ok .diag-mark {
  background: #dcfce7;
  color: #16a34a;
}
.diag-item.is-fail .diag-mark {
  background: #fee2e2;
  color: #dc2626;
}
.diag-item.is-warn .diag-mark {
  background: #fef3c7;
  color: #d97706;
}

.diag-item .diag-body {
  flex: 1 1 auto;
  min-width: 0;
}
.diag-item .diag-title {
  font-weight: 500;
  color: var(--text);
  font-size: 14.5px;
  margin-bottom: 3px;
}
.diag-item .diag-detail {
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1.6;
  word-break: break-word;
}
.diag-item .diag-detail code {
  font-family: var(--font-mono);
  font-size: 12.5px;
  background: #f1f5f9;
  padding: 1px 5px;
  border-radius: 4px;
  color: #334155;
}

/* 诊断结论 */
.diag-verdict {
  margin-top: 16px;
  padding: 14px 16px;
  border-radius: 10px;
  font-size: 14px;
  line-height: 1.7;
}
.diag-verdict.is-ok {
  background: #f0fdf4;
  border: 1px solid #bbf7d0;
  color: #166534;
}
.diag-verdict.is-fail {
  background: #fef2f2;
  border: 1px solid #fecaca;
  color: #991b1b;
}
.diag-verdict ol {
  margin: 8px 0 0;
  padding-left: 20px;
}
.diag-verdict li {
  margin-bottom: 5px;
}

.diag-video {
  margin-top: 12px;
  border-radius: 10px;
  overflow: hidden;
  background: #000;
  aspect-ratio: 16 / 9;
  position: relative;
}
.diag-video video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.diag-toolbar {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}

/* =====================================================================
   移动端适配：手机竖屏（员工端竖着拿手机看话术）
   ===================================================================== */
@media (max-width: 900px) {
  :root {
    --header-h: calc(54px + var(--sat));
  }

  body {
    font-size: 15px;
  }

  .topbar {
    padding: 0 14px;
    /* ⚠️ 简写 padding 会把上面的 padding-top:var(--sat) 一起重置成 0。
       这个断点是 ≤900px —— 正是 iPhone 全系，必须把安全区再写一遍。 */
    padding-top: var(--sat);
    padding-left: calc(14px + var(--sal));
    padding-right: calc(14px + var(--sar));
    gap: 10px;
  }

  /* 手机端改为上下堆叠：预览在上，话术在下 */
  .host-layout {
    display: flex;
    flex-direction: column;
    height: auto;
    min-height: calc(100vh - var(--header-h));
    min-height: calc(100dvh - var(--header-h));
    gap: 12px;
    padding: 12px 14px 22px;
  }

  /* 提示：请竖持手机使用 */
  .portrait-hint {
    display: flex;
    order: -2;
  }

  .host-side-col {
    order: -1;
    overflow: visible;
    gap: 12px;
  }

  /* 手机端是整页滚动，不做吸顶（避免遮挡上岗话术） */
  .preview-pin {
    position: relative;
    top: auto;
  }

  .host-script-col {
    min-height: 52vh;
  }

  /* 手机窄屏：麦克风音频条 + 5 个操作按钮放不下，允许按钮换到第二行
     （否则 op-btns 撑到 ~600px，整页横向溢出、顶部提示条被顶出屏） */
  .host-op-bar {
    flex-wrap: wrap;
  }
  .host-op-bar .op-btns {
    flex: 1 1 100%;   /* 独占一行，内部再换行，保证不横向溢出 */
    flex-wrap: wrap;
  }

  /* 移动端：BOSS端沟通 / 外部平台咨询区 上下堆叠 */
  .host-bottom-row {
    flex-direction: column;
    height: auto;
    margin-top: 12px;
    gap: 12px;
  }
  .host-bottom-row .chat-card,
  .host-bottom-row .dychat-card {
    min-height: 280px;
  }

  /* 移动端：话术框限高，滚屏同样在框内循环 */
  .script-card .script-scroll {
    flex: none;
    max-height: 58vh;
  }

  .script-content {
    font-size: 17px;
    line-height: 1.4;
  }

  .card-head {
    padding: 13px 15px;
  }

  .card-body {
    padding: 15px;
  }

  .btn {
    padding: 11px 16px;
  }

  .topbar-title {
    display: none;
  }

  .brand-title-inline {
    display: none;
  }

  .modal {
    max-height: 94vh;
  }

  .admin-wrap {
    padding: 14px 14px 50px;
  }

  /* 查看页：窄屏改为上下堆叠，主画面仍然占满，侧栏变成横向滑动 */
  .watch-main {
    padding: 10px 10px 6px;
  }
  .watch-main.has-side {
    flex-direction: column;
  }
  .watch-side {
    flex: 0 0 auto;
    width: 100%;
  }
  .side-list {
    flex-direction: row;
    overflow-x: auto;
    overflow-y: hidden;
    padding-bottom: 4px;
  }
  /* 只限查看页侧栏小窗（.side-list 内）；上岗页预览卡同名 .side-card，
     不加容器限定会被命中成 150px 窄条（2026-10-02 手机竖屏排版事故） */
  .side-list .side-card {
    flex: 0 0 150px;
    width: 150px;
  }

  /* 查看页手机竖屏：顶栏 7 个元素约 760px 放不进 390px，
     只留 导航 + 静音 + 连接状态（班次/日志与网络信息丸是桌面辅助信息） */
  body.cockpit-theme .topbar .brand,
  body.cockpit-theme .topbar .topbar-divider,
  body.cockpit-theme .topbar #btnShifts,
  body.cockpit-theme .topbar #netPill,
  body.cockpit-theme .topbar #netDownPill {
    display: none;
  }
}

/* 手机横屏（员工端横过来）—— 恢复左右布局 */
@media (max-width: 900px) and (orientation: landscape) {
  .host-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 260px;
    height: calc(100vh - var(--header-h));
    height: calc(100dvh - var(--header-h));
    padding: 12px;
  }
  .portrait-hint {
    display: none;
  }
  .host-side-col {
    order: 0;
    overflow-y: auto;
  }
  .host-script-col {
    min-height: 0;
    order: 0;
  }
}

@media (max-width: 480px) {
  .script-content {
    font-size: 16.5px;
  }
  .status {
    font-size: 12px;
    padding: 4px 9px;
  }

  /* ---- 顶栏在 320~360px 上会横向顶出屏幕 ----
     ⚠️ 顶栏里 4 个 `flex: 0 0 auto` 的项：品牌占位 100 + 分隔线 1 + 导航按钮 78 +
        状态徽标 107 = **286px**；再加 4 个 gap（10×4=40）与 .topbar-spacer 的 min-width:8，
        合计 334px。而 320px 屏上 `.topbar` 的可用内容宽只有 320-14-14 = **292px**。
        ⇒ 必然溢出：/diag 实测 320px 溢出 28px（88→2 个越界元素）、360px 溢出 13px。
        这是**既有问题**（用改动前的 CSS 复现同样数值），与安全区改动无关。

     处置两条，都只压「非内容」开销，不动任何要给人看 / 要给人点的东西：
       ① gap 10→8、左右内边距 14→10（省 24px）；
       ② 允许状态徽标被压缩、内部文字走省略号 —— 它是最可牺牲的一项。
     刻意不动：品牌、分隔线、导航按钮 —— 缩了要么丢客户标识、要么点不中。 */
  .topbar {
    gap: 8px;
    /* ⚠️ 只写 longhand。用 padding 简写会把上面 ≤900px 断点设的
       `padding-top: var(--sat)` 一起重置成 0 —— 刘海屏立刻钻到状态栏后面。 */
    padding-left: calc(10px + var(--sal));
    padding-right: calc(10px + var(--sar));
  }
  .topbar-spacer { min-width: 4px; }
  .topbar .status {
    flex: 0 1 auto;   /* 原本是 .status 的 flex:0 0 auto —— 明确改成「可压缩」 */
    min-width: 0;
    overflow: hidden;
  }
  .topbar .status > span:not(.status-dot) {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* 打印 / 截图友好：确保没有半透明遮挡 */
@media print {
  .btn,
  .float-btn {
    display: none !important;
  }
}

/* =============================================================
   v2 追加：工作台首页 / BOSS端侧边栏 / 聊天 / 话术差异 / 公告等
   ============================================================= */

/* ---------- 员工端工作台首页 ---------- */
.home-login-row {
  display: flex;
  gap: 12px;
  align-items: flex-end;
  flex-wrap: wrap;
}
.home-login-row .field {
  flex: 1 1 200px;
  margin-bottom: 0;
}
.schedule-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
.schedule-day-title {
  font-size: 14px;
  color: #64748b;
  margin: 0 0 10px;
  font-weight: 600;
}
.schedule-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.schedule-empty {
  padding: 14px;
  border: 1px dashed #e2e8f0;
  border-radius: 10px;
  text-align: center;
  font-size: 13px;
}
.schedule-item {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  padding: 10px 12px;
  background: #fff;
}
.schedule-time {
  font-variant-numeric: tabular-nums;
  color: #2563eb;
  font-weight: 600;
  white-space: nowrap;
  padding-top: 2px;
}
.room-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 14px;
}
.room-item {
  margin-bottom: 0 !important;
}

/* ---------- 协作页：主区 + 15% 侧边栏 ---------- */
.boss-wrap {
  display: flex;
  align-items: stretch;
  min-height: calc(100vh - 60px);
  min-height: calc(100dvh - 60px);
}
.boss-main {
  flex: 1 1 auto;
  min-width: 0;
}
.boss-side {
  flex: 0 0 15%;
  min-width: 230px;
  max-width: 320px;
  border-left: 1px solid #e2e8f0;
  background: #fff;
  display: flex;
  flex-direction: column;
  transition: flex-basis 0.18s ease, min-width 0.18s ease;
}
.boss-side.is-collapsed {
  flex-basis: 46px;
  min-width: 46px;
  overflow: hidden;
}
.boss-side.is-collapsed .boss-side-body,
.boss-side.is-collapsed .boss-side-title {
  display: none;
}
.boss-side-head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px;
  border-bottom: 1px solid #eef2f7;
}
.boss-side-title {
  font-size: 13px;
  font-weight: 600;
  color: #64748b;
}
.boss-side-body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}
.side-section {
  padding: 10px 12px;
  border-bottom: 1px solid #eef2f7;
}
.side-title {
  font-size: 13px;
  font-weight: 600;
  color: #475569;
  margin: 0 0 8px;
}
.side-chat {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-bottom: none;
}
.side-chat-target {
  margin-bottom: 8px;
}
.side-chat-target .select {
  width: 100%;
  font-size: 13px;
}
.side-chat-msgs {
  flex: 1 1 auto;
  min-height: 120px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 4px 2px;
}
.side-chat-input {
  display: flex;
  gap: 6px;
  margin-top: 8px;
}
.side-chat-input .input {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 13px;
}
.waiting-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 40vh;
  overflow-y: auto;
}
.waiting-item {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  align-items: center;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  padding: 8px 10px;
  background: #f8fafc;
}

/* ---------- 底部一行：BOSS端沟通 + 外部平台咨询区 并排 ---------- */
.host-bottom-row {
  display: flex;
  gap: 14px;
  height: 400px; /* 咨询区卡顶部新增「1号链接重要信息」条，加高让咨询区列表不吃挤压 */
  flex: 0 0 auto;
  margin-top: 14px;
  min-height: 0;
}
.host-bottom-row .chat-card {
  flex: 1 1 0;
  min-width: 0;
  margin-top: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.host-bottom-row .dychat-card {
  flex: 1.35 1 0; /* 咨询区是员工端边看边回的核心面板，占更宽 */
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.host-bottom-row .chat-card .card-body,
.host-bottom-row .dychat-card .card-body {
  flex: 1 1 auto;
  min-height: 0;
}
.host-bottom-row .chat-msgs {
  flex: 1 1 auto;
  height: auto;
  min-height: 0;
}
.host-bottom-row .dychat-list {
  flex: 1 1 auto;
  height: auto;
  min-height: 0;
}

/* ---------- 聊天（员工端 + BOSS端通用） ---------- */
.chat-card {
  margin-top: 14px;
}
.chat-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.chat-msgs {
  height: 200px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 4px 2px;
  background: #f8fafc;
  border: 1px solid #eef2f7;
  border-radius: 10px;
}
.chat-msg {
  max-width: 78%;
}
.chat-msg.is-mine {
  align-self: flex-end;
}
.chat-msg.is-other {
  align-self: flex-start;
}
.chat-meta {
  font-size: 11px;
  color: #94a3b8;
  margin-bottom: 2px;
}
.chat-msg.is-mine .chat-meta {
  text-align: right;
}
.chat-bubble {
  background: #eff6ff;
  color: #1e293b;
  border-radius: 10px;
  padding: 7px 10px;
  font-size: 13.5px;
  line-height: 1.55;
  word-break: break-word;
}
.chat-msg.is-mine .chat-bubble {
  background: #2563eb;
  color: #fff;
}
.chat-empty {
  text-align: center;
  font-size: 13px;
  padding: 16px 0;
}
.chat-input-row {
  display: flex;
  gap: 8px;
}
.chat-input-row .input {
  flex: 1 1 auto;
  min-width: 0;
}

/* ---------- 话术差异编辑器 ---------- */
.script-content.se-editor {
  white-space: pre-wrap;
  word-break: break-word;
  outline: none;
  line-height: 1.4;
}
.se-add {
  color: #2563eb;
}
.se-del {
  color: #94a3b8;
  text-decoration: line-through;
}
.script-legend {
  display: flex;
  gap: 12px;
  align-items: center;
  padding: 8px 16px;
  border-top: 1px dashed #e2e8f0;
  font-size: 12px;
  color: #64748b;
  flex-wrap: wrap;
}
.script-legend .lg::before {
  content: '';
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 3px;
  margin-right: 5px;
  vertical-align: -1px;
}
.script-legend .lg-same::before { background: #1e293b; }
.script-legend .lg-add::before { background: #2563eb; }
.script-legend .lg-del::before { background: #cbd5e1; }

/* ---------- 外部平台工作间弹窗 ---------- */
.modal-wide {
  max-width: 860px;
  width: 92vw;
}
.douyin-frame {
  width: 100%;
  height: 60vh;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  background: #f8fafc;
}

/* ---------- 员工端授权弹窗 ---------- */
.auth-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 50vh;
  overflow-y: auto;
}
.auth-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  cursor: pointer;
  font-size: 14px;
}
.auth-item:hover {
  border-color: #bfdbfe;
  background: #f8fafc;
}

/* ---------- 后台 Tab ---------- */
.admin-tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.admin-tab {
  border: 1px solid #e2e8f0;
  background: #fff;
  color: #475569;
  border-radius: 999px;
  padding: 7px 16px;
  font-size: 13.5px;
  cursor: pointer;
}
.admin-tab.is-active {
  background: #2563eb;
  border-color: #2563eb;
  color: #fff;
}
.tab-panel {
  margin-bottom: 18px;
}

/* 排班表「接单员工端」下的一行员工端简介（BOSS端排班表） */
.sched-host-intro {
  font-size: 12px;
  font-weight: 400;
  color: var(--text-muted);
  line-height: 1.5;
  margin-top: 2px;
  max-width: 240px;
  white-space: normal;
}

/* 排班表「接单员工端」列里的「看模卡 / 切片」入口 */
.sched-host-btn {
  margin-top: 6px;
  padding: 3px 10px;
  font-size: 12px;
  white-space: nowrap;
}

/* 弹窗底部左对齐按钮（「← 返回排班表」）——footer 默认右对齐，靠 auto 外边距推到左边 */
.modal-foot-left {
  margin-right: auto;
}

/* ---------- BOSS端：员工端档案（模卡 / 切片）只读视图 ---------- */

.hp-head {
  padding-bottom: 14px;
  border-bottom: 1px solid var(--border);
}
.hp-name {
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
}
.hp-tags {
  margin-top: 4px;
  font-size: 13px;
  color: var(--text-sub);
}
.hp-intro {
  margin-top: 10px;
  padding: 10px 12px;
  font-size: 13px;
  line-height: 1.7;
  color: var(--text);
  background: var(--secondary-soft);
  border-left: 3px solid var(--primary);
  border-radius: var(--radius-sm);
  white-space: pre-wrap;
}
.hp-sec {
  margin: 20px 0 10px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}

/* ---------- 我的模卡 / 我的切片（员工端工作台） ---------- */

.mc-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 12px;
}
.mc-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.mc-photos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 12px;
  margin-top: 16px;
}
.mc-photo {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--secondary-soft);
}
.mc-photo img {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  cursor: zoom-in;
}
.mc-photo .mc-del {
  position: absolute;
  right: 6px;
  bottom: 6px;
  padding: 3px 8px;
  font-size: 12px;
  color: var(--danger);
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.mc-photo .mc-del:hover {
  background: var(--danger-soft);
  border-color: var(--danger);
}
.clip-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.clip-row {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
}
.clip-row video {
  width: 160px;
  flex: 0 0 160px;
  border-radius: var(--radius-sm);
  background: #000;
}
.clip-meta {
  flex: 1 1 auto;
  min-width: 0;
}
.clip-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  word-break: break-all;
  margin-bottom: 4px;
}

/* ---------- 移动端适配 ---------- */
@media (max-width: 900px) {
  .schedule-grid {
    grid-template-columns: 1fr;
  }
  .mc-grid {
    grid-template-columns: 1fr;
  }
  .clip-row {
    flex-direction: column;
  }
  .clip-row video {
    width: 100%;
    flex: 0 0 auto;
  }
  .boss-wrap {
    flex-direction: column;
  }
  .boss-side {
    flex: 0 0 auto;
    max-width: none;
    border-left: none;
    border-top: 1px solid #e2e8f0;
    max-height: 45vh;
  }
  .boss-side.is-collapsed .boss-side-body,
  .boss-side.is-collapsed .boss-side-title {
    display: none;
  }
  .home-login-row {
    flex-direction: column;
    align-items: stretch;
  }
}

/* ---------- 外部平台内嵌受限提示卡 ---------- */
.douyin-hint {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  padding: 18px 20px;
  text-align: center;
}
.douyin-hint-icon { font-size: 30px; margin-bottom: 6px; }
.douyin-hint-title {
  font-weight: 600;
  color: #1e293b;
  margin: 0 0 6px;
}
.douyin-hint-btns {
  display: flex;
  gap: 10px;
  justify-content: center;
  margin-top: 14px;
  flex-wrap: wrap;
}

/* ---------- BOSS端房间卡：实时音频条 ---------- */
.audio-meter {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 2px 0 8px;
}
.audio-meter-track {
  flex: 1 1 auto;
  height: 8px;
  border-radius: 999px;
  background: #eef2f7;
  overflow: hidden;
}
.audio-meter-bar {
  height: 100%;
  width: 0%;
  border-radius: 999px;
  background: linear-gradient(90deg, #22c55e, #16a34a);
  transition: width 0.18s ease-out;
}

/* ---------- 查看页：员工端沟通聊天栏 ---------- */
.watch-chat {
  flex: 0 0 240px;
  width: 240px;
  border-left: 1px solid #e2e8f0;
  background: #fff;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.watch-chat .side-head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 12px;
  border-bottom: 1px solid #eef2f7;
}
.watch-chat .side-title {
  font-size: 13px;
  font-weight: 600;
  color: #475569;
}
.watch-chat-msgs {
  flex: 1 1 auto;
  min-height: 140px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px;
  background: #f8fafc;
}
.watch-chat-input {
  display: flex;
  gap: 6px;
  padding: 10px 12px;
  border-top: 1px solid #eef2f7;
}
.watch-chat-input .input {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 13px;
}

/* 查看主体：有聊天栏时也保持横向布局（聊天栏固定右侧一列） */
.watch-main.has-chat {
  flex-direction: row;
  align-items: stretch;
  gap: 12px;
}
.watch-main:not(.has-chat) .watch-chat {
  display: none;
}

/* bare 抓取模式：聊天栏隐藏，画面保持纯净 */
body.bare .watch-chat {
  display: none !important;
}

@media (max-width: 900px) {
  .watch-chat {
    flex: 0 0 auto;
    width: auto;
    border-left: none;
    border-top: 1px solid #e2e8f0;
    max-height: 40vh;
  }
}

/* ---------- 员工端话术：编辑模式文本框 + 滚屏速度 ---------- */
/* ---------- WPS 式基础编辑器工具栏（仅编辑模式显示） ---------- */
.script-editbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 3px;
  padding: 6px 12px;
  border-bottom: 1px solid #e2e8f0;
  background: #f8fafc;
  -webkit-user-select: none;
  user-select: none;
}
.script-editbar .eb-btn {
  min-width: 26px;
  height: 26px;
  padding: 0 6px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
  font-size: 13px;
  color: #334155;
  line-height: 1;
}
.script-editbar .eb-btn:hover { background: #e2e8f0; }
.script-editbar .eb-b { font-weight: 700; }
.script-editbar .eb-i { font-style: italic; font-family: Georgia, serif; }
.script-editbar .eb-u { text-decoration: underline; }
.script-editbar .eb-s { text-decoration: line-through; }
.script-editbar .eb-sep {
  width: 1px;
  height: 18px;
  background: #e2e8f0;
  margin: 0 4px;
}
.script-editbar .eb-select {
  height: 26px;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  background: #fff;
  font-size: 12px;
  color: #334155;
  padding: 0 4px;
}
.script-editbar .eb-color {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  height: 26px;
  padding: 0 6px;
  border: 1px solid transparent;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 700;
  color: #e11d48;
  cursor: pointer;
}
.script-editbar .eb-color:hover { background: #e2e8f0; }
.script-editbar .eb-color.eb-hl { color: #a16207; }
.script-editbar .eb-color input[type="color"] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}
/* 编辑模式正文：一眼看出在编辑 —— 琥珀底色与主题蓝白区分开；
   !important 压过阅读偏好（底色）写进 inline style 的 background */
.script-content[contenteditable="true"] {
  outline: none;
  background: #fef3c7 !important;
  box-shadow: inset 0 0 0 2px #f59e0b;
  border-radius: 8px;
  padding: 8px;
  min-height: 55vh;
  cursor: text;
}
.script-textarea {
  width: 100%;
  min-height: 55vh;
  height: 100%;
  resize: none;
  border: none;
  outline: none;
  background: #fff;
  color: #1e293b;
  line-height: 1.4;
  padding: 16px 18px;
  font-family: inherit;
  box-sizing: border-box;
}
.script-scroll {
  position: relative;
}
.scroll-speed-ctl {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.scroll-speed-ctl input[type='range'] {
  width: 90px;
  accent-color: #2563eb;
}

/* ==================== 画面优化 + 麦克风增强 ==================== */
.fx-stack {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
}
.fx-box {
  flex: 1 1 0;
  min-width: 0;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  padding: 8px 10px;
  background: #f8fafc;
}
.fx-box.is-active {
  border-color: #bfdbfe;
  background: #eff6ff;
}
/* 设备与画质（并入画面调节卡）：2×2 紧凑网格 */
.fx-dev-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 8px;
  margin-top: 8px;
}
.fx-dev-item {
  min-width: 0;
}
.fx-dev-label {
  display: block;
  font-size: 11px;
  color: #64748b;
  margin-bottom: 3px;
}
.fx-dev-item .select-sm {
  width: 100%;
  font-size: 12px;
  padding: 4px 6px;
  height: auto;
}
/* ---------- 剪映画面优化式分组排版（画面调节卡） ---------- */
.fx-groups {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 8px;
}
.fx-group {
  border: 1px solid #e8edf3;
  border-radius: 8px;
  background: #fff;
  overflow: hidden;
}
.fx-group-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 10px;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  background: #f1f5f9;
}
.fx-group-head:hover {
  background: #e8eef5;
}
.fx-group-title {
  font-size: 12px;
  font-weight: 600;
  color: #334155;
}
.fx-caret {
  font-size: 10px;
  color: #94a3b8;
  transition: transform 0.15s;
}
.fx-group.is-collapsed .fx-caret {
  transform: rotate(-90deg);
}
.fx-group.is-collapsed .fx-group-body {
  display: none;
}
.fx-group-body {
  padding: 6px 10px 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* 通栏滑杆行：标签 | 滑杆 | 数值（剪映同款三段式） */
.fx-line {
  display: flex;
  align-items: center;
  gap: 8px;
}
.fx-line-label {
  flex: 0 0 56px;
  font-size: 11.5px;
  color: #475569;
  white-space: nowrap;
}
.fx-line input[type="range"] {
  flex: 1 1 auto;
  min-width: 0;
}
.fx-line-val {
  flex: 0 0 44px;
  text-align: right;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: #2563eb;
}
/* 肤色色卡行 */
.fx-line-tint {
  margin-top: 2px;
}
.skin-swatches {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 6px;
}
.skin-dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid transparent;
  padding: 0;
  cursor: pointer;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}
.skin-dot.skin-none {
  background:
    linear-gradient(135deg, transparent 44%, #dc2626 46%, #dc2626 54%, transparent 56%),
    #fff;
}
.skin-dot:hover {
  transform: scale(1.12);
}
.skin-dot.is-active {
  border-color: #2563eb;
}
.skin-dot:disabled {
  opacity: 0.45;
  cursor: default;
}
/* 画面优化预设卡（对齐剪映「画面优化预设」卡片行）：可横向滚动的缩略卡 */
.look-row {
  display: flex;
  gap: 8px;
  padding: 2px 0 6px;
  margin-bottom: 2px;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
}
.look-row::-webkit-scrollbar {
  height: 6px;
}
.look-row::-webkit-scrollbar-thumb {
  background: #cbd5e1;
  border-radius: 3px;
}
.look-card {
  flex: 0 0 auto;
  width: 58px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  border-radius: 10px;
}
.look-tile {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  border: 2px solid transparent;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
  position: relative;
  overflow: hidden;
  transition: transform 0.12s, border-color 0.12s;
}
.look-card:hover .look-tile {
  transform: translateY(-1px);
}
/* 缩略图内的示例图（滤镜卡=风景实拍、画面优化卡=人像实拍；按预设参数 CSS 调色） */
.tile-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
}
.tile-tint {
  position: absolute;
  inset: 0;
  mix-blend-mode: soft-light;
  pointer-events: none;
}
.tile-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
/* 选中态：醒目红框（一眼看清当前套用的预设） */
.look-card.is-active .look-tile {
  border-color: #dc2626;
  box-shadow: 0 0 0 2px rgba(220, 38, 38, 0.22), inset 0 0 0 1px rgba(0, 0, 0, 0.06);
}
.look-card.is-active .look-name {
  color: #dc2626;
  font-weight: 600;
}
.look-name {
  font-size: 10.5px;
  line-height: 1.2;
  color: #64748b;
  white-space: nowrap;
}
/* 各预设缩略色块（近似该预设的肤色/氛围） */
.look-daily { background: linear-gradient(135deg, #fbe3d4, #f6c9b4); }
.look-milky { background: linear-gradient(135deg, #fdf1e8, #f8d9c4); }
.look-peach { background: linear-gradient(135deg, #ffd9cb, #ffb59e); }
.look-coolwhite { background: linear-gradient(135deg, #f4ecff, #dbe6ff); }
.look-sunny { background: linear-gradient(135deg, #ffe9c2, #ffcf8a); }
.look-dewy { background: linear-gradient(135deg, #fdeef0, #f3cfe0); }
.look-boyish { background: linear-gradient(135deg, #e9eef5, #c9d4e2); }
/* 「无」重置卡：白底 + 红色斜杠 */
.look-none .look-tile {
  background: #fff;
}
.look-slash {
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, transparent 45%, #dc2626 46%, #dc2626 54%, transparent 55%);
}
/* 滤镜卡缩略色块（滤镜·色彩组，近似滤镜成品色调） */
.flt-hd { background: linear-gradient(135deg, #eef4ff, #c7dbff); }
.flt-vivid { background: linear-gradient(135deg, #ffd9c9, #ff8f6b); }
.flt-airy { background: linear-gradient(135deg, #fdfbf3, #dfe7ff); }
.flt-coolwhite { background: linear-gradient(135deg, #f4ecff, #dbe6ff); }
.flt-sunset { background: linear-gradient(135deg, #ffe3b8, #ff9d5c); }
.flt-film { background: linear-gradient(135deg, #d8e3d0, #5d7a64); }
.flt-greenscreen { background: linear-gradient(135deg, #f6fbf0, #59c26a); }
/* 脸型·五官（AI 未开启）分组 */
.fx-group-disabled .fx-group-title {
  color: #94a3b8;
}
.fx-ai-note {
  font-size: 11px;
  line-height: 1.6;
  color: #94a3b8;
}
/* AI 虚拟背景（免绿幕）卡：模式三选 + 内置布景 + 上传 */
.fx-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.fx-bg-modes,
.fx-bg-swatches,
.fx-bg-upload {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.fx-bg-modes button,
.fx-bg-swatches button,
.fx-bg-upload button {
  padding: 7px 14px;
  border: 1px solid #e2e8f0;
  border-radius: 9px;
  background: #fff;
  color: #1e293b;
  font-size: 13px;
  cursor: pointer;
  transition: border-color .15s, color .15s, background .15s;
}
.fx-bg-modes button:hover,
.fx-bg-swatches button:hover,
.fx-bg-upload button:hover {
  border-color: #2563eb;
  color: #2563eb;
}
.fx-bg-modes button.is-on {
  background: #2563eb;
  border-color: #2563eb;
  color: #fff;
}
.fx-bg-swatches button[data-bgpreset="studio"] { background: linear-gradient(135deg, #3b4252, #1f232b); color: #f8fafc; border-color: #1f232b; }
.fx-bg-swatches button[data-bgpreset="blue"]   { background: linear-gradient(135deg, #1e3a8a, #172554); color: #f8fafc; border-color: #172554; }
.fx-bg-swatches button[data-bgpreset="warm"]   { background: linear-gradient(135deg, #7c2d12, #431407); color: #f8fafc; border-color: #431407; }
.fx-bg-upload #bgUploadBtn { flex: 1; }
/* 我的画面优化/调音记忆：保存/清除按钮行（按钮多、信息长：允许换行，不再挤出面板穿模） */
.fx-mem-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
}
.fx-mem-row .btn {
  flex-shrink: 0;
}
.fx-mem-info {
  margin-left: auto;
  font-size: 11px;
  color: #94a3b8;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}
.fx-preset {
  font-size: 12px;
  border: 1px solid #dbe3ee;
  border-radius: 8px;
  padding: 3px 6px;
  background: #fff;
  color: #334155;
  max-width: 150px;
}
.fx-preset:disabled {
  opacity: 0.5;
}
/* 专业相机式参数网格：两列 */
.procam-grid {
  margin-top: 8px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px 14px;
}
.pc-item {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
/* ---------- 变声：音色模型 chips + 变声比例 ---------- */
.voice-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 8px 12px;
  border-top: 1px dashed #e2e8f0;
}
.voice-label {
  font-size: 11.5px;
  color: #475569;
  font-weight: 600;
  flex-shrink: 0;
}
.voice-models {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  flex: 1 1 auto;
  min-width: 0;
}
.voice-chip {
  padding: 3px 9px;
  border: 1px solid #e2e8f0;
  border-radius: 999px;
  background: #fff;
  font-size: 11.5px;
  color: #475569;
  cursor: pointer;
  white-space: nowrap;
}
.voice-chip:hover { border-color: #cbd5e1; }
.voice-chip.is-active {
  border-color: #dc2626;
  color: #dc2626;
  font-weight: 600;
  background: #fef2f2;
}
.voice-mix {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1 1 100%;
  min-width: 0;
}
.voice-mix .vm-label {
  font-size: 11.5px;
  color: #475569;
  flex-shrink: 0;
}
.voice-mix input[type='range'] {
  flex: 1 1 auto;
  min-width: 0;
}
.pc-label {
  font-size: 11.5px;
  color: #475569;
  width: 52px;
  flex-shrink: 0;
  white-space: nowrap;
}
.pc-item input[type='range'] {
  flex: 1 1 auto;
  min-width: 0;
  accent-color: #2563eb;
  height: 16px;
}
.pc-item input[type='range']:disabled {
  opacity: 0.45;
}
.pc-val {
  font-size: 11px;
  color: #2563eb;
  width: 38px;
  text-align: right;
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.fx-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}
.fx-switch {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
}
.fx-switch input {
  display: none;
}
.fx-slider {
  width: 30px;
  height: 17px;
  border-radius: 999px;
  background: #cbd5e1;
  position: relative;
  transition: background 0.15s;
  flex-shrink: 0;
}
.fx-slider::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.15s;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
.fx-switch input:checked + .fx-slider {
  background: #2563eb;
}
.fx-switch input:checked + .fx-slider::after {
  transform: translateX(13px);
}
.fx-name {
  font-size: 12.5px;
  font-weight: 600;
  color: #334155;
  white-space: nowrap;
}
.fx-val {
  font-size: 11.5px;
  color: #64748b;
  white-space: nowrap;
}
.fx-ctl {
  margin-top: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.fx-ctl input[type='range'] {
  width: 100%;
  accent-color: #2563eb;
  height: 18px;
}
.fx-ctl input[type='range']:disabled {
  opacity: 0.45;
}
.fx-ctl-tip {
  font-size: 10.5px;
  color: #94a3b8;
  line-height: 1.3;
}

/* ==================== 员工端排班表（BOSS端，对齐企业微信智能表单） ==================== */
.sched-wrap {
  max-height: 60vh;
  overflow: auto;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
}
.sched-loading,
.sched-empty {
  padding: 22px 16px;
  text-align: center;
  color: #94a3b8;
  font-size: 13.5px;
}
.sched-empty {
  line-height: 1.7;
}
.sched-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.sched-table th {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  background: #f1f5f9;
  color: #475569;
  font-weight: 600;
  text-align: left;
  padding: 8px 10px;
  white-space: nowrap;
  border-bottom: 1px solid #e2e8f0;
  z-index: 1;
}
.sched-table td {
  padding: 7px 10px;
  border-bottom: 1px solid #f1f5f9;
  color: #334155;
  white-space: nowrap;
}
.sched-table tbody tr:nth-child(even) {
  background: #f8fafc;
}
.sched-table tbody tr:hover {
  background: #eff6ff;
}
.sched-table .sched-note {
  white-space: normal;
  min-width: 140px;
  max-width: 280px;
}
.shift-chip {
  display: inline-block;
  padding: 1px 9px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  color: #fff;
}
.shift-am {
  background: #16a34a;
} /* 早班 */
.shift-noon {
  background: #2563eb;
} /* 午班 */
.shift-pm {
  background: #7c3aed;
} /* 晚班 */
.shift-night {
  background: #dc2626;
} /* 夜班 */
/* 排档期 1班~6班（对齐企微智能表单截图配色） */
.shift-1 { background: #f9c8c8; color: #7f1d1d; } /* 粉 */
.shift-2 { background: #fbdede; color: #9f1239; } /* 浅粉 */
.shift-3 { background: #e5484d; color: #fff; } /* 红 */
.shift-4 { background: #dbe7ff; color: #1e40af; } /* 淡蓝 */
.shift-5 { background: #bcd3f7; color: #1e3a8a; } /* 浅蓝 */
.shift-6 { background: #3f83f8; color: #fff; } /* 蓝 */
.oncam-ok { background: #ecfdf5; color: #047857; }
.oncam {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 6px;
  background: #fef2f2;
  color: #b91c1c;
  font-size: 12px;
}

/* ==================== 外部平台咨询区采集面板 ==================== */
.dychat-body {
  padding-top: 8px;
}
.dychat-list {
  height: 180px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 6px 8px;
  background: #f8fafc;
  border: 1px solid #eef2f7;
  border-radius: 10px;
  font-size: 13px;
  line-height: 1.5;
}
.dychat-item {
  word-break: break-all;
}
.dychat-item .n {
  color: #2563eb;
  font-weight: 600;
  margin-right: 4px;
}
.dychat-item .t {
  color: #334155;
}
.dychat-empty {
  color: #94a3b8;
  text-align: center;
  margin: auto;
  font-size: 12.5px;
}

/* ---------- 预览 HUD（手机相机取景式白色小字） ---------- */
.video-hud {
  position: absolute;
  left: 10px;
  bottom: 46px; /* 底部工具+音频合并条(8)之上 */
  z-index: 6;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.video-hud .hud-line {
  font-size: 11px;
  line-height: 1.35;
  font-family: var(--font);
  font-variant-numeric: tabular-nums;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9), 0 0 6px rgba(0, 0, 0, 0.55);
  white-space: nowrap;
}

/* ---------- 实时时钟贴片（参考OBS 捕获软件 NTP 时间码） ---------- */
.video-clock {
  position: absolute;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 6;
  pointer-events: none;
  text-align: center;
  color: #fff;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.9), 0 0 8px rgba(0, 0, 0, 0.55);
  background: rgba(15, 23, 42, 0.35);
  border-radius: 8px;
  padding: 3px 10px;
}
.video-clock .vc-date {
  font-size: 10.5px;
  line-height: 1.3;
  opacity: 0.9;
}
.video-clock .vc-time {
  font-size: 15px;
  line-height: 1.2;
  font-weight: var(--fw-bold);
  font-family: var(--font);
  font-variant-numeric: tabular-nums;
  min-width: 8.2ch; /* 数字等宽兜底：秒数跳动时块宽不抖 */
  display: block;
  letter-spacing: 0.5px;
}
.video-clock-btn {
  right: 62px;
}
.video-clock-btn.is-on {
  background: rgba(37, 99, 235, 0.85);
}

/* 前置/后置翻转按钮（host 预览右上角，时钟按钮左侧）：仅触屏设备显示 */
.video-flip-btn {
  right: 116px;
}
.only-touch {
  display: none; /* 桌面（鼠标精确指针）不显示——桌面用设备下拉选摄像头更合适 */
}
@media (pointer: coarse) {
  .only-touch {
    display: inline-flex;
    align-items: center;
  }
}

/* ---------- 脸部定位圈（定点美型辅助：拖滑杆时短暂显示） ---------- */
.face-guide {
  position: absolute;
  left: 50%;
  top: 45%;
  width: 75%;              /* 宽 = 高 × 0.75（与着色器椭圆一致） */
  aspect-ratio: 3 / 4;
  transform: translate(-50%, -50%);
  border: 2px dashed rgba(220, 38, 38, 0.9);
  border-radius: 50%;
  z-index: 6;
  pointer-events: none;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0); /* 不遮画面，仅圈 */
  transition: opacity 0.15s;
}
.face-guide.hidden {
  display: none;
}
.face-guide .fg-eye {
  position: absolute;
  top: 39%;
  width: 40%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border: 1.5px dashed rgba(220, 38, 38, 0.65);
  border-radius: 50%;
}
.face-guide .fg-eye-l { left: 30%; }
.face-guide .fg-eye-r { left: 70%; }

/* ---------- 话术卡：字号控件（顶部滑条，与速率滑条同款） ---------- */
.font-ctl {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: var(--text-muted);
}
.font-ctl input[type='range'] {
  width: 76px;
  accent-color: #2563eb;
}

/* 编辑栏右侧：整篇阅读偏好组（行距/字距/底色）+ 员工端本人最后保存时间 */
.script-editbar .eb-right {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.script-editbar .eb-mytime {
  margin-left: auto;
  font-size: 12px;
  color: var(--text-muted);
  white-space: nowrap;
  padding-right: 4px;
}
/* 编辑中有改动未保存：红色醒目徽标（保存后消失） */
.script-editbar .eb-dirty {
  font-size: 12px;
  font-weight: 700;
  color: #dc2626;
  white-space: nowrap;
  padding-right: 4px;
}
.script-editbar .eb-dirty.hidden {
  display: none;
}

/* ---------- 查看页：主位徽标 ---------- */
.main-pos-badge {
  background: #2563eb;
  font-weight: 600;
  top: 10px;
  left: 10px;
}
.main-pos-badge.hidden {
  display: none;
}

/* =============================================================
   全局字体与字重规范 —— 阿里妈妈数黑体
   -------------------------------------------------------------
   基础字体：阿里妈妈数黑体（系统已安装则自动生效）→ 未安装回退系统无衬线黑体
   字重严格两档：
     · 加粗 700（Bold）  ：页面大标题 / 模块标题 / 关键数据 / 主按钮文字
     · 常规 400（Regular）：正文内容 / 辅助说明 / 次要标签 / 输入框 / 次要按钮
   仅替换字体与字重，不改动布局、配色、字号与模块位置。
   ============================================================= */

/* ---------- 一、加粗档：页面大标题 / 模块标题 / 表头 / 关键数据 / 主按钮 ---------- */
.topbar-title,
.topbar-title [data-brand-name],
[data-brand-name],
.brand-name,
.brand-logo-placeholder,
.card-title,
.side-title,
.watch-chat .side-title,
.boss-side-title,
.block-card h2,
.modal-head h3,
.diag-head h1,
.schedule-day-title,
.douyin-hint-title,
.fx-group-title,
.fx-name,
table.tbl th,
.sched-table th,
.kv .v,
.schedule-time,
.shift-chip,
.main-pos-badge,
.video-clock .vc-time,
.look-card.is-active .look-name {
  font-weight: var(--fw-bold);
}

/* 主按钮加粗（写在常规档 .btn 之后并用双类提高优先级，确保不被覆盖） */
.btn.btn-primary,
.btn.btn-danger,
.btn.btn-accent {
  font-weight: var(--fw-bold);
}

/* ---------- 二、常规档：正文 / 辅助说明 / 次要标签 / 输入框 / 次要按钮 ---------- */
.topbar-title .muted,
.status,
.btn,
.btn-outline,
.btn-ghost,
.card-sub,
.video-badge,
.portrait-hint,
.field-label,
.kv .k,
.kv .v.mono,
.side-name,
.tag,
.diag-item .diag-title,
.dychat-item .n,
.look-card .look-name,
.script-content,
.hud-line,
.muted,
.text-sm {
  font-weight: var(--fw-regular);
}

/* 统计数值沿用等宽数字特性，保证秒表/码率跳动时不抖动 */
.kv .v,
.video-clock .vc-time,
.hud-line,
.vm-val {
  font-variant-numeric: tabular-nums;
}

/* ---------- 三、代码 / 诊断详情：保留等宽（语义化技术内容） ---------- */
code,
kbd,
pre,
samp,
.diag-item .diag-detail code {
  font-family: var(--font-code);
}

/* ---------- 总管理员后台 · 总看板 / 系统监控 ---------- */
.kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}
.kpi-card {
  background: #fff;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  padding: 14px 16px 12px;
  min-width: 0;
}
.kpi-label {
  font-size: 12px;
  color: #64748b;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kpi-num {
  font-size: 26px;
  font-weight: 700;
  color: #1e293b;
  margin-top: 4px;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kpi-num.is-live { color: var(--primary); }
.kpi-sub {
  font-size: 11px;
  color: #94a3b8;
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 近 7 天上岗场次柱状图（纯 CSS，无图表库） */
.week-chart {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  height: 150px;
  padding: 6px 4px 0;
}
.week-col {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  min-width: 0;
  height: 100%;
}
.week-bar-label {
  font-size: 12px;
  font-weight: 600;
  color: #1e293b;
  font-variant-numeric: tabular-nums;
}
.week-bar {
  width: 100%;
  max-width: 46px;
  background: linear-gradient(180deg, #60a5fa, var(--primary));
  border-radius: 6px 6px 2px 2px;
  transition: height 0.3s ease;
}
.week-day {
  font-size: 11px;
  color: #64748b;
  white-space: nowrap;
}

/* ==========================================================
   管理后台 · 异常通知 / 导入导出 / 千牛式装修管理
   ========================================================== */

/* ---------- 异常通知 ---------- */
.alert-badge {
  display: inline-block;
  min-width: 17px;
  height: 17px;
  padding: 0 5px;
  margin-left: 5px;
  border-radius: 9px;
  background: var(--danger);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 17px;
  text-align: center;
  vertical-align: 1px;
}
.alert-toast {
  position: fixed;
  right: 18px;
  bottom: 18px;
  right: calc(18px + var(--sar));
  bottom: calc(18px + var(--sab));
  z-index: 9998;
  width: 320px;
  padding: 13px 15px;
  background: #fff;
  border: 1px solid #fecaca;
  border-left: 4px solid var(--danger);
  border-radius: 12px;
  box-shadow: 0 10px 30px rgba(15, 23, 42, 0.16);
  cursor: pointer;
  animation: alertToastIn 0.25s ease;
}
@keyframes alertToastIn {
  from { transform: translateY(14px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}
.alert-toast-head { font-weight: 700; font-size: 13px; color: var(--danger); }
.alert-toast-msg { margin-top: 5px; font-size: 13px; color: var(--text); line-height: 1.5; word-break: break-all; }
.alert-toast-foot { margin-top: 7px; font-size: 12px; color: var(--text-muted); }

.alert-level { display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 12px; font-weight: 600; }
.alert-level.danger { background: var(--danger-soft); color: var(--danger); }
.alert-level.warn { background: #fffbeb; color: var(--warning); }
.alert-level.info { background: var(--primary-soft); color: var(--primary); }

/* ---------- 导入导出插槽 ---------- */
.ie-slot { display: inline-flex; gap: 6px; align-items: center; }

/* ---------- 千牛式装修布局 ---------- */
.decor-layout { display: flex; gap: 14px; align-items: flex-start; }
.decor-side {
  flex: 0 0 168px;
  position: -webkit-sticky;
  position: sticky;
  top: 12px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 10px 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.decor-side-title {
  padding: 8px 10px 4px;
  font-size: 12px;
  font-weight: 700;
  color: var(--text-muted);
  letter-spacing: 0.05em;
}
.decor-nav {
  border: 0;
  background: transparent;
  text-align: left;
  padding: 8px 12px;
  border-radius: 9px;
  font-size: 13.5px;
  color: var(--text);
  cursor: pointer;
}
.decor-nav:hover { background: var(--secondary-soft); }
.decor-nav.is-active { background: var(--primary-soft); color: var(--primary); font-weight: 600; }
.decor-nav-sub { padding-left: 24px; font-size: 13px; }
.decor-main { flex: 1; min-width: 0; }

.input-sm { height: 32px; font-size: 13px; }

/* ---------- DIY 页面 / 模板 ---------- */
.tpl-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 14px;
}
.tpl-card {
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  background: #fff;
  display: flex;
  flex-direction: column;
}
.tpl-thumb {
  height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  font-weight: 700;
  color: #fff;
  letter-spacing: 0.08em;
}
.tpl-body { padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 8px; }
.tpl-name { font-weight: 600; font-size: 13.5px; }
.tpl-desc { font-size: 12px; color: var(--text-muted); line-height: 1.5; }

/* ---------- 店铺主题 ---------- */
.theme-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.theme-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: #fff;
  font-size: 13px;
  cursor: pointer;
}
.theme-chip:hover { border-color: var(--primary-border); }
.theme-chip.is-active { border-color: var(--primary); color: var(--primary); font-weight: 600; background: var(--primary-soft); }
.theme-chip-dot { width: 12px; height: 12px; border-radius: 50%; }
.theme-preview {
  width: 240px;
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  background: #fff;
  padding-bottom: 14px;
  text-align: center;
}
.theme-preview-bar { height: 64px; background: var(--primary); margin-bottom: 14px; }
.theme-preview-tag {
  display: inline-block;
  margin-left: 10px;
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--primary-soft);
  color: var(--primary);
  font-size: 12px;
}

/* ---------- 素材管理 ---------- */
.mat-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 12px; }
.mat-tab {
  border: 0;
  background: transparent;
  padding: 8px 14px;
  font-size: 13.5px;
  color: var(--text-sub);
  cursor: pointer;
  border-bottom: 2px solid transparent;
}
.mat-tab.is-active { color: var(--primary); font-weight: 600; border-bottom-color: var(--primary); }
.mat-layout { display: flex; gap: 14px; }
.mat-folders { flex: 0 0 150px; display: flex; flex-direction: column; gap: 2px; }
.mat-folder {
  border: 0;
  background: transparent;
  text-align: left;
  padding: 7px 10px;
  border-radius: 8px;
  font-size: 13px;
  cursor: pointer;
  color: var(--text);
  display: flex;
  justify-content: space-between;
}
.mat-folder:hover { background: var(--secondary-soft); }
.mat-folder.is-active { background: var(--primary-soft); color: var(--primary); font-weight: 600; }
.mat-list { flex: 1; min-width: 0; }
.mat-thumb {
  width: 42px;
  height: 42px;
  border-radius: 8px;
  object-fit: cover;
  background: var(--secondary-soft);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  flex: 0 0 42px;
}
.mat-name { font-size: 13px; font-weight: 600; word-break: break-all; }
.mat-url { font-size: 12px; color: var(--text-muted); word-break: break-all; }

/* ---------- 设置表单 ---------- */
.form-row { display: flex; gap: 14px; padding: 9px 0; border-bottom: 1px dashed var(--border); align-items: flex-start; }
.form-row:last-of-type { border-bottom: 0; }
.form-row-label { flex: 0 0 150px; font-size: 13.5px; font-weight: 600; color: var(--text); padding-top: 6px; }
.form-row-body { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.form-row-body .input, .form-row-body .select, .form-row-body .textarea { max-width: 420px; }
.form-hint { flex-basis: 100%; font-size: 12px; color: var(--text-muted); line-height: 1.5; }

/* 开关 */
.switch { position: relative; display: inline-block; width: 40px; height: 22px; flex: 0 0 auto; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch-slider {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: #cbd5e1;
  transition: background 0.18s ease;
}
.switch-slider::before {
  content: "";
  position: absolute;
  width: 16px;
  height: 16px;
  left: 3px;
  top: 3px;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.18s ease;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.3);
}
.switch input:checked + .switch-slider { background: var(--primary); }
.switch input:checked + .switch-slider::before { transform: translateX(18px); }
.switch-label { font-size: 13px; color: var(--text-sub); }

/* 列表编辑器（快捷导航/热门搜索/帮助/机器人） */
.list-editor { display: flex; flex-direction: column; gap: 8px; }
.list-editor-row { display: flex; gap: 8px; align-items: center; }
.list-editor-row .input { flex: 1; }

/* 跑马灯预览 */
.marquee-preview {
  position: relative;
  width: 100%;
  max-width: 420px;
  height: 120px;
  border-radius: 10px;
  background: linear-gradient(135deg, #94a3b8, #64748b);
  overflow: hidden;
}
.marquee-preview-text {
  position: absolute;
  white-space: nowrap;
  font-weight: 600;
}

@media (max-width: 900px) {
  .decor-layout { flex-direction: column; }
  .decor-side { position: static; flex: none; width: 100%; flex-direction: row; flex-wrap: wrap; }
  .decor-side-title { flex-basis: 100%; }
  .form-row { flex-direction: column; gap: 4px; }
  .form-row-label { flex: none; padding-top: 0; }
  .mat-layout { flex-direction: column; }
}

/* ==========================================================
   管理后台 · 板块内子页 / 筛选行 / 关联链接（ui 224）
   ========================================================== */

/* 板块内分段 Tab（课程管理 / 权限管理 / 分销中心） */
.seg-tabs {
  display: flex;
  gap: 4px;
  padding: 6px 8px;
  margin-bottom: 14px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow-x: auto;
}
.seg-tabs-inline {
  border: 0;
  padding: 0;
  margin-bottom: 12px;
  background: transparent;
}
.seg-tab {
  border: 0;
  background: transparent;
  padding: 8px 16px;
  border-radius: 9px;
  font-size: 13.5px;
  color: var(--text-sub);
  cursor: pointer;
  white-space: nowrap;
}
.seg-tab:hover { background: var(--secondary-soft); }
.seg-tab.is-active { background: var(--primary-soft); color: var(--primary); font-weight: 600; }

/* 板块内子页容器 */
.csec { display: block; }
.csec.hidden { display: none; }

/* 筛选行（操作日志等） */
.filter-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 12px;
  margin-bottom: 12px;
  background: var(--secondary-soft);
  border-radius: 10px;
}
.filter-label { font-size: 13px; color: var(--text-sub); }

/* 关联跳转链接 */
.link { color: var(--primary); text-decoration: none; cursor: pointer; }
.link:hover { text-decoration: underline; }

.tag-info { background: var(--primary-soft); color: var(--primary); }
.tag-warn { background: #fffbeb; color: var(--warning); }

/* 数据表内嵌选择器 */
.tbl .select.input-sm, .tbl .input-sm { height: 30px; font-size: 12.5px; }

/* ==========================================================
   管理后台 · 员工端工作台（管理员代看 / 代管）
   ========================================================== */
.wb-layout { display: flex; gap: 14px; align-items: flex-start; }
.wb-side {
  flex: 0 0 216px;
  position: -webkit-sticky;
  position: sticky;
  top: 12px;
  max-height: calc(100vh - 96px);
  max-height: calc(100dvh - 96px);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.wb-side-head { display: flex; flex-direction: column; gap: 6px; }
.wb-host-list { overflow-y: auto; display: flex; flex-direction: column; gap: 2px; min-height: 60px; }
.wb-host-item {
  border: 0;
  background: transparent;
  text-align: left;
  padding: 8px 10px;
  border-radius: 9px;
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
}
.wb-host-item:hover { background: var(--secondary-soft); }
.wb-host-item.is-active { background: var(--primary-soft); color: var(--primary); font-weight: 600; }
.wb-host-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wb-dot { width: 8px; height: 8px; border-radius: 50%; background: #cbd5e1; flex: 0 0 auto; }
.wb-dot.on { background: #16a34a; box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.18); }
.wb-main { flex: 1; min-width: 0; }
.wb-info {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed var(--border);
  font-size: 13px;
}
.wb-info-item { display: flex; gap: 4px; }
.wb-info-k { color: var(--text-muted); }
.wb-sub-title { margin: 18px 0 8px; font-size: 13px; font-weight: 600; color: var(--text-sub); }
.wb-grant-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 6px;
  max-height: 320px;
  overflow-y: auto;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: 10px;
}
.wb-grant-row { display: flex; align-items: center; gap: 8px; font-size: 13px; padding: 5px 6px; border-radius: 8px; cursor: pointer; }
.wb-grant-row:hover { background: var(--secondary-soft); }
@media (max-width: 900px) {
  .wb-layout { flex-direction: column; }
  .wb-side { position: static; flex: none; width: 100%; max-height: none; }
  .wb-host-list { flex-direction: row; flex-wrap: wrap; }
}


/* 小号按钮（表格内紧凑操作按钮） */
.btn-xs { padding: 3px 9px; font-size: 12px; border-radius: var(--radius-sm); }

/* =============================================================
   查看页「驾驶舱」主题（body.cockpit-theme）
   -------------------------------------------------------------
   VI 与 docs/设计稿/驾驶舱-Cockpit.html 完全一致：
     主色 #0B6BFF · 强调 #39FF88 · 背景 #121418 · 卡片 #191C21
     字体 阿里巴巴普惠体 3.0（本地自托管子集，离线自动回退系统黑体）
   只改配色 / 圆角 / 字体，不改布局与任何功能。
   纯净模式（?bare=1）不受影响：抓进工作间的画面仍是纯黑视频。
   ============================================================= */

/* ⚠️ 字体必须本地自托管，不要再改回公网 CDN（2026-10-12 实测的教训）：
   - 原来指向 cdn.jsdelivr.net 上那个 5,256,740 B 的完整 woff2。该字族被放在
     body.cockpit-theme 字体栈首位，于是**查看页/老板端/员工端冷启动都要先下 5.26MB**，
     实测 /watch 冷启动 load 被拖到 7912ms；国内访问 jsDelivr 还经常抽风 —— 一旦抽风
     整站字体同时掉线。
   - 现改为本地子集（1.18MB，-77%）：覆盖「界面实采字符 ∪ GB2312 全部 6763 汉字 ∪
     ASCII ∪ 常用中英标点」。生成脚本 .workbuddy/tools/subset-font.py，可重复执行。
   - 缺失的生僻字（GB2312 之外的罕用字，如少数姓名用字）自动回退系统黑体，
     这是刻意的：宁可变一个字，也不为了一个字拉 5MB。 */
@font-face {
  font-family: 'Alibaba PuHuiTi 3';
  src: url('../vendor/fonts/AlibabaPuHuiTi-3-55-Regular.subset.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

body.cockpit-theme {
  --ck-bg: #121418;
  --ck-card: #191C21;
  --ck-line: rgba(255, 255, 255, 0.07);
  --ck-text: #E6EAF2;
  --ck-muted: #8A93A3;
  --ck-primary: #0B6BFF;
  --ck-primary-hover: #3182FF;
  --ck-acc: #39FF88;

  background: var(--ck-bg);
  color: var(--ck-text);
  font-family: 'Alibaba PuHuiTi 3', 'PingFang SC', 'Microsoft YaHei', system-ui, sans-serif;
}

/* ---------- 滚动条 ---------- */
body.cockpit-theme ::-webkit-scrollbar { width: 8px; height: 8px; }
body.cockpit-theme ::-webkit-scrollbar-thumb { background: rgba(255,255,255,.14); border-radius: 4px; }
body.cockpit-theme ::-webkit-scrollbar-track { background: transparent; }

/* ---------- 顶部栏 ---------- */
body.cockpit-theme .topbar {
  background: var(--ck-card);
  border-bottom: 1px solid var(--ck-line);
}
body.cockpit-theme .topbar-title,
body.cockpit-theme .topbar-title [data-site-title] { color: var(--ck-text); }
body.cockpit-theme .topbar-title .muted { color: var(--ck-muted); }
body.cockpit-theme .topbar-divider { background: var(--ck-line); }
body.cockpit-theme .brand-logo-placeholder {
  background: rgba(11, 107, 255, 0.14);
  border: 1px solid rgba(11, 107, 255, 0.45);
  color: var(--ck-primary-hover);
}

/* ---------- 连接状态胶囊 ---------- */
body.cockpit-theme .status {
  background: rgba(255, 255, 255, 0.05);
  border-color: var(--ck-line);
  color: var(--ck-muted);
}
body.cockpit-theme .status.is-live {
  color: var(--ck-acc);
  background: rgba(57, 255, 136, 0.08);
  border-color: rgba(57, 255, 136, 0.35);
}
body.cockpit-theme .status.is-ok {
  color: var(--ck-acc);
  background: rgba(57, 255, 136, 0.08);
  border-color: rgba(57, 255, 136, 0.35);
}
body.cockpit-theme .status.is-warn {
  color: #FFB020;
  background: rgba(255, 176, 32, 0.08);
  border-color: rgba(255, 176, 32, 0.35);
}
body.cockpit-theme .status.is-error {
  color: #FF6B6B;
  background: rgba(255, 107, 107, 0.08);
  border-color: rgba(255, 107, 107, 0.35);
}

/* ---------- 大画面 ---------- */
body.cockpit-theme .video-frame {
  border-radius: 18px;
  border: 1px solid var(--ck-line);
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.45);
}
body.cockpit-theme .video-overlay { color: var(--ck-text); }
body.cockpit-theme .video-overlay .muted { color: var(--ck-muted); }
body.cockpit-theme .video-badge {
  background: rgba(10, 12, 15, 0.68);
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: #fff;
}
body.cockpit-theme .video-badge .live-dot { background: #FF4D4F; }
body.cockpit-theme .main-pos-badge {
  background: var(--ck-primary);
  border: 1px solid rgba(255, 255, 255, 0.16);
}

/* ---------- 底部信息行 ---------- */
body.cockpit-theme .watch-meta { color: var(--ck-muted); }
body.cockpit-theme .watch-meta #hostName { color: var(--ck-text); font-weight: 600; }

/* ---------- 按钮 ---------- */
body.cockpit-theme .btn.btn-primary {
  background: var(--ck-primary);
}
body.cockpit-theme .btn.btn-primary:hover { background: var(--ck-primary-hover); }
body.cockpit-theme .btn.btn-ghost {
  color: var(--ck-muted);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--ck-line);
}
body.cockpit-theme .btn.btn-ghost:hover {
  color: var(--ck-text);
  border-color: rgba(11, 107, 255, 0.55);
  background: rgba(11, 107, 255, 0.12);
}
body.cockpit-theme .btn.btn-outline {
  color: var(--ck-text);
  background: rgba(25, 28, 33, 0.92);
  border: 1px solid var(--ck-line);
}
body.cockpit-theme .btn.btn-outline:hover {
  border-color: rgba(11, 107, 255, 0.55);
  background: rgba(11, 107, 255, 0.16);
}

/* ---------- 交接班侧栏 ---------- */
body.cockpit-theme .side-title { color: var(--ck-text); }
body.cockpit-theme .side-card {
  background: var(--ck-card);
  border: 1px solid var(--ck-line);
  border-radius: 14px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
}
body.cockpit-theme .side-card:hover { border-color: rgba(11, 107, 255, 0.55); }
body.cockpit-theme .side-card.is-active {
  border-color: var(--ck-primary);
  box-shadow: 0 0 0 2px rgba(11, 107, 255, 0.28);
}
body.cockpit-theme .side-thumb { background: #0B0E12; }
body.cockpit-theme .side-placeholder {
  background: linear-gradient(180deg, #1A1E24 0%, #0B0E12 100%);
  color: var(--ck-muted);
}
body.cockpit-theme .side-name { color: var(--ck-text); }
body.cockpit-theme .side-flag {
  background: rgba(10, 12, 15, 0.72);
  color: #fff;
}
body.cockpit-theme .side-flag.is-live {
  background: var(--ck-acc);
  color: #06281A;
  font-weight: 600;
}
body.cockpit-theme .side-flag.is-ready { background: var(--ck-primary); }

/* ---------- 员工端沟通聊天栏 ---------- */
body.cockpit-theme .watch-chat {
  background: var(--ck-card);
  border-left: 1px solid var(--ck-line);
  border-radius: 18px;
}
body.cockpit-theme .watch-chat .side-head { border-bottom: 1px solid var(--ck-line); }
body.cockpit-theme .watch-chat .side-title { color: var(--ck-text); }
body.cockpit-theme .watch-chat .text-sm.muted { color: var(--ck-muted); }
body.cockpit-theme .watch-chat-msgs { background: transparent; }
body.cockpit-theme .chat-meta { color: #6B7280; }
body.cockpit-theme .chat-bubble {
  background: #232830;
  color: var(--ck-text);
  border-radius: 12px;
}
body.cockpit-theme .chat-msg.is-mine .chat-bubble {
  background: var(--ck-primary);
  color: #fff;
}
body.cockpit-theme .watch-chat-input { border-top: 1px solid var(--ck-line); }
body.cockpit-theme .watch-chat-input .input {
  background: #121418;
  border: 1px solid var(--ck-line);
  color: var(--ck-text);
}
body.cockpit-theme .watch-chat-input .input::placeholder { color: #5B6472; }
body.cockpit-theme .watch-chat-input .input:focus {
  border-color: rgba(11, 107, 255, 0.6);
  outline: none;
}

/* ---------- 窄屏（手机竖屏）时聊天栏在下方，圆角改上边 ---------- */
@media (max-width: 900px) {
  body.cockpit-theme .watch-chat {
    border-left: none;
    border-top: 1px solid var(--ck-line);
  }
  /* 原断点只处理了 .has-side 的堆叠，漏了 .has-chat（主轴方向仍是 row，
     导致手机竖屏时画面被聊天栏挤成窄条）。这里补上，与下方 40vh 预期配套。 */
  body.cockpit-theme .watch-main.has-chat {
    flex-direction: column;
  }
  body.cockpit-theme .watch-chat {
    flex: 0 0 auto;
    width: auto;
    max-height: 40vh;
  }
}

/* ---------- 纯净模式（?bare=1）：OBS 捕获软件抓取画面必须保持纯黑无装饰 ---------- */
body.cockpit-theme.bare { background: #000; }
body.cockpit-theme.bare .video-frame {
  border-radius: 0;
  border: none;
  box-shadow: none;
}

/* =============================================================
   上岗页：采集前占位 —— 绿幕坐姿示意图（替代黑屏）
   -------------------------------------------------------------
   参考 VI：绿 #00B140 / 肤 #EEC9A4 / 衣 #F2F4F7（见 img/posture-placeholder.svg）
   采集成功后 overlay 整体 hidden，示意图随之消失，不影响正式画面。
   仅作用于上岗页带 .posture 类的覆盖层，查看页同名结构不受影响。
   ============================================================= */
.video-overlay.posture {
  background: #00B140 url('/img/posture-placeholder.svg') center / cover no-repeat;
  justify-content: flex-end;
  padding-bottom: 3.5%;
}
.video-overlay.posture .icon { display: none; }
.video-overlay.posture .overlay-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: fit-content;
  max-width: 90%;
  max-height: 78%;
  overflow-y: auto;
  margin: 0 auto;
  background: rgba(11, 18, 32, 0.7);
  border: 1px solid rgba(255, 255, 255, 0.12);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  border-radius: 14px;
  padding: 10px 18px;
  color: #E8EEF6;
  text-align: center;
}
.video-overlay.posture .overlay-panel .text-sm.muted { color: #AEBBCC; }
.video-overlay.posture .posture-hint {
  font-size: 13px;
  font-weight: 600;
  color: #A8F0C6;
}
.video-overlay.posture .overlay-env {
  width: 100%;
  text-align: left;
}

/* =============================================================
   查看页：实时数据角标 + 体检胶囊 + 班次/单场日志弹窗
   -------------------------------------------------------------
   视觉对齐驾驶舱稿（暗色玻璃小签 + 荧光绿语义色）。
   【红线】?bare=1 是OBS 捕获软件抓取画面，以下所有新增 DOM 必须隐藏。
   ============================================================= */

/* ---------- 画面内数据角标 ---------- */
.data-badge {
  position: absolute;
  z-index: 6;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.3px;
  color: #fff;
  background: rgba(10, 12, 15, 0.68);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 8px;
  padding: 5px 10px;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  font-variant-numeric: tabular-nums;
}
.data-badge.hidden { display: none; }
.data-remote { top: 10px; right: 10px; }
.data-remote .data-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: #39FF88; flex: none;
}
.data-remote.is-bad .data-dot { background: #FF6B6B; }
.data-elapsed { left: 10px; bottom: 10px; }
.data-quality { right: 10px; bottom: 10px; color: #D9E4F2; font-weight: 500; }

/* ---------- 体检胶囊行 ---------- */
.watch-vitals {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 26px;
}
.watch-vitals.hidden { display: none; }
.vital {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: #B9C4D4;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 999px;
  padding: 4px 12px;
}
.vital i {
  width: 6px; height: 6px; border-radius: 50%;
  background: #8A93A3; flex: none;
}
.vital b { font-weight: 600; color: #E6EAF2; }
.vital.is-ok i { background: #39FF88; }
.vital.is-ok b { color: #39FF88; }
.vital.is-warn i { background: #FFB020; }
.vital.is-warn b { color: #FFB020; }
.vital.is-bad i { background: #FF6B6B; }
.vital.is-bad b { color: #FF6B6B; }

/* ---------- 班次与单场日志弹窗 ---------- */
.shift-mask {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: rgba(5, 7, 10, 0.66);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.shift-mask.hidden { display: none; }
.shift-modal {
  width: min(860px, 100%);
  max-height: 84vh;
  display: flex;
  flex-direction: column;
  background: #191C21;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 18px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.55);
  overflow: hidden;
}
.shift-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.shift-title { font-size: 15px; font-weight: 700; color: #E6EAF2; }
.shift-head-spacer { flex: 1 1 auto; }
.shift-body {
  overflow-y: auto;
  padding: 14px 18px 20px;
}
.shift-sec {
  font-size: 13px;
  font-weight: 700;
  color: #8A93A3;
  letter-spacing: 1px;
  margin: 10px 0 8px;
}
.shift-list { display: flex; flex-direction: column; gap: 8px; }
.shift-empty { padding: 14px 0; text-align: center; font-size: 13px; }
.shift-row {
  background: #121418;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  overflow: hidden;
}
.shift-main {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 10px 14px;
  font-size: 13px;
  color: #E6EAF2;
}
.shift-code { font-family: Consolas, monospace; font-size: 12px; color: #8A93A3; }
.shift-label { font-weight: 700; color: #4D9BFF; }
.shift-time { font-variant-numeric: tabular-nums; }
.shift-host { color: #B9C4D4; }
.shift-status {
  font-size: 12px;
  font-weight: 600;
  padding: 2px 9px;
  border-radius: 999px;
}
.shift-status.st-live { color: #06281A; background: #39FF88; }
.shift-status.st-done { color: #B9C4D4; background: rgba(255, 255, 255, 0.08); }
.shift-status.st-wait { color: #FFB020; background: rgba(255, 176, 32, 0.12); }
.shift-status.st-none { color: #6B7280; background: rgba(255, 255, 255, 0.05); }
.shift-detail {
  border-top: 1px dashed rgba(255, 255, 255, 0.1);
  padding: 10px 14px 12px;
  font-size: 12.5px;
  line-height: 1.7;
  color: #C6CFDC;
}
.shift-detail.hidden { display: none; }
.sd-line { margin-top: 4px; }
.sd-k {
  display: inline-block;
  min-width: 64px;
  font-weight: 700;
  color: #8A93A3;
  margin-right: 8px;
}
.sd-sub {
  padding-left: 72px;
  font-family: Consolas, monospace;
  font-size: 12px;
  color: #AEBBCC;
}

/* ---------- 【红线】bare 抓取模式：新增元素一律隐藏 ---------- */
body.bare .data-badge,
body.bare .watch-vitals {
  display: none !important;
}

/* =============================================================
   查看页升级（2026-09-30 晚）：
   ① 画面放大 + 沉浸模式  ② 顶栏BOSS端 IP/下行带宽  ③ 最近三班速览条
   ④ 底部工作间名/员工端名称/上行码率  ⑤ 远程效果工具栏  ⑥ 待接班侧栏常显
   【红线】bare 抓取模式（?bare=1）下新增元素一律隐藏，画面保持纯黑纯净
   ============================================================= */

/* ---------- ① 画面尽量放大：压缩主区留白 ---------- */
.watch-main {
  padding: 8px 10px 6px;
  gap: 6px;
}
.watch-body { gap: 6px; }
.watch-main.has-side,
.watch-main.has-chat { gap: 10px; }
/* 数据行与体检胶囊更紧凑，把高度让给画面 */
.watch-meta { min-height: 20px; font-size: 12.5px; }

/* ---------- ① 沉浸模式：只留大画面（Esc 或按钮退出） ---------- */
body.immersive .topbar,
body.immersive .watch-meta,
body.immersive .watch-vitals,
body.immersive .watch-side,
body.immersive .watch-chat,
body.immersive .main-pos-badge {
  display: none !important;
}
body.immersive .watch-main {
  height: 100vh;
  height: 100dvh;
  padding: 0;
  gap: 0;
}
body.immersive .video-frame {
  border-radius: 0;
  border: none;
  box-shadow: none;
}
body.immersive .data-badge { opacity: 0.85; }

/* ---------- ② 顶栏网络信息胶囊 ---------- */
.net-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  font-size: 12px;
  color: #8A93A3;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 999px;
  white-space: nowrap;
}
.net-pill.hidden { display: none; }
body.cockpit-theme .net-pill { font-family: inherit; }

/* （旧 .watch-home-btn 已删除：查看页的「返回/主页」改用统一的 .nav-btn 组件，见文件末尾 VI 段） */
/* 非驾驶舱主题的浅色兜底 */
body:not(.cockpit-theme) .net-pill {
  color: var(--text-muted, #64748b);
  background: rgba(37, 99, 235, 0.06);
  border-color: var(--border, #e2e8f0);
}
body.bare .net-pill { display: none !important; }

/* ---------- ③ 最近三班速览条（聊天栏顶部） ---------- */
.shift-strip {
  flex: 0 0 auto;
  padding: 8px 10px 6px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}
.shift-strip-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
}
.shift-strip-cards {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.strip-card {
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 10px;
  padding: 6px 8px;
  cursor: pointer;
  transition: border-color 0.15s;
}
.strip-card:hover { border-color: rgba(11, 107, 255, 0.55); }
.strip-card.is-empty { cursor: default; opacity: 0.6; }
/* 「正在播」= 速览条重心：绿框发光 + 加粗放大，一眼锁定当前班次 */
.strip-card.is-live {
  background: linear-gradient(160deg, rgba(57, 255, 136, 0.14), rgba(57, 255, 136, 0.04));
  border-color: rgba(57, 255, 136, 0.7);
  box-shadow: 0 0 18px rgba(57, 255, 136, 0.18), inset 0 0 14px rgba(57, 255, 136, 0.06);
}
.strip-card.is-live:hover { border-color: rgba(57, 255, 136, 0.9); }
.strip-card.is-live .strip-label {
  background: #39FF88;
  color: #06281A;
  font-size: 12px;
  padding: 2px 9px;
}
.strip-card.is-live .strip-host { font-size: 13.5px; font-weight: 700; color: #EAFFF2; }
.strip-label {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  color: #39FF88;
  background: rgba(57, 255, 136, 0.1);
  border-radius: 6px;
  padding: 1px 7px;
  margin-bottom: 3px;
}
.strip-main {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 8px;
  font-size: 12px;
  color: #E6EAF2;
}
.strip-host { font-weight: 600; }
.strip-time { color: #8A93A3; font-size: 11.5px; }
/* 订单编号小字：便于在排班表/企微表单里查找 */
.strip-code {
  margin-top: 3px;
  font-size: 11px;
  letter-spacing: 0.3px;
  color: #7E8896;
  font-family: var(--font-code, Consolas, monospace);
}
.strip-card.is-live .strip-code { color: #9FB8AA; }
.strip-detail {
  margin-top: 6px;
  border-top: 1px dashed rgba(255, 255, 255, 0.1);
  padding-top: 6px;
  font-size: 12px;
  line-height: 1.7;
  color: #C6CFDC;
}
.strip-detail.hidden { display: none; }
.strip-empty { font-size: 12px; color: #8A93A3; }
/* 浅色主题兜底 */
body:not(.cockpit-theme) .shift-strip { border-bottom-color: #eef2f7; }
body:not(.cockpit-theme) .strip-card { background: #f8fafc; border-color: #e2e8f0; }
body:not(.cockpit-theme) .strip-main { color: #1e293b; }
body.bare .shift-strip { display: none !important; }
/* 窄屏：速览条折叠为一行三块，避免聊天栏被顶太长 */
@media (max-width: 900px) {
  .shift-strip-cards { flex-direction: row; }
  .strip-card { flex: 1 1 0; min-width: 0; }
  .strip-time { display: none; }
}

/* ---------- ⑤ 远程效果工具栏：悬浮画面下沿，鼠标移开自动隐藏 ---------- */
.fx-toolbar {
  position: absolute;
  left: 50%;
  bottom: 14px;
  transform: translateX(-50%);
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  background: rgba(10, 12, 15, 0.78);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 999px;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}
.video-frame:hover .fx-toolbar,
.fx-toolbar:focus-within {
  opacity: 1;
  pointer-events: auto;
}
.fx-toolbar button {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 11px;
  font-size: 12.5px;
  color: #E6EAF2;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
}
/* 细线条 SVG 图标（统一规格：14px、随文字颜色变化） */
.fx-toolbar button svg {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
}
.fx-toolbar button:hover {
  background: rgba(11, 107, 255, 0.25);
  border-color: rgba(11, 107, 255, 0.55);
}
.fx-toolbar button.is-on {
  background: #0B6BFF;
  border-color: #0B6BFF;
  color: #fff;
  font-weight: 600;
}
.fx-toolbar .fx-sep {
  width: 1px;
  height: 16px;
  background: rgba(255, 255, 255, 0.15);
}
/* 自动投影开关（勾选式）：外观与工具栏按钮一致 */
.fx-toolbar .fx-auto {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 10px;
  font-size: 12.5px;
  color: #E6EAF2;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
  -webkit-user-select: none;
  user-select: none;
}
.fx-toolbar .fx-auto:hover {
  background: rgba(11, 107, 255, 0.25);
  border-color: rgba(11, 107, 255, 0.55);
}
.fx-toolbar .fx-auto input {
  width: 13px;
  height: 13px;
  margin: 0;
  accent-color: #0B6BFF;
  cursor: pointer;
}
.fx-toolbar .fx-auto.is-on {
  background: #0B6BFF;
  border-color: #0B6BFF;
  color: #fff;
  font-weight: 600;
}
/* 自动投影开启时工具栏常显：随时能看到「已自动」状态，不然鼠标一移开就藏了 */
.fx-toolbar.auto-on {
  opacity: 1;
  pointer-events: auto;
}
body.bare .fx-toolbar { display: none !important; }

/* ---------- 底部条：工作间名字 ---------- */
.live-title {
  color: #E6EAF2;
  font-weight: 600;
  max-width: 40vw;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.live-title.hidden { display: none; }
body:not(.cockpit-theme) .live-title { color: #1e293b; }

/* ---------- ⑥ 待接班侧栏常显：空态占位框 ---------- */
.side-empty {
  flex: 0 0 auto;
  border: 1px dashed rgba(255, 255, 255, 0.14);
  border-radius: 14px;
  padding: 18px 10px;
  font-size: 12px;
  line-height: 1.8;
  color: #8A93A3;
  text-align: center;
  white-space: pre-line;
  background: rgba(255, 255, 255, 0.02);
}
body:not(.cockpit-theme) .side-empty { border-color: #cbd5e1; color: #64748b; background: #f8fafc; }

/* ---------- 【红线】bare 抓取模式：本次新增元素一并隐藏 ---------- */
body.bare .fx-toolbar,
body.bare .net-pill,
body.bare .shift-strip,
body.bare .live-title,
body.immersive .fx-toolbar .hidden {
  display: none !important;
}

/* =============================================================
   查看页第三轮（2026-09-30 深夜）：
   ① 投影弹窗（?proj=1）② 主位声浪徽标 ③ 交接班并入右栏（三栏→两栏）
   【红线】bare 抓取模式所有新元素依旧隐藏
   ============================================================= */

/* ---------- ① 投影弹窗：无滚动条，画面撑满，窗口比例=画面比例 ---------- */
body.proj { overflow: hidden !important; }
body.proj .watch-main { height: 100vh; height: 100dvh; padding: 0; }
body.proj .video-frame {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  border-radius: 0;
  border: none;
  box-shadow: none;
  background: #000;
}
body.proj #remoteVideo { width: 100%; height: 100%; object-fit: contain; }

/* ---------- ② 主位声浪徽标（数据源=查看端实测音量） ---------- */
.data-audio { align-items: center; gap: 8px; }
.data-audio canvas { display: block; }
.data-audio b {
  font-size: 11px;
  font-weight: 600;
  color: #39FF88;
  min-width: 36px;
  text-align: right;
}
body:not(.cockpit-theme) .data-audio b { color: #16a34a; }
body.bare .data-audio { display: none !important; }

/* ---------- ③ 交接班并入右栏：三栏 → 两栏，宽度让给员工端画面 ---------- */
.watch-chat .side-list {
  flex: 0 1 auto;
  max-height: 32vh;
  overflow-y: auto;
  padding: 8px 10px 2px;
  gap: 8px;
}
.watch-chat .side-empty { margin: 8px 10px 2px; }
@media (max-width: 900px) {
  .watch-chat .side-list { max-height: 22vh; }
}

/* ---------- 红线补漏：bare 抓取模式漏网的「工作中/当前主位」徽标一并隐藏 ---------- */
body.bare .video-badge { display: none !important; }

/* ---------- 投影页背景纯黑：cockpit 主题底色是深蓝，直接抓屏会带蓝调 ---------- */
body.proj { background: #000 !important; }
body.proj .watch-stage { background: transparent; }
body.proj .watch-main,
body.proj .watch-body,
body.proj .watch-stage { background: #000 !important; }
/* 「正在连接」浮层自带深蓝底色，投影窗口里同样压成纯黑（连通后浮层自然消失） */
body.proj .video-overlay { background: #000 !important; }

/* ---------- 投影窗「极限纯净」（2026-10-04）：
   除了画面什么都没有 —— 无边框/无阴影/无悬浮灰底，静止时连光标都收起来。
   唯一控件是 18px 无敌小 ✕，只在鼠标动时淡出 2.5s（抓屏桥 nofit=1 模式不创建它）。
   注意：真正零边框的输出是虚拟摄像头（无头抓屏），投影弹窗只是兜底，
   弹窗的标题栏是浏览器/系统画的，网页层去不掉 —— 兜底捕获请用「窗口捕获」并关掉「捕获光标」。 ---------- */
body.proj,
body.proj * { box-shadow: none !important; outline: none !important; text-shadow: none !important; }
body.proj *:not(#projClose) { transition: none !important; }
/* 悬浮不出现任何灰底/高亮（画面本体是 video，不受影响） */
body.proj *:hover { background-color: transparent !important; filter: none !important; }
/* 静止时藏光标：鼠标一动（.proj-ui）恢复，2.5s 后再藏 */
body.proj { cursor: none; }
body.proj.proj-ui { cursor: default; }
/* 无敌小叉：18px，透明度 0.4，不抢镜 */
#projClose {
  position: fixed;
  top: 3px;
  right: 3px;
  z-index: 9999;
  width: 18px;
  height: 18px;
  padding: 0;
  border: none;
  border-radius: 4px;
  font-size: 11px;
  line-height: 18px;
  text-align: center;
  color: rgba(255, 255, 255, 0.4);
  background: transparent;
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
}
body.proj.proj-ui #projClose { opacity: 1; pointer-events: auto; }
#projClose:hover { color: #fff; }

/* =============================================================
   查看/员工端 第四轮（2026-09-30 深夜②）：诊断分离 + 特效同步
   ============================================================= */

/* 员工端操作条：长音频条 + 操作按钮（参考OBS 捕获软件底栏，位于预览框与特效快捷条之间） */
.host-op-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
  padding: 7px 10px;
  border-radius: 12px;
  background: rgba(15, 23, 42, 0.04);
  border: 1px solid var(--line);
}
.op-meter-icon { font-size: 14px; flex: 0 0 auto; }
.op-meter {
  position: relative;
  flex: 1 1 auto;
  min-width: 120px;
  height: 16px;
  border-radius: 999px;
  overflow: hidden;
  background: rgba(15, 23, 42, 0.08);
}
/* 常驻渐变：绿 → 黄 → 红（阈值 55 / 75，与建议引擎分档一致） */
.op-meter-grad {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, #22c55e 0%, #4ade80 50%, #facc15 70%, #ef4444 88%);
  opacity: 0.9;
}
/* 灰色遮罩从右往左收：width = (100 - 音量)%（与BOSS端电平条同一套 mask 语义） */
.op-meter-mask {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  background: rgba(15, 23, 42, 0.18);
  transition: width 0.12s linear;
}
.op-meter.is-mute .op-meter-grad { opacity: 0.12; }
.op-meter.is-mute .op-meter-mask { background: rgba(15, 23, 42, 0.35); }
.op-meter-val {
  flex: 0 0 auto;
  min-width: 44px;
  text-align: right;
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  white-space: nowrap;
  transition: color 0.15s ease;
}
.op-meter-val.is-warn {
  color: #dc2626;
  font-weight: 600;
}
.op-btns { display: flex; gap: 6px; flex: 0 0 auto; }
.op-btn {
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--text);
  border-radius: 999px;
  padding: 4px 11px;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
  transition: all 0.15s ease;
}
.op-btn:hover:not(:disabled) { border-color: var(--primary); color: var(--primary); }
.op-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.op-btn.is-on {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
  font-weight: 600;
}
.op-btn.is-danger {
  background: #dc2626;
  border-color: #dc2626;
  color: #fff;
  font-weight: 600;
  animation: opRecPulse 1.2s ease-in-out infinite;
}
@keyframes opRecPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.35); }
  50% { box-shadow: 0 0 0 6px rgba(220, 38, 38, 0); }
}
/* 调音台定位高亮闪烁 */
@keyframes opMixerFlash {
  0%, 100% { box-shadow: 0 0 0 0 rgba(37, 99, 235, 0); }
  50% { box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.4); }
}
.fx-box.op-mixer-flash { animation: opMixerFlash 0.9s ease-in-out 2; }

/* 员工端特效快捷条（与BOSS端工具栏双向同步） */
.fx-quick-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}
.fx-quick-bar button {
  padding: 5px 12px;
  font-size: 12.5px;
  color: #475569;
  background: #fff;
  border: 1px solid var(--border, #e2e8f0);
  border-radius: 999px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.fx-quick-bar button:hover { border-color: #2563eb; color: #2563eb; }
.fx-quick-bar button.is-on {
  background: #2563eb;
  border-color: #2563eb;
  color: #fff;
  font-weight: 600;
}

/* 时钟贴片可拖拽（时钟开启时可抓取） */
.video-clock:not(.hidden) { pointer-events: auto; cursor: grab; }
.video-clock:active { cursor: grabbing; }
/* 合成管线运行时（时钟已烘焙进输出画面）：DOM 预览那份只隐去视觉、保留拖拽热区。
   若用 .hidden 直接 display:none，pointerdown 永远收不到 → 用户实测「时钟拖不动」。
   （2026-10-12） */
.video-clock.is-baked { opacity: 0; pointer-events: auto; cursor: grab; }

/* 查看页远程接入徽标警告色 */
.data-badge.is-warn { border-color: rgba(245, 158, 11, 0.55); color: #fbbf24; }

/* =============================================================
   第五轮（2026-09-30 深夜③）：时钟 10 款样式选择条
   ============================================================= */
.clock-styles {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 6px;
}
.clock-style-chip {
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 600;
  color: #475569;
  background: rgba(15, 23, 42, 0.06);
  border: 1px solid var(--border, #e2e8f0);
  border-radius: 8px;
  cursor: pointer;
  transition: transform 0.12s, box-shadow 0.12s;
}
.clock-style-chip:hover { transform: translateY(-1px); box-shadow: 0 2px 6px rgba(15, 23, 42, 0.12); }
.clock-style-chip.is-active {
  box-shadow: 0 0 0 2px #2563eb inset, 0 2px 6px rgba(37, 99, 235, 0.25);
  border-color: #2563eb;
}

/* ---------- 监听声音开关（顶栏 net-pill 按钮形态）：重置 button 默认样式 ---------- */
button.net-pill-btn {
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}
button.net-pill-btn:hover { border-color: rgba(11, 107, 255, 0.6); color: #cdd6e4; }
body:not(.cockpit-theme) button.net-pill-btn:hover { border-color: #2563eb; color: #2563eb; }

/* ============================================================================
   统一交互 VI：顶部导航（返回上一层 / 返回主页）+ 用户登录 / 用户信息小标
   —— 全站一套：简约干净商务风，无花哨动画（悬浮轻微变色 + 极短过渡）
   色板沿用 VI：主色 #2563eb / 辅助 #64748b / 正文 #1e293b / 底 #f8fafc
   ============================================================================ */
.topbar-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}
.nav-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 30px;
  padding: 0 10px;
  border: 1px solid var(--border, #e2e8f0);
  border-radius: 8px;
  background: var(--card, #fff);
  color: var(--text-secondary, #64748b);
  font-size: 12.5px;
  font-family: inherit;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.nav-btn svg { width: 15px; height: 15px; flex: 0 0 auto; }
.nav-btn:hover { background: #eff6ff; border-color: #bfdbfe; color: #2563eb; }
.nav-btn:active { background: #dbeafe; }
.nav-btn[disabled] { opacity: 0.5; cursor: not-allowed; }

/* ---------- 用户登录入口 ---------- */
.nav-id-slot { position: relative; display: flex; align-items: center; }
.nav-login {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 14px;
  border: 1px solid #2563eb;
  border-radius: 8px;
  background: #2563eb;
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  font-family: inherit;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.nav-login svg { width: 15px; height: 15px; }
.nav-login:hover { background: #1d4ed8; border-color: #1d4ed8; }
.nav-login-caret { display: inline-flex; margin-left: 2px; opacity: 0.9; }
.nav-login-caret svg { width: 13px; height: 13px; }
.nav-login.is-open { background: #1d4ed8; }

/* ---------- 用户信息小标（头像 + 昵称 + 角色编号） ---------- */
.id-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 36px;
  padding: 0 10px 0 4px;
  border: 1px solid var(--border, #e2e8f0);
  border-radius: 999px;
  background: var(--card, #fff);
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.id-chip:hover,
.id-chip.is-open { border-color: #bfdbfe; background: #f8fafc; }
.id-avatar {
  width: 28px;
  height: 28px;
  flex: 0 0 auto;
  border-radius: 50%;
  overflow: hidden;
  background: #2563eb;
  color: #fff;
  font-size: 12.5px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.id-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.id-text { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.18; }
.id-name { font-size: 12.5px; font-weight: 600; color: var(--text, #1e293b); }
.id-meta { font-size: 10.5px; font-style: normal; color: var(--text-secondary, #64748b); }
.id-caret { display: inline-flex; color: #94a3b8; }
.id-caret svg { width: 14px; height: 14px; }
.id-chip.is-open .id-caret { transform: rotate(180deg); }

/* ---------- 下拉菜单（账号信息 / 退出登录 / 登录入口分组） ---------- */
.id-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  min-width: 200px;
  padding: 6px;
  background: var(--card, #fff);
  border: 1px solid var(--border, #e2e8f0);
  border-radius: 12px;
  box-shadow: 0 10px 30px rgba(15, 23, 42, 0.12);
  z-index: 9500;
}
.id-menu[hidden] { display: none; }
.id-menu-head {
  padding: 8px 10px 9px;
  border-bottom: 1px solid #f1f5f9;
  margin-bottom: 5px;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.id-menu-head b { font-size: 13px; color: var(--text, #1e293b); }
.id-menu-head span { font-size: 11px; color: var(--text-secondary, #64748b); }
.id-menu-note { padding: 0 10px 8px; font-size: 11px; color: var(--text-secondary, #64748b); }
.id-menu-item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text, #1e293b);
  font-size: 12.5px;
  font-family: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.id-menu-item svg { width: 15px; height: 15px; flex: 0 0 auto; color: #94a3b8; }
.id-menu-item:hover { background: #f1f5f9; }
.id-menu-item:hover svg { color: #2563eb; }
.id-menu-item em { margin-left: auto; font-size: 11px; font-style: normal; color: var(--text-secondary, #64748b); }
.id-menu-item.is-danger { color: #dc2626; }
.id-menu-item.is-danger svg { color: #f87171; }
.id-menu-item.is-danger:hover { background: #fef2f2; }
.id-menu-item.is-danger:hover svg { color: #dc2626; }
.id-menu-sep { height: 1px; margin: 5px 6px; background: #f1f5f9; }

/* ---------- 窄屏：只留图标，腾出空间给页面内容 ---------- */
@media (max-width: 860px) {
  .nav-btn-t { display: none; }
  .nav-btn { padding: 0 8px; }
  .id-text { display: none; }
  .id-chip { padding: 0 6px 0 4px; }
  .topbar-actions { gap: 6px; }
}

/* 旧版顶栏「退出登录」按钮 / 身份文本：已由统一的「用户信息小标」菜单取代
   （元素保留在 DOM 里，旧逻辑照常读写 hidden，只是不再占位显示） */
#btnLogout,
#bossWho { display: none !important; }

/* ---------- 统一导航 VI 在查看页（body.cockpit-theme 深色驾驶舱）下的适配 ---------- */
body.cockpit-theme .nav-btn {
  background: rgba(255, 255, 255, 0.05);
  border-color: var(--ck-line);
  color: var(--ck-muted);
}
body.cockpit-theme .nav-btn:hover {
  background: rgba(11, 107, 255, 0.18);
  border-color: rgba(11, 107, 255, 0.5);
  color: #DCE8FF;
}
body.cockpit-theme .nav-btn:active { background: rgba(11, 107, 255, 0.3); }
body.cockpit-theme .id-chip {
  background: rgba(255, 255, 255, 0.05);
  border-color: var(--ck-line);
}
body.cockpit-theme .id-chip:hover,
body.cockpit-theme .id-chip.is-open {
  background: rgba(255, 255, 255, 0.09);
  border-color: rgba(11, 107, 255, 0.45);
}
body.cockpit-theme .id-avatar { background: var(--ck-primary); }
body.cockpit-theme .id-name { color: var(--ck-text); }
body.cockpit-theme .id-meta { color: var(--ck-muted); }
body.cockpit-theme .id-caret { color: var(--ck-muted); }
body.cockpit-theme .id-menu {
  background: var(--ck-card);
  border-color: rgba(255, 255, 255, 0.1);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.55);
}
body.cockpit-theme .id-menu-head { border-bottom-color: var(--ck-line); }
body.cockpit-theme .id-menu-head b { color: var(--ck-text); }
body.cockpit-theme .id-menu-head span,
body.cockpit-theme .id-menu-note,
body.cockpit-theme .id-menu-item em { color: var(--ck-muted); }
body.cockpit-theme .id-menu-item { color: var(--ck-text); }
body.cockpit-theme .id-menu-item svg { color: var(--ck-muted); }
body.cockpit-theme .id-menu-item:hover { background: rgba(255, 255, 255, 0.07); }
body.cockpit-theme .id-menu-item:hover svg { color: var(--ck-primary-hover); }
body.cockpit-theme .id-menu-item.is-danger { color: #FF8A8E; }
body.cockpit-theme .id-menu-item.is-danger:hover { background: rgba(229, 72, 77, 0.16); }
body.cockpit-theme .id-menu-sep { background: var(--ck-line); }
body.cockpit-theme .nav-login {
  background: var(--ck-primary);
  border-color: var(--ck-primary);
}
body.cockpit-theme .nav-login:hover { background: var(--ck-primary-hover); border-color: var(--ck-primary-hover); }

/* ---------- 统一导航 VI 在上岗页（body.zt-theme 暖色主题）下的适配：
   跟随该页自己的主题变量（--primary），不硬编码蓝色，保证页面内 VI 一致 ---------- */
body.zt-theme .nav-btn {
  border-color: var(--border-strong, #e2e8f0);
  color: var(--text-sub, #64748b);
}
body.zt-theme .nav-btn:hover {
  background: var(--primary-soft);
  border-color: var(--primary-border);
  color: var(--primary);
}
body.zt-theme .nav-btn:active { background: var(--primary-soft); }
body.zt-theme .id-chip { border-color: var(--border-strong, #e2e8f0); }
body.zt-theme .id-chip:hover,
body.zt-theme .id-chip.is-open { background: #fff; border-color: var(--primary-border); }
body.zt-theme .id-avatar { background: var(--primary); }
body.zt-theme .id-name { color: var(--text); }
body.zt-theme .id-meta { color: var(--text-muted); }
body.zt-theme .id-caret { color: var(--text-muted); }
body.zt-theme .id-menu { background: #fff; border-color: var(--border-strong, #e2e8f0); }
body.zt-theme .id-menu-head b { color: var(--text); }
body.zt-theme .id-menu-head span,
body.zt-theme .id-menu-note,
body.zt-theme .id-menu-item em { color: var(--text-muted); }
body.zt-theme .id-menu-item { color: var(--text); }
body.zt-theme .id-menu-item:hover { background: var(--primary-soft); }
body.zt-theme .id-menu-item:hover svg { color: var(--primary); }
body.zt-theme .id-menu-item.is-danger { color: #C8102E; }
body.zt-theme .id-menu-item.is-danger:hover { background: rgba(200, 16, 46, 0.08); }
body.zt-theme .nav-login { background: var(--primary); border-color: var(--primary); }
body.zt-theme .nav-login:hover { background: var(--primary-hover); border-color: var(--primary-hover); }

/* ============================================================================
   备案号页脚（仅大陆服务器上线时需要）
   工信部要求首页底部悬挂 ICP 备案号并链接查询页；公安备案号同理。
   未配置备案号时组件不渲染 DOM，所以本地 / 香港部署完全无感。
   定位：固定底部居中、胶囊底、pointer-events 只在链接上生效 —— 绝不挡操作。
   ============================================================================ */
.wb-footer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  /* 全站页脚：整条上移出 Home 指示条，横屏时左右也让开圆角 */
  left: var(--sal);
  right: var(--sar);
  bottom: var(--sab);
  z-index: 8000;
  display: flex;
  justify-content: center;
  padding: 0 8px 5px;
  pointer-events: none;
}
.wb-footer[hidden] { display: none; }
.wb-footer-inner {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  padding: 3px 10px;
  border-radius: 999px;
  background: rgba(248, 250, 252, 0.88);
  box-shadow: 0 1px 6px rgba(15, 23, 42, 0.06);
  font-size: 11px;
  line-height: 1.6;
  color: var(--text-secondary, #64748b);
  overflow: hidden;
}
.wb-footer-item {
  color: var(--text-secondary, #64748b);
  text-decoration: none;
  white-space: nowrap;
}
a.wb-footer-item:hover { color: #2563eb; text-decoration: underline; }
.wb-footer-sep { color: #cbd5e1; }
.wb-footer-name { cursor: default; }

/* bare 纯净模式：备案号绝不能进外部平台工作间画面 */
body.bare .wb-footer { display: none !important; }

/* 深色主题适配 */
body.boss-theme .wb-footer-inner {
  background: rgba(18, 22, 30, 0.82);
  color: var(--b-ink-3, #8b95a7);
  box-shadow: 0 1px 8px rgba(0, 0, 0, 0.4);
}
body.boss-theme .wb-footer-item { color: var(--b-ink-3, #8b95a7); }
body.boss-theme a.wb-footer-item:hover { color: var(--b-accent, #0B6BFF); }
body.boss-theme .wb-footer-sep { color: rgba(255, 255, 255, 0.18); }
body.cockpit-theme .wb-footer-inner {
  background: rgba(18, 22, 30, 0.82);
  color: var(--ck-muted, #8b95a7);
  box-shadow: 0 1px 8px rgba(0, 0, 0, 0.4);
}
body.cockpit-theme .wb-footer-item { color: var(--ck-muted, #8b95a7); }
body.cockpit-theme a.wb-footer-item:hover { color: var(--ck-primary-hover, #4d8dff); }
body.cockpit-theme .wb-footer-sep { color: rgba(255, 255, 255, 0.18); }

/* 首页（body.lp-body 深色科技风，home.css 只管首页与 /login）：
   备案号页脚走深色胶囊，配色对齐首页自家页脚（.lp-foot 链接色 #5f6f8f / hover 蓝），
   别让浅色胶囊压在 #04060b 的深色页上显得突兀。 */
body.lp-body .wb-footer-inner {
  background: rgba(4, 6, 11, 0.86);
  color: #7c8aa5;
  box-shadow: 0 1px 8px rgba(0, 0, 0, 0.45);
}
body.lp-body .wb-footer-item { color: #7c8aa5; }
body.lp-body a.wb-footer-item:hover { color: #60a5fa; text-decoration: underline; }
body.lp-body .wb-footer-sep { color: rgba(255, 255, 255, 0.18); }

/* ===== 单子管理（新增：品类多选 / 派单模式 / 对标资料上传列表） ===== */
.cat-chips { display: flex; flex-wrap: wrap; gap: 6px 10px; }
.cat-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; color: #334155; background: #f1f5f9; border-radius: 8px; padding: 4px 9px; cursor: pointer; -webkit-user-select: none; user-select: none; }
.cat-chip input { margin: 0; }
.task-mode-row { display: flex; gap: 18px; margin: 4px 0 2px; }
.task-radio { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer; }
.bench-editor { margin-top: 4px; }
.bench-pick { display: flex; align-items: center; }
.bench-list { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; }
.bench-item { display: flex; align-items: center; gap: 8px; padding: 7px 10px; border: 1px solid var(--border); border-radius: 10px; background: #f8fafc; }
.bench-name { flex: 1; min-width: 0; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bench-st { font-size: 12px; white-space: nowrap; }
.bench-st-done { color: #16a34a; }
.bench-st-uploading, .bench-st-queued { color: var(--primary); }
.bench-st-error { color: #dc2626; }

/* ===== 企微智能表单 · 三表（admin 单子管理） ===== */
.subtabs { display: inline-flex; gap: 4px; background: var(--bg, #f1f5f9); border-radius: 8px; padding: 3px; }
.sub-tab { border: 0; background: transparent; color: var(--text-2, #64748b); font-size: 13px; padding: 5px 12px; border-radius: 6px; cursor: pointer; white-space: nowrap; }
.sub-tab:hover { color: var(--text-1, #1e293b); }
.sub-tab.is-active { background: #fff; color: var(--primary, #2563eb); font-weight: 600; box-shadow: 0 1px 2px rgb(0 0 0 / 8%); }
.form-tbl { font-size: 12px; }
.form-tbl th, .form-tbl td { white-space: nowrap; padding: 6px 8px; }
.form-group-row .fg { text-align: center; font-weight: 700; }
.fg-a { background: #eff6ff; color: #1d4ed8; }
.fg-b { background: #f0fdf4; color: #15803d; }
.fg-c { background: #fefce8; color: #a16207; }
.pill { display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: 11px; line-height: 18px; }
#formTable tbody tr { cursor: pointer; }
#formTable tbody tr:hover { background: #f8fafc; }
#formTable tfoot td { font-weight: 700; background: #f8fafc; }

/* ===== 通用批量导入弹窗（batch-import.js） ===== */
.bi-mask { position: fixed; inset: 0; background: rgb(15 23 42 / 42%); display: flex; align-items: center; justify-content: center; z-index: 3000; padding: 20px; }
.bi-box { background: #fff; border-radius: 14px; width: 100%; max-width: 1080px; max-height: 88vh; display: flex; flex-direction: column; padding: 20px 22px; box-shadow: 0 18px 50px rgb(15 23 42 / 24%); }
.bi-head { display: flex; align-items: center; margin-bottom: 6px; }
.bi-head h3 { font-size: 17px; margin: 0; color: var(--text-1, #1e293b); flex: 1; }
.bi-x { border: 0; background: transparent; font-size: 24px; line-height: 1; color: #94a3b8; cursor: pointer; }
.bi-x:hover { color: #475569; }
.bi-hint { font-size: 12px; color: #64748b; line-height: 1.7; margin-bottom: 12px; }
.bi-drop { border: 2px dashed #cbd5e1; border-radius: 12px; padding: 26px 16px; text-align: center; cursor: pointer; transition: .15s; background: #f8fafc; }
.bi-drop:hover, .bi-drop.is-over { border-color: var(--primary, #2563eb); background: #eff6ff; }
.bi-drop-main { font-size: 15px; font-weight: 600; color: #334155; }
.bi-drop-sub { font-size: 12px; color: #94a3b8; margin-top: 6px; }
.bi-file { font-size: 12px; color: #2563eb; margin-top: 8px; }
.bi-opt { display: flex; align-items: center; gap: 6px; font-size: 13px; color: #475569; margin: 12px 0 4px; cursor: pointer; }
.bi-msg { font-size: 13px; margin-top: 8px; padding: 8px 10px; border-radius: 8px; background: #f1f5f9; color: #475569; }
.bi-msg.is-ok { background: #f0fdf4; color: #15803d; }
.bi-msg.is-warn { background: #fffbeb; color: #b45309; }
.bi-msg.is-error { background: #fef2f2; color: #b91c1c; }
.bi-summary { font-size: 13px; font-weight: 600; color: #334155; margin: 10px 0 6px; }
.bi-preview { overflow: auto; max-height: 46vh; border: 1px solid #e2e8f0; border-radius: 10px; }
.bi-tbl { border-collapse: collapse; font-size: 12px; width: 100%; }
.bi-tbl th, .bi-tbl td { border-bottom: 1px solid #eef2f7; padding: 6px 8px; white-space: nowrap; text-align: left; }
.bi-tbl thead th { position: -webkit-sticky; position: sticky; top: 0; background: #f8fafc; z-index: 1; font-weight: 600; color: #475569; }
.bi-tbl tr.is-err { background: #fef2f2; }
.bi-tbl tr.is-skip { background: #f8fafc; color: #94a3b8; }
.bi-tbl tr.is-upd { background: #fffbeb; }
.bi-badge { display: inline-block; padding: 0 6px; border-radius: 4px; font-size: 11px; line-height: 18px; }
.bi-b-create { background: #dcfce7; color: #15803d; }
.bi-b-update { background: #fef3c7; color: #b45309; }
.bi-b-skip { background: #e2e8f0; color: #64748b; }
.bi-b-error { background: #fee2e2; color: #b91c1c; }
.bi-why { color: #b91c1c; max-width: 260px; white-space: normal; }
.bi-idx { color: #94a3b8; }
.bi-foot { display: flex; align-items: center; gap: 8px; margin-top: 14px; }
.bi-spacer { flex: 1; }
.bi-btn-primary, .bi-btn-ghost { border-radius: 8px; padding: 8px 16px; font-size: 14px; cursor: pointer; border: 1px solid transparent; }
.bi-btn-primary { background: var(--primary, #2563eb); color: #fff; }
.bi-btn-primary:hover { filter: brightness(1.08); }
.bi-btn-primary:disabled { background: #cbd5e1; cursor: not-allowed; }
.bi-btn-ghost { background: #fff; border-color: #dbe3ee; color: #475569; }
.bi-btn-ghost:hover { border-color: var(--primary, #2563eb); color: var(--primary, #2563eb); }

/* ===== AI 小助理【多多】浮动面板 ===== */
.dd-fab { position: fixed; right: 22px; bottom: 22px; right: calc(22px + var(--sar)); bottom: calc(22px + var(--sab)); z-index: 2900; display: inline-flex; align-items: center; gap: 6px; background: linear-gradient(135deg, #2563eb, #7c3aed); color: #fff; border: 0; border-radius: 999px; padding: 10px 18px; font-size: 14px; font-weight: 600; cursor: pointer; box-shadow: 0 8px 22px rgb(37 99 235 / 35%); }
.dd-fab:hover { filter: brightness(1.08); }
.dd-panel { position: fixed; right: 22px; bottom: 78px; right: calc(22px + var(--sar)); bottom: calc(78px + var(--sab)); z-index: 2901; width: 460px; max-width: calc(100vw - 32px); height: 560px; max-height: calc(100vh - 120px); max-height: calc(100dvh - 120px); background: #fff; border-radius: 16px; box-shadow: 0 20px 60px rgb(15 23 42 / 26%); display: flex; flex-direction: column; overflow: hidden; }
.dd-head { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-bottom: 1px solid #eef2f7; }
.dd-avatar { font-size: 22px; }
.dd-titlewrap { flex: 1; min-width: 0; }
.dd-title { font-size: 14px; font-weight: 700; color: #1e293b; }
.dd-mode { font-size: 11px; color: #94a3b8; }
.dd-mode.is-ai { color: #16a34a; }
.dd-mode.is-rule { color: #d97706; }
.dd-icon { border: 0; background: transparent; font-size: 16px; color: #94a3b8; cursor: pointer; padding: 4px 6px; }
.dd-icon:hover { color: #475569; }
.dd-body { flex: 1; overflow-y: auto; padding: 12px 14px; background: #f8fafc; display: flex; flex-direction: column; gap: 10px; }
.dd-row { display: flex; }
.dd-row.dd-user { justify-content: flex-end; }
.dd-bubble { max-width: 86%; padding: 9px 12px; border-radius: 12px; font-size: 13px; line-height: 1.7; background: #fff; color: #1e293b; box-shadow: 0 1px 3px rgb(15 23 42 / 8%); }
.dd-user .dd-bubble { background: #2563eb; color: #fff; }
.dd-card { max-width: 100%; background: #fff; border: 1px solid #e2e8f0; border-radius: 12px; padding: 10px 12px; box-shadow: 0 1px 3px rgb(15 23 42 / 6%); }
.dd-card-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.dd-card-title { font-size: 13px; font-weight: 700; color: #1e293b; flex: 1; }
.dd-card-stat { font-size: 11px; color: #64748b; }
.dd-card-err { font-size: 12px; color: #b91c1c; }
.dd-tblwrap { overflow: auto; max-height: 200px; border: 1px solid #eef2f7; border-radius: 8px; }
.dd-tbl { border-collapse: collapse; font-size: 11px; width: 100%; }
.dd-tbl th, .dd-tbl td { padding: 4px 6px; border-bottom: 1px solid #f1f5f9; text-align: left; white-space: nowrap; }
.dd-tbl thead th { background: #f8fafc; color: #64748b; position: -webkit-sticky; position: sticky; top: 0; }
.dd-tbl tr.is-err { background: #fef2f2; }
.dd-tbl tr.is-skip { color: #94a3b8; }
.dd-badge { padding: 0 5px; border-radius: 4px; font-size: 10px; }
.dd-b-create { background: #dcfce7; color: #15803d; }
.dd-b-update { background: #fef3c7; color: #b45309; }
.dd-b-skip { background: #e2e8f0; color: #64748b; }
.dd-b-error { background: #fee2e2; color: #b91c1c; }
.dd-why { color: #b91c1c; }
.dd-more { font-size: 11px; color: #94a3b8; padding: 4px 6px; }
.dd-card-foot { display: flex; justify-content: flex-end; margin-top: 8px; }
.dd-exec { background: #2563eb; color: #fff; border: 0; border-radius: 8px; padding: 7px 14px; font-size: 13px; cursor: pointer; }
.dd-exec:disabled { background: #cbd5e1; cursor: not-allowed; }
.dd-btn-ghost { background: #fff; border: 1px solid #dbe3ee; color: #475569; border-radius: 8px; padding: 7px 14px; font-size: 13px; cursor: pointer; }
.dd-chips { display: flex; gap: 6px; padding: 8px 12px 0; flex-wrap: wrap; }
.dd-chip { border: 1px solid #dbe3ee; background: #fff; color: #475569; font-size: 11px; border-radius: 999px; padding: 4px 10px; cursor: pointer; }
.dd-chip:hover { border-color: #2563eb; color: #2563eb; }
.dd-foot { display: flex; gap: 8px; padding: 10px 12px; border-top: 1px solid #eef2f7; }
.dd-input { flex: 1; border: 1px solid #e2e8f0; border-radius: 10px; padding: 8px 10px; font-size: 13px; resize: none; font-family: inherit; max-height: 90px; }
.dd-send { background: #2563eb; color: #fff; border: 0; border-radius: 10px; padding: 0 16px; font-size: 13px; cursor: pointer; }
.dd-send:disabled { background: #cbd5e1; }
.dd-cfg { padding: 12px 14px; border-top: 1px solid #eef2f7; background: #fff; display: flex; flex-direction: column; gap: 8px; }
.dd-cfg-title { font-size: 13px; font-weight: 700; color: #1e293b; }
.dd-cfg-input { border: 1px solid #e2e8f0; border-radius: 8px; padding: 7px 10px; font-size: 12px; width: 100%; box-sizing: border-box; }
.dd-cfg-tip { font-size: 11px; color: #94a3b8; line-height: 1.7; }
.dd-cfg-row { display: flex; gap: 8px; }
.dd-cfg-msg { font-size: 12px; }
.dd-cfg-msg.is-ok { color: #15803d; }
.dd-cfg-msg.is-err { color: #b91c1c; }
@media (max-width: 560px) {
  /* 覆盖陷阱：同名 right/left/bottom 会盖掉上面的 calc(… + var(--s*)) */
  .dd-panel { right: 8px; left: 8px; width: auto; bottom: 72px; height: 70vh;
    right: calc(8px + var(--sar)); left: calc(8px + var(--sal)); bottom: calc(72px + var(--sab)); }
  .dd-fab { right: 14px; bottom: 14px;
    right: calc(14px + var(--sar)); bottom: calc(14px + var(--sab)); }
}

/* ===== 素材拖拽批量上传区 ===== */
.mat-drop { border: 2px dashed #cbd5e1; border-radius: 12px; padding: 18px; text-align: center; cursor: pointer; background: #f8fafc; margin-bottom: 14px; transition: .15s; }
.mat-drop:hover, .mat-drop.is-over { border-color: var(--primary, #2563eb); background: #eff6ff; }
.mat-drop-main { font-size: 14px; font-weight: 600; color: #334155; }
.mat-drop-sub { font-size: 12px; color: #94a3b8; margin-top: 5px; }

/* ===== 对标资料拖拽区 ===== */
.bench-drop { border: 2px dashed #cbd5e1; border-radius: 10px; padding: 14px; text-align: center; font-size: 13px; color: #475569; cursor: pointer; background: #f8fafc; margin: 8px 0; }
.bench-drop:hover, .bench-drop.is-over { border-color: var(--primary, #2563eb); background: #eff6ff; }
.bench-drop-sub { font-size: 11px; color: #94a3b8; margin-top: 4px; }

/* ==========================================================================
   后台效率手感（2026-10-09）
   A. 宽表可读性：粘性两层表头 + 粘性首列 + 密度切换（受 table-density.js 控制）
   B. 批量导入结果条 / 只看失败行 / 导出失败行
   ========================================================================== */

/* ---------- A1. 宽表滚动容器 ----------
   sticky 只在「最近的可滚动祖先」内生效。.table-wrap 默认只有 overflow-x:auto
   （另一轴按 CSS 规范计算成 auto），高度不受限 → 它永远不滚 → 表头贴不上去。
   所以给宽表加 .is-tall，让表格自己带上高度上限。 */
.table-wrap.is-tall {
  max-height: 74vh;
  overflow: auto;
}

/* ---------- A2. 粘性两层表头 ---------- */
/* border-collapse: collapse 之下，粘住的 th 会丢掉 border-bottom，用 inset 阴影补回来。
   默认 top:0 —— 没有分组行的表（老板档案 / 员工档案）表头就贴容器顶。 */
.table-wrap.is-tall > table.tbl > thead > th,
.table-wrap.is-tall > table.tbl > thead > tr > th {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 3;
  box-shadow: inset 0 -1px 0 var(--border);
}
/* 派单总表有**两层**表头：分组行吸顶，列名行吸在分组行下面。
   分组行高度被固定成 26px，第二层的 top 才是确定值（不然跟着字体度量飘）。
   ⚠️ 这里必须用 #formTable 限定：否则没分组行的档案表也会被顶下去 26px（QA 实测的空隙缺陷）。 */
.form-tbl tr.form-group-row > th { height: 26px; padding: 0 8px; line-height: 26px; }
#formTable thead > tr:not(.form-group-row) > th { top: 26px; }

/* ---------- A3. 粘性首列：横滑时始终知道「这是谁的单」 ---------- */
.table-wrap.is-tall > table.tbl > thead > tr:not(.form-group-row) > th:first-child,
.table-wrap.is-tall > table.tbl > tbody > tr > td:first-child,
.table-wrap.is-tall > table.tbl > tfoot > tr > td:first-child {
  position: -webkit-sticky;
  position: sticky;
  left: 0;
  z-index: 2;
  background: #fff;
  box-shadow: 1px 0 0 var(--border);
}
/* 表头首列要压在 tbody 首列之上；分组行首列本身有底色（.fg-a），只借位置不换色 */
.table-wrap.is-tall > table.tbl > thead > tr:not(.form-group-row) > th:first-child { z-index: 4; background: var(--secondary-soft); }
.table-wrap.is-tall > table.tbl > thead > tr.form-group-row > th:first-child { z-index: 4; }
/* 悬停/合计行时首列要保持不透明，否则下面的内容会透出来 */
#formTable tbody tr:hover td:first-child { background: #f8fafc; }
.table-wrap.is-tall > table.tbl > tfoot > tr > td:first-child { background: #f8fafc; }

/* ---------- A5. 最后一列吸右（全局，2026-10-10）----------
   需求：后台任意宽表在窄窗口下最后一列（通常是「操作」）被截断，只能横向滚动才能看到
   按钮 —— 要求「每次调整之后自动更新比例排版」。吸右 = 不管表格多宽、以后加多少列，
   最后一列永远完整可见，无需逐表调宽度。
   ⚠️ :not([colspan]) 必须带：空状态行 / 派单总表分组行都是整行 colspan，
   若被吸右会整行贴右边并带白底与阴影（视觉事故）。
   ⚠️ 与 A3 吸左首列同款配方：不透明背景 + 1px 阴影补 border-collapse 丢掉的边线。
   表格没超出容器时 sticky 无视觉效果，零副作用。 */
.table-wrap > table.tbl > thead > tr > th:last-child:not([colspan]),
.table-wrap > table.tbl > tbody > tr > td:last-child:not([colspan]),
.table-wrap > table.tbl > tfoot > tr > td:last-child:not([colspan]) {
  position: -webkit-sticky;
  position: sticky;
  right: 0;
  z-index: 2;
  background: #fff;
  box-shadow: -1px 0 0 var(--border);
}
/* 表头最后一列要压过 tbody 吸左首列（z2）与吸顶表头（z3） */
.table-wrap > table.tbl > thead > tr > th:last-child:not([colspan]) {
  z-index: 5;
  background: var(--secondary-soft);
}
/* 悬停行时吸右列保持不透明（权重高于 table.tbl tr:hover td） */
.table-wrap > table.tbl > tbody > tr:hover > td:last-child:not([colspan]) { background: #fbfdff; }
/* 横向溢出时（JS 给 .table-wrap 打 is-scrollable）：吸右列投影加深，提示「往左还有内容」 */
.table-wrap.is-scrollable > table.tbl > thead > tr > th:last-child:not([colspan]),
.table-wrap.is-scrollable > table.tbl > tbody > tr > td:last-child:not([colspan]) {
  box-shadow: -1px 0 0 var(--border), -10px 0 14px -10px rgba(15, 23, 42, 0.35);
}

/* ---------- A6. 房间管理：按 BOSS 端分组（2026-10-10）----------
   第一列 = 老板（rowspan 跨该老板全部可见房间行），第二列 = 房间，第三列 = 房间情况。
   组与组之间用 2px 分隔线；老板格淡底 + 顶对齐，扫一眼就能看出「一人一段」。 */
.table-wrap > table.tbl > tbody > tr.gstart > td {
  border-top: 2px solid var(--border);
}
.table-wrap > table.tbl > tbody > tr.gstart > td[rowspan] {
  vertical-align: top;
}

/* ---------- A4. 密度切换（只影响派单总表；按钮文案已写明「总表密度」） ----------
   ⚠️ 必须用 #formTable（id 权重 1,0,0）压过 `table.tbl td{padding:12px}`（0,1,2）：
   早先用 `.form-tbl td`（0,1,1）时被基线压过 → 两态只剩 cozy 生效、**紧凑反而比舒适更松**（QA 实测反转）。
   同时按 tbody/tfoot 与「第二层表头」逐个限定，**绕开分组行**——分组行高度必须是钉死的 26px。 */
#formTable thead > tr:not(.form-group-row) > th,
#formTable tbody > tr > td,
#formTable tfoot > tr > td { padding: 4px 8px; }
body.tbl-cozy #formTable thead > tr:not(.form-group-row) > th,
body.tbl-cozy #formTable tbody > tr > td,
body.tbl-cozy #formTable tfoot > tr > td { padding: 9px 12px; }

/* ---------- B1. 导入结果条 ---------- */
.bi-summary { font-size: 13px; font-weight: 600; color: #334155; margin: 10px 0 6px; }
.bi-result { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 12px 0 8px; }
.bi-bar { flex: 1; min-width: 180px; height: 10px; display: flex; border-radius: 999px; overflow: hidden; background: #eef2f7; }
.bi-bar-seg { height: 100%; min-width: 2px; }
.bi-bar-seg.is-ok { background: #22c55e; }
.bi-bar-seg.is-skip { background: #cbd5e1; }
.bi-bar-seg.is-err { background: #ef4444; }
.bi-lg { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: #475569; white-space: nowrap; }
.bi-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.bi-dot.is-ok { background: #22c55e; }
.bi-dot.is-skip { background: #cbd5e1; }
.bi-dot.is-err { background: #ef4444; }
/* ---------- B2. 只看失败行 + 导出失败行 ---------- */
.bi-tools { display: flex; align-items: center; gap: 10px; margin: 0 0 8px; }
.bi-check { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: #475569; cursor: pointer; }
.bi-check input { cursor: pointer; }
.bi-export { border: 1px solid #dbe3ee; background: #fff; color: #475569; border-radius: 8px; padding: 5px 12px; font-size: 12.5px; cursor: pointer; }
.bi-export:hover { border-color: var(--primary, #2563eb); color: var(--primary, #2563eb); }
.bi-export:disabled { opacity: .5; cursor: not-allowed; border-color: #dbe3ee; color: #94a3b8; }
.bi-preview.is-only-failed .bi-tbl tbody tr:not(.is-err) { display: none; }

/* ---------- C. 空状态四态（统一规范，见 deliverables/gstack/design-优化设计方案.md §3.4） ----------
   规则：空状态**必有下半句**（告诉用户下一步）+ **必有主操作**；错误态**必有重试**。
   四态：无数据(empty) / 无搜索结果(search) / 加载中(loading 骨架条) / 出错(warn) —— 由 js/empty-state.js 产出。
   图标用内联 SVG（CSP `script-src 'self'` 不禁内联 SVG，禁的只是内联 script/onclick）。 */
.es { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px; padding: 30px 16px; text-align: center; color: var(--muted, #64748b); }
.es-ico { width: 42px; height: 42px; color: #cbd5e1; }
.es-ico svg { width: 100%; height: 100%; display: block; }
.es-title { font-size: 14px; font-weight: 600; color: var(--text, #1e293b); }
.es-hint { font-size: 12.5px; line-height: 1.65; max-width: 460px; }
.es-act { margin-top: 5px; display: flex; gap: 8px; align-items: center; justify-content: center; flex-wrap: wrap; }
.es-code { font-size: 11.5px; color: #94a3b8; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.es-tone-warn .es-ico { color: #f59e0b; }
.es-tone-err .es-ico { color: #ef4444; }
/* 表格整行铺开：必须 !important —— 密度规则用的是 `#formTable tbody > tr > td`（带 id 提权），比类名重 */
.es-row > td { padding: 0 !important; }
.es-row:hover > td { background: transparent !important; }
.es-row > td .es { padding: 26px 16px; }
/* 加载中：3 条骨架条（不用「加载中…」文字，减少跳动） */
.es-skel { width: min(520px, 82%); display: flex; flex-direction: column; gap: 9px; margin: 4px 0; }
.es-skel i { display: block; height: 12px; border-radius: 6px; background: linear-gradient(90deg, #eef2f7 25%, #e2e8f0 37%, #eef2f7 63%); background-size: 400% 100%; animation: esShimmer 1.3s ease-in-out infinite; }
.es-skel i:nth-child(2) { width: 86%; }
.es-skel i:nth-child(3) { width: 62%; }
@keyframes esShimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }
@media (prefers-reduced-motion: reduce) { .es-skel i { animation: none; } }
/* 侧栏/窄容器里的紧凑版 */
.es.is-compact { padding: 14px 10px; gap: 4px; }
.es.is-compact .es-ico { width: 28px; height: 28px; }
.es.is-compact .es-title { font-size: 12.5px; }
body.tbl-cozy .es-row > td .es { padding: 32px 16px; }
/* 卡片式空状态（如工作台右侧 #wbEmpty）：没有表格包裹，留白给足 */
#wbEmpty .es { padding: 44px 16px; }

/* ============ 流体渐变 + 复古噪点 动态背景（wb-aurora.js 自研 shader，零依赖） ============
   宿主加 isolation:isolate：canvas 用 z-index:-1 也能「垫在板块底色之上、内容之下」；
   静态定位的宿主由 JS 补 .wb-aurora-host（position:relative），已定位的宿主（如 .lp-bg）不动 */
[data-aurora] { isolation: isolate; }
.wb-aurora-host { position: relative; }
.wb-aurora {
  position: absolute;
  inset: 0;
  z-index: -1;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
  /* 内部画布只有 1/3 分辨率：pixelated 放大 = 复古噪点的颗粒感来源，还省 9 倍 GPU */
  image-rendering: pixelated;
}
/* 系统开了「减弱动态」：shader 只画一帧，观感退化为一张静态渐变图，不做像素风强调 */
@media (prefers-reduced-motion: reduce) {
  .wb-aurora { image-rendering: auto; }
}
