/* ============================================================================
 * ui.css —— 借 shadcn/ui 的设计系统，但不上 React
 *
 * shadcn/ui 本体是 React + Tailwind + Radix。这个前端是零构建的原生 HTML/CSS/JS，
 * 直接搬等于把整个界面重写一遍，还会毁掉「clone 下来双击就能跑」这个开源项目最值钱的性质。
 * 所以搬的是它真正可移植的那两层：
 *   1. 令牌契约 —— background / foreground / muted / border / ring / radius 这套名字和语义，
 *      和 shadcn v4 一字不差。--owb-* 全部改成指向它们，颜色只有这一个真源。
 *   2. 组件几何 —— 按钮 h-36 / 圆角 8 / 字号 14 / 图标 16 / focus 3px ring，
 *      输入框 h-36，卡片 rounded-lg，尺寸档 sm/lg/icon，全部照抄 shadcn 的数值。
 * 结果是：以后真要迁到 React，这份文件整份丢掉、className 换成 shadcn 的类名即可，
 * 是一次重命名，不是一次重写。今天则立刻拿到统一的控件节奏。
 *
 * 图标用 lucide（shadcn 官方图标集，ISC 协议），以内联 sprite 形式随页面走，不联网。
 * ========================================================================== */

/* ---------- 令牌契约（命名与语义同 shadcn v4） ---------- */
:root {
  /* 圆角阶梯：以 10px 为基准，每档差 2px，一路到底不留空档。
     index.html 那 1400 行内联样式原来自己写死了 29 个不同的圆角（3/5/7/9/20/22/26 都有），
     挨着的两个控件差 1px 谁也看不出是设计，只看得出没对齐。现在全都落到这七档上。
     xl 从 14 调到 12 是为了把阶梯补齐（ui.css 里 .ui-card 和表格容器跟着圆 2px），
     原来的 14 挪到 2xl，弹窗、登录卡这类大面继续用它。 */
  --radius: 10px;
  --radius-xs: calc(var(--radius) - 6px);   /* 4  行内 code、极小的角标 */
  --radius-sm: calc(var(--radius) - 4px);   /* 6  小芯片、小缩略图 */
  --radius-md: calc(var(--radius) - 2px);   /* 8  按钮、输入框、导航项 */
  --radius-lg: var(--radius);               /* 10 卡片、头像方块 */
  --radius-xl: calc(var(--radius) + 2px);   /* 12 面板 */
  --radius-2xl: calc(var(--radius) + 4px);  /* 14 弹窗、气泡这类大面 */
  --radius-full: 999px;                     /* 胶囊、进度条、细指示条 */

  --background: #ffffff;
  --foreground: #17181c;
  --card: #ffffff;
  --card-foreground: #17181c;
  --popover: #ffffff;
  --popover-foreground: #17181c;
  --primary: #5b5ff7;
  --primary-foreground: #ffffff;
  --secondary: #f7f8fa;
  --secondary-foreground: #17181c;
  --muted: #f7f8fa;
  --muted-foreground: #5c6270;   /* 白底 6.11:1 */
  --subtle-foreground: #686d7b;      /* 比 muted 更淡的第三级文字，shadcn 没这一档，本项目要。白底 5.23:1。
                                        原 #6a6f7d 白底 5.02 够用，但落到选中行那层淡紫底(#eef0ff)只剩 4.43，
                                        账号页那行 11px 的日期就卡在 4.5 线下面——暗这一档后是 4.62 */
  --accent: #eef0f4;
  --accent-foreground: #17181c;
  --destructive: #e5484d;
  --destructive-foreground: #ffffff;
  --success: #16a34a;
  --border: #ecedf3;                 /* 分隔线 / 卡片边：要退到背后去，卡片靠投影立住 */
  --input: #dcdfe8;                  /* 输入框边：比分隔线深一档，不然表单看着「没框」 */
  --ring: #5b5ff7;
  --ring-weak: #eef0ff;              /* focus 光圈用的低饱和底色 */
  --brand-text: #5155e8;             /* 品牌色当文字用的那一档：白底 5.51 / 选中底 4.86 */
  --danger-text: #bf3035;            /* 同理，红色当文字用：浅红底 4.73 */
  --success-text: #127538;           /* 绿色当文字用：#16a34a 白底只有 3.30，浅绿底 2.82 */
  --warning: #a86400;                /* shadcn 没这一档，本项目「跳过了一些零件」这类提示要用。白底 4.75:1。
                                        原 #b26a00 只有 4.27，12–13px 的小字（.ch-warn、「纯服务端模式」那句）不够。
                                        它同时被 color-mix 当淡染底和边框用，暗这一档对那几处只有好处 */
  /* 等宽字就这两份，别处一律 var() 过来，不再各写一串。
     中文回退得写明：不写的话 Windows 上 Chromium 给等宽里的汉字挑的是新宋体，细、发虚、比旁边小一号，
     代码块和工具输出里一句中文像换了个程序。PingFang SC（mac）、微软雅黑（Windows）排在西文等宽字后面——
     它们自己也带拉丁字母，排到前面英文就不等宽了。Linux 上这几款都没有，照旧落到系统默认的等宽字 */
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "PingFang SC", "Microsoft YaHei UI", "Microsoft YaHei", monospace;
  /* 有几处一直用的是浏览器默认等宽字（工具输出、文件预览的纯文本、审批条的命令、名单框；有的前面垫了个 Consolas），
     mac/Linux 上看到的就是默认那款。换成上面那份 mac 上会变成 SF Mono，样子就动了；
     所以单留这份：只在 Consolas 后面补 Windows 的中文字体，这几款 mac/Linux 都没有，看着一点不变。
     末尾必须是 monospace 而不是写死某款：mac/Linux 靠它落回默认那款 */
  --font-mono-sys: Consolas, "Microsoft YaHei UI", "Microsoft YaHei", monospace;

  /* 状态胶囊的淡染底：绿/红各自 12% 压在页面底上，配 --success-text / --danger-text 那两档文字色，
     浅色下 4.9:1 以上。之前每处各写一串 color-mix，同一个「成功」在三个页面深浅都不一样 */
  --success-bg: color-mix(in srgb, var(--success) 12%, transparent);
  --danger-bg: color-mix(in srgb, var(--destructive) 12%, transparent);
  --warning-bg: color-mix(in srgb, var(--warning) 14%, transparent);
  /* 紫这一档是给「素材种类」用的（语音/音频）：品牌紫已经被 @引用 和图片锚点占了，
     再拿它标音频就分不出谁是谁。#8b6cf5 当填充，文字要压到 #6a46d4（淡紫底 4.63 / 白底 6.11） */
  --violet: #8b6cf5;
  --violet-text: #6a46d4;
  --violet-bg: color-mix(in srgb, var(--violet) 14%, transparent);
  /* 投影的底色。上面三档 --shadow-* 里的 rgba(19,21,28) 就是它，
     单独留一个名字是给那些只要「一层淡影」、不想整档抬起来的地方用（如自动化页的行悬停） */
  --shadow-color: #13151c;

  /* ---------- 表面层级与投影（照 Linear / Multica 那套做法补的） ----------
     之前 --background 和 --card 都是纯白：外壳、画布、卡片三层一个颜色，
     卡片只能靠一根 1px 灰线证明自己在那儿，整页看着像一张摊平的表格——这正是「糙」的来源。
     拆成三档底色，再给卡片一层极淡投影，层级就能用眼睛直接读，不用靠边框讲。
     三档之间差值很小（4–10/255），这是刻意的：色差一大就变成「色块拼贴」，
     Linear 的精致感恰恰来自「看得出有层，但说不出边界在哪」。 */
  --app-shell: #f5f6fa;        /* 最外层框架：左栏、成果文件面板 */
  --page-canvas: #fbfbfd;      /* 内容画布：卡片落在它上面 */
  --surface: #ffffff;          /* 卡片面 */
  --surface-raised: #ffffff;   /* 菜单、弹层面 */
  --surface-hover: #f6f7f9;    /* 行悬停：比 --accent 轻一档，扫过去不「咚」一下 */
  --surface-selected: #edeff4; /* 中性选中态（品牌色选中仍走 --ring-weak） */

  /* 投影只有三档高度：贴着画布（卡片）/ 抬起来（菜单、浮动按钮）/ 悬空（对话框）。
     之前是十几处各写一串 rgba，同一个下拉菜单在不同页面深浅都不一样。 */
  --shadow-surface: 0 1px 2px rgba(19,21,28,.045), 0 1px 1px rgba(19,21,28,.03);
  --shadow-menu: 0 8px 24px rgba(19,21,28,.08), 0 2px 6px rgba(19,21,28,.05);
  --shadow-floating: 0 16px 40px rgba(19,21,28,.14), 0 3px 10px rgba(19,21,28,.08);

  /* 滚动条滑块用半透明黑：同一条规则在白卡片、灰外壳、深色代码块上都看得见，
     不用为每种底色各写一遍。之前滑块是 --border（#e9ebf0）压白底，等于没画。 */
  --scrollbar-thumb: rgba(19,21,28,.18);
  --scrollbar-thumb-hover: rgba(19,21,28,.32);
}
/* ----------------------------------------------------------------------------
 * 长串兜底：一条 180 字符的网址、一个没有空格的文件名，只要某一处忘了写断词规则，
 * 它就把所在的盒子顶穿——右边的字被切掉，或者整页横着多出一条滚动条。
 * 这毛病修过好几轮，每轮都是「在出事的那一处补一句 overflow-wrap」，下一处照犯。
 * 所以改成一条继承下去的兜底，默认允许在任意位置断行；哪一块另有主张（代码块不折行、
 * 标签不换行）在自己的规则里照旧写，权重都比这条高，一行现成样式都不用改。
 *
 * 用 anywhere 不用 break-word：只有 anywhere 会把「最小内容宽度」也当成可断的，
 * flex / grid 的子项才肯缩回容器里去。break-word 只是让字换了行，盒子照样被撑着
 * ——看上去像修了，窄窗口一拖还是漏出来。
 * 放在 :root 而不是 *：* 是给每个元素各赋一份值，会盖掉「父级说了不折行」的继承；
 * :root 只发一次，任何一条更具体的规则都压得住它。 */
:root { overflow-wrap: anywhere; }

/* 原生控件（下拉框弹出来那一列、日期选择器、滚动条、复选框）画成深还是浅，浏览器只看 color-scheme，不看我们的令牌。
   不写的话深色主题里一点下拉，弹出来的是一整块白底；Windows 上原生控件多，最扎眼。浅色写明 light 跟不写是一个样子 */
html { color-scheme: light; }
html[data-theme="dark"] { color-scheme: dark; }

html[data-theme="dark"] {
  --background: #1e1f24;
  --foreground: #e8eaf0;
  --card: #1e1f24;
  --card-foreground: #e8eaf0;
  --popover: #24262c;
  --popover-foreground: #e8eaf0;
  --primary: #5b5ff7;
  --primary-foreground: #ffffff;
  --secondary: #17181c;
  --secondary-foreground: #e8eaf0;
  --muted: #17181c;
  --muted-foreground: #a4a9b6;
  --subtle-foreground: #8f96a6;   /* 暗底 5.55:1，原 #7a8090 只有 4.17 */
  --accent: #2b2d34;
  --accent-foreground: #e8eaf0;
  --destructive: #e5484d;
  --border: #2e3038;
  --input: #3d404a;
  --ring: #8b8fff;
  --ring-weak: #2e3054;
  --brand-text: #9ea1fb;          /* 暗色下 #5b5ff7 当文字只有 3.47，提亮到 7.01 */
  --danger-text: #f2757a;         /* 同上：暗红底上 #e5484d 3.63 → 5.14 */
  --success-text: #3fc978;        /* 暗绿底上 #16a34a 4.18 → 6.46 */
  --warning: #d9a441;
  /* 暗色底上 12% 的染色几乎看不出来，要厚一倍多才读得出「这是个状态」 */
  --success-bg: color-mix(in srgb, var(--success) 26%, transparent);
  --danger-bg: color-mix(in srgb, var(--destructive) 26%, transparent);
  --warning-bg: color-mix(in srgb, var(--warning) 26%, transparent);
  --violet: #8b6cf5;
  --violet-text: #b9a5ff;   /* 暗紫底上 #8b6cf5 当文字只有 3.2，提亮到 5.47 */
  --violet-bg: color-mix(in srgb, var(--violet) 26%, transparent);
  --shadow-color: #000000;
  /* 暗色的三层：外壳最深、画布中间、卡片最浅——和浅色恰好反过来，
     但「卡片比它所在的底更亮」这条关系不变，所以卡片仍然是浮起来的那一层。 */
  --app-shell: #16171c;
  --page-canvas: #1a1b21;
  --surface: #1e1f24;
  --surface-raised: #24262c;
  --surface-hover: #26282f;
  --surface-selected: #2e3037;
  /* 暗底上黑影几乎不可见，alpha 要比浅色主题厚一倍多才读得出高度 */
  --shadow-surface: 0 1px 2px rgba(0,0,0,.32), 0 1px 1px rgba(0,0,0,.22);
  --shadow-menu: 0 8px 24px rgba(0,0,0,.44), 0 2px 6px rgba(0,0,0,.3);
  --shadow-floating: 0 16px 40px rgba(0,0,0,.56), 0 3px 10px rgba(0,0,0,.36);
  --scrollbar-thumb: rgba(255,255,255,.16);
  --scrollbar-thumb-hover: rgba(255,255,255,.3);
}

/* ---------- 图标：lucide sprite 的统一外观 ---------- */
/* stroke/fill/stroke-width 都是可继承属性，写在 .i 上，<use> 影子树里的图形会继承过去 */
.i {
  width: 1em; height: 1em; flex: none; display: inline-block; vertical-align: -0.145em;
  stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
  pointer-events: none;
}
.i.i-sm { width: .875em; height: .875em; }
#owb-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---------- Button（几何照抄 shadcn：h-9 / px-4 / rounded-md / text-sm / icon 16px） ---------- */
.ui-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 36px; padding: 0 16px; border-radius: var(--radius-md);
  font-size: 14px; font-weight: 500; line-height: 1; white-space: nowrap;
  border: 1px solid transparent; background: transparent; color: var(--foreground);
  cursor: pointer; user-select: none; text-decoration: none;
  transition: background-color .18s var(--owb-ease, ease), border-color .18s var(--owb-ease, ease),
              color .18s var(--owb-ease, ease), box-shadow .18s var(--owb-ease, ease), opacity .18s var(--owb-ease, ease);
}
.ui-btn .i { width: 16px; height: 16px; }
.ui-btn:focus-visible { outline: none; border-color: var(--ring); box-shadow: 0 0 0 3px var(--ring-weak); }
.ui-btn:disabled, .ui-btn[aria-disabled="true"] { opacity: .5; pointer-events: none; }
.ui-btn:active { transform: scale(.97); }

.ui-btn--default { background: var(--primary); color: var(--primary-foreground); }
.ui-btn--default:hover { filter: brightness(1.06); }
.ui-btn--secondary { background: var(--secondary); color: var(--secondary-foreground); }
.ui-btn--secondary:hover { background: var(--accent); }
.ui-btn--outline { background: var(--surface); color: var(--foreground); border-color: var(--input); box-shadow: var(--shadow-surface); }
.ui-btn--outline:hover { background: var(--accent); }
.ui-btn--ghost { color: var(--muted-foreground); }
.ui-btn--ghost:hover { background: var(--accent); color: var(--accent-foreground); }
.ui-btn--destructive { background: var(--destructive); color: var(--destructive-foreground); }
.ui-btn--destructive:hover { filter: brightness(1.06); }
.ui-btn--link { color: var(--brand-text); height: auto; padding: 0; }
.ui-btn--link:hover { text-decoration: underline; }

.ui-btn--sm { height: 32px; padding: 0 12px; font-size: 13px; gap: 6px; border-radius: var(--radius-sm); }
.ui-btn--sm .i { width: 14px; height: 14px; }
.ui-btn--xs { height: 26px; padding: 0 10px; font-size: 12px; gap: 5px; border-radius: var(--radius-sm); }
.ui-btn--xs .i { width: 13px; height: 13px; }
.ui-btn--lg { height: 40px; padding: 0 24px; font-size: 15px; }
.ui-btn--icon { width: 36px; height: 36px; padding: 0; }
.ui-btn--icon.ui-btn--sm { width: 32px; height: 32px; }
.ui-btn--block { display: flex; width: 100%; }

/* ---------- Input（h-9，focus 走 ring） ---------- */
.ui-input {
  height: 36px; width: 100%; min-width: 0; padding: 0 12px;
  border: 1px solid var(--input); border-radius: var(--radius-md);
  background: var(--surface); color: var(--foreground); font-size: 14px;
  transition: border-color .18s var(--owb-ease, ease), box-shadow .18s var(--owb-ease, ease);
}
.ui-input::placeholder { color: var(--subtle-foreground); }
.ui-input:focus { outline: none; border-color: var(--ring); box-shadow: 0 0 0 3px var(--ring-weak); }

/* ---------- Card ---------- */
.ui-card { background: var(--surface); color: var(--card-foreground); border: 1px solid var(--border); border-radius: var(--radius-xl); box-shadow: var(--shadow-surface); }
.ui-card-header { padding: 14px 16px 0; }
.ui-card-title { font-size: 15px; font-weight: 600; letter-spacing: -.011em; }
.ui-card-desc { font-size: 13px; color: var(--muted-foreground); margin-top: 2px; }
.ui-card-content { padding: 12px 16px; }
.ui-card-footer { display: flex; align-items: center; gap: 8px; padding: 0 16px 14px; }

/* ---------- Badge ---------- */
/* 定高，不是靠 line-height 撑。原来没写 height：里面塞个图标就比纯文字的同类高 2.5px，
   一行里几个徽章挨着摆就参差不齐。定高之后塞什么都一样高（box-sizing 全局是 border-box）。
   两档：24 给有地方的（后台控制台、独占一行的状态位），20 给挤在正文/卡片标题里的小角标。 */
.ui-badge {
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  height: 24px; padding: 0 8px; flex: none; vertical-align: middle;
  border: 1px solid transparent; border-radius: 999px;
  font-size: 12px; font-weight: 500; line-height: 1; white-space: nowrap; font-style: normal;
}
.ui-badge--sm { height: 20px; padding: 0 7px; font-size: 11px; gap: 3px; }
.ui-badge .i { width: 12px; height: 12px; }
.ui-badge--sm .i { width: 11px; height: 11px; }
.ui-badge--secondary { background: var(--secondary); color: var(--secondary-foreground); }
.ui-badge--outline { border-color: var(--border); color: var(--muted-foreground); }
.ui-badge--destructive { background: color-mix(in srgb, var(--destructive) 14%, transparent); color: var(--danger-text); }
.ui-badge--success { background: color-mix(in srgb, var(--success) 14%, transparent); color: var(--success-text); }

/* ---------- Separator ---------- */
.ui-separator { height: 1px; background: var(--border); border: 0; margin: 8px 0; }
.ui-separator[data-orientation="vertical"] { width: 1px; height: auto; align-self: stretch; margin: 0 8px; }

/* ---------- Tooltip（顶掉浏览器原生 title：原生那个又慢又丑，长路径直接糊一大片灰） ---------- */
.ui-tooltip {
  position: fixed; z-index: 9999; max-width: 320px; padding: 6px 10px;
  border-radius: var(--radius-sm); background: var(--foreground); color: var(--background);
  font-size: 12px; line-height: 1.5; word-break: break-all; pointer-events: none;
  box-shadow: var(--shadow-menu);
  opacity: 0; transform: translateY(2px); transition: opacity .12s var(--owb-ease, ease), transform .12s var(--owb-ease, ease);
}
.ui-tooltip.show { opacity: 1; transform: translateY(0); }

/* ---------- Skeleton ---------- */
.ui-skeleton { background: var(--accent); border-radius: var(--radius-sm); animation: uiPulse 1.6s ease-in-out infinite; }
@keyframes uiPulse { 0%,100% { opacity: 1 } 50% { opacity: .5 } }

/* ============================================================================
 * 下面这一批是 shadcn 里「后台管理」那几个页面在用的组件：Alert / Table / Progress /
 * Select / Stat / Switch / Dialog。之前企业后台是每处手搓 inline style 拼出来的，
 * 拼出来的东西对不齐：同样是「一句提示」，安全页是整块高饱和紫底、计量页是橙底，
 * 表格的分隔线又停在卡片内边距上不到边——看着就散。搬进这里之后是同一套几何。
 *
 * 几何仍然照抄 shadcn v4：Alert 用卡片底 + 淡边框（不是一整块色），Table 表头 muted、
 * 行分隔线到边，Progress 圆头，Select 自带角标。颜色一律走上面那套令牌，没有硬编码。
 * ========================================================================== */

/* ---------- Alert ---------- */
/* 关键差别：shadcn 的 Alert 不是「一块颜色」，是「一张卡片，只有图标带颜色」。
   整块高饱和底色在一页里出现两三次就开始抢正文，这也是这页之前最刺眼的地方。 */
.ui-alert {
  display: grid; grid-template-columns: auto 1fr; gap: 12px;
  padding: 14px 16px; border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--card); color: var(--foreground); font-size: 14px; line-height: 1.75;
}
.ui-alert > .i { width: 16px; height: 16px; margin-top: 5px; color: var(--muted-foreground); }
.ui-alert-title { font-weight: 600; margin-bottom: 2px; }
.ui-alert b, .ui-alert strong { font-weight: 600; }
.ui-alert code { font-family: var(--font-mono); font-size: .92em; padding: 1px 5px; border-radius: var(--radius-sm); background: var(--muted); }
.ui-alert--info { border-color: color-mix(in srgb, var(--primary) 28%, var(--border)); background: color-mix(in srgb, var(--primary) 5%, var(--card)); }
.ui-alert--info > .i { color: var(--brand-text); }
.ui-alert--warn { border-color: color-mix(in srgb, var(--warning) 36%, var(--border)); background: color-mix(in srgb, var(--warning) 7%, var(--card)); }
.ui-alert--warn > .i { color: var(--warning); }
.ui-alert--success { border-color: color-mix(in srgb, var(--success) 30%, var(--border)); background: color-mix(in srgb, var(--success) 6%, var(--card)); }
.ui-alert--success > .i { color: var(--success-text); }
.ui-alert--destructive { border-color: color-mix(in srgb, var(--destructive) 32%, var(--border)); background: color-mix(in srgb, var(--destructive) 6%, var(--card)); }
.ui-alert--destructive > .i { color: var(--danger-text); }

/* ---------- Table ---------- */
/* 外框自己带圆角和边框；放进卡片里当「贴边表格」时加 .ui-table-wrap--flush，
   由卡片提供左右边框，分隔线就能一直画到卡片边上，不再是一截悬空的横线。 */
.ui-table-wrap {
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface); overflow: auto; overscroll-behavior-x: contain;
  box-shadow: var(--shadow-surface);
}
.ui-table-wrap--flush { border: 0; border-radius: 0; background: transparent; }
.ui-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 14px; }
.ui-table th {
  text-align: left; font-weight: 500; font-size: 12.5px; letter-spacing: .02em;
  color: var(--subtle-foreground); padding: 10px 14px; white-space: nowrap;
  background: var(--muted); border-bottom: 1px solid var(--border);
}
.ui-table td { padding: 12px 14px; border-bottom: 1px solid var(--border); vertical-align: middle; line-height: 1.5; }
.ui-table tbody tr:last-child td { border-bottom: 0; }
.ui-table tbody tr:hover td { background: color-mix(in srgb, var(--muted) 62%, var(--card)); }
.ui-table .ui-num { font-variant-numeric: tabular-nums; text-align: right; }

/* ---------- Progress ---------- */
.ui-progress { height: 8px; border-radius: 999px; background: var(--accent); overflow: hidden; }
.ui-progress > i { display: block; height: 100%; border-radius: 999px; background: var(--primary); transition: width .35s var(--owb-ease, ease); }
.ui-progress--warn > i { background: var(--warning); }
.ui-progress--full > i { background: var(--destructive); }

/* ---------- Select（原生 select 的下拉箭头两套主题下不可控，自己画一个） ---------- */
.ui-select {
  appearance: none; -webkit-appearance: none; padding-right: 34px; cursor: pointer;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236a6f7d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center; background-size: 16px 16px;
}
html[data-theme="dark"] .ui-select {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238f96a6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
.ui-select:disabled { cursor: not-allowed; }

/* ---------- AI 短剧无限画布 ---------- */
.drama-page, .drama-page * { min-width: 0; }
.drama-loading { padding: 70px 20px; text-align: center; color: var(--owb-text-3); }
.drama-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; margin-bottom: 16px; }
.drama-kicker { color: var(--owb-brand-text); font-size: 12px; font-weight: 600; letter-spacing: .04em; margin-bottom: 6px; }
.drama-head h1 { font-size: 24px; line-height: 1.25; }
.drama-sub { margin-top: 5px; color: var(--owb-text-2); font-size: 13px; max-width: 680px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.drama-head-actions { display: flex; gap: 8px; align-items: center; flex: none; }
.drama-head-actions select { min-width: 210px; max-width: 280px; height: 32px; font-size: 13px; }
.drama-toolbar { display: flex; align-items: center; gap: 14px; height: 36px; margin-bottom: 10px; color: var(--owb-text-2); font-size: 12px; }
.drama-toolbar-hint { color: var(--owb-text-3); }
.drama-zoom-box { display: inline-flex; align-items: center; gap: 3px; margin-left: auto; padding: 2px 4px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: var(--owb-bg); }
.drama-zoom-box > span { min-width: 42px; text-align: center; font-variant-numeric: tabular-nums; }
.drama-viewport { position: relative; height: calc(100vh - 224px); min-height: 480px; overflow: hidden; border: 1px solid var(--owb-border); border-radius: var(--radius-xl); background-color: var(--owb-canvas); background-image: radial-gradient(circle, color-mix(in srgb, var(--owb-text-3) 18%, transparent) 1px, transparent 1px); background-size: 22px 22px; cursor: grab; touch-action: none; }
.drama-viewport.dragging { cursor: grabbing; }
.drama-world { position: relative; width: 100%; height: 100%; overflow: visible; }
.drama-world .joint-paper, .drama-world > svg { overflow: visible; }
.drama-joint-scene { width: 100%; height: 100%; overflow: visible; }
.drama-joint-scene > .drama-scene { height: 100%; box-sizing: border-box; }
.drama-scene { align-self: start; padding: 0 10px 12px; border: 1px solid color-mix(in srgb, var(--owb-brand) 28%, var(--owb-border)); border-radius: var(--radius-xl); background: color-mix(in srgb, var(--owb-brand-weak) 24%, var(--owb-bg)); box-shadow: var(--shadow-surface); }
.drama-scene-head { display: flex; align-items: center; gap: 9px; height: 48px; color: var(--owb-text); }
.drama-scene-head > div { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.drama-scene-head b { font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.drama-scene-head small { margin-top: 2px; color: var(--owb-text-3); font-size: 11px; }
.drama-scene-id { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 22px; border-radius: var(--radius-sm); background: var(--owb-brand-weak); color: var(--owb-brand-text); font: 600 11px var(--font-mono); }
.drama-scene-count { color: var(--owb-text-3); font-size: 11px; white-space: nowrap; }
.drama-shot-list { display: grid; gap: 8px; }
.drama-shot { display: grid; grid-template-columns: 92px 1fr; grid-template-rows: auto 1fr auto; column-gap: 11px; min-height: 124px; padding: 9px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg); box-shadow: var(--shadow-surface); cursor: default; }
.drama-shot:hover { border-color: color-mix(in srgb, var(--owb-brand) 50%, var(--owb-border)); }
.drama-shot-top { grid-column: 1 / -1; display: flex; align-items: center; gap: 7px; margin-bottom: 7px; font-size: 11px; color: var(--owb-text-3); }
.drama-shot-top b { color: var(--owb-text); font: 600 12px var(--font-mono); }
.drama-shot-top span { padding-left: 7px; border-left: 1px solid var(--owb-border); }
.drama-shot-thumb, .drama-shot-empty { width: 92px; height: 72px; grid-row: 2 / 4; object-fit: contain; object-position: center; border-radius: var(--radius-sm); background: var(--owb-bg-side); }
.drama-shot-empty { display: flex; align-items: center; justify-content: center; color: var(--owb-text-3); font-size: 11px; }
.drama-shot-copy { min-width: 0; }
.drama-shot-place { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--owb-text-2); font-size: 12px; }
.drama-shot-line { display: -webkit-box; margin-top: 5px; overflow: hidden; color: var(--owb-text); font-size: 12px; line-height: 1.45; -webkit-box-orient: vertical; -webkit-line-clamp: 3; }
.drama-shot-line span, .drama-shot-line.muted { color: var(--owb-text-3); }
.drama-shot-actions { display: flex; gap: 5px; align-items: end; }
.drama-shot-actions .ui-btn { height: 25px; padding: 0 8px; }
/* 镜头版本留底：浮层而不是卡片里的弹出层——卡片长在 JointJS 的 foreignObject 里，跟着缩放和裁切 */
.drama-hist { position: fixed; z-index: 5000; inset: 0; display: grid; place-items: center; padding: 24px; background: color-mix(in srgb, #000 46%, transparent); animation: uiFade .16s var(--owb-ease, ease); }
.drama-hist-panel { display: flex; flex-direction: column; width: min(520px, 100%); max-height: min(620px, 100%); border: 1px solid var(--owb-border); border-radius: var(--radius-xl); background: var(--owb-bg); box-shadow: var(--shadow-menu); animation: uiPop .18s var(--owb-ease, cubic-bezier(.16,1,.3,1)); }
.drama-hist-head { display: flex; align-items: center; gap: 9px; padding: 15px 16px; border-bottom: 1px solid var(--owb-border); }
.drama-hist-head b { font: 600 13px var(--font-mono); }
.drama-hist-head span { flex: 1; min-width: 0; color: var(--owb-text-3); font-size: 11px; }
.drama-hist-list { display: grid; gap: 8px; overflow-y: auto; margin: 0; padding: 12px; list-style: none; }
.drama-hist-item { display: grid; grid-template-columns: 78px 1fr auto; align-items: center; gap: 11px; padding: 9px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg); }
.drama-hist-item.is-now { border-color: color-mix(in srgb, var(--owb-brand) 50%, var(--owb-border)); background: var(--owb-brand-weak); }
.drama-hist-thumb { width: 78px; height: 60px; object-fit: contain; border-radius: var(--radius-sm); background: var(--owb-bg-side); }
.drama-hist-nopic { display: flex; align-items: center; justify-content: center; padding: 4px; color: var(--owb-text-3); text-align: center; font-size: 10px; }
.drama-hist-body { min-width: 0; }
.drama-hist-when { color: var(--owb-text); font: 600 12px var(--font-mono); }
.drama-hist-now { margin-left: 6px; color: var(--owb-brand-text); font-weight: 600; font-size: 10px; }
.drama-hist-why, .drama-hist-line, .drama-hist-gone { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11px; }
.drama-hist-why { margin-top: 3px; color: var(--owb-text-3); }
.drama-hist-line { margin-top: 2px; color: var(--owb-text-2); }
.drama-hist-gone { margin-top: 3px; color: var(--owb-err-text); white-space: normal; }
.drama-hist-loading { padding: 26px 18px; color: var(--owb-text-3); text-align: center; font-size: 12px; line-height: 1.6; }
@media (prefers-reduced-motion: reduce) { .drama-hist, .drama-hist-panel { animation: none; } }

.drama-empty-shot { padding: 18px; color: var(--owb-text-3); text-align: center; font-size: 12px; }
.drama-empty { max-width: 620px; margin: 80px auto; padding: 36px; border: 1px solid var(--owb-border); border-radius: var(--radius-xl); background: var(--owb-bg); box-shadow: var(--shadow-surface); text-align: center; }
.drama-empty-icon { margin-bottom: 12px; color: var(--owb-brand-text); font-size: 32px; }

/* ---------- 通用无限画布：JointJS 只管图模型与视口，节点仍吃工作台自己的视觉令牌 ---------- */
/* 画布要接键盘（Delete / ⌘A / Space），就得能拿焦点；tabindex=-1 在 JS 里加。鼠标点出来的焦点不该有框 */
.assist-page:focus, .assist-page:focus-visible { outline: none; }
.canvas-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 30px; margin-bottom: 1px; }
.canvas-head .canvas-kicker, .canvas-head h1 { display: none; }
.canvas-page:fullscreen { box-sizing: border-box; width: 100vw; height: 100vh; overflow: auto; padding: 18px 22px 22px; background: var(--owb-bg); }
.canvas-page:fullscreen .canvas-viewport { height: calc(100vh - 326px - var(--cp-h, 0px)); }
.canvas-page:fullscreen .canvas-inspector { min-height: 0; }
.canvas-head h1 { font-size: 18px; line-height: 1.2; }
.canvas-kicker { color: var(--owb-brand-text); font-size: 12px; font-weight: 600; letter-spacing: .08em; margin-bottom: 6px; }
.canvas-board-switch { display: flex; align-items: center; gap: 4px; margin-top: 0; }
.canvas-board-switch select { max-width: 210px; height: 26px; padding: 0 7px; border: 1px solid var(--owb-border); border-radius: var(--radius-sm); background: var(--owb-bg); color: var(--owb-text); font: inherit; font-size: 11px; }
.canvas-sub { display: none; }
.canvas-head-actions { display: flex; gap: 8px; flex: none; }
.canvas-toolbar { display: flex; align-items: center; gap: 8px; height: 29px; margin-bottom: 3px; color: var(--owb-text-2); font-size: 11px; }
.canvas-toolbar-hint { color: var(--owb-text-3); }
.canvas-zoom-box { display: inline-flex; align-items: center; gap: 3px; margin-left: auto; padding: 2px 4px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: var(--owb-bg); }
.canvas-zoom-box > span { min-width: 42px; text-align: center; font-variant-numeric: tabular-nums; }
/* 一键补齐同时跑几条：挤在缩放条最右，一个字的下拉框就够 */
.canvas-batch-limit { display: inline-flex; align-items: center; gap: 4px; margin-left: 4px; padding-left: 8px; border-left: 1px solid var(--owb-border); color: var(--owb-text-3); white-space: nowrap; }
.canvas-batch-limit select { height: 20px; padding: 0 4px; border: 1px solid var(--owb-border); border-radius: var(--radius-sm); background: var(--owb-bg); color: var(--owb-text); font-size: 11px; font-variant-numeric: tabular-nums; }
.canvas-viewport { position: relative; height: clamp(420px, calc(100vh - 278px - var(--cp-h, 0px)), 980px); min-height: 420px; overflow: hidden; border: 1px solid var(--owb-border); border-radius: var(--radius-xl); background-color: var(--owb-canvas); background-image: radial-gradient(circle, color-mix(in srgb, var(--owb-text-3) 18%, transparent) 1px, transparent 1px); background-size: 22px 22px; cursor: grab; touch-action: none; }
.canvas-viewport.dragging { cursor: grabbing; }
.canvas-world { position: relative; width: 2400px; height: 1600px; overflow: visible; }
.canvas-world .joint-paper, .canvas-world > svg { overflow: visible; }
.canvas-world .joint-link .connection, .canvas-world .link .connection { stroke: var(--owb-brand-text) !important; stroke-width: 2px !important; stroke-linecap: round; }
.canvas-world .joint-link .marker-target, .canvas-world .link .marker-target { fill: var(--owb-brand-text) !important; stroke: var(--owb-brand-text) !important; }
.canvas-joint-node { width: 100%; height: 100%; overflow: visible; }
.canvas-joint-node.is-selected .canvas-node { border-color: var(--owb-brand); box-shadow: 0 0 0 2px color-mix(in srgb, var(--owb-brand) 24%, transparent), var(--shadow-surface); }
/* 镜头号撞了：两张卡生成会写进同一个文件，红框比选中框优先——选中的时候更该看见 */
.canvas-joint-node.is-dup-id .canvas-node { border-color: var(--owb-err); box-shadow: 0 0 0 2px color-mix(in srgb, var(--owb-err) 24%, transparent), var(--shadow-surface); }
.canvas-node { width: 100%; height: 100%; box-sizing: border-box; border: 1px solid color-mix(in srgb, var(--owb-brand) 28%, var(--owb-border)); border-radius: var(--radius-xl); background: color-mix(in srgb, var(--owb-brand-weak) 24%, var(--owb-bg)); box-shadow: var(--shadow-surface); color: var(--owb-text); overflow: hidden; }
.canvas-node-head { display: flex; align-items: center; gap: 9px; min-height: 52px; padding: 0 12px; border-bottom: 1px solid var(--owb-border); }
.canvas-node-head > div { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.canvas-node-head b { font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.canvas-node-head small { margin-top: 2px; color: var(--owb-text-3); font-size: 11px; }
.canvas-node-icon { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: var(--radius-md); background: var(--owb-brand-weak); color: var(--owb-brand-text); flex: none; }
.canvas-node-icon .i { width: 16px; height: 16px; }
.canvas-node-remove, .canvas-node-settings { display: inline-flex; align-items: center; justify-content: center; border: none; background: transparent; color: var(--owb-text-3); cursor: pointer; padding: 5px; border-radius: var(--radius-sm); }
.canvas-node-remove:hover, .canvas-node-settings:hover { color: var(--owb-brand-text); background: var(--owb-bg-hover); }
.canvas-node-settings .i { width: 15px; height: 15px; }
.canvas-node-body { padding: 12px; font-size: 13px; line-height: 1.6; }
.canvas-node-body label { display: block; color: var(--owb-text-3); font-size: 12px; margin-bottom: 5px; }
.canvas-node-body select { width: 100%; height: 32px; margin-bottom: 9px; }
.canvas-node-body .ui-btn { display: inline-flex; align-items: center; gap: 5px; }
.canvas-node-hint { margin: 9px 0 0; color: var(--owb-text-3); font-size: 12px; }
.canvas-node-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.canvas-node-copy, .canvas-shot-prompt, .canvas-media-text { white-space: pre-wrap; overflow-wrap: anywhere; color: var(--owb-text-2); }
/* 「AI 生成」角标：对话模型出的卡、草稿里的每一镜都挂一个。只装这四个字（英文界面是两个词），裁掉兜底 */
.canvas-ai-badge { display: inline-block; flex: none; max-width: 112px; height: 20px; padding: 0 8px; box-sizing: border-box; border-radius: 999px; background: var(--owb-brand-weak); color: var(--owb-brand-text); font-size: 11px; font-weight: 600; line-height: 20px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: middle; }
/* 剧本卡：正文占满剩下的高度，「生成分镜表」和那句成本提示钉在卡底，正文再长也挤不掉它们 */
.canvas-node-script { display: flex; flex-direction: column; }
.canvas-script-body { display: flex; flex-direction: column; flex: 1; min-height: 0; gap: 8px; }
.canvas-script-text { flex: 1; min-height: 0; overflow: hidden; }
.canvas-script-actions { flex: none; align-items: center; }
.canvas-script-cost { color: var(--owb-text-3); font-size: 11px; line-height: 1.4; }
.canvas-shot-line { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--owb-border); color: var(--owb-text-3); white-space: pre-wrap; overflow-wrap: anywhere; }
.canvas-media-kind { color: var(--owb-brand-text); font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; }
.canvas-media-text { min-height: 72px; margin-top: 7px; font-size: 12px; }
.canvas-note-edit { min-height: 106px; white-space: pre-wrap; overflow-wrap: anywhere; outline: none; }
.canvas-note-edit:focus { background: color-mix(in srgb, var(--owb-bg) 40%, transparent); }
.canvas-scene-count { color: var(--owb-brand-text); font-weight: 600; margin-bottom: 6px; }
.canvas-shot-row { display: grid; grid-template-columns: 56px 60px minmax(0, 1fr); gap: 7px; padding: 5px 0; border-top: 1px solid color-mix(in srgb, var(--owb-border) 70%, transparent); font-size: 12px; }
.canvas-shot-row span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.canvas-shot-row span:first-child { color: var(--owb-brand-text); font-family: var(--font-mono); }
.canvas-shot-row span:nth-child(2) { color: var(--owb-text-3); }
/* 预览框的宽高比写在元素自己的 style 上（canvasAspectAttr：量过的按真比例，没量过的按画布设定），
 * 框跟图一个形状，图整张放下，不拉不裁也不留黑边。横的按宽摆、封个顶；竖的（data-shape=tall）按高摆、宽跟着缩，居中 */
.canvas-node-preview { display: block; width: 100%; height: auto; max-height: 260px; margin: 0 0 9px; border-radius: var(--radius-md); background: var(--owb-bg-hover); object-fit: contain; object-position: center; }
.canvas-node-preview[data-shape="tall"] { width: auto; max-width: 100%; height: 260px; max-height: none; margin-inline: auto; }
.canvas-node-image .canvas-node-preview, .canvas-node-character .canvas-node-preview, .canvas-node-location .canvas-node-preview { margin-bottom: 7px; cursor: default; }
.canvas-node-image .canvas-node-preview { max-height: 400px; }
.canvas-node-image .canvas-node-preview[data-shape="tall"] { height: 360px; max-height: none; }
.canvas-node-character .canvas-node-preview, .canvas-node-location .canvas-node-preview { max-height: 300px; }
/* 竖的图配一段字：图在左、字在右，不然一张 9:16 的图加上字和按钮，卡要拉到六百多像素高 */
.canvas-media-row.is-side { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 10px; align-items: start; margin-bottom: 9px; }
.canvas-media-row.is-side .canvas-node-preview { width: auto; max-width: 150px; height: 190px; max-height: none; margin: 0; }
.canvas-media-side { min-width: 0; }
/* 字太长就截行，按钮永远在卡上：以前是卡高写死、内容一长按钮被挤出卡外裁掉，点不到。全文在右侧面板里 */
.canvas-node-shot .canvas-shot-prompt, .canvas-node-desc, .canvas-node-agent .canvas-node-copy, .canvas-node-shot .canvas-shot-line { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; }
.canvas-node-shot .canvas-shot-prompt { -webkit-line-clamp: 4; }
.canvas-node-shot .canvas-shot-line { -webkit-line-clamp: 2; }
.canvas-node-shot .is-side .canvas-shot-prompt { -webkit-line-clamp: 5; }
.canvas-node-desc { line-height: 1.45; -webkit-line-clamp: 4; }
.is-side .canvas-node-desc { -webkit-line-clamp: 9; }
.canvas-node-agent .canvas-node-copy { -webkit-line-clamp: 4; margin-bottom: 9px; }
.canvas-node-image .canvas-node-body, .canvas-node-character .canvas-node-body, .canvas-node-location .canvas-node-body { padding: 9px; }
.canvas-node-image .canvas-node-head, .canvas-node-character .canvas-node-head, .canvas-node-location .canvas-node-head { min-height: 46px; padding: 0 9px; gap: 7px; }
.canvas-node-image .canvas-node-head small, .canvas-node-character .canvas-node-head small, .canvas-node-location .canvas-node-head small { display: none; }
.canvas-node-image .canvas-media-text { display: none; }
.canvas-node-image .canvas-node-actions { min-height: 29px; align-items: center; justify-content: flex-end; }
.canvas-node-image .canvas-node-actions [data-canvas-agent] { display: none; }
.canvas-node-character .canvas-node-desc, .canvas-node-location .canvas-node-desc { margin-bottom: 8px; }
.canvas-node-character .is-side .canvas-node-desc, .canvas-node-location .is-side .canvas-node-desc { margin-bottom: 0; }
.canvas-image-preview { cursor: default; }
.canvas-audio-preview { display: block; width: 100%; height: 38px; margin: 2px 0 10px; }
/* 12px × 1.6 = 一行，封顶写成3.2em/4.8em 这种整数倍：写成 58px 会在底下留下第四行的一条发丝。 */
.canvas-node-audio .canvas-media-text { min-height: 3.2em; max-height: 4.8em; overflow: hidden; }
.canvas-media-error, .canvas-media-missing { margin: 2px 0 9px; padding: 7px 9px; border: 1px solid color-mix(in srgb, var(--destructive) 32%, var(--owb-border)); border-radius: 8px; background: color-mix(in srgb, var(--destructive) 8%, var(--owb-bg)); color: var(--owb-err-text); font-size: 11px; line-height: 1.45; }
.canvas-node-video .canvas-node-body { padding: 10px; }
.canvas-video-stage { position: relative; display: flex; align-items: center; justify-content: center; min-height: 120px; overflow: hidden; border-radius: var(--radius-md); background: var(--secondary); }
.canvas-video-stage:has(.canvas-video-empty) { height: 168px; }
/* 跟 .canvas-node-preview 一样：框的比例跟着片子走，竖屏片按高摆 */
.canvas-video-preview { display: block; width: 100%; height: auto; max-height: 300px; border-radius: var(--radius-md); object-fit: contain; background: var(--secondary); }
.canvas-video-preview[data-shape="tall"] { width: auto; max-width: 100%; height: 300px; max-height: none; margin-inline: auto; }
.canvas-node-timeline .canvas-video-preview { margin-bottom: 9px; }
.canvas-video-empty { display: flex; flex-direction: column; align-items: center; gap: 8px; color: color-mix(in srgb, var(--primary-foreground) 52%, transparent); font-size: 11px; }
.canvas-video-empty .i { width: 34px; height: 34px; padding: 8px; border: 1px solid color-mix(in srgb, var(--primary-foreground) 28%, transparent); border-radius: 10px; }
.canvas-video-prompt { width: 100%; min-height: 52px; box-sizing: border-box; margin-top: 8px; padding: 7px 8px; resize: none; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: var(--owb-bg); color: var(--owb-text); font: inherit; font-size: 12px; line-height: 1.45; outline: none; }
.canvas-video-prompt:focus { border-color: var(--owb-brand); box-shadow: 0 0 0 2px color-mix(in srgb, var(--owb-brand) 15%, transparent); }
.canvas-card-prompt-label { display: grid; gap: 5px; margin-top: 8px; font-size: 12px; color: var(--owb-text-2); }
.canvas-card-prompt-label .canvas-card-prompt { margin-top: 0; min-height: 76px; max-height: 240px; resize: vertical; }
.canvas-selection-tools { position: absolute; z-index: 20; left: 12px; top: 12px; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 4px 8px; max-width: calc(100% - 24px); border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg); box-shadow: var(--shadow-menu); font-size: 12px; }
.canvas-selection-tools[hidden], .canvas-minimap[hidden] { display: none; }
.canvas-selection-tools > span { white-space: nowrap; color: var(--owb-text-2); }
.canvas-selection-tools select { min-width: 0; max-width: 150px; border: 0; background: var(--owb-bg); color: var(--owb-text); font: inherit; padding: 5px; }
.canvas-minimap { position: absolute; z-index: 19; left: 12px; bottom: 12px; width: 176px; max-width: calc(100% - 24px); overflow: hidden; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg); box-shadow: var(--shadow-menu); }
.canvas-minimap-head { display: flex; align-items: center; justify-content: space-between; padding: 4px 8px; font-size: 11px; color: var(--owb-text-2); }
.canvas-minimap-head button { display: grid; place-items: center; width: 24px; height: 24px; padding: 0; border: 0; border-radius: var(--radius-sm); color: var(--owb-text-2); background: transparent; cursor: pointer; }
.canvas-minimap-head button:hover { background: var(--owb-bg-hover); }
.canvas-minimap-head svg { width: 12px; height: 12px; }
.canvas-minimap > svg { display: block; width: 100%; height: 100px; cursor: crosshair; touch-action: none; }
.canvas-map-node { fill: var(--owb-text-3); opacity: .5; }
.canvas-map-node.is-selected { fill: var(--owb-brand); opacity: .85; }
.canvas-map-view { fill: color-mix(in srgb, var(--owb-brand) 8%, transparent); stroke: var(--owb-brand-text); stroke-width: 1.5px; vector-effect: non-scaling-stroke; pointer-events: none; }
.canvas-video-refs, .canvas-video-settings { display: flex; gap: 5px; margin-top: 7px; overflow: hidden; }
.canvas-video-refs span, .canvas-video-settings span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 3px 6px; border-radius: 999px; background: var(--owb-bg-hover); color: var(--owb-text-3); font-size: 10px; }
.canvas-video-settings span { background: var(--owb-brand-weak); color: var(--owb-brand-text); }
.canvas-reference-chip { display: flex; align-items: center; gap: 5px; margin: -2px 0 8px; padding: 4px 6px; border-radius: var(--radius-sm); background: var(--owb-bg-hover); color: var(--owb-text-3); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.canvas-reference-chip .i { width: 13px; height: 13px; color: var(--owb-brand-text); flex: none; }
.canvas-generation-lineage { display: inline-flex; align-items: center; max-width: 100%; gap: 5px; margin: 8px 0 2px; padding: 4px 7px; border: 1px solid color-mix(in srgb, var(--owb-brand) 18%, var(--owb-border)); border-radius: 999px; background: color-mix(in srgb, var(--owb-brand-weak) 44%, var(--owb-bg)); color: var(--owb-text-3); font-size: 10px; line-height: 1.2; }
.canvas-generation-lineage .i { width: 12px; height: 12px; color: var(--owb-brand-text); flex: none; }
.canvas-generation-lineage span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 上一单没收回来：红边一条，三颗按钮跟在后面，窄卡片上自动折行 */
.canvas-job-pending { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; margin: 8px 0 2px; padding: 6px 8px; border: 1px solid color-mix(in srgb, var(--owb-err) 34%, var(--owb-border)); border-radius: var(--radius-md, 8px); background: var(--danger-bg); color: var(--danger-text); font-size: 11px; line-height: 1.4; }
.canvas-job-pending .i { width: 12px; height: 12px; flex: none; }
.canvas-job-pending span { flex: 1 1 140px; min-width: 0; }
.canvas-empty { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; color: var(--owb-text-3); }
/* 「这张画布读不出来」的整页兜底。要长得像一条说明，不像一张空白布——
   看着像空白布，用户就会开始在上面画，而那正是我们拦下来的动作 */
.canvas-broken > div { max-width: 520px; padding: 22px 24px; border: 1px solid color-mix(in srgb, var(--owb-err) 34%, var(--owb-border)); border-radius: var(--radius-lg); background: var(--owb-bg); text-align: left; }
.canvas-broken h3 { margin: 0 0 8px; color: var(--owb-text); font-size: 15px; }
.canvas-broken p { margin: 0 0 8px; font-size: 12px; line-height: 1.7; }
.canvas-broken-why { padding: 8px 10px; border-radius: var(--radius-sm); background: var(--owb-bg-hover); color: var(--owb-text-2); font-family: var(--font-mono); word-break: break-all; }
.canvas-broken-acts { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0 10px; }
.canvas-broken-tip { color: var(--owb-text-3); font-size: 11px; }
/* 这个版本认不出的节点类型：看得见、拿不动。别让它长得像一张能写字的空笔记 */
.canvas-node-unknown { border-style: dashed; opacity: .92; }
.canvas-unknown-tip { margin: 0 0 6px; color: var(--owb-text-3); font-size: 11px; line-height: 1.6; }
.canvas-unknown-keys { display: grid; gap: 3px; margin: 0; padding: 0; list-style: none; }
.canvas-unknown-keys li { display: flex; gap: 6px; font-size: 11px; line-height: 1.5; }
.canvas-unknown-keys b { flex: none; max-width: 38%; overflow: hidden; color: var(--owb-text-3); font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
.canvas-unknown-keys span { overflow: hidden; color: var(--owb-text-2); text-overflow: ellipsis; white-space: nowrap; }
.canvas-node-menu { margin-bottom: 4px; padding: 0 8px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: color-mix(in srgb, var(--owb-bg) 84%, transparent); }
.canvas-node-menu summary { display: flex; align-items: center; min-height: 27px; cursor: pointer; list-style: none; }
.canvas-node-menu summary::-webkit-details-marker { display: none; }
.canvas-node-menu-body { display: flex; align-items: center; flex-wrap: wrap; gap: 3px 6px; padding: 0 0 4px; }
.canvas-menu-label { margin: 0 5px 0 2px; color: var(--owb-text-3); font-size: 11px; font-weight: 600; }
.canvas-menu-group { display: inline-flex; align-items: center; gap: 4px; padding-right: 7px; border-right: 1px solid var(--owb-border); }
.canvas-menu-group:last-of-type { border-right: 0; }
.canvas-menu-group-label { color: var(--owb-text-3); font-size: 10px; }
.canvas-type-btn { display: inline-flex; align-items: center; gap: 4px; height: 27px; padding: 0 8px; border: 1px solid transparent; border-radius: var(--radius-sm); background: transparent; color: var(--owb-text-2); cursor: pointer; font-size: 11px; }
.canvas-type-btn:hover { border-color: var(--owb-border); background: var(--owb-bg-hover); color: var(--owb-text); }
.canvas-type-btn .i { width: 14px; height: 14px; color: var(--owb-brand-text); }
.canvas-menu-hint { margin-left: auto; color: var(--owb-text-3); font-size: 11px; }
.canvas-library { margin: 0 0 8px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: color-mix(in srgb, var(--owb-bg) 84%, transparent); }
.canvas-library summary { display: flex; align-items: center; gap: 8px; min-height: 29px; padding: 0 9px; color: var(--owb-text-2); cursor: pointer; list-style: none; font-size: 11px; }
.canvas-library summary::-webkit-details-marker { display: none; }
.canvas-library summary > span { display: inline-flex; align-items: center; justify-content: center; width: 27px; height: 27px; border: 1px solid var(--owb-border); border-radius: var(--radius-sm); background: var(--owb-bg); color: var(--owb-brand-text); font-weight: 600; }
.canvas-library summary > span .i { width: 14px; height: 14px; }
.canvas-library summary small { color: var(--owb-text-3); font-size: 11px; }
.canvas-library summary button { display: inline-flex; align-items: center; justify-content: center; width: 27px; height: 27px; margin-left: auto; padding: 0; }
.canvas-library summary button .i { width: 14px; height: 14px; }
.canvas-library-tools { display: flex; align-items: center; gap: 8px; padding: 0 9px 8px; }
.canvas-page .canvas-library-tools { display: grid; grid-template-columns: minmax(0, 1fr) 96px; gap: 6px; padding: 7px 8px 8px; }
.canvas-library-tools input { flex: 1; min-width: 120px; height: 28px; padding: 0 8px; border: 1px solid var(--owb-border); border-radius: var(--radius-sm); background: var(--owb-bg); color: var(--owb-text); font: inherit; font-size: 12px; outline: none; }
.canvas-library-tools input:focus { border-color: var(--owb-brand); }
.canvas-library-tools select { height: 28px; padding: 0 6px; border: 1px solid var(--owb-border); border-radius: var(--radius-sm); background: var(--owb-bg); color: var(--owb-text); font: inherit; font-size: 12px; }
.canvas-library-tools span { color: var(--owb-text-3); font-size: 11px; }
.canvas-library-items { display: grid; grid-template-columns: repeat(auto-fill, minmax(205px, 1fr)); gap: 6px; padding: 0 9px 9px; }
.canvas-page .canvas-library-items { grid-template-columns: 1fr; max-height: 260px; overflow: auto; padding: 0 8px 8px; }
.canvas-library-item { display: grid; grid-template-columns: 27px minmax(0, 1fr) 18px; align-items: center; gap: 7px; min-width: 0; padding: 7px; border: 1px solid var(--owb-border); border-radius: var(--radius-sm); background: var(--owb-bg); color: var(--owb-text); text-align: left; cursor: pointer; }
.canvas-page .canvas-library-item { padding: 6px; }
.canvas-library-item:hover { border-color: var(--owb-brand); background: var(--owb-bg-hover); }
.canvas-library-icon { display: inline-flex; align-items: center; justify-content: center; width: 27px; height: 27px; border-radius: var(--radius-sm); background: var(--owb-brand-weak); color: var(--owb-brand-text); }
.canvas-library-icon .i { width: 15px; height: 15px; }
.canvas-library-item b, .canvas-library-item small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.canvas-library-item b { font-size: 12px; }
.canvas-library-item small { margin-top: 2px; color: var(--owb-text-3); font-size: 10px; }
.canvas-library-add { color: var(--owb-brand-text); font-size: 17px; line-height: 1; text-align: center; }
.canvas-library-empty { grid-column: 1 / -1; padding: 9px 2px; color: var(--owb-text-3); font-size: 11px; }
/* 素材台账。这个面板的重点不是文件名，是「这是什么用的」和「谁在用」——
   做短剧最常问的两句话正是这两句 */
.canvas-page .canvas-library-tools { grid-template-columns: minmax(0, 1fr) 84px 84px auto auto; }
.canvas-library-toggle { display: inline-flex; align-items: center; gap: 4px; color: var(--owb-text-2); font-size: 11px; white-space: nowrap; cursor: pointer; }
.canvas-library-toggle input { width: 13px; height: 13px; min-width: 0; padding: 0; accent-color: var(--owb-brand); }
.canvas-library-stat { grid-column: 1 / -1; padding: 2px 2px 6px; color: var(--owb-text-3); font-size: 11px; }
.canvas-library-stat b { color: var(--owb-text-2); font-weight: 600; }
.canvas-library-role { margin-left: 5px; padding: 1px 5px; border-radius: 999px; background: var(--owb-brand-weak); color: var(--owb-brand-text); font-size: 10px; font-style: normal; }
.canvas-library-use { display: block; margin-top: 2px; color: var(--owb-text-3); font-size: 10px; }
.canvas-library-use.is-orphan { color: var(--owb-text-3); opacity: .75; }
/* 引用了但盘上没有的：那一镜现在就是生不出来。摆在最前面，别让它藏在列表里 */
.canvas-library-missing { grid-column: 1 / -1; margin: 0 0 7px; padding: 8px 9px; border: 1px solid color-mix(in srgb, var(--owb-err) 34%, var(--owb-border)); border-radius: var(--radius-sm); background: var(--owb-bg); }
.canvas-library-missing b { display: flex; align-items: center; gap: 5px; margin-bottom: 5px; color: var(--owb-text); font-size: 11px; }
.canvas-library-missing b .i { width: 13px; height: 13px; }
.canvas-library-missing > div { display: grid; gap: 1px; padding: 3px 0; }
.canvas-library-missing span { overflow: hidden; color: var(--owb-text-2); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
.canvas-library-missing small { color: var(--owb-text-3); font-size: 10px; }
.canvas-library-missing-tip { display: block; margin-top: 5px; line-height: 1.6; }
.canvas-library-more { grid-column: 1 / -1; padding: 6px 2px 0; color: var(--owb-text-3); font-size: 10px; }

/* ── 短剧制片进度带 ─────────────────────────────────────────────────────── */
/* 收起来只占一行：一条进度条 + 七个档位 + 下一步。展开才给卡点和镜头明细。
   做短剧的人大部分时间在画布上干活，不是在看进度——这条带子平时不该抢地方。 */
.canvas-page .canvas-progress { margin: 0 0 8px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: color-mix(in srgb, var(--owb-bg) 84%, transparent); overflow: hidden; }
.canvas-page .cp-bar { height: 3px; background: var(--owb-bg-side); }
.canvas-page .cp-bar i { display: block; height: 100%; background: var(--owb-brand); transition: width .35s var(--owb-ease, ease); }
.canvas-page .cp-head { display: flex; align-items: center; gap: 10px; width: 100%; padding: 7px 12px; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.canvas-page .cp-head:hover { background: var(--owb-bg-hover); }
.canvas-page .cp-pct { flex: 0 0 auto; font-weight: 600; font-size: 13px; font-variant-numeric: tabular-nums; }
.canvas-page .cp-stages { display: flex; flex-wrap: wrap; gap: 4px; min-width: 0; }
.canvas-page .cp-chip { display: inline-flex; align-items: center; gap: 4px; padding: 1px 7px; border-radius: var(--radius-full); background: var(--owb-bg-side); color: var(--owb-text-2); font-size: 11px; white-space: nowrap; }
.canvas-page .cp-chip b { font-weight: 600; font-variant-numeric: tabular-nums; }
.canvas-page .cp-chip.is-done { background: var(--owb-ok-bg); color: var(--owb-ok-text); }
.canvas-page .cp-chip.is-doing { background: color-mix(in srgb, var(--owb-brand) 16%, transparent); color: var(--owb-brand-text); }
.canvas-page .cp-chip.is-none { opacity: .45; }
.canvas-page .cp-next { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--owb-text-2); font-size: 12px; }
.canvas-page .cp-caret { flex: 0 0 auto; color: var(--owb-text-3); }
.canvas-page .cp-caret .i { width: 14px; height: 14px; }
.canvas-page .cp-body { max-height: 40vh; overflow: auto; padding: 0 12px 10px; border-top: 1px solid var(--owb-border); }
/* 展开之后卡点清单加上三十行镜头表能长到一屏还多，把画布连同下面的对话区一起挤没。
   封顶 + 自己滚，它再长也只占这么高；视口那边同时按 --cp-h 让位（canvasProgressHeight） */
.canvas-page .cp-blockers { margin: 8px 0 0; padding: 0; list-style: none; display: grid; gap: 4px; }
.canvas-page .cp-blocker { display: flex; align-items: center; gap: 8px; padding: 5px 8px; border-radius: var(--radius-sm); background: var(--owb-bg-hover); font-size: 12px; }
.canvas-page .cp-blocker.is-stop { border-left: 2px solid var(--owb-err); }
.canvas-page .cp-blocker span { flex: 1 1 auto; min-width: 0; }
.canvas-page .cp-jobs { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 8px; font-size: 12px; }
.canvas-page .cp-jobs-label { color: var(--owb-text-3); }
.canvas-page .cp-eta { color: var(--owb-text-2); }
.canvas-page .cp-eta.is-unknown { color: var(--owb-text-3); }
.canvas-page .cp-running { color: var(--owb-brand-text); }
.canvas-page .cp-shots { width: 100%; margin-top: 8px; border-collapse: collapse; font-size: 12px; }
.canvas-page .cp-shots th { padding: 3px 6px; color: var(--owb-text-3); font-weight: 500; text-align: left; }
.canvas-page .cp-shots td { padding: 3px 6px; border-top: 1px solid var(--owb-border); }
.canvas-page .cp-shots tbody tr { cursor: pointer; }
.canvas-page .cp-shots tbody tr:hover { background: var(--owb-bg-hover); }
.canvas-page .cp-x.is-ok { color: var(--owb-ok-text); }
.canvas-page .cp-x.is-lost { color: var(--owb-err-text); }
.canvas-page .cp-x.is-todo, .canvas-page .cp-x.is-skip { color: var(--owb-text-3); }
.canvas-page .cp-why { color: var(--owb-text-3); }
.canvas-page .cp-more, .canvas-page .cp-warn { margin-top: 6px; color: var(--owb-text-3); font-size: 11px; }
.canvas-page .cp-warn { color: var(--owb-err-text); }
/* 合成成片那一块：方案 → 跑动 → 结果，三种样子长在同一块地方，不弹窗。
   镜头顺序这张单子是要人过一眼的——顺序排错的片子能播、时长也对，只有情节是乱的。 */
.canvas-page .cp-compose { margin-top: 8px; padding: 8px 10px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: var(--owb-bg-side); font-size: 12px; }
.canvas-page .cp-compose.is-done { border-color: color-mix(in srgb, var(--owb-ok) 55%, var(--owb-border)); }
.canvas-page .cp-compose.is-bad { border-color: color-mix(in srgb, var(--owb-err) 55%, var(--owb-border)); }
.canvas-page .cp-compose-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.canvas-page .cp-compose-head b { font-size: 12px; }
.canvas-page .cp-compose-head span { color: var(--owb-text-2); }
.canvas-page .cp-compose-head code, .canvas-page .cp-compose-out code { padding: 1px 5px; border-radius: var(--radius-xs); background: var(--owb-bg-hover); font-size: 11px; }
.canvas-page .cp-compose-tip { color: var(--owb-text-3); }
.canvas-page .cp-compose .cp-bar.is-sub { height: 3px; margin: 7px 0 2px; border-radius: var(--radius-full); overflow: hidden; }
.canvas-page .cp-compose-log { margin-top: 4px; color: var(--owb-text-3); font-size: 11px; overflow-wrap: anywhere; }
.canvas-page .cp-compose-log.is-stop { color: var(--owb-err-text); }
.canvas-page .cp-compose-log.is-warn { color: var(--owb-warn-text); }
.canvas-page .cp-order { max-height: 190px; margin: 7px 0 0; padding: 0; overflow: auto; list-style: none; }
.canvas-page .cp-order li { display: flex; align-items: center; gap: 8px; padding: 3px 0; border-top: 1px solid var(--owb-border); }
.canvas-page .cp-order li.is-bad { color: var(--owb-err-text); }
.canvas-page .cp-order li span { color: var(--owb-text-3); }
.canvas-page .cp-ord { flex: 0 0 18px; color: var(--owb-text-3); font-variant-numeric: tabular-nums; }
.canvas-page .cp-compose-sub { display: flex; align-items: center; gap: 6px; margin-top: 8px; color: var(--owb-text-2); cursor: pointer; }
.canvas-page .cp-compose-out { margin-top: 6px; color: var(--owb-text-3); font-size: 11px; }
.canvas-page .cp-compose-act { display: flex; gap: 8px; margin-top: 8px; }
.canvas-layout { display: grid; grid-template-columns: minmax(0, 1fr) 286px; gap: 10px; align-items: stretch; }
.canvas-layout.canvas-inspector-hidden { grid-template-columns: minmax(0, 1fr); }
.canvas-layout .canvas-viewport { min-width: 0; }
.canvas-inspector { min-width: 0; min-height: 480px; overflow: auto; border: 1px solid var(--owb-border); border-radius: var(--radius-xl); background: color-mix(in srgb, var(--owb-bg) 88%, transparent); }
.canvas-inspector-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 300px; padding: 24px; color: var(--owb-text-3); text-align: center; }
.canvas-inspector-empty b { margin-top: 10px; color: var(--owb-text-2); font-size: 13px; }
.canvas-inspector-empty p { margin: 8px 0 0; font-size: 12px; line-height: 1.6; }
.canvas-inspector-empty-icon { color: var(--owb-brand-text); }
.canvas-inspector-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; padding: 14px 14px 12px; border-bottom: 1px solid var(--owb-border); }
.canvas-inspector-head small { color: var(--owb-text-3); font-size: 11px; }
.canvas-inspector-head h3 { margin-top: 3px; font-size: 15px; }
.canvas-inspector-fields { display: grid; gap: 10px; padding: 13px 14px; }
.canvas-inspector-field { display: grid; gap: 5px; color: var(--owb-text-3); font-size: 11px; }
.canvas-inspector-field input, .canvas-inspector-field textarea, .canvas-inspector-field select, .canvas-connect-row select { width: 100%; min-width: 0; border: 1px solid var(--owb-border); border-radius: var(--radius-sm); background: var(--owb-bg); color: var(--owb-text); font: inherit; font-size: 12px; outline: none; }
.canvas-inspector-field input, .canvas-inspector-field select, .canvas-connect-row select { height: 30px; padding: 0 8px; }
.canvas-inspector-field textarea { min-height: 78px; padding: 7px 8px; resize: vertical; line-height: 1.5; }
.canvas-file-picker { display: grid; gap: 6px; color: var(--owb-text-3); font-size: 11px; }
.canvas-file-picker-row { display: flex; align-items: center; gap: 6px; }
.canvas-file-drop { min-height: 34px; display: flex; align-items: center; justify-content: center; padding: 5px 8px; border: 1px dashed color-mix(in srgb, var(--owb-brand) 48%, var(--owb-border)); border-radius: var(--radius-sm); background: color-mix(in srgb, var(--owb-brand-weak) 24%, transparent); color: var(--owb-text-2); text-align: center; line-height: 1.4; }
.canvas-file-drop.is-dragging { border-color: var(--owb-brand); background: var(--owb-brand-weak); color: var(--owb-brand-text); }
.canvas-file-picker small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--owb-text-3); }
.canvas-viewport.is-drop-target { border-color: var(--owb-brand); box-shadow: 0 0 0 2px color-mix(in srgb, var(--owb-brand) 22%, transparent); }
.canvas-viewport.is-drop-target::after { content: "松开后把图片、视频或音频加入画布"; position: absolute; inset: 14px; display: flex; align-items: center; justify-content: center; border: 2px dashed color-mix(in srgb, var(--owb-brand) 60%, transparent); border-radius: var(--radius-lg); background: color-mix(in srgb, var(--owb-brand-weak) 35%, transparent); color: var(--owb-brand-text); font-size: 13px; font-weight: 600; pointer-events: none; }
.canvas-selection-box { position: absolute; z-index: 30; box-sizing: border-box; border: 1px solid var(--owb-brand); background: color-mix(in srgb, var(--owb-brand-weak) 28%, transparent); pointer-events: none; }
.canvas-agent-status { display: inline-flex; margin-bottom: 8px; padding: 3px 7px; border-radius: var(--radius-full); background: var(--owb-brand-weak); color: var(--owb-brand-text); font-size: 11px; }
.canvas-inspector-field input:focus, .canvas-inspector-field textarea:focus, .canvas-inspector-field select:focus, .canvas-connect-row select:focus { border-color: var(--owb-brand); box-shadow: 0 0 0 2px color-mix(in srgb, var(--owb-brand) 16%, transparent); }
.canvas-inspector-section { padding: 12px 14px; border-top: 1px solid var(--owb-border); }
.canvas-inspector-section-title { display: block; margin-bottom: 8px; color: var(--owb-text-2); font-size: 12px; font-weight: 600; }
.canvas-connect-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(76px, 96px) auto; gap: 6px; }
.canvas-connected-list { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
.canvas-connected-list span { padding: 3px 6px; border-radius: var(--radius-full); background: var(--owb-brand-weak); color: var(--owb-brand-text); font-size: 11px; }
.canvas-connected-list span { display: inline-flex; align-items: center; gap: 2px; padding-right: 2px; }
.canvas-disconnect { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; padding: 0; border: none; border-radius: var(--radius-full); background: transparent; color: inherit; cursor: pointer; opacity: .65; }
.canvas-disconnect:hover, .canvas-disconnect:focus-visible { opacity: 1; color: var(--owb-err-text); background: var(--owb-bg-hover); }
.canvas-disconnect .i { width: 11px; height: 11px; }
/* 停在连线上冒出来的那颗 ×（见 canvasBindLinkHover） */
.canvas-link-remove { fill: var(--owb-bg); stroke: var(--owb-border); stroke-width: 1; }
.canvas-link-remove-icon { stroke: var(--owb-text-3); stroke-width: 1.6; stroke-linecap: round; }
.joint-tool:hover .canvas-link-remove { stroke: var(--owb-err-text); }
.joint-tool:hover .canvas-link-remove-icon { stroke: var(--owb-err-text); }
.canvas-inspector-hint { margin: 9px 0 0; color: var(--owb-text-3); font-size: 11px; line-height: 1.55; }
.canvas-provenance { display: grid; gap: 8px; }
.canvas-provenance-meta, .canvas-provenance-inputs { display: flex; flex-wrap: wrap; gap: 5px; }
.canvas-provenance-meta span, .canvas-provenance-inputs span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 3px 6px; border-radius: var(--radius-full); background: var(--owb-bg-hover); color: var(--owb-text-3); font-size: 10px; }
.canvas-provenance-meta span:first-child { background: var(--owb-brand-weak); color: var(--owb-brand-text); }
.canvas-provenance-output { display: flex; align-items: center; min-width: 0; gap: 6px; color: var(--owb-text-2); font-size: 11px; }
.canvas-provenance-output .i { width: 14px; height: 14px; color: var(--owb-brand-text); flex: none; }
.canvas-provenance-output span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.canvas-dup-hint { color: var(--owb-err-text); }
.canvas-dup-hint[hidden] { display: none; }
/* 历史版本：一行一版，缩略图 + 版本号 + 「用这一版」 */
.canvas-history-group + .canvas-history-group { margin-top: 12px; }
.canvas-history-kind { display: block; margin-bottom: 4px; color: var(--owb-text-3); font-size: 11px; }
.canvas-history-list { display: grid; gap: 4px; margin: 0; padding: 0; list-style: none; }
.canvas-history-row { display: flex; align-items: center; gap: 8px; min-width: 0; padding: 4px; border-radius: var(--radius-sm); }
.canvas-history-row.is-current { background: var(--owb-brand-weak); }
.canvas-history-thumb { display: flex; align-items: center; justify-content: center; flex: none; width: 40px; height: 40px; overflow: hidden; border-radius: var(--radius-sm); background: var(--owb-bg-hover); color: var(--owb-text-3); }
.canvas-history-thumb img { width: 100%; height: 100%; object-fit: contain; }
.canvas-history-thumb .i { width: 16px; height: 16px; }
.canvas-history-meta { display: flex; flex-direction: column; flex: 1; min-width: 0; gap: 4px; }
.canvas-history-meta b { color: var(--owb-text); font-size: 12px; font-weight: 600; }
.canvas-history-meta small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--owb-text-3); font-size: 11px; }
.canvas-history-row .ui-btn { flex: none; }
.canvas-inspector-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 0 14px 14px; }
/* 生成按钮旁的预估价：跟按钮贴着，字小一号，空着的时候不占位 */
.canvas-price { color: var(--owb-text-3); font-size: 11px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.canvas-price:empty { display: none; }
.canvas-reroll-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 0 14px 14px; }
.canvas-reroll-row small { color: var(--owb-text-3); font-size: 11px; }
.canvas-inspector-delete { margin-left: auto; color: var(--owb-err-text); }
.canvas-chat { position: sticky; bottom: 0; z-index: 8; margin-top: 6px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: color-mix(in srgb, var(--owb-bg) 94%, transparent); box-shadow: var(--shadow-menu); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); }
.canvas-chat-head { display: none !important; }
.canvas-chat-head > div { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.canvas-chat-head b { color: var(--owb-text); font-size: 13px; }
.canvas-chat-head small { margin-top: 1px; color: var(--owb-text-3); font-size: 10px; }
.canvas-chat-head small, .canvas-chat-head > span, .canvas-chat-log > .canvas-chat-message:first-child { display: none; }
.canvas-chat-head > span { padding: 3px 7px; border-radius: var(--radius-full); background: var(--owb-brand-weak); color: var(--owb-brand-text); font-size: 10px; white-space: nowrap; }
.canvas-chat-log { display: flex; flex-direction: column; gap: 4px; max-height: 132px; overflow: auto; padding: 7px 10px; background: color-mix(in srgb, var(--owb-bg-side) 42%, transparent); scrollbar-gutter: stable; }
.canvas-chat-message { display: flex; align-items: flex-start; gap: 7px; color: var(--owb-text-2); font-size: 12px; line-height: 1.45; }
.canvas-chat-message.is-user { color: var(--owb-text); }
.canvas-chat-role { flex: none; min-width: 36px; padding-top: 1px; color: var(--owb-brand-text); font-weight: 600; }
.canvas-chat-message-body { display: flex; flex: 1; flex-direction: column; gap: 5px; min-width: 0; }
.canvas-chat-message-refs { display: flex; flex-wrap: wrap; gap: 5px; }
.canvas-chat-text { max-width: 100%; white-space: pre-wrap; overflow-wrap: anywhere; }
.canvas-chat-message.is-live .canvas-chat-text { max-height: 4.35em; overflow: auto; }
.canvas-chat-message.is-status { gap: 5px; color: var(--owb-text-3); font-size: 11px; }
.canvas-chat-message.is-status .canvas-chat-role { color: var(--owb-text-3); font-weight: 500; }
.canvas-chat-message.is-running .canvas-chat-text::before { content: ""; display: inline-block; width: 6px; height: 6px; margin: 0 5px 1px 0; border-radius: 50%; background: var(--owb-brand); box-shadow: 0 0 0 3px var(--owb-brand-weak); }
.canvas-chat-message.is-complete .canvas-chat-text { color: var(--owb-ok-text, var(--owb-brand-text)); }
.canvas-chat-message.is-error .canvas-chat-text { color: var(--owb-err-text); }
.canvas-chat-compose { display: flex; align-items: flex-end; gap: 8px; padding: 8px 10px 10px; border-top: 1px solid var(--owb-border); }
.canvas-chat-compose textarea { flex: 1; min-width: 0; min-height: 36px; max-height: 110px; padding: 8px 9px; resize: vertical; border: 0; border-radius: var(--radius-md); background: transparent; color: var(--owb-text); font: inherit; font-size: 13px; line-height: 1.45; outline: none; }
.canvas-chat-compose textarea:focus { border-color: var(--owb-brand); box-shadow: 0 0 0 2px color-mix(in srgb, var(--owb-brand) 15%, transparent); }
.canvas-chat-compose button { flex: none; }
.canvas-chat-mention-menu { position: absolute; z-index: 40; right: 10px; bottom: 82px; width: min(360px, calc(100% - 20px)); max-height: 250px; overflow: auto; padding: 6px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg); box-shadow: var(--shadow-menu); }
.canvas-chat-mention-menu[hidden] { display: none; }
.canvas-chat-mention-item { display: flex; align-items: center; gap: 8px; width: 100%; min-width: 0; padding: 7px 8px; border: 0; border-radius: var(--radius-md); background: transparent; color: var(--owb-text); text-align: left; cursor: pointer; }
.canvas-chat-mention-item:hover { background: var(--owb-bg-hover); }
.canvas-chat-mention-item > span:last-child { display: flex; flex-direction: column; min-width: 0; }
.canvas-chat-mention-item b, .canvas-chat-mention-item small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.canvas-chat-mention-item b { font-size: 12px; }
.canvas-chat-mention-item small { margin-top: 2px; color: var(--owb-text-3); font-size: 10px; }
.canvas-chat-mention-icon { display: inline-flex; align-items: center; justify-content: center; width: 25px; height: 25px; flex: none; border-radius: var(--radius-sm); background: var(--owb-brand-weak); color: var(--owb-brand-text); }
.canvas-chat-mention-icon .i { width: 14px; height: 14px; }
.canvas-chat-mention-empty { padding: 12px 9px; color: var(--owb-text-3); font-size: 11px; }
.canvas-chat-ref-chips { display: flex; flex-wrap: wrap; gap: 4px; width: 100%; }
.canvas-chat-ref-chip { --canvas-ref-accent: var(--owb-brand); display: inline-grid; grid-template-columns: 24px minmax(0, 1fr) auto; align-items: center; gap: 6px; max-width: min(260px, 100%); min-height: 38px; padding: 3px 5px 3px 4px; border: 1px solid color-mix(in srgb, var(--canvas-ref-accent) 34%, var(--owb-border)); border-radius: var(--radius-md); background: color-mix(in srgb, var(--canvas-ref-accent) 9%, var(--owb-bg)); color: var(--owb-text); box-shadow: 0 1px 2px color-mix(in srgb, var(--owb-text) 6%, transparent); }
.canvas-chat-ref-chip[data-ref-use="character"] { --canvas-ref-accent: #f59e0b; }
.canvas-chat-ref-chip[data-ref-use="background"] { --canvas-ref-accent: #10b981; }
.canvas-chat-ref-chip[data-ref-use="motion"] { --canvas-ref-accent: #8b5cf6; }
.canvas-chat-ref-chip[data-ref-use="style"] { --canvas-ref-accent: #ec4899; }
.canvas-chat-ref-chip[data-ref-use="first_frame"], .canvas-chat-ref-chip[data-ref-use="last_frame"] { --canvas-ref-accent: #3b82f6; }
.canvas-chat-ref-chip[data-ref-use="audio"] { --canvas-ref-accent: #06b6d4; }
.canvas-chat-ref-icon { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: var(--radius-sm); background: color-mix(in srgb, var(--canvas-ref-accent) 14%, var(--owb-bg)); color: var(--canvas-ref-accent); }
.canvas-chat-ref-icon .i { width: 14px; height: 14px; }
.canvas-chat-ref-copy { display: flex; flex-direction: column; min-width: 0; line-height: 1.15; }
.canvas-chat-ref-copy b, .canvas-chat-ref-copy small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.canvas-chat-ref-copy b { font-size: 10px; font-weight: 600; }
.canvas-chat-ref-copy small { margin-top: 2px; color: var(--owb-text-3); font-size: 9px; }
.canvas-chat-ref-copy select { width: max-content; max-width: 122px; height: 18px; margin: 1px 0 0 -3px; padding: 0 15px 0 3px; border: 0; border-radius: var(--radius-xs); background: transparent; color: var(--canvas-ref-accent); font: inherit; font-size: 9px; font-weight: 600; outline: none; cursor: pointer; }
.canvas-chat-ref-copy select:hover, .canvas-chat-ref-copy select:focus { background: color-mix(in srgb, var(--canvas-ref-accent) 12%, transparent); }
.canvas-chat-ref-chip button { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: inherit; cursor: pointer; }
.canvas-chat-ref-chip button:hover { background: color-mix(in srgb, var(--owb-brand-text) 18%, transparent); }
.canvas-chat-ref-chip button .i { width: 11px; height: 11px; }
.canvas-chat-message-refs .canvas-chat-ref-chip { min-height: 30px; background: var(--owb-bg-hover); box-shadow: none; }
.canvas-chat-tools { display: flex; align-items: center; gap: 5px; width: 100%; padding-top: 3px; }
.canvas-chat-tool { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--owb-text-2); cursor: pointer; font-size: 15px; }
.canvas-chat-tool:hover { background: var(--owb-bg-hover); color: var(--owb-text); }
.canvas-chat-tool .i { width: 16px; height: 16px; }
.canvas-chat-tools-spacer { flex: 1; }
.canvas-chat-mode, .canvas-chat-model { height: 28px; max-width: 150px; padding: 0 7px; border: 1px solid transparent; border-radius: var(--radius-md); background: transparent; color: var(--owb-text-2); font: inherit; font-size: 11px; cursor: pointer; outline: none; }
.canvas-chat-mode:hover, .canvas-chat-model:hover, .canvas-chat-mode:focus, .canvas-chat-model:focus { border-color: var(--owb-border); background: var(--owb-bg-hover); color: var(--owb-text); }
.canvas-chat-send { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 50%; background: var(--owb-brand-grad); color: var(--primary-foreground); cursor: pointer; box-shadow: 0 4px 12px color-mix(in srgb, var(--owb-brand) 22%, transparent); }
.canvas-chat-send:disabled { opacity: .48; cursor: not-allowed; }
.canvas-chat-send .i { width: 17px; height: 17px; }
.canvas-chat-send.is-stop { background: var(--owb-text); box-shadow: none; }
.canvas-chat-send.is-stop .i { width: 11px; height: 11px; fill: currentColor; }
.canvas-chat-send.is-interject { background: color-mix(in srgb, var(--owb-brand) 84%, var(--destructive)); }
.canvas-chat-compose.is-dragging { border-color: var(--owb-brand); background: color-mix(in srgb, var(--owb-brand) 7%, var(--owb-bg)); box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--owb-brand) 18%, transparent); }
/* 画布是主工作区：工具和属性以浮层存在，不再挤压画布本体。 */
.canvas-page { position: relative; margin-top: -16px; }
/* 42 是「进度带还不存在」那会儿量出来的，浮在画布顶上正合适。进度带一出现就顶在这个位置，
   工具条原地不动就盖在它脸上——剧本、定妆那两格永远露不出来。跟着一起让位 */
.canvas-page > .canvas-toolbar { position: absolute; z-index: 24; top: calc(42px + var(--cp-h, 0px)); right: 10px; left: 10px; justify-content: space-between; margin: 0; pointer-events: none; }
.canvas-tool-cluster { position: relative; display: inline-flex; align-items: center; gap: 2px; height: 34px; padding: 2px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: color-mix(in srgb, var(--owb-bg) 92%, transparent); box-shadow: var(--shadow-surface); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); pointer-events: auto; }
.canvas-tool-cluster .canvas-node-menu, .canvas-tool-cluster .canvas-library { position: relative; width: 30px; margin: 0; border: 0; border-radius: var(--radius-sm); background: transparent; }
.canvas-tool-cluster .canvas-node-menu summary, .canvas-tool-cluster .canvas-library summary { display: flex; align-items: center; justify-content: center; width: 30px; min-height: 30px; padding: 0; border-radius: var(--radius-sm); color: var(--owb-text-2); }
.canvas-tool-cluster .canvas-node-menu summary:hover, .canvas-tool-cluster .canvas-library summary:hover, .canvas-tool-cluster details[open] > summary { background: var(--owb-bg-hover); color: var(--owb-brand-text); }
.canvas-tool-cluster .canvas-menu-label, .canvas-tool-cluster .canvas-library summary > span { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; margin: 0; border: 0; background: transparent; color: inherit; }
.canvas-tool-cluster .canvas-menu-label .i, .canvas-tool-cluster .canvas-library summary > span .i { width: 16px; height: 16px; }
.canvas-tool-divider { width: 1px; height: 18px; margin: 0 3px; background: var(--owb-border); }
.canvas-tool-button { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; padding: 0; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--owb-text-2); cursor: pointer; }
.canvas-tool-button:hover { background: var(--owb-bg-hover); color: var(--owb-brand-text); }
.canvas-tool-button .i { width: 16px; height: 16px; }
.canvas-tool-button.is-redo .i { transform: scaleX(-1); }
.canvas-tool-button.is-active { background: var(--owb-brand-weak); color: var(--owb-brand-text); }
.canvas-viewport.is-marquee { cursor: crosshair; }
.canvas-tool-cluster .canvas-node-menu-body, .canvas-tool-cluster .canvas-library-panel { position: absolute; z-index: 30; top: 38px; left: 0; box-sizing: border-box; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: color-mix(in srgb, var(--owb-bg) 97%, transparent); box-shadow: var(--shadow-menu); }
.canvas-tool-cluster .canvas-node-menu-body { width: min(470px, calc(100vw - 370px)); }
.canvas-tool-cluster .canvas-library-panel { width: min(340px, calc(100vw - 370px)); overflow: hidden; }
.canvas-tool-cluster .canvas-library-tools { grid-template-columns: minmax(0, 1fr) 88px 30px; }
.canvas-tool-cluster .canvas-library-items { max-height: 290px; }
.canvas-workspace-switch { display: inline-flex; align-items: center; gap: 5px; min-width: 0; height: 28px; padding: 0 5px 0 8px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: var(--owb-bg); color: var(--owb-text-2); }
.canvas-workspace-switch .i { width: 14px; height: 14px; flex: none; }
.canvas-workspace-switch select { max-width: 155px; height: 26px; padding: 0 20px 0 0; border: 0; background: transparent; color: var(--owb-text); font: inherit; font-size: 12px; outline: 0; cursor: pointer; }
.canvas-switch-divider { width: 1px; height: 18px; background: var(--owb-border); }
.canvas-node-icon-action { display: inline-flex; align-items: center; justify-content: center; width: 29px; height: 29px; margin-left: auto; padding: 0; border: 1px solid var(--owb-border); border-radius: var(--radius-sm); background: var(--owb-bg); color: var(--owb-text-2); cursor: pointer; }
.canvas-node-icon-action:hover { border-color: var(--owb-brand); color: var(--owb-brand-text); background: var(--owb-brand-weak); }
.canvas-node-icon-action .i { width: 15px; height: 15px; }
.canvas-context-menu { position: fixed; z-index: 4000; display: grid; min-width: 188px; padding: 6px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: color-mix(in srgb, var(--owb-bg) 98%, transparent); box-shadow: var(--shadow-menu); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
.canvas-context-menu button { display: grid; grid-template-columns: 20px 1fr; align-items: center; gap: 8px; min-height: 34px; padding: 6px 9px; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--owb-text); text-align: left; cursor: pointer; font: inherit; font-size: 12px; }
.canvas-context-menu button:hover { background: var(--owb-bg-hover); }
.canvas-context-menu button.is-danger { color: var(--owb-err-text); }
.canvas-context-menu button .i { width: 15px; height: 15px; }
.canvas-context-divider { height: 1px; margin: 5px 4px; background: var(--owb-border); }
/* 卡右边那颗连接点（canvasDecorateNode）：往外拖是连线，点一下是「新建并连上」。
   平时藏着，指到卡上、选中卡、键盘挪到它上面才露出来；触屏没有「指到」，一直露着 */
.canvas-joint-node { position: relative; }
.canvas-port { position: absolute; top: 50%; right: -11px; z-index: 3; display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; width: 22px; height: 22px; margin-top: -11px; padding: 0; border: 1px solid var(--owb-border); border-radius: 50%; background: var(--owb-bg); color: var(--owb-brand-text); box-shadow: var(--shadow-surface); cursor: crosshair; opacity: 0; touch-action: none; user-select: none; transition: opacity .12s var(--owb-ease); }
.canvas-port .i { width: 13px; height: 13px; }
.canvas-port:hover { border-color: var(--owb-brand); background: var(--owb-brand-weak); }
.canvas-joint-node:hover .canvas-port, .canvas-joint-node.is-selected .canvas-port, .canvas-port:focus-visible { opacity: 1; }
@media (hover: none) { .canvas-port { opacity: 1; } }
/* 拖出来的那根线、悬停时的红绿框：线画在视口上单独一层 svg 里，不进图、不存盘；红框旁边那句是连不上的原因 */
.canvas-viewport.is-wiring { cursor: crosshair; user-select: none; }
.canvas-wire-layer { position: absolute; inset: 0; z-index: 20; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.canvas-wire { fill: none; stroke: var(--owb-brand-text); stroke-width: 2; stroke-dasharray: 6 4; }
.canvas-wire.is-bad { stroke: var(--owb-err); }
.canvas-joint-node.is-link-ok .canvas-node { border-color: var(--owb-ok); box-shadow: 0 0 0 3px color-mix(in srgb, var(--owb-ok) 30%, transparent), var(--shadow-surface); }
.canvas-joint-node.is-link-bad .canvas-node { border-color: var(--owb-err); box-shadow: 0 0 0 3px color-mix(in srgb, var(--owb-err) 30%, transparent), var(--shadow-surface); }
.canvas-wire-tag { position: absolute; z-index: 21; padding: 4px 8px; border: 1px solid var(--owb-err); border-radius: var(--radius-sm); background: color-mix(in srgb, var(--destructive) 10%, var(--owb-bg)); color: var(--owb-err-text); box-shadow: var(--shadow-surface); font-size: 12px; white-space: nowrap; pointer-events: none; }
.canvas-wire-tag[hidden] { display: none; }
/* 点连接点弹出来的「新建并连上」：跟工具栏「添加节点」同一套按钮（.canvas-page 下那几条也管它），只列连得上的几种 */
.canvas-port-menu { position: fixed; z-index: 4000; box-sizing: border-box; width: min(360px, calc(100vw - 16px)); padding: 6px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: color-mix(in srgb, var(--owb-bg) 98%, transparent); box-shadow: var(--shadow-menu); }
.canvas-port-menu-head { padding: 4px 6px 8px; color: var(--owb-text-2); font-size: 12px; font-weight: 600; }
.canvas-port-menu-body { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; max-height: 300px; overflow: auto; }
/* 卡上能直接改的那几格：选中了才像能点（指上去垫一层底色、光标变竖线）；没选中点一下只是选中 */
.canvas-joint-node.is-selected [data-canvas-inline-edit] { cursor: text; border-radius: var(--radius-xs); }
.canvas-joint-node.is-selected [data-canvas-inline-edit]:hover { background: var(--owb-bg-hover); box-shadow: 0 0 0 2px var(--owb-bg-hover); }
.canvas-inline-input, .canvas-inline-text { box-sizing: border-box; width: 100%; margin: 0; padding: 4px 6px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: var(--owb-bg); color: var(--owb-text); font: inherit; font-size: 12px; line-height: 1.45; }
.canvas-inline-input { font-size: 13px; font-weight: 600; }
.canvas-inline-text { display: block; margin-bottom: 8px; resize: vertical; }
.canvas-script-body > .canvas-inline-text { flex: 1; min-height: 0; margin-bottom: 0; resize: none; }
.canvas-inline-input:focus, .canvas-inline-text:focus { outline: none; border-color: var(--owb-brand); box-shadow: 0 0 0 2px var(--owb-brand-weak); }
.canvas-create-board-dialog { position: fixed; z-index: 5000; inset: 0; display: grid; place-items: center; padding: 24px; background: color-mix(in srgb, var(--foreground) 42%, transparent); opacity: 0; transition: opacity .14s var(--owb-ease); }
.canvas-create-board-dialog.is-open { opacity: 1; }
.canvas-create-board-card { width: min(410px, 100%); padding: 20px; border: 1px solid var(--owb-border); border-radius: var(--radius-xl); background: var(--owb-bg); box-shadow: var(--shadow-menu); }
.canvas-create-board-head { display: flex; align-items: center; gap: 11px; margin-bottom: 18px; }
.canvas-create-board-icon { display: inline-flex; align-items: center; justify-content: center; width: 38px; height: 38px; border-radius: var(--radius-md); background: var(--owb-brand-weak); color: var(--owb-brand-text); }
.canvas-create-board-head > div { display: flex; flex-direction: column; gap: 2px; }
.canvas-create-board-head b { font-size: 16px; }
.canvas-create-board-head small, .canvas-create-board-card label > span { color: var(--owb-text-3); font-size: 11px; }
.canvas-create-board-card label { display: grid; gap: 6px; }
.canvas-create-board-card input { width: 100%; box-sizing: border-box; }
.canvas-create-board-error { min-height: 18px; padding-top: 5px; color: var(--owb-err-text); font-size: 11px; }
.canvas-create-board-actions { display: flex; justify-content: flex-end; gap: 7px; margin-top: 7px; }
/* 新建短剧表单：名字之外多了画幅、时长、风格、两个模型，小屏上表单自己滚，不把按钮挤出屏幕 */
.canvas-drama-form { display: grid; gap: 12px; max-height: calc(100vh - 48px); overflow: auto; box-sizing: border-box; }
.canvas-drama-form .canvas-create-board-head { margin-bottom: 4px; }
.canvas-drama-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; }
.canvas-create-board-card select { width: 100%; box-sizing: border-box; }
.canvas-drama-price { color: var(--owb-text-3); font-size: 11px; }
.canvas-drama-price:empty { display: none; }
/* 分镜表草稿预览：表格区自己滚，风格栏和底部按钮一直看得见。窄屏上表格横着滚，不把整页顶宽 */
.canvas-draft-card { display: flex; flex-direction: column; gap: 12px; width: min(960px, 100%); max-height: calc(100vh - 48px); box-sizing: border-box; }
.canvas-draft-card .canvas-create-board-head { margin-bottom: 0; }
.canvas-draft-card .canvas-create-board-head > div { flex: 1; min-width: 0; }
.canvas-draft-style { flex: none; }
.canvas-draft-warnings { flex: none; margin: 0; padding: 8px 12px 8px 28px; border-radius: var(--radius-md); background: var(--owb-bg-hover); color: var(--owb-text-2); font-size: 12px; }
.canvas-draft-scroll { flex: 1; min-height: 120px; overflow: auto; border: 1px solid var(--owb-border); border-radius: var(--radius-md); }
.canvas-draft-table { width: 100%; min-width: 640px; table-layout: fixed; border-collapse: collapse; font-size: 12px; }
.canvas-draft-col-id { width: 88px; }
.canvas-draft-col-size { width: 72px; }
.canvas-draft-col-sec { width: 64px; }
.canvas-draft-col-tail { width: 104px; }
.canvas-draft-table th { position: sticky; top: 0; z-index: 1; padding: 8px; border-bottom: 1px solid var(--owb-border); background: var(--owb-bg); color: var(--owb-text-3); font-weight: 600; text-align: left; }
.canvas-draft-table td { padding: 4px; border-bottom: 1px solid var(--owb-border); vertical-align: top; }
.canvas-draft-table input, .canvas-draft-table textarea { width: 100%; min-width: 0; box-sizing: border-box; padding: 4px 8px; border: 1px solid transparent; border-radius: var(--radius-sm); background: transparent; color: var(--owb-text); font: inherit; }
.canvas-draft-table textarea { resize: vertical; line-height: 1.5; }
.canvas-draft-table input:focus, .canvas-draft-table textarea:focus { border-color: var(--owb-brand); outline: none; background: var(--owb-bg); }
.canvas-draft-scene td { padding: 8px; background: var(--owb-bg-hover); }
.canvas-draft-scene b { margin-right: 8px; font-family: var(--font-mono); }
.canvas-draft-scene span { color: var(--owb-text-2); }
.canvas-draft-tail { text-align: right; }
.canvas-draft-remove { display: inline-flex; align-items: center; justify-content: center; margin-left: 4px; padding: 4px; border: none; border-radius: var(--radius-sm); background: transparent; color: var(--owb-text-3); cursor: pointer; vertical-align: middle; }
.canvas-draft-remove:hover { background: var(--owb-bg-hover); color: var(--owb-err-text); }
.canvas-draft-meta { display: flex; flex-wrap: wrap; gap: 12px; color: var(--owb-text-3); font-size: 12px; }
/* 追加 / 替换 / 取消：压在草稿预览上面一层 */
.canvas-draft-choice { z-index: 5001; }
.canvas-draft-choice-note { margin: 0 0 8px; color: var(--owb-text-2); font-size: 12px; }
.canvas-page .canvas-zoom-box { pointer-events: auto; box-shadow: var(--shadow-surface); }
.canvas-page .canvas-toolbar-hint, .canvas-page .canvas-menu-hint, .canvas-page .canvas-library summary small, .canvas-page .canvas-library-tools span { display: none !important; }
.canvas-page .canvas-node-menu-body { max-height: 270px; overflow: auto; }
.canvas-page .canvas-node-menu-body { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; padding: 8px; }
.canvas-page .canvas-menu-group { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px; min-width: 0; padding: 6px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: color-mix(in srgb, var(--owb-bg) 78%, transparent); }
.canvas-page .canvas-menu-group-label { grid-column: 1 / -1; padding: 1px 3px 4px; color: var(--owb-text-3); font-size: 10px; font-weight: 600; }
.canvas-page .canvas-type-btn { justify-content: flex-start; width: 100%; min-width: 0; height: 32px; padding: 0 6px; border-color: transparent; background: var(--owb-bg); }
.canvas-page .canvas-type-btn span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.canvas-layout { position: relative; display: block; }
.canvas-page .canvas-viewport { height: clamp(420px, calc(100vh - 120px - var(--cp-h, 0px)), 1200px); }
.canvas-page .canvas-inspector { position: absolute; z-index: 22; top: 10px; right: 10px; width: 286px; min-height: 0; max-height: calc(100% - 20px); box-shadow: var(--shadow-menu); }
.canvas-page .canvas-layout.canvas-inspector-hidden .canvas-inspector { display: none; }
.canvas-page > .canvas-chat { position: absolute; z-index: 25; right: 0; bottom: 0; left: 0; margin: 0; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
.canvas-page > .canvas-chat { border-radius: var(--radius-lg); }
.canvas-page .canvas-chat-log { max-height: 116px; padding: 6px 10px; }
.canvas-page .canvas-chat-compose { display: grid; gap: 2px; padding: 7px 9px 8px; border-top: 0; }
.canvas-page .canvas-chat-compose textarea { min-height: 32px; max-height: 76px; padding: 5px 6px 4px; resize: none; line-height: 1.4; }
.canvas-page .canvas-chat-tools { padding-top: 2px; }
.canvas-page .canvas-chat-mode, .canvas-page .canvas-chat-model { max-width: 128px; }
.canvas-page .canvas-chat-mention-menu { bottom: 92px; }
/* 底部时间线：浮在对话框正上方。对话框多高由 canvasBindTimeline 量出来写进 --ctl-chat-h，量不到时按 132 算。
   整层不接鼠标，只有面板本身接——收起来时两边空出来的地方照样能拖画布 */
.canvas-page > .canvas-timeline { position: absolute; z-index: 24; right: 10px; bottom: calc(var(--ctl-chat-h, 132px) + 8px); left: 10px; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; pointer-events: none; }
.canvas-page > .canvas-timeline[hidden] { display: none; }
.canvas-page .ctl-panel { max-width: 100%; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: color-mix(in srgb, var(--owb-bg) 92%, transparent); box-shadow: var(--shadow-surface); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); pointer-events: auto; }
.canvas-page .canvas-timeline.is-open .ctl-panel { width: 100%; }
.canvas-page .ctl-head { display: flex; align-items: center; gap: 8px; min-height: 32px; padding: 0 4px; color: var(--owb-text-2); font-size: 12px; }
.canvas-page .ctl-toggle { display: inline-flex; align-items: center; gap: 4px; height: 28px; padding: 0 8px 0 4px; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--owb-text); font: inherit; cursor: pointer; }
.canvas-page .ctl-toggle:hover { background: var(--owb-bg-hover); }
.canvas-page .ctl-toggle .i { width: 16px; height: 16px; color: var(--owb-text-2); }
.canvas-page .ctl-meta { display: inline-flex; align-items: center; gap: 8px; min-width: 0; color: var(--owb-text-3); white-space: nowrap; }
.canvas-page .ctl-lack { display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 8px; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--owb-err-text); font: inherit; white-space: nowrap; }
.canvas-page button.ctl-lack { cursor: pointer; }
.canvas-page button.ctl-lack:hover { background: var(--owb-bg-hover); }
.canvas-page .ctl-actions { display: inline-flex; align-items: center; gap: 4px; margin-left: auto; }
.canvas-page .ctl-actions .ui-btn.is-active { background: var(--owb-brand-weak); color: var(--owb-brand-text); }
/* 触屏上只认左右滑（滚时间线）；按住一格拿起来、拖着换顺序靠 canvasTimelineDragStart 截住 touchmove */
.canvas-page .ctl-strip { display: flex; gap: 4px; padding: 4px 8px 8px; overflow-x: auto; overscroll-behavior-x: contain; touch-action: pan-x; }
.canvas-page .ctl-cell { position: relative; flex: 0 0 var(--ctl-w, 96px); display: flex; flex-direction: column; gap: 4px; width: var(--ctl-w, 96px); padding: 4px; border: 1px solid var(--owb-border); border-radius: var(--radius-sm); background: var(--owb-bg); color: var(--owb-text); font: inherit; text-align: left; cursor: pointer; }
.canvas-page .ctl-cell:hover { border-color: color-mix(in srgb, var(--owb-brand-text) 40%, var(--owb-border)); }
.canvas-page .ctl-cell.is-selected { border-color: var(--owb-brand-text); box-shadow: 0 0 0 2px var(--owb-brand-weak); }
.canvas-page .ctl-thumb { position: relative; display: flex; align-items: center; justify-content: center; height: 48px; overflow: hidden; border-radius: 4px; background: var(--owb-bg-hover); color: var(--owb-text-3); }
/* 首帧排成胶片条：每帧整张缩进格子，放得下几帧排几帧、帧间均匀留缝，不切半帧。
   <img> 只用来等加载、记宽高比，不显示。以前是 cover：竖屏的首帧只剩中间一截 */
.canvas-page .ctl-thumb.is-film { background-repeat: space no-repeat; background-size: contain; background-position: center; }
.canvas-page .ctl-thumb.is-film img { position: absolute; opacity: 0; pointer-events: none; }
.canvas-page .ctl-thumb img, .canvas-page .ctl-thumb video { flex: none; width: auto; max-width: 100%; height: 100%; object-fit: contain; background: var(--owb-bg-hover); box-shadow: 1px 0 0 rgba(0, 0, 0, .35); }
.canvas-page .ctl-thumb video { width: 100%; pointer-events: none; }
.canvas-page .ctl-tc { position: absolute; left: 3px; bottom: 3px; padding: 0 4px; border-radius: 3px; background: rgba(0, 0, 0, .58); color: #fff; font-family: var(--font-mono); font-size: 10px; line-height: 15px; }
/* 首帧 / 视频 / 配音三段：有了是品牌色，缺了是红，用不上是灰。字在悬停放大的那张里 */
.canvas-page .ctl-pips { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; }
.canvas-page .ctl-pips i { height: 3px; border-radius: 2px; background: var(--owb-border); }
.canvas-page .ctl-pips i.is-ok { background: var(--owb-brand); }
.canvas-page .ctl-pips i.is-miss { background: color-mix(in srgb, var(--owb-err) 70%, transparent); }
.canvas-page .ctl-cell.is-playing { border-color: var(--owb-brand); box-shadow: 0 0 0 2px color-mix(in srgb, var(--owb-brand) 35%, transparent); }
.canvas-page .ctl-cell.is-playing .ctl-tc { background: var(--owb-brand); }
.canvas-page .ctl-cell:focus-visible { outline: 2px solid var(--owb-brand); outline-offset: 1px; }
/* 拖一格换顺序：拖着的那格变淡，松手会插在哪两格中间就亮一道竖线 */
.canvas-page .ctl-strip.is-reordering, .canvas-page .ctl-strip.is-reordering .ctl-cell { cursor: grabbing; user-select: none; }
.canvas-page .ctl-cell.is-dragging { opacity: .45; }
/* 手指按住不动、这一格拿起来了：亮一圈，说明再拖就是换顺序。长按也别弹系统的图片菜单 */
.canvas-page .ctl-cell { -webkit-touch-callout: none; }
.canvas-page .ctl-cell.is-armed { border-color: var(--owb-brand); box-shadow: 0 0 0 2px var(--owb-brand-weak); }
.canvas-page .ctl-cell.is-drop-before::before, .canvas-page .ctl-cell.is-drop-after::after { content: ""; position: absolute; top: 2px; bottom: 2px; width: 2px; border-radius: 1px; background: var(--owb-brand); pointer-events: none; }
.canvas-page .ctl-cell.is-drop-before::before { left: -4px; }
.canvas-page .ctl-cell.is-drop-after::after { right: -4px; }
.canvas-page .ctl-peek { position: absolute; z-index: 2; display: grid; gap: 6px; width: max-content; max-width: 280px; padding: 8px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: var(--owb-bg); box-shadow: var(--shadow-menu); color: var(--owb-text); font-size: 12px; pointer-events: none; opacity: 0; transition: opacity .12s var(--owb-ease); }
.canvas-page .ctl-peek.is-open { opacity: 1; }
.canvas-page .ctl-peek-media { display: flex; justify-content: center; min-width: 160px; border-radius: 6px; background: var(--owb-bg-hover); overflow: hidden; }
.canvas-page .ctl-peek-media img, .canvas-page .ctl-peek-media video { display: block; width: 264px; height: auto; max-height: 200px; object-fit: contain; }
.canvas-page .ctl-peek-media [data-shape="tall"] { width: auto; height: 200px; }
.canvas-page .ctl-peek-none { padding: 28px 12px; color: var(--owb-text-3); }
.canvas-page .ctl-peek-meta { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.canvas-page .ctl-peek-meta span { color: var(--owb-text-3); font-family: var(--font-mono); font-size: 11px; }
.canvas-page .ctl-peek-line { display: -webkit-box; margin: 0; overflow: hidden; color: var(--owb-text-2); -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
.canvas-page .ctl-peek-parts { display: flex; gap: 4px; }
.canvas-page .ctl-peek-parts span { padding: 1px 6px; border-radius: 999px; background: var(--owb-bg-hover); color: var(--owb-text-3); font-size: 11px; }
.canvas-page .ctl-peek-parts .is-ok { background: var(--owb-brand-weak); color: var(--owb-brand-text); }
.canvas-page .ctl-peek-parts .is-miss { background: color-mix(in srgb, var(--owb-err) 12%, var(--owb-bg)); color: var(--owb-err-text); }
.canvas-page .ctl-peek-parts .is-off { text-decoration: line-through; }
.canvas-page .ctl-thumb .i { width: 16px; height: 16px; }
.canvas-page .ctl-cap { display: flex; align-items: baseline; justify-content: space-between; gap: 4px; min-width: 0; font-size: 11px; }
.canvas-page .ctl-cap b { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.canvas-page .ctl-cap span { flex: none; color: var(--owb-text-3); }
.canvas-page .ctl-dot { display: inline-block; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--owb-err); }
.canvas-page .ctl-cell > .ctl-dot { position: absolute; top: 8px; right: 8px; box-shadow: 0 0 0 2px var(--owb-bg); }
/* 角色面板：从时间线上方弹出来，跟时间线一起走 */
.canvas-page .ctl-cast { width: min(560px, 100%); max-height: min(360px, 48vh); display: flex; flex-direction: column; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: var(--owb-bg); box-shadow: var(--shadow-menu); pointer-events: auto; }
.canvas-page .ctl-cast-head { display: flex; align-items: center; gap: 8px; min-height: 40px; padding: 0 4px 0 12px; border-bottom: 1px solid var(--owb-border); font-size: 12px; }
/* 右边那一组（全部挂上、关闭）靠右；没有「全部挂上」时关闭自己靠右 */
.canvas-page .ctl-cast-head > .canvas-tool-button, .canvas-page .ctl-cast-head .ui-btn { margin-left: auto; }
.canvas-page .ctl-cast-head .ui-btn + .canvas-tool-button { margin-left: 0; }
.canvas-page .ctl-cast-list { display: grid; gap: 4px; padding: 8px; overflow-y: auto; }
.canvas-page .ctl-cast-row { display: flex; gap: 8px; padding: 4px; border-radius: var(--radius-sm); }
.canvas-page .ctl-cast-row:hover { background: var(--owb-bg-hover); }
.canvas-page .ctl-cast-photo { flex: none; display: flex; align-items: center; justify-content: center; width: 48px; height: 64px; padding: 0; overflow: hidden; border: 1px solid var(--owb-border); border-radius: var(--radius-sm); background: var(--owb-bg-hover); color: var(--owb-text-3); font: inherit; font-size: 10px; line-height: 1.3; text-align: center; cursor: pointer; }
.canvas-page .ctl-cast-photo img { width: 100%; height: 100%; object-fit: contain; }
.canvas-page .ctl-cast-body { display: grid; align-content: start; gap: 4px; min-width: 0; }
.canvas-page .ctl-cast-name { display: flex; align-items: baseline; gap: 8px; font-size: 12px; }
.canvas-page .ctl-cast-name small, .canvas-page .ctl-cast-shots > small { color: var(--owb-text-3); font-size: 11px; }
.canvas-page .ctl-cast-shots { display: flex; flex-wrap: wrap; gap: 4px; }
.canvas-page .ctl-chip { display: inline-flex; align-items: center; height: 24px; padding: 0 8px; border: 1px solid var(--owb-border); border-radius: var(--radius-sm); background: var(--owb-bg); color: var(--owb-text-2); font: inherit; font-size: 11px; cursor: pointer; }
.canvas-page button.ctl-chip:hover { color: var(--owb-brand-text); }
.canvas-page .ctl-chip.is-loose { gap: 4px; padding: 0 0 0 8px; overflow: hidden; border-color: color-mix(in srgb, var(--owb-err) 45%, var(--owb-border)); color: var(--owb-err-text); cursor: default; }
.canvas-page .ctl-chip.is-loose button { height: 100%; padding: 0; border: 0; background: transparent; color: inherit; font: inherit; cursor: pointer; }
.canvas-page .ctl-chip.is-loose .ctl-attach { padding: 0 8px; border-left: 1px solid color-mix(in srgb, var(--owb-err) 30%, var(--owb-border)); color: var(--owb-brand-text); }
.canvas-page .ctl-chip.is-loose .ctl-attach:hover { background: var(--owb-brand-weak); }
.canvas-page .ctl-cast-empty { padding: 12px; color: var(--owb-text-3); font-size: 12px; }
/* ⌘F 搜索条：工具条正下方居中。进度带展开时一起往下让 */
.canvas-page > .canvas-find { position: absolute; z-index: 26; top: calc(84px + var(--cp-h, 0px)); left: 50%; display: flex; align-items: center; gap: 4px; width: min(420px, calc(100% - 20px)); height: 40px; padding: 0 4px 0 8px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: var(--owb-bg); box-shadow: var(--shadow-menu); transform: translateX(-50%); }
.canvas-page > .canvas-find[hidden] { display: none; }
.canvas-page .canvas-find input { flex: 1; min-width: 0; height: 28px; padding: 0 4px; border: 0; outline: none; background: transparent; color: var(--owb-text); font: inherit; font-size: 13px; }
.canvas-page .canvas-find-count { flex: none; color: var(--owb-text-3); font-size: 12px; white-space: nowrap; }
.canvas-page .canvas-find-count.is-miss { color: var(--owb-err-text); }
/* 画布顶上的横幅（Agent 删了一片给「撤销」、没存进项目给「重试保存」）：位置跟 ⌘F 搜索条一样，
   搜索条开着就排在它下面。底色不透明——底下是一张满是卡片的画布，半透明的字压在卡片上读不清 */
.canvas-page > .canvas-bars { position: absolute; z-index: 27; top: calc(84px + var(--cp-h, 0px)); left: 50%; display: flex; flex-direction: column; gap: 6px; width: min(560px, calc(100% - 20px)); transform: translateX(-50%); pointer-events: none; }
.canvas-page > .canvas-bars[hidden] { display: none; }
.canvas-page > .canvas-find:not([hidden]) ~ .canvas-bars { top: calc(130px + var(--cp-h, 0px)); }
.canvas-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 7px 8px 7px 10px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: var(--owb-bg); box-shadow: var(--shadow-menu); color: var(--owb-text); font-size: 12px; line-height: 1.5; pointer-events: auto; }
.canvas-bar > .i { width: 14px; height: 14px; flex: none; }
.canvas-bar-text { flex: 1 1 220px; min-width: 0; overflow-wrap: anywhere; }
.canvas-bar.is-warn { border-color: color-mix(in srgb, var(--warning) 40%, var(--owb-border)); background: color-mix(in srgb, var(--warning) 10%, var(--owb-bg)); }
.canvas-bar.is-warn > .i { color: var(--warning); }
.canvas-bar.is-err { border-color: color-mix(in srgb, var(--owb-err) 40%, var(--owb-border)); background: color-mix(in srgb, var(--owb-err) 9%, var(--owb-bg)); color: var(--danger-text); }
/* 连播预览：跟看大图那层一个样子 */
.canvas-playback { position: fixed; z-index: 1200; inset: 0; display: flex; align-items: center; justify-content: center; padding: 28px; background: rgba(8, 9, 12, .76); opacity: 0; transition: opacity .16s var(--owb-ease); }
.canvas-playback.is-open { opacity: 1; }
.canvas-playback .cpb-card { display: flex; flex-direction: column; width: min(960px, 94vw); max-height: 92vh; overflow: hidden; border: 1px solid color-mix(in srgb, var(--primary-foreground) 18%, transparent); border-radius: var(--radius-xl); background: var(--owb-bg); box-shadow: 0 24px 80px rgba(0, 0, 0, .42); }
/* 放映框跟着戏的比例（--cpb-ar，连播开始时写上）：竖屏戏是一个竖的框，不是横框中间一条 */
.canvas-playback .cpb-card { width: max(min(440px, 94vw), min(960px, 94vw, calc((92vh - 48px) * var(--cpb-ar, 1.7778)))); }
.canvas-playback .cpb-stage { display: flex; align-items: center; justify-content: center; aspect-ratio: var(--cpb-ar, 16 / 9); max-height: calc(92vh - 48px); background: #000; }
.canvas-playback .cpb-media { width: 100%; height: 100%; object-fit: contain; }
.canvas-playback .cpb-empty { display: grid; justify-items: center; gap: 8px; color: rgba(255, 255, 255, .72); font-size: 13px; }
.canvas-playback .cpb-empty b { color: #fff; font-size: 16px; }
.canvas-playback .cpb-bar { display: flex; align-items: center; gap: 8px; min-height: 48px; padding: 0 12px 0 16px; border-top: 1px solid var(--owb-border); color: var(--owb-text); font-size: 12px; }
.canvas-playback .cpb-now { font-weight: 600; white-space: nowrap; }
.canvas-playback .cpb-note { min-width: 0; overflow: hidden; color: var(--owb-text-3); text-overflow: ellipsis; white-space: nowrap; }
.canvas-playback .cpb-spacer { flex: 1; }
@media (max-width: 640px) {
  .canvas-page .ctl-meta > span:nth-child(2) { display: none; }
  .canvas-playback { padding: 12px; }
}
.im-group-policy { display: grid; grid-template-columns: 110px minmax(0, 1fr); align-items: center; gap: 7px 9px; margin-top: 8px; padding: 9px 10px; border: 1px solid color-mix(in srgb, var(--owb-brand) 18%, var(--owb-border)); border-radius: var(--radius-md); background: color-mix(in srgb, var(--owb-brand) 4%, var(--owb-bg)); color: var(--owb-text-2); font-size: 12px; }
.im-group-policy select { min-width: 0; height: 30px; padding: 0 8px; border: 1px solid var(--owb-border); border-radius: var(--radius-sm); background: var(--owb-bg); color: var(--owb-text); font: inherit; }
.im-group-policy small { grid-column: 1 / -1; color: var(--owb-text-3); font-size: 11px; line-height: 1.45; }
.canvas-media-lightbox { position: fixed; z-index: 1200; inset: 0; display: flex; align-items: center; justify-content: center; padding: 28px; background: rgba(8, 9, 12, .76); opacity: 0; transition: opacity .16s var(--owb-ease); }
.canvas-media-lightbox.is-open { opacity: 1; }
.canvas-media-lightbox-card { width: min(1120px, 94vw); max-height: 92vh; overflow: hidden; border: 1px solid color-mix(in srgb, var(--primary-foreground) 18%, transparent); border-radius: var(--radius-xl); background: var(--owb-bg); box-shadow: 0 24px 80px rgba(0, 0, 0, .42); }
.canvas-media-lightbox-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 44px; padding: 0 12px 0 16px; border-bottom: 1px solid var(--owb-border); color: var(--owb-text); }
.canvas-media-lightbox-head b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
.canvas-media-lightbox-close { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border: 0; border-radius: 50%; background: transparent; color: var(--owb-text-2); cursor: pointer; }
.canvas-media-lightbox-close:hover { background: var(--owb-bg-hover); color: var(--owb-text); }
.canvas-media-lightbox-close .i { width: 17px; height: 17px; }
.canvas-media-lightbox-stage { display: flex; align-items: center; justify-content: center; min-height: min(68vh, 720px); max-height: calc(92vh - 45px); padding: 18px; background: var(--secondary); }
.canvas-media-lightbox-stage img { display: block; max-width: 100%; max-height: calc(92vh - 90px); object-fit: contain; }
.canvas-page:fullscreen .canvas-viewport { height: calc(100vh - 90px - var(--cp-h, 0px)); }
/* ---------- 执行追踪（更多 → 执行追踪，整页） ---------- */
/* 这块原来长在设置页那条窄栏里：字号被压到 9–10px、列表限高 330px、工具名和路径挤在
   同一行里被省略号切掉，结果就是「看不出调了什么工具、动了哪个文件」。搬到整页之后按
   正常阅读尺寸重画——左边一列任务，右边是那趟任务的时间线，路径单独占一行完整显示。 */
.tp { display: flex; flex-direction: column; gap: 14px; }
.tp-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tp-bar .tp-grow { flex: 1; }
.tp-note { display: flex; align-items: center; gap: 8px; padding: 9px 12px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg-side); color: var(--owb-text-2); font-size: 12px; }
.tp-note .i { width: 15px; height: 15px; flex: none; color: var(--owb-text-3); }
.tp-note a { margin-left: auto; white-space: nowrap; }
.tp-note.is-on { border-color: color-mix(in srgb, var(--owb-ok) 45%, var(--owb-border)); background: var(--owb-ok-bg); color: var(--owb-ok-text); }
.tp-note.is-warn { border-color: color-mix(in srgb, var(--owb-warn) 45%, var(--owb-border)); background: var(--owb-warn-bg); color: var(--owb-warn-text); }

/* 「还在跑」和「中断」是按需出现的，格子数会在 4 和 6 之间变。写死 5 列会留一个空洞，
   auto-fit 让它自己排匀 */
.tp-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); gap: 10px; }
.tp-stat { display: flex; flex-direction: column; gap: 3px; min-width: 0; padding: 12px 14px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-card); }
.tp-stat b { color: var(--owb-text); font: 600 22px/1.15 inherit; font-variant-numeric: tabular-nums; }
.tp-stat span { color: var(--owb-text-3); font-size: 12px; }
.tp-stat.is-error b { color: var(--owb-err-text); }
.tp-stat.is-run b { color: var(--owb-brand-text); }
.tp-stat.is-stale b { color: var(--owb-warn-text); }

.tp-body { display: grid; grid-template-columns: minmax(260px, 320px) minmax(0, 1fr); gap: 14px; align-items: start; }
.tp-list { display: grid; align-content: start; gap: 8px; max-height: calc(100vh - 290px); overflow-y: auto; scrollbar-gutter: stable; }
.tp-row { display: grid; grid-template-columns: 8px minmax(0, 1fr); align-items: start; gap: 10px; width: 100%; padding: 11px 13px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-card); color: var(--owb-text); text-align: left; cursor: pointer; }
.tp-row:hover { border-color: var(--owb-brand); background: var(--owb-bg-hover); }
.tp-row.on { border-color: var(--owb-brand); background: var(--owb-brand-weak); }
.tp-row i.dot { width: 8px; height: 8px; margin-top: 5px; border-radius: var(--radius-full); background: var(--owb-ok); }
.tp-row.is-error i.dot { background: var(--owb-err); }
.tp-row.is-running i.dot { background: var(--owb-brand); box-shadow: 0 0 0 3px var(--owb-brand-weak); }
/* 开工记了、收尾没记上。用警示色而不是品牌色：它跟「还在跑」长得太像的话，
   用户会一直等一个永远不会亮的绿灯 */
.tp-row.is-stale i.dot { background: var(--owb-warn); }
.tp-rmain { display: block; min-width: 0; }
/* 名字和耗时同一行：耗时靠右不换行，名字吃掉剩下的宽度并省略。
   以前耗时挤在第二行的第一格，扫一列的时候要跳着看 */
.tp-rtop { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.tp-rtop b { flex: 1; }
.tp-rtop em { flex: none; color: var(--owb-text-3); font-style: normal; font-family: var(--mono); font-size: 12px; }
.tp-row b { display: block; overflow: hidden; font-size: 13px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
/* 名字是从用户第一句话里截来的、不是他起的标题：用引号和常规字重标出来，
   免得「随便做点什么」看着像个正式任务名 */
.tp-row b.is-said, .tp-dhead b.is-said { font-weight: 500; font-style: normal; color: var(--owb-text-2); }
.tp-row b.is-said::before, .tp-dhead b.is-said::before { content: "\201C"; }
.tp-row b.is-said::after, .tp-dhead b.is-said::after { content: "\201D"; }
.tp-row .tp-meta { display: flex; flex-wrap: wrap; gap: 4px 10px; margin-top: 5px; color: var(--owb-text-3); font-size: 12px; }
.tp-row .tp-meta > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.tp-row .tp-meta em { font-style: normal; font-family: var(--mono); }
.tp-row .tp-rst { padding: 0 7px; border-radius: var(--radius-full); background: var(--owb-bg-side); color: var(--owb-text-2); }
.tp-row.is-error .tp-rst { background: var(--owb-err-bg); color: var(--owb-err-text); }
.tp-row.is-stale .tp-rst { background: var(--owb-warn-bg); color: var(--owb-warn-text); }
.tp-row.is-running .tp-rst { background: var(--owb-brand-weak); color: var(--owb-brand-text); }

.tp-detail { border: 1px solid var(--owb-border); border-radius: var(--radius-xl); background: var(--owb-card); overflow: hidden; }
.tp-dhead { display: flex; align-items: flex-start; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--owb-border); }
.tp-dhead > div { min-width: 0; }
.tp-dhead b { display: block; font-size: 15px; font-weight: 600; }
.tp-dhead small { display: block; margin-top: 3px; overflow: hidden; color: var(--owb-text-3); font: 12px/1.4 var(--mono); text-overflow: ellipsis; white-space: nowrap; }
.tp-pill { flex: none; padding: 3px 10px; border-radius: var(--radius-full); background: var(--owb-ok-bg); color: var(--owb-ok-text); font-size: 12px; white-space: nowrap; }
.tp-pill.is-error { background: var(--owb-err-bg); color: var(--owb-err-text); }
.tp-pill.is-running { background: var(--owb-brand-weak); color: var(--owb-brand-text); }
.tp-pill.is-stale { background: var(--owb-warn-bg); color: var(--owb-warn-text); }
.tp-sum { display: grid; grid-template-columns: repeat(auto-fit, minmax(104px, 1fr)); gap: 1px; background: var(--owb-border); border-bottom: 1px solid var(--owb-border); }
.tp-sum > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: 11px 14px; background: var(--owb-bg); }
.tp-sum b { overflow: hidden; color: var(--owb-text); font-size: 15px; font-variant-numeric: tabular-nums; text-overflow: ellipsis; white-space: nowrap; }
.tp-sum span { color: var(--owb-text-3); font-size: 11px; }
.tp-models { display: flex; flex-wrap: wrap; gap: 5px; padding: 10px 16px; border-bottom: 1px solid var(--owb-border); color: var(--owb-text-3); font-size: 12px; }
.tp-models i { padding: 2px 9px; border-radius: var(--radius-full); background: var(--owb-brand-weak); color: var(--owb-brand-text); font: normal 12px/1.5 var(--mono); }

.tp-steps { display: grid; gap: 8px; padding: 14px 16px; }
.tp-steps-label { display: flex; align-items: center; justify-content: space-between; gap: 10px; color: var(--owb-text-3); font-size: 12px; }
.tp-step { --trace-depth: 0; margin-left: calc(var(--trace-depth) * 20px); border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg); }
.tp-step.is-error { border-color: color-mix(in srgb, var(--owb-err) 50%, var(--owb-border)); }
.tp-step > summary { display: grid; grid-template-columns: 26px auto minmax(0, 1fr) auto; align-items: center; gap: 10px; padding: 10px 13px; cursor: pointer; list-style: none; }
.tp-step > summary::-webkit-details-marker { display: none; }
.tp-step > summary:hover { background: var(--owb-bg-hover); border-radius: var(--radius-lg); }
.tp-no { color: var(--owb-text-3); font: 12px/1 var(--mono); text-align: right; }
.tp-kind { padding: 2px 8px; border-radius: var(--radius-full); font-size: 11px; white-space: nowrap; }
.tp-kind.is-tool { background: var(--owb-bg-side); color: var(--owb-text-2); }
.tp-kind.is-model { background: var(--owb-brand-weak); color: var(--owb-brand-text); }
.tp-kind.is-agent { background: var(--owb-violet-bg); color: var(--owb-violet-text); }
.tp-sname { min-width: 0; overflow: hidden; font: 600 13px/1.4 var(--mono); text-overflow: ellipsis; white-space: nowrap; }
.tp-cost { display: flex; align-items: center; gap: 10px; color: var(--owb-text-3); font: 12px/1 var(--mono); white-space: nowrap; }
.tp-cost b { color: var(--owb-text-2); font-weight: 600; }
.tp-step.is-error .tp-cost b { color: var(--owb-err-text); }
/* 路径单独占一行、完整显示：这一行就是「它到底动了哪个文件」的答案，不许被省略号切掉 */
.tp-target { margin: 0 13px 9px 49px; color: var(--owb-text-2); font: 12px/1.6 var(--mono); overflow-wrap: anywhere; }
.tp-bar-line { height: 3px; margin: 0 13px 10px 49px; border-radius: var(--radius-full); background: var(--owb-border); }
.tp-bar-line > i { display: block; height: 100%; border-radius: var(--radius-full); background: var(--owb-brand); }
.tp-step.is-error .tp-bar-line > i { background: var(--owb-err); }
.tp-err { margin: 0 13px 10px 49px; padding: 8px 10px; border-radius: var(--radius-md); background: var(--owb-err-bg); color: var(--owb-err-text); font-size: 12px; white-space: pre-wrap; overflow-wrap: anywhere; }
.tp-fold { margin: 0 13px 10px 49px; }
.tp-fold details { margin-top: 6px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: var(--owb-card); }
.tp-fold summary { padding: 7px 10px; color: var(--owb-text-2); cursor: pointer; font-size: 12px; }
.tp-fold pre { max-height: 300px; margin: 0; padding: 0 10px 9px; overflow: auto; scrollbar-gutter: stable; color: var(--owb-text-2); font: 12px/1.65 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; }
.tp-io { padding: 0 16px 16px; }
.tp-io details { border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg); }
.tp-io summary { padding: 10px 13px; color: var(--owb-text-2); cursor: pointer; font-size: 13px; }
.tp-io pre { max-height: 340px; margin: 0; padding: 0 13px 11px; overflow: auto; scrollbar-gutter: stable; color: var(--owb-text-2); font: 12px/1.7 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; }
.tp-io details.is-final { border-color: color-mix(in srgb, var(--owb-ok) 40%, var(--owb-border)); background: color-mix(in srgb, var(--owb-ok) 5%, var(--owb-bg)); }
.tp-empty { padding: 28px 16px; color: var(--owb-text-3); font-size: 13px; text-align: center; }
@media (max-width: 1080px) {
  .tp-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .tp-body { grid-template-columns: minmax(0, 1fr); }
  .tp-list { max-height: 260px; }
}
/* ---------- 评测（更多 → 评测，整页） ---------- */
/* 这页原来整个是内联样式堆出来的：开门第一屏是一段 13px 的灰字，把「三条评分线怎么打分」
   压成一整坨没人读得完的话；三个下拉挤在标题行里换行乱飞；历史成绩十列表格上下内边距
   只有 6px，密到看不出哪行是哪行；明细卡片里颜色全靠 style 现写，深浅两套主题各飘各的。
   重画的思路很直白：跑一轮的控件归一张卡、怎么打分的解释拆成三张扫一眼就懂的小卡、
   成绩表按正常行高喘口气、明细做成一张有头有脸的面板。 */
.ev { display: flex; flex-direction: column; gap: 18px; }
.ev-sec { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; color: var(--owb-text); font-size: 14px; font-weight: 600; }
.ev-sec span { color: var(--owb-text-3); font-size: 12px; font-weight: 400; }

/* 跑一轮：三个下拉一人一格、标签在上，按钮和状态跟在同一条基线上 */
.ev-run { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px 14px; padding: 15px 16px; border: 1px solid var(--owb-border); border-radius: var(--radius-xl); background: var(--owb-card); }
.ev-f { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.ev-f > span { color: var(--owb-text-3); font-size: 12px; }
.ev-f select { min-width: 168px; }
.ev-run .btn-brand { white-space: nowrap; }
.ev-run .btn-brand.is-arm { background: var(--owb-err); border-color: var(--owb-err); }
.ev-state { display: flex; align-items: center; gap: 6px; color: var(--owb-text-3); font-size: 13px; }
.ev-run-note { flex: 1 1 260px; min-width: 0; color: var(--owb-text-3); font-size: 12px; line-height: 1.7; }
.ev-run-note b { color: var(--owb-warn-text); font-weight: 600; }
.ev-run-note code { padding: 1px 6px; border-radius: var(--radius-xs); background: var(--owb-bg-side); font: 12px/1.5 var(--mono); }

/* 三条评分线：原来是一段话里的三个加粗词，现在一人一张卡，各自说清「凭什么算过」 */
.ev-lines { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.ev-line p .link { margin-left: 4px; overflow-wrap: anywhere; }
.ev-line p .i { width: 12px; height: 12px; vertical-align: -1px; }
.ev-line { display: flex; flex-direction: column; gap: 5px; padding: 13px 15px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg-side); }
.ev-line b { display: flex; align-items: center; gap: 7px; color: var(--owb-text); font-size: 13px; font-weight: 600; }
.ev-line b .i { width: 15px; height: 15px; color: var(--owb-text-3); }
.ev-line p { margin: 0; color: var(--owb-text-2); font-size: 12px; line-height: 1.75; }
.ev-line p em { font-style: normal; color: var(--owb-text-3); }

/* 跑批日志：黑底终端那套在浅色主题下是个突兀的黑洞，跟别处一样走卡片底色 */
.ev-log { max-height: 320px; margin: 0; padding: 12px 14px; overflow: auto; scrollbar-gutter: stable; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg-side); color: var(--owb-text-2); font: 12px/1.8 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; }

/* 历史成绩 */
.ev-bl { display: flex; align-items: center; gap: 7px; margin-bottom: 9px; color: var(--owb-text-3); font-size: 12px; }
.ev-bl .i { width: 14px; height: 14px; }
.ev-bl code { padding: 1px 6px; border-radius: var(--radius-xs); background: var(--owb-bg-side); font: 12px/1.5 var(--mono); }
.ev-tab-wrap { overflow-x: auto; scrollbar-gutter: stable; border: 1px solid var(--owb-border); border-radius: var(--radius-xl); background: var(--owb-card); }
.ev-tab { width: 100%; border-collapse: collapse; font-size: 13px; }
.ev-tab th { padding: 10px 12px; color: var(--owb-text-3); font-size: 12px; font-weight: 500; text-align: left; white-space: nowrap; border-bottom: 1px solid var(--owb-border); }
.ev-tab td { padding: 11px 12px; border-top: 1px solid var(--owb-border); white-space: nowrap; }
.ev-tab tbody tr { cursor: pointer; }
.ev-tab tbody tr:hover { background: var(--owb-bg-hover); }
.ev-tab tbody tr.on { background: var(--owb-brand-weak); }
.ev-tab .num { font-variant-numeric: tabular-nums; }
.ev-tab .score { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }
.ev-tab .score.is-ok { color: var(--owb-ok-text); }
.ev-tab .score.is-bad { color: var(--owb-err-text); }
.ev-tab code { color: var(--owb-text-3); font: 12px/1.5 var(--mono); }
.ev-up { color: var(--owb-ok-text); }
.ev-down { color: var(--owb-err-text); }
.ev-flaky { color: var(--owb-warn-text); }
.ev-empty { padding: 26px 16px; border: 1px dashed var(--owb-border); border-radius: var(--radius-xl); color: var(--owb-text-3); font-size: 13px; line-height: 1.8; text-align: center; }
.ev-empty code { padding: 1px 6px; border-radius: var(--radius-xs); background: var(--owb-bg-side); font-family: var(--mono); }

/* 单轮明细 */
.ev-det { border: 1px solid var(--owb-border); border-radius: var(--radius-xl); background: var(--owb-card); overflow: hidden; }
.ev-det-head { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--owb-border); }
.ev-det-head b { font-size: 15px; font-weight: 600; }
.ev-det-head .ev-det-ops { display: flex; align-items: center; gap: 12px; margin-left: auto; }
.ev-sum { display: grid; grid-template-columns: repeat(auto-fit, minmax(108px, 1fr)); gap: 1px; background: var(--owb-border); border-bottom: 1px solid var(--owb-border); }
.ev-sum > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: 11px 14px; background: var(--owb-bg); }
.ev-sum b { overflow: hidden; color: var(--owb-text); font-size: 15px; font-variant-numeric: tabular-nums; text-overflow: ellipsis; white-space: nowrap; }
.ev-sum b.is-ok { color: var(--owb-ok-text); }
.ev-sum b.is-bad { color: var(--owb-err-text); }
.ev-sum span { color: var(--owb-text-3); font-size: 11px; }
.ev-tasks { display: grid; gap: 10px; padding: 14px 16px; }
.ev-task { border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg); }
.ev-task.is-bad { border-color: color-mix(in srgb, var(--owb-err) 45%, var(--owb-border)); }
.ev-task.is-flaky { border-color: color-mix(in srgb, var(--owb-warn) 45%, var(--owb-border)); }
.ev-task-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; padding: 11px 14px; }
.ev-task-head > .i { width: 17px; height: 17px; }
.ev-task-head .nm { font-size: 13px; font-weight: 600; }
.ev-task.is-bad .ev-task-head > .i { color: var(--owb-err-text); }
.ev-task.is-flaky .ev-task-head > .i { color: var(--owb-warn-text); }
.ev-task:not(.is-bad):not(.is-flaky) .ev-task-head > .i { color: var(--owb-ok-text); }
.ev-lv { padding: 2px 8px; border: 1px solid var(--owb-border); border-radius: var(--radius-full); background: var(--owb-bg-side); color: var(--owb-text-3); font-size: 11px; white-space: nowrap; }
.ev-code { padding: 2px 9px; border-radius: var(--radius-full); background: var(--owb-err-bg); color: var(--owb-err-text); font-size: 11px; white-space: nowrap; }
.ev-tries { display: inline-flex; gap: 4px; }
.ev-try { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: var(--radius-xs); background: var(--owb-ok-bg); color: var(--owb-ok-text); }
.ev-try.is-bad { background: var(--owb-err-bg); color: var(--owb-err-text); }
.ev-try .i { width: 12px; height: 12px; }
.ev-facts { color: var(--owb-text-3); font-size: 12px; font-variant-numeric: tabular-nums; }
.ev-rate { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.ev-stars { display: inline-flex; gap: 1px; }
.ev-star { padding: 2px; border: none; background: none; color: var(--owb-text-3); cursor: pointer; line-height: 0; }
.ev-star .i { width: 16px; height: 16px; }
.ev-star:hover { color: var(--owb-warn); }
.ev-star.on { color: var(--owb-warn); }
.ev-star.on .i { fill: currentColor; }
.ev-cmt { width: 148px; padding: 5px 9px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: var(--owb-bg-side); color: var(--owb-text); font-size: 12px; }
.ev-chks { display: grid; gap: 4px; padding: 0 14px 12px; }
.ev-chk { display: flex; align-items: flex-start; gap: 7px; color: var(--owb-ok-text); font-size: 12px; line-height: 1.6; }
.ev-chk.is-bad { color: var(--owb-err-text); }
.ev-chk .i { width: 14px; height: 14px; margin-top: 2px; }
.ev-chk em { font-style: normal; color: var(--owb-text-3); }
.ev-judge { margin: 0 14px 12px; padding: 10px 12px; border-radius: var(--radius-md); background: var(--owb-bg-side); font-size: 12px; }
.ev-judge > b { display: flex; align-items: center; gap: 7px; margin-bottom: 6px; color: var(--owb-text-2); font-weight: 600; }
.ev-judge > b .i { width: 14px; height: 14px; }
.ev-judge .ev-chk { padding: 1px 0; }
.ev-judge .note { color: var(--owb-text-3); line-height: 1.7; }
.ev-judge .cut { color: var(--owb-err-text); line-height: 1.7; }
.ev-final { margin: 0 14px 12px; }
.ev-final summary { color: var(--owb-text-3); font-size: 12px; cursor: pointer; }
.ev-final pre { max-height: 220px; margin: 6px 0 0; padding: 10px 12px; overflow: auto; scrollbar-gutter: stable; border-radius: var(--radius-md); background: var(--owb-bg-side); color: var(--owb-text-2); font: 12px/1.75 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; }
/* 评测：自评警告、评委提示词编辑器 */
.ev-self { flex-basis: 100%; display: flex; align-items: center; gap: 6px; color: var(--owb-warn-text); font-size: 12px; }
.ev-self[hidden] { display: none; }
.ev-self .i { width: 14px; height: 14px; }
.ev-jp { display: flex; flex-direction: column; gap: 8px; padding: 15px 16px; border: 1px solid var(--owb-border); border-radius: var(--radius-xl); background: var(--owb-card); }
.ev-jp[hidden] { display: none; }
.ev-jp-head { display: flex; align-items: center; gap: 10px; }
.ev-jp-head b { display: flex; align-items: center; gap: 7px; font-size: 14px; }
.ev-jp-head .i { width: 15px; height: 15px; }
.ev-jp-head .link { margin-left: auto; }
.ev-jp-note { margin: 0; color: var(--owb-text-3); font-size: 12px; line-height: 1.7; }
.ev-jp-lab { display: flex; align-items: baseline; gap: 8px; margin-top: 6px; color: var(--owb-text); font-size: 13px; font-weight: 600; }
.ev-jp-lab span { color: var(--owb-text-3); font-size: 12px; font-weight: 400; }
.ev-jp textarea { width: 100%; box-sizing: border-box; resize: vertical; font: 12px/1.75 var(--mono); }
.ev-jp-dim { display: flex; gap: 6px; margin-bottom: 6px; }
.ev-jp-dim input { flex: 1; min-width: 0; font-size: 12px; }
.ev-jp-dim .btn-plain { padding: 4px 8px; line-height: 0; }
.ev-jp .ev-final { margin: 4px 0 0; }
.ev-jp-ops { display: flex; align-items: center; gap: 10px; margin-top: 4px; }
/* 明细：多维成绩 */
.ev-dims-wrap { padding: 14px 16px 4px; border-bottom: 1px solid var(--owb-border); }
.ev-dims { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px; }
.ev-dim { padding: 10px 12px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg); min-width: 0; }
.ev-dim .k { display: flex; align-items: center; gap: 6px; color: var(--owb-text-3); font-size: 12px; }
.ev-dim .k .i { width: 13px; height: 13px; }
.ev-dim .v { margin: 4px 0 2px; color: var(--owb-text); font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; }
.ev-dim.is-bad .v { color: var(--owb-err-text); }
.ev-dim .s { color: var(--owb-text-3); font-size: 11px; line-height: 1.6; }
.ev-split { margin: 10px 0; }
.ev-split summary { color: var(--owb-text-3); font-size: 12px; cursor: pointer; }
.ev-split-in { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px; margin-top: 8px; }
.ev-rej { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; padding: 10px 16px; border-bottom: 1px solid var(--owb-border); color: var(--owb-text-3); font-size: 12px; }
.ev-rej > .i { width: 14px; height: 14px; }
.ev-rej > span { flex: 1 1 260px; min-width: 0; }
.ev-rej select { min-width: 140px; }
.ev-rej .btn-plain.is-arm { border-color: var(--owb-err); color: var(--owb-err-text); }
.ev-filt { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; padding: 12px 16px 0; }
.ev-filt button { padding: 4px 11px; border: 1px solid var(--owb-border); border-radius: var(--radius-full); background: var(--owb-bg); color: var(--owb-text-2); font-size: 12px; cursor: pointer; }
.ev-filt button em { font-style: normal; color: var(--owb-text-3); font-variant-numeric: tabular-nums; }
.ev-filt button.on { border-color: var(--owb-brand); background: var(--owb-brand-weak); color: var(--owb-brand-text); }
.ev-filt-tip { margin-left: auto; color: var(--owb-text-3); font-size: 12px; }
.ev-code.is-warn { background: var(--owb-warn-bg, color-mix(in srgb, var(--owb-warn) 15%, transparent)); color: var(--owb-warn-text); }
.ev-agree { color: var(--owb-text-3); }
.ev-agree.is-bad { color: var(--owb-err-text); }
/* 明细：每题三块（机器 / 质量维度 / 人工）+ 证据 */
.ev-block { margin: 0 14px 10px; }
.ev-block-h { display: flex; align-items: center; gap: 6px; margin-bottom: 5px; color: var(--owb-text-2); font-size: 12px; font-weight: 600; }
.ev-block-h .i { width: 13px; height: 13px; }
.ev-block-h span { color: var(--owb-text-3); font-weight: 400; }
.ev-block .ev-chks { padding: 0; }
.ev-dimrow { display: flex; align-items: flex-start; gap: 8px; padding: 4px 6px; border-radius: var(--radius-sm, 4px); font-size: 12px; line-height: 1.6; }
.ev-dimrow.is-clash { background: color-mix(in srgb, var(--owb-warn) 12%, transparent); }
.ev-dimrow .q { flex: 1; min-width: 0; color: var(--owb-text); }
.ev-dimrow .q em { font-style: normal; color: var(--owb-text-3); }
.ev-tag { margin-right: 6px; padding: 0 6px; border-radius: var(--radius-full); background: var(--owb-bg-side); color: var(--owb-text-3); font-size: 11px; }
.ev-jv { display: inline-flex; align-items: center; gap: 2px; flex: none; min-width: 30px; margin-top: 2px; color: var(--owb-ok-text); }
.ev-jv.is-bad { color: var(--owb-err-text); }
.ev-jv.none { color: var(--owb-text-3); }
.ev-jv .i { width: 14px; height: 14px; }
.ev-hv { display: inline-flex; flex: none; gap: 2px; }
.ev-hv button { padding: 2px 5px; border: 1px solid var(--owb-border); border-radius: var(--radius-sm, 4px); background: var(--owb-bg); color: var(--owb-text-3); cursor: pointer; line-height: 0; }
.ev-hv button .i { width: 13px; height: 13px; }
.ev-hv button.on { border-color: var(--owb-ok-text); background: var(--owb-ok-bg); color: var(--owb-ok-text); }
.ev-hv button.on.bad { border-color: var(--owb-err-text); background: var(--owb-err-bg); color: var(--owb-err-text); }
.ev-human { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; }
.ev-human .ev-block-h { margin: 0; }
.ev-human .ev-cmt { flex: 1 1 220px; width: auto; }
.ev-evid { display: flex; flex-direction: column; gap: 6px; padding-bottom: 6px; }
.ev-evid .ev-final { margin: 0 14px; }
.ev-steps { max-height: 280px; margin-top: 6px; overflow: auto; padding: 6px 10px; border-radius: var(--radius-md); background: var(--owb-bg-side); font-size: 12px; }
.ev-step { display: grid; grid-template-columns: 26px 110px minmax(0, 1fr) minmax(0, 1fr); gap: 8px; padding: 3px 0; align-items: baseline; }
.ev-step b { color: var(--owb-text-3); font-weight: 500; font-variant-numeric: tabular-nums; }
.ev-step .nm { color: var(--owb-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-step code { overflow: hidden; color: var(--owb-text-2); font: 11px/1.6 var(--mono); text-overflow: ellipsis; white-space: nowrap; }
.ev-step .out { overflow: hidden; color: var(--owb-text-3); text-overflow: ellipsis; white-space: nowrap; }
.ev-step.is-bad .out { color: var(--owb-err-text); }
.ev-step.sub { padding-left: 14px; }
.ev-step.more { display: block; color: var(--owb-text-3); }
.ev-arts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.ev-art { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border: 1px solid var(--owb-border); border-radius: var(--radius-full); color: var(--owb-text-2); font-size: 12px; text-decoration: none; }
.ev-art .i { width: 13px; height: 13px; }
.ev-art em { font-style: normal; color: var(--owb-text-3); }
.ev-art:hover { border-color: var(--owb-brand); color: var(--owb-brand-text); }
@media (max-width: 1080px) {
  .ev-lines { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ev-step { grid-template-columns: 26px 90px minmax(0, 1fr); }
  .ev-step .out { grid-column: 3; }
  .ev-f select { min-width: 140px; }
}

/* ---------- 模型与 Key（设置 → 模型） ----------
   老版本这一页是「渠道优先」的：顶上五个只能看的小格，底下一长串渠道卡，媒体那四路再吊在最后。
   可文本、语音、视频、图像每一路都可能要配好几个渠道、好几个模型——
   人脑子里的单位是「能力」，不是「渠道」。渠道只是那把 Key 住的地方。
   所以改成能力优先：顶上六格说清「现在在用谁、还压着几个备选」，中间六张卡一路一张
   （对话和看图/画图/视频/配音/转写长一个样），最后才是渠道与 Key 那一段。
   六格现在是按钮：点哪一路就展开哪一路——原来那五格看完只能干瞪眼，而人看完第一反应就是想改它。 */
.model-route-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.model-route-head > div { display: flex; flex-direction: column; gap: 3px; }
.model-route-head b { color: var(--owb-text); font-size: 15px; }
.model-route-head > div > span { color: var(--owb-text-3); font-size: 12px; line-height: 1.6; }
.model-route-head > span { flex: none; padding: 4px 10px; border-radius: var(--radius-full); background: var(--owb-brand-weak); color: var(--owb-brand-text); font-size: 12px; white-space: nowrap; }

/* 六格两行，一行三个。挤成一行六个的话每格只剩 110px，模型名一律省略号，等于白写 */
.model-route-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-bottom: 10px; }
.model-route-grid .rt { display: flex; flex-direction: column; align-items: stretch; min-width: 0; padding: 10px 12px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg-side); text-align: left; cursor: pointer; font: inherit; color: inherit; }
.model-route-grid .rt:hover { border-color: color-mix(in srgb, var(--owb-brand) 50%, var(--owb-border)); background: var(--owb-bg-hover); }
.model-route-grid .rt.is-primary { border-color: color-mix(in srgb, var(--owb-brand) 45%, var(--owb-border)); background: var(--owb-brand-weak); }
.model-route-grid .rt-k { display: flex; align-items: center; gap: 5px; color: var(--owb-text-3); font-size: 11px; }
.model-route-grid .rt-k .i { width: 13px; height: 13px; }
.model-route-grid b, .model-route-grid small, .model-route-grid i { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.model-route-grid b { margin-top: 7px; color: var(--owb-text); font-size: 13px; font-weight: 600; }
.model-route-grid small { margin-top: 3px; color: var(--owb-text-3); font-family: var(--mono); font-size: 11px; }
.model-route-grid i { margin-top: 5px; color: var(--owb-brand-text); font-size: 11px; font-style: normal; }
/* 这一路一个都没配：主名字降成灰的，别让「未设置」看着像个模型名 */
.model-route-grid .rt.is-empty b { color: var(--owb-text-3); font-weight: 400; }
.model-route-grid .rt.is-empty small { font-family: inherit; }

.model-route-warn { display: flex; align-items: flex-start; gap: 7px; margin-bottom: 8px; padding: 9px 12px; border: 1px solid color-mix(in srgb, var(--owb-warn) 40%, transparent); border-radius: var(--radius-lg); background: color-mix(in srgb, var(--owb-warn) 8%, transparent); color: var(--owb-warn); font-size: 12px; line-height: 1.7; }
.model-route-warn .i { flex: none; width: 14px; height: 14px; margin-top: 3px; }
.model-route-note { margin-bottom: 18px; padding: 9px 12px; border-left: 2px solid var(--owb-brand); background: color-mix(in srgb, var(--owb-brand) 5%, transparent); color: var(--owb-text-3); font-size: 12px; line-height: 1.7; }

/* 两段小标题：「按能力配置」和「渠道与 Key」。这一页最要紧的一件事就是让人看懂
   「上面挑模型、下面填 Key」是两件事——老版本这两段之间什么分隔都没有。
   标题本身复用全站那个 .hub-sec-title，这儿只补一条：右侧那颗「添加渠道」推到行尾 */
.settings-pane .hub-sec-title { align-items: baseline; }
.settings-pane .hub-sec-title > .i { align-self: center; }
.settings-pane .hub-sec-title .sub { min-width: 0; line-height: 1.6; }
.mm-sec-act { flex: none; margin: 0 0 0 auto; }

/* 能力卡头上那颗图标：对话 / 看图 / 画图… 六张卡一眼扫下来靠它区分，不靠读字 */
.cap-ic { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: var(--radius-sm); background: var(--owb-bg-side); color: var(--owb-text-2); }
.cap-ic .i { width: 13px; height: 13px; }
.ch-card.open .cap-ic { background: var(--owb-brand-weak); color: var(--owb-brand-text); }
.ch-count.is-empty { color: var(--owb-text-3); opacity: .75; }
/* 正在用的那一行加一点底色：一张卡里五六行，光靠一个选中的单选钮找不出是哪行 */
.mrow.is-on { margin: 0 -8px; padding-right: 8px; padding-left: 8px; border-radius: var(--radius-md); background: var(--owb-brand-weak); }
.mrow.is-on + .mrow { border-top-color: transparent; }
/* 挂错家的型号：本机没有那家渠道，自愈挪不动，只能在它头上挂一行。
   红字压在行**上面**而不是行里：行里那几列是等宽对齐的，塞一句长话进去会把整张表挤歪 */
.mrow-bad { margin-top: 6px; border-left: 3px solid var(--owb-warn); padding-left: 8px; color: var(--owb-warn-text); background: var(--owb-warn-bg); border-radius: var(--radius-sm); }

/* 渠道测活：折起来时看头上那颗点，展开时看底下那一整句 */
.ch-pill { display: inline-flex; flex: none; align-items: center; gap: 4px; margin-left: 2px; padding: 2px 8px; border-radius: var(--radius-full); font-size: 11px; white-space: nowrap; }
.ch-pill .i { width: 12px; height: 12px; }
.ch-pill.is-ok { background: var(--owb-ok-bg); color: var(--owb-ok-text); }
.ch-pill.is-bad { background: color-mix(in srgb, var(--owb-err) 14%, transparent); color: var(--owb-err-text); }
.ch-pill.is-run { background: var(--owb-bg-side); color: var(--owb-text-3); }
.ch-pill.is-half { background: var(--owb-bg-side); color: var(--owb-text-2); }
.ch-res { display: flex; align-items: flex-start; gap: 7px; margin: 0 0 10px; padding: 9px 12px; border-radius: var(--radius-lg); font-size: 12px; line-height: 1.75; }
.ch-res .i { flex: none; width: 14px; height: 14px; margin-top: 3px; }
.ch-res code { padding: 1px 5px; border-radius: var(--radius-xs); background: color-mix(in srgb, currentColor 10%, transparent); font-family: var(--mono); font-size: 11px; }
.ch-res.is-ok { background: color-mix(in srgb, var(--owb-ok) 9%, transparent); color: var(--owb-ok-text); }
.ch-res.is-bad { background: color-mix(in srgb, var(--owb-err) 9%, transparent); color: var(--owb-err-text); }
.ch-key .ck-test { margin: 0; }

/* 「主模型出故障时换哪个」：从 设置 → 智能体 挪过来的，落在对话卡最底下 */
.ch-fb { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--owb-border); }
.ch-fb label { flex: none; color: var(--owb-text-2); font-size: 12px; }
.ch-fb select { min-width: 220px; margin: 0; }
.ch-fb > span { flex: 1 1 100%; color: var(--owb-text-3); font-size: 12px; line-height: 1.7; }

/* 自定义模型「它会什么」。勾错了只影响提醒，所以说明写在同一行，不另起一段吓人 */
.ca-caps { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin-bottom: 8px; font-size: 12px; }
.ca-caps > span { color: var(--owb-text-2); }
.ca-caps label { display: inline-flex; align-items: center; gap: 5px; color: var(--owb-text); cursor: pointer; }
.ca-caps input { margin: 0; }
.ca-caps em { flex: 1 1 100%; color: var(--owb-text-3); font-size: 11px; font-style: normal; line-height: 1.6; }


.hub-install-box { margin: 4px 0 14px !important; border-color: color-mix(in srgb, var(--owb-brand) 42%, var(--owb-border)); background: linear-gradient(135deg, color-mix(in srgb, var(--owb-brand) 6%, var(--owb-bg)), var(--owb-bg)); }
/* MCP 卡片里的路径与启动错误来自外部进程，长度不可控：必须在卡片内折行，不能挤开操作区。 */
.mcp-server-card { min-width: 0; overflow: hidden; }
.mcp-server-card .nm, .mcp-server-card .tg, .mcp-server-card .ops { min-width: 0; }
/* 3 行 × 1.55 = 4.65em。写成 3.7em 会把第三行从字中间横切开，看着像被遮住了。 */
.mcp-server-command { max-height: 4.65em; overflow: auto; overflow-wrap: anywhere; word-break: break-word; line-height: 1.55; scrollbar-width: thin; }
.mcp-server-card .tg { align-items: flex-start; }
/* 失败原因带着进程死前的 stderr，两三百字是常事：给它整块红底，先显三行，点一下展开全文。 */
.ex-card .mcp-server-error { flex: none; max-width: 100%; margin: 0; padding: 7px 9px; border-radius: var(--radius-md); background: var(--owb-err-bg); color: var(--owb-err-text); font-size: 12px; font-style: normal; line-height: 1.6; overflow-wrap: anywhere; word-break: break-word; cursor: default; }
/* 没被裁就不必装得能点：旁边那颗「展开」还在，才算有东西可展 */
.ex-card .mcp-server-error:has(+ .mcp-err-more:not([hidden])) { cursor: pointer; }
/* 夹行数要落在内层：-webkit-line-clamp 只管内容盒高，它自己再带 padding 的话，
   下边那平 padding 会把第四行漏出来一条缝，正是看着像被遮住的那一条。 */
.ex-card .mcp-server-error > span { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 3; }
.ex-card .mcp-server-error.open { max-height: 240px; overflow: auto; cursor: default; }
.ex-card .mcp-server-error.open > span { display: block; }
.ex-card .mcp-err-more { align-self: flex-start; margin: -4px 0 0; padding: 0; border: 0; background: none; color: var(--owb-err-text); font-size: 12px; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.mcp-server-card .ops { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; justify-content: flex-end; margin-top: auto; }
.mcp-switch { display: inline-flex; align-items: center; gap: 5px; margin-right: auto; color: var(--owb-text-2); font-size: 12px; }
.mcp-switch input { accent-color: var(--owb-brand); }
.mcp-dialog { width: min(720px, calc(100vw - 32px)); max-height: calc(100dvh - 48px); padding: 0; box-sizing: border-box; border: 1px solid var(--owb-border); border-radius: var(--radius-xl); background: var(--owb-bg); color: var(--owb-text); overflow: auto; }
.mcp-dialog::backdrop { background: rgb(0 0 0 / .35); }
.mcp-dialog > .ex-editor, .mcp-dialog-body { margin: 0; padding: 24px; }
.mcp-dialog h2 { margin: 0 0 16px; font-size: 18px; }
.mcp-dialog-content > p { color: var(--owb-text-2); font-size: 13px; line-height: 1.6; }
.mcp-dialog-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 20px; }
.mcp-dialog-error { color: var(--owb-err-text); font-size: 13px; min-height: 1.5em; }
.mcp-key-field { display: flex; align-items: center; gap: 16px; margin: 12px 0; font-size: 13px; }
.mcp-key-field > span { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.mcp-key-field > input, .mcp-key-field > select { width: 55%; padding: 8px 10px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: var(--owb-bg-side); color: var(--owb-text); box-sizing: border-box; }
.mcp-import-row { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--owb-border); cursor: pointer; }
.mcp-import-row span { min-width: 0; overflow-wrap: anywhere; }
.mcp-import-row small { display: block; margin-top: 3px; color: var(--owb-text-2); }
#mcp-category { max-width: 180px; margin-left: auto; padding: 4px 8px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); color: var(--owb-text); background: var(--owb-bg); }
@media (max-width: 500px) {
  .mcp-dialog > .ex-editor, .mcp-dialog-body { padding: 16px; }
  .mcp-key-field { flex-direction: column; align-items: stretch; gap: 6px; }
  .mcp-key-field > input, .mcp-key-field > select { width: 100%; }
}
@media (max-width: 900px) { .model-route-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 900px) {
  .canvas-head { display: block; }
  .canvas-head-actions { margin-top: 12px; }
  .canvas-toolbar-hint { display: none; }
  .canvas-viewport { height: calc(100vh - 280px - var(--cp-h, 0px)); }
  .canvas-layout { grid-template-columns: 1fr; }
  .canvas-inspector { min-height: 260px; max-height: 360px; }
  .canvas-menu-hint { display: none; }
  .canvas-library summary small, .canvas-library-tools span { display: none; }
  .canvas-library-tools { display: block; }
  .canvas-library-tools input { width: 100%; box-sizing: border-box; }
}
.drama-empty h2 { font-size: 18px; }
.drama-empty p { margin: 10px auto 18px; color: var(--owb-text-2); font-size: 13px; line-height: 1.7; }
.drama-empty code { padding: 2px 5px; border-radius: var(--radius-xs); background: var(--owb-bg-side); font-family: var(--font-mono); }
.drama-busy .drama-shot-actions button:disabled { opacity: .58; }
@media (max-width: 900px) {
  .drama-head { display: block; }
  .drama-head-actions { margin-top: 12px; }
  .drama-head-actions select { flex: 1; }
  .drama-toolbar-hint { display: none; }
  .drama-viewport { height: calc(100vh - 280px); }
}

/* ---------- Stat（KPI 卡：标签在上、数字在下、注脚更淡） ---------- */
.ui-stats { display: grid; grid-template-columns: repeat(var(--n, 4), minmax(0, 1fr)); gap: 12px; }
/* 窄了就不认那个列数了，交给 auto-fit：宁可多折一行，也别把卡片挤成一条 */
@media (max-width: 1100px) { .ui-stats { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); } }
@media (max-width: 560px) { .ui-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.ui-stat { padding: 16px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); box-shadow: var(--shadow-surface); }
.ui-stat .l { font-size: 13px; color: var(--muted-foreground); line-height: 1.5; }
.ui-stat .v { margin-top: 6px; font-size: 26px; font-weight: 600; line-height: 1.2; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.ui-stat .h { margin-top: 4px; font-size: 12.5px; color: var(--subtle-foreground); line-height: 1.5; }

/* ---------- Switch（原生 checkbox 在两套主题下颜色不可控，自己画一个） ---------- */
.ui-switch { position: relative; display: inline-block; width: 40px; height: 24px; flex: none; }
.ui-switch input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.ui-switch i {
  position: absolute; inset: 0; border-radius: var(--radius-full); background: var(--input);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--foreground) 6%, transparent);
  transition: background-color .18s var(--owb-ease, ease); pointer-events: none;
}
.ui-switch i::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.18);
  transition: transform .18s var(--owb-ease, ease);
}
.ui-switch input:checked + i { background: var(--primary); }
.ui-switch input:checked + i::after { transform: translateX(16px); }
.ui-switch input:focus-visible + i { box-shadow: 0 0 0 3px var(--ring-weak); }
.ui-switch input:disabled { cursor: not-allowed; }
.ui-switch input:disabled + i { opacity: .5; }

/* ---------- Dialog ---------- */
.ui-overlay {
  position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center; padding: 24px;
  background: color-mix(in srgb, #000 46%, transparent); animation: uiFade .16s var(--owb-ease, ease);
}
.ui-dialog {
  width: 100%; max-width: 480px; max-height: 100%; overflow-y: auto;
  background: var(--popover); color: var(--popover-foreground);
  border: 1px solid var(--border); border-radius: var(--radius-xl);
  box-shadow: var(--shadow-floating); animation: uiPop .18s var(--owb-ease, cubic-bezier(.16,1,.3,1));
}
@keyframes uiFade { from { opacity: 0 } to { opacity: 1 } }
@keyframes uiPop { from { opacity: 0; transform: translateY(8px) scale(.98) } to { opacity: 1; transform: none } }
@media (prefers-reduced-motion: reduce) {
  .ui-overlay, .ui-dialog { animation: none; }
  .ui-progress > i, .ui-switch i, .ui-switch i::after { transition: none; }
}

/* ---- 技能装之前那份体检清单 ----
   刻意长得不像「一个红色警告弹窗」。警告弹窗的下场是被练成肌肉记忆，看都不看就点掉；
   这块东西的全部价值在于让人真的扫一眼哪个文件哪一行，所以做成一份可读的清单：
   文件名和行号在最上面，为什么可疑一句话说清，底下贴原文片段。 */
.sk-scan { margin-top: 8px; border: 1px solid color-mix(in srgb, var(--owb-warn) 40%, var(--owb-border)); border-radius: 10px; background: var(--owb-warn-bg); padding: 10px 12px; font-size: 12px; line-height: 1.55; }
.sk-scan.is-block { border-color: color-mix(in srgb, var(--destructive) 40%, var(--owb-border)); background: var(--owb-err-bg); }
.sk-scan-head { font-weight: 600; color: var(--owb-warn-text); margin-bottom: 8px; }
.sk-scan.is-block .sk-scan-head { color: var(--owb-err-text); }
.sk-scan-row { padding: 7px 0; border-top: 1px solid color-mix(in srgb, var(--owb-border) 60%, transparent); }
.sk-scan-row:first-of-type { border-top: 0; }
.sk-scan-where { font-family: var(--font-mono); font-size: 11px; color: var(--owb-warn-text); }
.sk-scan-row.is-block .sk-scan-where { color: var(--owb-err-text); }
.sk-scan-why { color: var(--owb-text); margin-top: 2px; }
/* 片段要能横着滚：命中的往往是一长行命令，截断了就等于没给人看 */
.sk-scan-ex { margin: 4px 0 0; padding: 5px 7px; border-radius: 6px; background: color-mix(in srgb, var(--owb-bg) 70%, transparent); font-family: var(--font-mono); font-size: 11px; white-space: pre; overflow-x: auto; }
.sk-scan-more, .sk-scan-hosts { margin-top: 6px; font-size: 11px; opacity: .85; }
.sk-scan-foot { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 10px; }
.sk-scan-no { padding: 6px 14px; }
.sk-scan-note { font-size: 11px; opacity: .8; flex: 1 1 200px; }

/* ---- 提示条上的那颗按钮（「撤销」「重试失败的 2 条」） ----
   提示条本身是 pointer-events:none（不挡底下的画布），挂了按钮的那一条才让它接得住点击；
   一消失就又变回穿透，不会在右下角留一块点不透的隐形区域。 */
#owb-toast.show:has(.owb-toast-act) { pointer-events: auto; }
.owb-toast-act { flex: none; margin-left: 4px; padding: 0 8px; min-height: 24px; border: 1px solid color-mix(in srgb, var(--owb-brand-text) 40%, var(--owb-border)); border-radius: var(--radius-sm); background: transparent; color: var(--owb-brand-text); font: inherit; font-weight: 600; white-space: nowrap; cursor: pointer; }
.owb-toast-act:hover { background: var(--owb-bg-hover); }
.owb-toast-act:focus-visible { outline: 2px solid var(--owb-brand-text); outline-offset: 1px; }

/* Sharing settings stay in the conversation flow. */
.session-share-panel { max-width: var(--owb-content-w, 760px); width: calc(100% - 40px); box-sizing: border-box; margin: 12px auto; padding: 16px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg); font-size: 13px; }
.share-head, .share-buttons { display: flex; align-items: center; gap: 10px; }
.share-head { justify-content: space-between; }
.session-share-panel p { color: var(--owb-text-2); margin: 8px 0; line-height: 1.6; }
.share-controls label { display: grid; gap: 6px; }
.share-controls input { min-width: 0; width: 100%; box-sizing: border-box; padding: 8px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); color: var(--owb-text); background: var(--owb-bg-side); }
.share-buttons { margin-top: 10px; flex-wrap: wrap; }
.mcp-oauth-panel { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--owb-border); font-size: 12px; line-height: 1.6; }
.mcp-oauth-panel label { display: grid; gap: 5px; margin-top: 8px; }
.mcp-oauth-panel input { min-width: 0; box-sizing: border-box; width: 100%; padding: 7px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); color: var(--owb-text); background: var(--owb-bg); }
.mcp-oauth-panel details summary { cursor: pointer; color: var(--owb-text-2); }

/* Reviews stay in the task and preserve the surrounding conversation. */
.checkpoint-review { width:100%; min-width:0; padding:12px 0; }
.step-act:has(.checkpoint-review) { flex-wrap:wrap; }
.review-path { overflow-wrap:anywhere; font-family:var(--mono); font-size:12px; }
.review-hunk { margin:10px 0; border:1px solid var(--owb-border); border-radius:8px; overflow:hidden; }
.review-hunk > .step-rewind { margin:6px; }
.review-line { display:block; width:100%; text-align:left; border:0; border-top:1px solid var(--owb-border); background:transparent; color:inherit; white-space:pre-wrap; overflow-wrap:anywhere; font:12px/1.6 var(--mono); padding:4px 10px; cursor:pointer; }
.review-line.d-add { background:rgba(47,140,87,.09); }.review-line.d-del { background:rgba(190,60,60,.09); }
.review-line:focus-visible { outline:2px solid var(--owb-brand-text); outline-offset:-2px; }
.review-note { padding:10px; }.review-note label { display:block; font-size:13px; }.review-note textarea { display:block; width:100%; min-height:65px; box-sizing:border-box; margin:8px 0; resize:vertical; }
.preview-annotation { padding:10px 14px; background:var(--owb-bg-side); border-bottom:1px solid var(--owb-border); flex-shrink:0; }
.preview-annotation p { margin:0 0 8px; font-size:12px; }.preview-annotation label {font-size:13px;display:block;}.preview-annotation textarea {display:block;box-sizing:border-box;width:100%;min-height:55px;margin:5px 0 8px;resize:vertical;}.preview-annotation button {margin-right:8px;}
#pv-body { position:relative; }.annotation-overlay { position:absolute;z-index:10;cursor:crosshair;touch-action:none;background:rgba(80,90,90,.025); }.annotation-mark {position:absolute;pointer-events:none;border:2px solid var(--owb-brand-text);background:rgba(40,120,100,.12);box-sizing:border-box;}
#task-billing-scope { max-width:160px;font:inherit;font-size:12px;border:0;background:transparent;color:var(--owb-text-2);padding:4px; }#task-billing-control[hidden],#task-billing-cost[hidden] {display:none!important;}
.browser-recording label {display:block;font-size:13px;margin:10px 0;}.browser-recording input,.browser-recording textarea {display:block;box-sizing:border-box;width:100%;margin-top:5px;padding:8px;border:1px solid var(--owb-border);border-radius:6px;background:var(--owb-bg);color:inherit;}.browser-recording textarea {font:12px/1.6 var(--mono);resize:vertical;}

/* 创作画布：常用入口始终可见，次要操作按需展开。 */
.canvas-page .canvas-head { min-height: 40px; align-items: center; gap: 12px; padding-bottom: 8px; }
.canvas-page .canvas-head-actions { align-items: center; gap: 5px; }
.canvas-workflow-menu, .canvas-view-menu { position: relative; font-size: 12px; }
.canvas-workflow-menu summary, .canvas-view-menu summary { display: flex; align-items: center; justify-content: center; gap: 7px; height: 30px; padding: 0 9px; border-radius: var(--radius-sm); color: var(--owb-text-2); cursor: pointer; list-style: none; }
.canvas-workflow-menu summary::-webkit-details-marker, .canvas-view-menu summary::-webkit-details-marker { display: none; }
.canvas-workflow-menu summary:hover, .canvas-view-menu summary:hover { background: var(--owb-bg-hover); }
.canvas-workflow-menu .i, .canvas-view-menu .i { width: 15px; height: 15px; flex: none; }
.canvas-workflow-menu > div, .canvas-view-menu > div { position: absolute; z-index: 40; right: 0; display: grid; width: 190px; padding: 6px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg); box-shadow: var(--shadow-menu); }
.canvas-workflow-menu > div { top: 36px; }
.canvas-view-menu > div { bottom: 38px; }
.canvas-workflow-menu > div > button, .canvas-view-menu > div > button { display: flex; align-items: center; gap: 9px; min-height: 34px; padding: 6px 9px; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--owb-text); font: inherit; text-align: left; cursor: pointer; }
.canvas-workflow-menu > div > button:hover, .canvas-view-menu > div > button:hover { background: var(--owb-bg-hover); }
.canvas-view-menu .canvas-batch-limit { display: flex; justify-content: space-between; margin: 0; padding: 9px; border: 0; }
.canvas-page > .canvas-toolbar { top: calc(var(--canvas-surface-top, 48px) + 12px); left: 12px; right: 12px; height: auto; }
.canvas-tool-cluster { height: 38px; padding: 3px; gap: 2px; background: var(--owb-bg); backdrop-filter: none; -webkit-backdrop-filter: none; }
.canvas-quick-add { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 32px; padding: 0 10px; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--owb-text-2); font: inherit; font-size: 12px; font-weight: 500; line-height: 1; white-space: nowrap; cursor: pointer; }
.canvas-quick-add:hover { color: var(--owb-brand-text); background: var(--owb-brand-weak); }
.canvas-quick-add .i { width: 16px; height: 16px; flex: none; }
.canvas-page .canvas-viewport > .canvas-zoom-box { position: absolute; z-index: 24; right: 12px; bottom: 12px; height: 34px; box-sizing: content-box; margin: 0; padding: 3px; font-size: 12px; }
.canvas-viewport > .canvas-zoom-box > span { min-width: 38px; }
.canvas-viewport > .canvas-zoom-box > .canvas-tool-divider { min-width: 1px; }
.canvas-page .canvas-viewport { height: clamp(420px, calc(100vh - 78px - var(--canvas-head-h, 48px) - var(--cp-h, 0px)), 1600px); }
.canvas-page:fullscreen .canvas-viewport { height: calc(100vh - 60px - var(--cp-h, 0px)); }
.canvas-page .canvas-inspector { top: 62px; max-height: calc(100% - 124px); }
.canvas-page .canvas-selection-tools { top: 62px; }
.canvas-viewport.is-file-drop { box-shadow: inset 0 0 0 3px var(--owb-brand); background-color: var(--owb-brand-weak); }
.canvas-start { position: absolute; z-index: 2; left: 50%; top: 43%; width: min(570px, calc(100% - 72px)); transform: translate(-50%, -50%); cursor: default; }
.canvas-start[hidden] { display: none; }
.canvas-start-eyebrow { color: var(--owb-brand-text); font-size: 12px; font-weight: 600; }
.canvas-start h2 { margin: 8px 0 10px; color: var(--owb-text); font-size: 28px; font-weight: 650; line-height: 1.25; letter-spacing: -.025em; }
.canvas-start > p { margin: 0 0 24px; color: var(--owb-text-2); font-size: 13px; line-height: 1.6; }
.canvas-start-options { display: grid; gap: 9px; }
.canvas-start-options > button { display: grid; grid-template-columns: 38px minmax(0, 1fr) 20px; grid-template-rows: auto auto; align-items: center; gap: 3px 12px; min-height: 72px; padding: 13px 16px; border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg); color: var(--owb-text); box-shadow: var(--shadow-surface); font: inherit; text-align: left; cursor: pointer; transition: border-color .12s var(--owb-ease), background .12s var(--owb-ease); }
.canvas-start-options > button > .i:first-child { grid-row: 1 / 3; width: 20px; height: 20px; padding: 9px; box-sizing: content-box; border-radius: var(--radius-md); background: var(--owb-brand-weak); color: var(--owb-brand-text); }
.canvas-start-options > button > b { font-size: 14px; font-weight: 600; }
.canvas-start-options > button > small { grid-column: 2; color: var(--owb-text-3); font-size: 12px; }
.canvas-start-options > button > .i:last-child { grid-row: 1 / 3; grid-column: 3; width: 16px; height: 16px; color: var(--owb-text-3); }
.canvas-start-options > button:hover { border-color: var(--owb-brand); background: var(--owb-bg-hover); }
.canvas-start-foot { display: flex; flex-wrap: wrap; gap: 8px 24px; margin: 18px 0 14px; }
.canvas-start-foot button { display: flex; align-items: center; gap: 8px; padding: 3px 0; border: 0; background: transparent; color: var(--owb-text-2); font: inherit; font-size: 12px; cursor: pointer; }
.canvas-start-foot button:hover { color: var(--owb-brand-text); }
.canvas-start-foot .i { width: 14px; height: 14px; }
.canvas-start-help { color: var(--owb-text-3); font-size: 11px; line-height: 1.6; }
.canvas-page > .canvas-chat { left: 12px; right: auto; bottom: 12px; width: min(550px, calc(100% - 24px)); border: 1px solid var(--owb-border); border-radius: var(--radius-lg); background: var(--owb-bg); box-shadow: var(--shadow-menu); overflow: visible; }
.canvas-page > .canvas-chat.is-collapsed { width: min(410px, calc(100% - 350px)); box-shadow: var(--shadow-surface); }
.canvas-chat-toggle { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 42px; padding: 9px 12px; border: 0; border-radius: var(--radius-lg); background: transparent; color: var(--owb-text); font: inherit; font-size: 12px; text-align: left; cursor: pointer; }
.canvas-chat-toggle > .i { width: 16px; height: 16px; flex: none; color: var(--owb-brand-text); }
.canvas-chat-toggle > b { font-weight: 600; white-space: nowrap; }
.canvas-chat-toggle > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--owb-text-3); font-size: 11px; }
.canvas-chat-toggle > .i:last-child { margin-left: auto; color: var(--owb-text-3); transform: rotate(180deg); }
.is-collapsed > .canvas-chat-toggle > .i:last-child { transform: none; }
.canvas-chat-toggle:hover { background: var(--owb-bg-hover); }
.canvas-chat-body[hidden] { display: none; }
.canvas-page .canvas-chat-log { max-height: min(220px, 25vh); padding: 0 12px; }
.canvas-page .canvas-chat-compose { padding: 10px; border-top: 1px solid var(--owb-border); }
.canvas-page .canvas-chat-compose textarea { min-height: 58px; max-height: 130px; font-size: 13px; }
.canvas-page > .canvas-timeline { bottom: calc(var(--ctl-chat-h, 42px) + 24px); }
.canvas-page .canvas-node-media { background: var(--owb-bg); border-color: var(--owb-border); border-radius: var(--radius-lg); }
.canvas-page .canvas-node-media .canvas-node-head { min-height: 42px; padding: 0 10px; }
.canvas-page .canvas-node-media .canvas-node-head small { display: none; }
.canvas-page .canvas-node-media .canvas-node-head b { font-size: 13px; }
.canvas-page .canvas-node-media .canvas-node-icon { width: 25px; height: 25px; }
.canvas-page .canvas-node-media .canvas-node-body { padding: 11px; }
.canvas-card-result { position: relative; margin: -1px -1px 12px; overflow: hidden; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: var(--owb-bg-hover); }
.canvas-card-result > span { position: absolute; right: 6px; top: 6px; padding: 3px 6px; border: 1px solid var(--owb-border); border-radius: var(--radius-sm); background: var(--owb-bg); color: var(--owb-text-2); font-size: 10px; pointer-events: none; }
.canvas-card-result .canvas-node-preview, .canvas-card-result .canvas-video-preview { display: block; width: 100%; max-height: 280px; margin: 0; border-radius: 0; object-fit: contain; }
.canvas-card-inputs { display: grid; gap: 5px; margin-bottom: 10px; }
.canvas-card-inputs-head { display: flex; align-items: center; justify-content: space-between; min-height: 23px; color: var(--owb-text-3); font-size: 11px; }
.canvas-card-inputs-head button { display: inline-flex; align-items: center; gap: 3px; padding: 3px; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--owb-text-2); font: inherit; font-size: 11px; cursor: pointer; }
.canvas-card-inputs-head button:hover { color: var(--owb-brand-text); background: var(--owb-brand-weak); }
.canvas-card-inputs-head .i { width: 12px; height: 12px; }
.canvas-card-ref { display: flex; align-items: center; gap: 4px; min-width: 0; padding: 3px; border: 1px solid var(--owb-border); border-radius: var(--radius-md); background: var(--owb-bg-hover); }
.canvas-card-ref button { display: inline-flex; align-items: center; gap: 6px; min-width: 0; padding: 3px; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--owb-text-2); font: inherit; font-size: 11px; cursor: pointer; }
.canvas-card-ref button:hover { background: var(--owb-bg); color: var(--owb-brand-text); }
.canvas-card-ref-source { flex: 1; }
.canvas-card-ref-source > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.canvas-card-ref-source img { flex: none; width: 28px; height: 28px; border-radius: var(--radius-sm); object-fit: cover; }
.canvas-card-ref .i { flex: none; width: 13px; height: 13px; }
.canvas-card-ref > select { max-width: 85px; min-width: 0; padding: 4px; border: 0; background: transparent; color: var(--owb-text-2); font: inherit; font-size: 10px; }
.canvas-card-ref.is-direct > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 3px; font-size: 11px; color: var(--owb-text-2); }
.canvas-card-ref-add { width: 100%; height: 28px; padding: 0 6px; border: 1px dashed var(--owb-border); border-radius: var(--radius-sm); background: transparent; color: var(--owb-text-3); font: inherit; font-size: 11px; cursor: pointer; }
.canvas-card-ref-add:hover { border-color: var(--owb-brand); color: var(--owb-brand-text); }
.canvas-page .canvas-card-prompt-label { margin-top: 0; gap: 6px; font-size: 11px; color: var(--owb-text-2); }
.canvas-page .canvas-card-prompt-label textarea { min-height: 82px; padding: 9px; font-size: 12px; line-height: 1.6; border-radius: var(--radius-md); }
.canvas-card-prompt::placeholder { color: var(--owb-text-3); }
.canvas-card-settings { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.canvas-card-settings label { display: flex; align-items: center; gap: 4px; min-width: 0; color: var(--owb-text-3); font-size: 10px; }
.canvas-card-settings select, .canvas-card-settings input { min-width: 0; height: 27px; padding: 0 5px; border: 1px solid var(--owb-border); border-radius: var(--radius-sm); background: var(--owb-bg); color: var(--owb-text-2); font: inherit; font-size: 11px; }
.canvas-card-model { flex: 1 1 100%; }
.canvas-card-model > select { width: 100%; flex: 1; }
.canvas-card-settings .canvas-card-assets { display: grid; width: 100%; gap: 5px; }
.canvas-card-assets textarea { width: 100%; min-height: 48px; resize: vertical; font: inherit; }
.canvas-card-assets small { font-size: 10px; line-height: 1.5; }
.canvas-card-model-settings { display: inline-flex; align-items: center; gap: 4px; padding: 3px 0; border: 0; background: transparent; color: var(--owb-text-2); font: inherit; font-size: 11px; cursor: pointer; }
.canvas-card-model-settings:hover { color: var(--owb-brand-text); }
.canvas-card-model-settings .i { width: 12px; height: 12px; }
.canvas-card-model-problem { flex-basis: 100%; margin: 0; color: var(--owb-text-2); font-size: 11px; line-height: 1.5; overflow-wrap: anywhere; }
.canvas-generation-error { display: flex; gap: 6px; margin-top: 9px; padding: 8px; border: 1px solid var(--owb-border); border-radius: var(--radius-sm); color: var(--owb-text-2); font-size: 11px; line-height: 1.5; overflow-wrap: anywhere; }
.canvas-generation-error .i { flex: none; width: 14px; height: 14px; }
.canvas-generation-error b { display: block; margin-bottom: 3px; color: var(--owb-text); }
.canvas-card-voice input { width: 150px; }
.canvas-card-next { display: flex; flex-wrap: wrap; align-items: center; gap: 5px 10px; margin-top: 11px; padding-top: 9px; border-top: 1px solid var(--owb-border); font-size: 11px; }
.canvas-card-next > span { color: var(--owb-text-3); }
.canvas-card-next button { display: inline-flex; align-items: center; gap: 4px; padding: 3px 0; border: 0; background: transparent; color: var(--owb-text-2); font: inherit; cursor: pointer; }
.canvas-card-next button:hover { color: var(--owb-brand-text); }
.canvas-card-next .i { width: 12px; height: 12px; }
.canvas-card-generate { flex: 1; justify-content: center; }
.canvas-compare .canvas-media-lightbox-card { width: min(1120px, calc(100vw - 48px)); }
.canvas-compare-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; padding: 12px; }
.canvas-compare-columns section { display: grid; gap: 10px; min-width: 0; align-content: start; }
.canvas-compare-columns select { width: 100%; min-width: 0; height: 30px; border: 1px solid var(--owb-border); border-radius: var(--radius-sm); background: var(--owb-bg); color: var(--owb-text); }
.canvas-compare-columns [data-compare-media] { display: grid; place-items: center; height: min(56vh, 560px); overflow: hidden; border-radius: var(--radius-md); background: var(--owb-bg-hover); }
.canvas-compare-columns img, .canvas-compare-columns video { max-width: 100%; max-height: 100%; object-fit: contain; }
@media (max-width: 1000px) {
  .canvas-quick-add { padding: 0 7px; }
  .canvas-page .canvas-board-switch { min-width: 0; }
  .canvas-page .canvas-head-actions { gap: 2px; }
  .canvas-page .canvas-board-switch select { max-width: 130px; }
  .canvas-workspace-switch select { max-width: 130px; }
  .canvas-chat-toggle > span { display: none; }
  .canvas-page > .canvas-chat.is-collapsed { width: 150px; }
}
@media (max-width: 700px) {
  .canvas-page .canvas-head { display: flex; flex-wrap: wrap; }
  .canvas-page .canvas-head-actions { margin-top: 0; margin-left: auto; }
  .canvas-quick-add { width: 30px; padding: 0; }
  .canvas-quick-add > span { display: none; }
  .canvas-start { width: calc(100% - 40px); top: 45%; }
  .canvas-start h2 { font-size: 23px; }
  .canvas-start-options > button { min-height: 62px; padding: 10px 12px; }
  .canvas-start-options > button > small { font-size: 11px; }
  .canvas-start-help { display: none; }
  .canvas-page > .canvas-chat.is-collapsed { width: 112px; }
  .canvas-page .canvas-viewport > .canvas-zoom-box { right: 8px; }
  .canvas-zoom-box [data-canvas-layout], .canvas-zoom-box > .canvas-tool-divider { display: none; }
  .canvas-compare-columns { grid-template-columns: minmax(0, 1fr); }
  .canvas-compare-columns [data-compare-media] { height: 30vh; }
}
/* 已有素材保持紧凑；选中后在原卡片内继续编辑，无需跳往设置页。 */
.canvas-joint-node:not(.is-selected) .canvas-node-media.is-has-media .canvas-card-editor { display: none; }
.canvas-node-media.is-has-media .canvas-card-result { margin-bottom: 0; }
.canvas-joint-node.is-selected .canvas-node-media .canvas-card-result { margin-bottom: 12px; }
.canvas-node-media .canvas-card-settings label { display: flex; margin: 0; }
.canvas-node-media .canvas-card-settings label > span { flex: none; white-space: nowrap; }
.canvas-node-media .canvas-card-settings select { width: auto; height: 27px; margin: 0; }
.canvas-node-media .canvas-card-model select { width: 100%; }
.canvas-node-media .canvas-card-ref select { width: 82px; height: 26px; margin: 0; }
.canvas-node-media .canvas-card-ref-add { height: 28px; margin: 0; }
.canvas-card-advanced { width: 100%; margin: 1px 0 6px; }
.canvas-card-advanced > summary { display: flex; align-items: center; gap: 5px; padding: 4px 0; color: var(--owb-text-3); font-size: 11px; cursor: pointer; list-style: none; }
.canvas-card-advanced > summary::-webkit-details-marker { display: none; }
.canvas-card-advanced > summary .i { width: 12px; height: 12px; }
.canvas-card-advanced[open] > summary .i { transform: rotate(180deg); }
.canvas-card-advanced > div { display: flex; flex-wrap: wrap; gap: 8px; padding: 6px 0; }
.canvas-card-prompt-label > span { display: block; }
.canvas-quick-add:focus-visible, .canvas-chat-toggle:focus-visible, .canvas-start button:focus-visible { outline: 2px solid var(--owb-brand); outline-offset: 2px; }
.canvas-card-result .canvas-node-preview[data-shape="tall"], .canvas-card-result .canvas-video-preview[data-shape="tall"] { width: auto; max-width: 100%; height: 280px; max-height: none; margin-inline: auto; }

.canvas-page { container-type: inline-size; container-name: canvas-workspace; }
@container canvas-workspace (max-width: 740px) {
  .canvas-head { flex-wrap: wrap; }
  .canvas-head-actions { margin-left: auto; }
  .canvas-quick-add { width: 30px; padding: 0; }
  .canvas-quick-add > span { display: none; }
  .canvas-board-switch select, .canvas-workspace-switch select { max-width: 130px; }
  .canvas-chat-toggle > span { display: none; }
  .canvas-chat.is-collapsed { width: 150px; }
}
@container canvas-workspace (max-width: 420px) {
  .canvas-tool-cluster { gap: 0; }
  .canvas-quick-add[data-canvas-add="audio"] { display: none; }
  .canvas-start { width: calc(100% - 32px); }
  .canvas-start-options > button { padding: 10px; gap: 4px 9px; }
  .canvas-start-options > button > small { font-size: 11px; }
  .canvas-start-help { display: none; }
  .canvas-head-actions { margin-top: 0; }
  .canvas-workspace-switch select { max-width: 115px; }
}
