/**
 * This file is part of Kinema.
 * Copyright (C) 2018-2099 BladeX (https://bladex.cn)
 *
 * SPDX-License-Identifier: AGPL-3.0-or-later
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

/* ============================================================================
   kinema · Studio — “剪辑室控制台” 设计系统
   深炭底 + 钨丝灯琥珀 tally 强调 · 等宽时间码语言 · hairline 分割 · 场记板分镜卡
   ========================================================================== */

:root {
  --bg: #0b0c0f;
  --bg-panel: #101216;
  --bg-card: #14171c;
  --bg-card-2: #181b21;
  /* 设定图承托面：图与它的文字体共用这一层近黑，卡片才是一整块。
     卡片缺省的 --bg-card 渐变比它亮一档，图片下方会突然亮起来，读作「文字块贴在图上」 */
  --bg-sheet: #0d0f13;
  --bg-hover: #1d212a;
  /* 边框是稀缺资源：hairline 只负责「分隔」，层次交给底色步进与顶光。
     常态压到将现未现，交互态才提亮——盒子感的根源就是人人一圈亮边。 */
  --line: rgba(255, 255, 255, .05);
  --line-2: rgba(255, 255, 255, .09);
  /* 软填底：无边框按钮/标签的常态底色，比 hairline 盒子安静一个数量级 */
  --fill-soft: rgba(255, 255, 255, .045);
  /* 卡片顶光：1px 内侧高光模拟顶部来光，卡片是「浮起的面」而不是「画出的框」 */
  --hi: inset 0 1px 0 rgba(255, 255, 255, .04);
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .22), 0 2px 10px rgba(0, 0, 0, .16);
  --shadow-2: 0 2px 6px rgba(0, 0, 0, .28), 0 14px 36px rgba(0, 0, 0, .32);
  --text: #e9ebf1;
  --text-2: #a6adbd;
  --text-3: #626b7d;

  --amber: #f0a63c;
  --amber-deep: #d98324;
  --amber-soft: rgba(240, 166, 60, .13);
  /* 「绿色」全部并入蓝色（无绿设计）——保留 green 令牌名以兼容既有类，值同 --blue */
  --green: #5c9ee8;
  --green-soft: rgba(92, 158, 232, .13);
  --blue: #5c9ee8;
  --blue-soft: rgba(92, 158, 232, .13);
  --cyan: #4cc3d9;
  --cyan-soft: rgba(76, 195, 217, .13);
  --red: #ef6a5a;
  --red-soft: rgba(239, 106, 90, .13);

  --font-ui: "Avenir Next", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB",
             "Source Han Sans SC", "Microsoft YaHei", sans-serif;
  --font-mono: "SF Mono", ui-monospace, "JetBrains Mono", Menlo, Consolas, monospace;
  /* 衬线仅用于「书」的语境（小说工作台题头/章扉/正文）——控制台语境仍走 ui/mono */
  --font-serif: "Songti SC", "Noto Serif SC", "Source Han Serif SC", "STSong",
                "SimSun", Georgia, serif;

  --rail-w: 244px;
  --topnav-h: 52px;
  /* 外壳形态的两个让位量，互斥：侧栏形态让左边、顶栏形态让上边。主区与所有
     吸顶/满幅算式只读这两个派生量，形态切换才不必逐处改常量。 */
  --shell-left: var(--rail-w);
  --shell-top: 0px;
  /* 页面顶部 chrome 总高。--topbar-h 是沿用下来的调校常量（实测 topbar 渲染高约
     65px，由右侧按钮而非面包屑决定，55 留出的余量正是吸顶栏与它之间的呼吸位），
     照原样保留可让侧栏形态下的吸顶偏移逐像素稳定。
     3D 满幅视口与章节页吸顶栏必须引用这两个变量——各写死 55 / 76 / 96 一类魔数，形态一变必错。 */
  --topbar-h: 55px;
  --chrome-h: calc(var(--shell-top) + var(--topbar-h));
  --r-lg: 14px;
  --r-md: 10px;
  --r-sm: 7px;

  /* 按钮度量 token：标准/紧凑两档——四级按钮体系共用（归级表见「通用组件·按钮体系」） */
  --btn-fs: 12.5px;
  --btn-pad: 7px 14px;
  --btn-r: 8px;
  --btn-fs-sm: 11px;
  --btn-pad-sm: 2px 7px;
  --shadow-pop: 0 24px 64px rgba(0, 0, 0, .55), 0 4px 16px rgba(0, 0, 0, .35);
  /* 模态遮罩：全站唯一一档，弹层/灯箱/放映厅/命令面板共用。压得住底下的页面，
     又不至于把它抹成一块黑板——不透明度一过 .8，backdrop-filter 那层毛玻璃就
     完全看不出来了，模态浮在自己的场景之上这件事也随之消失。 */
  --scrim: rgba(5, 6, 8, .72);
  --scrim-blur: blur(6px);
  --ease: cubic-bezier(.22, .8, .3, 1);
}

/* 顶栏形态：只换两个让位量，DOM 一个节点都不重排——全站有四处按 id/class 直抓
   rail 子节点（app.js 绑 .rail-brand、shell.js 取 #rail-tree/#queue-badge、
   syncRailActive 的三条 querySelectorAll），重排它们不报错、只静默失效。
   属性由 index.html 的启动脚本在首帧前写在 <html> 上。 */
html[data-shell="top"] {
  --shell-left: 0px;
  --shell-top: var(--topnav-h);
  /* 顶栏形态下面包屑栏收紧到 52px（见下方 .topbar 覆盖），这里同步缩掉 13px，
     吸顶偏移与侧栏形态沿用同一条 11px 呼吸位，两种形态的疏密节奏才一致。 */
  --topbar-h: 42px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  background: var(--bg);
  color: var(--text);
  font: 400 14px/1.6 var(--font-ui);
  font-variant-numeric: tabular-nums;
  min-height: 100vh;
  overflow-x: hidden;
}
::selection { background: rgba(240, 166, 60, .3); }

/* 细腻胶片颗粒，给纯黑底一层“物理感” */
.grain {
  position: fixed; inset: 0; z-index: 0; pointer-events: none; opacity: .5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='0.05'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* 滚动条 */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: #262b35; border-radius: 6px; border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: #333a48; }
::-webkit-scrollbar-track { background: transparent; }

[hidden] { display: none !important; }
img, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
code { font-family: var(--font-mono); }

/* 等宽微标签 —— 全站的“控制台语言” */
.k {
  font: 600 10px/1 var(--font-mono);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-3);
}
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* ============================================================ 左侧导航 rail */
.rail {
  position: fixed; z-index: 30; inset: 0 auto 0 0; width: var(--rail-w);
  background: linear-gradient(180deg, #0e1013 0%, #0b0c0f 100%);
  border-right: 1px solid var(--line);
  display: flex; flex-direction: column;
  padding: 18px 12px 12px;
}
.rail-brand {
  display: flex; align-items: center; gap: 11px;
  padding: 6px 10px 20px; cursor: pointer; user-select: none;
}
.mark {
  width: 34px; height: 34px; border-radius: 9px; position: relative; flex: none;
  background: linear-gradient(145deg, #1d2027, #14161b);
  border: 1px solid var(--line-2);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06);
}
.mark span {
  position: absolute; inset: 0; margin: auto; width: 0; height: 0;
  border-left: 11px solid var(--amber); border-top: 7px solid transparent;
  border-bottom: 7px solid transparent; transform: translateX(2px);
  filter: drop-shadow(0 0 6px rgba(240, 166, 60, .55));
}
.brand-txt b { display: block; font: 700 13.5px/1.15 var(--font-mono); letter-spacing: .1em; }
.brand-txt i { display: block; font: 500 8.5px/1 var(--font-mono); letter-spacing: .3em; color: var(--text-3); font-style: normal; margin-top: 4px; }

.rail-nav { display: flex; flex-direction: column; gap: 2px; }
.nav-item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: var(--r-sm);
  color: var(--text-2); transition: background .15s var(--ease), color .15s;
  position: relative;
}
.nav-item svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.4; flex: none; }
.nav-item span { font-size: 13.5px; font-weight: 500; }
.nav-item em { font: 500 8.5px/1 var(--font-mono); letter-spacing: .2em; color: var(--text-3); font-style: normal; margin-left: auto; }
.nav-item:hover { background: var(--bg-hover); color: var(--text); }
/* 激活态＝琥珀字 + 边缘光条（侧栏贴左缘、顶栏落下划线），不再铺药丸底——
   全站只有一盏 tally 亮着，导航靠「灯」定位而不是靠色块。 */
.nav-item.active { color: var(--amber); }
.nav-item.active em { color: rgba(240, 166, 60, .6); }
.nav-item.active::before {
  content: ""; position: absolute; left: -12px; top: 8px; bottom: 8px; width: 2px;
  background: var(--amber); border-radius: 2px; box-shadow: 0 0 8px rgba(240, 166, 60, .6);
}

/* 「项目 PROJECTS」= 与上方主菜单同款 nav-item；上下留白与下方筛选框分隔 */
.nav-item.nav-sec { margin: 8px 0 10px; }

.rail-tree { flex: 1; overflow-y: auto; padding: 0 2px 10px; min-height: 0;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.rail-tree::-webkit-scrollbar { width: 5px; }
.rail-tree::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 4px; }
.rail-search { width: calc(100% - 16px); margin: 0 8px 8px; padding: 6px 9px;
  border-radius: var(--r-sm); border: 1px solid var(--line);
  background: var(--bg-card-2); color: var(--text); font-size: 12px; outline: none;
  transition: border-color .15s; }
.rail-search:focus { border-color: var(--amber); }
.rail-search::placeholder { color: var(--text-3); }
.tp-caret { flex: none; width: 14px; height: 14px; display: grid; place-items: center;
  background: none; border: none; padding: 0; color: var(--text-3); font-size: 9px;
  cursor: pointer; transition: transform .15s var(--ease); transform: rotate(90deg); }
.tree-proj.closed .tp-caret { transform: rotate(0deg); }
.tp-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tp-cnt { margin-left: auto; font: 500 9.5px/1 var(--font-mono); color: var(--text-3);
  font-style: normal; flex: none; }
.tree-empty { padding: 12px 8px; color: var(--text-3); font-size: 12px; text-align: center; }
.tc-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ch-code { margin-left: 12px; vertical-align: middle;
  font: 600 13px/1 var(--font-mono); color: var(--amber); letter-spacing: .12em; }
/* 系统组件：下拉选择器 us / 勾选 us-check（全站禁用原生 select/checkbox） */
.us { position: relative; width: 100%; }
.us-btn { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; padding: 8px 12px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: var(--bg-card-2); color: var(--text);
  font-size: 12.5px; line-height: 1.4; text-align: left; transition: border-color .15s; }
.us-btn:hover { border-color: var(--text-3); }
.us-caret { font-style: normal; font-size: 10px; color: var(--text-3); flex: none;
  transition: transform .15s; }
.us-menu { position: fixed; z-index: 300; overflow-y: auto; padding: 5px;
  overscroll-behavior: contain; background: var(--bg-panel);
  border: 1px solid var(--line-2); border-radius: var(--r-sm);
  box-shadow: 0 14px 42px rgba(0, 0, 0, .45);
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent;
  animation: dlg-in .12s var(--ease); }
.us-menu::-webkit-scrollbar { width: 5px; }
.us-menu::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 4px; }
.us-opt { display: block; width: 100%; padding: 7px 10px; border: none;
  border-radius: 7px; background: none; color: var(--text-2); font-size: 12.5px;
  text-align: left; transition: background .12s, color .12s; }
.us-opt:hover { background: var(--bg-hover); color: var(--text); }
.us-opt.on { background: var(--amber-soft); color: var(--amber); }
/* 预演路径选择弹层里的选项：一行短名、一行说明，行距给足，当前生效的沿用 .on 的琥珀底 */
.guide-opt { padding: 10px 12px; margin-top: 6px; }
.guide-opt b { display: block; font-size: 13px; }
.guide-opt .dlg-msg { margin-top: 3px; font-size: 12px; }
.guide-opt.on .dlg-msg { color: var(--amber); opacity: .85; }
.us-check { flex: none; width: 16px; height: 16px; padding: 0; border-radius: 5px;
  border: 1px solid var(--line-2); background: var(--bg-card-2);
  display: inline-grid; place-items: center; vertical-align: -3px;
  transition: all .15s; cursor: pointer; }
.us-check i { font-style: normal; font-size: 10px; line-height: 1; color: transparent;
  transition: color .12s; }
.us-check.on { background: var(--amber); border-color: var(--amber); }
.us-check.on i { color: #14161b; }
.us-check:hover { border-color: var(--amber); }
.lb-refine.col { display: flex; flex-direction: column; align-items: stretch; gap: 8px;
  margin-top: 4px; }
.lb-refine-foot { display: flex; align-items: center; justify-content: space-between; }
/* 主按钮（primary）：关键动作专用——琥珀实底 + 微光提拉 */
.btn-primary { padding: 7px 18px; border-radius: 9px; font-size: 12.5px; font-weight: 700;
  color: #16130c; border: 1px solid rgba(240, 166, 60, .55);
  background: linear-gradient(180deg, #f6b354, #e79a2e);
  box-shadow: 0 4px 14px rgba(240, 166, 60, .22);
  transition: transform .12s var(--ease), box-shadow .15s, filter .15s; }
.btn-primary:hover { filter: brightness(1.07); transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(240, 166, 60, .3); }
.btn-primary:active { transform: scale(.97); }
.btn-primary:disabled { opacity: .55; transform: none; box-shadow: none; }

/* ═══ 生成等待遮罩（分镜卡·数据驱动忙态）＋ 制式弹层骨架 ═══ */
.gen-wait { position: absolute; inset: 0; z-index: 3; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 8px; text-align: center;
  background: rgba(10, 12, 16, .78); backdrop-filter: blur(3px); color: #fff; }
.gen-wait b { font-size: 13px; letter-spacing: .06em; }
.gen-wait i { font: 500 10px/1.6 var(--font-mono); color: var(--text-3); font-style: normal; }
.gw-ring { width: 34px; height: 34px; border-radius: 50%;
  border: 3px solid rgba(240, 166, 60, .18); border-top-color: var(--amber);
  animation: gw-spin .9s linear infinite; }
@keyframes gw-spin { to { transform: rotate(360deg); } }
.shot-ops { display: flex; gap: 8px; margin-top: auto; padding-top: 2px; }
.act-btn:disabled { opacity: .38; cursor: not-allowed; pointer-events: none; }
/* 按钮忙态（runBusy）：转圈 + 文案换成「…中」。忙态**保持可读不置灰**——
   置灰会让"正在处理"看起来像"被禁用了"，而这恰恰是用户最需要看清的一刻。 */
/* 转圈走**伪元素**而不是插一个 <i>：站里有一半忙态是 `btn.textContent = "…中"`
   写的，插进去的子节点会被 textContent 整个冲掉，只有伪元素两条路都活得下来。 */
.is-busy { opacity: 1 !important; cursor: progress; }
.is-busy::before { content: ""; width: 11px; height: 11px; margin-right: 6px;
  flex: none; display: inline-block; border-radius: 50%; vertical-align: -1px;
  border: 1.5px solid currentColor; border-top-color: transparent;
  animation: btn-spin .7s linear infinite; }
@keyframes btn-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .is-busy::before { animation: none; opacity: .6; } }

/* 系统级即时提示（data-tip）：零延迟、body 级悬浮，替代原生 title */
#sys-tip { position: fixed; z-index: 400; max-width: 300px; pointer-events: none;
  background: rgba(22, 25, 33, .62); backdrop-filter: blur(18px) saturate(160%);
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, .12); border-radius: var(--r-md);
  padding: 9px 12px 10px; box-shadow: 0 14px 40px rgba(0, 0, 0, .5);
  opacity: 0; transform: translateY(3px);
  transition: opacity .1s var(--ease), transform .1s var(--ease); }
#sys-tip.on { opacity: 1; transform: none; }
#sys-tip b { display: block; font-size: 11.5px; letter-spacing: .03em;
  color: var(--amber); margin-bottom: 4px; }
/* 内嵌缩略图（data-tip-img）：定宽随高——contain 保整图可读（分镜多为竖版 9:16，
   cover 会裁掉大半），墨底承托竖图两侧留白 */
#sys-tip .tip-img { display: block; width: 248px; max-height: 300px;
  object-fit: contain; border-radius: 7px; margin-bottom: 8px;
  background: #0a0c10; border: 1px solid rgba(255, 255, 255, .08); }
#sys-tip p { margin: 0; font-size: 11px; line-height: 1.7; color: var(--text-2);
  white-space: pre-line; }   /* 正文支持多行（\n 原样换行） */

.rf-overlay { position: fixed; inset: 0; z-index: 200; display: grid; place-items: center;
  background: var(--scrim); backdrop-filter: var(--scrim-blur);
  -webkit-backdrop-filter: var(--scrim-blur); animation: dlg-in .16s var(--ease); }
.rf-head { display: flex; align-items: center; justify-content: space-between; }
.rf-head .k .chip { margin-left: 10px; }
.rf-x { width: 28px; height: 28px; border-radius: 8px; background: var(--fill-soft);
  border: 1px solid transparent; color: var(--text-2); font-size: 13px; }
.rf-x:hover { color: var(--text); background: var(--bg-hover); }
.rf-note { width: 100%; resize: vertical; min-height: 52px; padding: 9px 12px;
  border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--bg-card-2);
  color: var(--text); font-size: 13px; outline: none; font-family: inherit; }
.rf-note:focus { border-color: var(--amber); }

/* 长文输入基座（单一真源）——站内所有「写一段字给引擎/给模型」的输入框共用：
   指令台 `.dq-ta` · 声线描述 `.vd-desc` · 音频剧本逐段 `.aus-ta`。
   各写一份必然漏项：`.vd-desc` 只设 font-family/resize 时，底色描边内距全掉回
   浏览器默认，暗色编辑部里露出一块浏览器默认样式的亮灰控件。
   墨底比卡面更深一档（输入区是"凹下去"的），描边平时压到几乎看不见，
   聚焦才亮出琥珀环——注意力跟着光标走，不依赖常驻的盒子边框。 */
.ta-field, .dq-ta, .vd-desc, .aus-ta {
  width: 100%; box-sizing: border-box; display: block; resize: vertical;
  background: #0a0c10; border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 11px 13px; color: var(--text); font: 13px/1.75 var(--font-ui);
  outline: none; transition: border-color .15s, box-shadow .18s var(--ease);
}
.ta-field::placeholder, .dq-ta::placeholder,
.vd-desc::placeholder, .aus-ta::placeholder { color: var(--text-3); }
.ta-field:hover, .dq-ta:hover, .vd-desc:hover, .aus-ta:hover { border-color: var(--line-2); }
.ta-field:focus, .dq-ta:focus, .vd-desc:focus, .aus-ta:focus {
  border-color: rgba(240, 166, 60, .55); box-shadow: 0 0 0 3px rgba(240, 166, 60, .08); }
/* 拖拽手柄由 UA 绘制，在暗色底上是一块亮白方片（最扎眼的一处「没做完」）。
   重画成两道斜纹：拖拽能力不动，颜色跟随描边体系；hover 才提亮，平时几乎隐形。 */
.ta-field::-webkit-resizer, .dq-ta::-webkit-resizer,
.vd-desc::-webkit-resizer, .aus-ta::-webkit-resizer {
  background: linear-gradient(135deg, transparent 0 46%, var(--line-2) 46% 54%,
              transparent 54% 70%, var(--line-2) 70% 78%, transparent 78%);
}
.ta-field:hover::-webkit-resizer, .dq-ta:hover::-webkit-resizer,
.vd-desc:hover::-webkit-resizer, .aus-ta:hover::-webkit-resizer {
  background: linear-gradient(135deg, transparent 0 46%, var(--text-3) 46% 54%,
              transparent 54% 70%, var(--text-3) 70% 78%, transparent 78%);
}
/* 滚动条同批入编。这不只是配色：WebKit 只有在元素启用自定义滚动条时才会用
   上面自绘的 resizer 与角落——不写这段，内容一溢出就渲原生滚动条 + 原生
   白色角块，斜纹手柄形同虚设。 */
.ta-field::-webkit-scrollbar, .dq-ta::-webkit-scrollbar,
.vd-desc::-webkit-scrollbar, .aus-ta::-webkit-scrollbar { width: 6px; }
.ta-field::-webkit-scrollbar-thumb, .dq-ta::-webkit-scrollbar-thumb,
.vd-desc::-webkit-scrollbar-thumb, .aus-ta::-webkit-scrollbar-thumb {
  background: var(--line-2); border-radius: 4px; }
.ta-field::-webkit-scrollbar-corner, .dq-ta::-webkit-scrollbar-corner,
.vd-desc::-webkit-scrollbar-corner, .aus-ta::-webkit-scrollbar-corner {
  background: transparent; }
.rf-foot { display: flex; align-items: center; justify-content: space-between; }
.rf-cost { font: 500 10.5px/1.6 var(--font-mono); color: var(--text-3); }

/* ⇪ 素材直供选择器：复用本作品画面（同图换运镜）或上传本地图片 */
.sup-wrap { position: relative; width: min(820px, 94vw); max-height: 86vh;
  background: var(--bg-panel); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 18px 20px 16px; display: flex; flex-direction: column; gap: 12px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, .5);
  animation: pop .16s var(--ease); }
.sup-intro { font-size: 12px; line-height: 1.75; color: var(--text-2); margin: 0; }
.sup-scroll { overflow: auto; overscroll-behavior: contain; min-height: 120px;
  display: flex; flex-direction: column; gap: 14px; padding-right: 4px; }
.sup-k { display: block; font: 600 10.5px/1 var(--font-mono); letter-spacing: .12em;
  color: var(--text-3); margin-bottom: 8px; }
.sup-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(128px, 1fr));
  gap: 10px; }
.sup-tile { position: relative; border: 1px solid var(--line-2); border-radius: var(--r-md);
  overflow: hidden; cursor: pointer; background: var(--bg-card-2);
  transition: border-color .15s, box-shadow .15s, transform .12s var(--ease); }
.sup-tile:hover { border-color: var(--text-3); transform: translateY(-1px); }
/* 选中＝仅最外层一道金色描边（1px 边框换金·不叠 inset 环免双线·无外投影光晕），配勾角即好看 */
.sup-tile.on { border-color: var(--amber); box-shadow: none; }
.sup-tile img { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.sup-tile i { display: block; padding: 5px 8px; font: 500 10.5px/1.4 var(--font-mono);
  color: var(--text-3); font-style: normal; text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sup-tile.on i { color: var(--amber); }
.sup-empty { padding: 26px 0; text-align: center; color: var(--text-3); font-size: 12px; }
/* ⛭ 垫图参考选择器：多选勾角 + 快捷操作条 + 分镜卡「本镜已单独设定」态 */
.ref-check { position: absolute; top: 6px; right: 6px; width: 20px; height: 20px; border-radius: 5px;
  background: var(--amber); color: #1a1205; font-size: 12px; font-weight: 800; line-height: 20px;
  text-align: center; opacity: 0; transform: scale(.6); transition: all .13s var(--ease); }
.ref-tile.on .ref-check { opacity: 1; transform: scale(1); }
.ref-tile:not(.on) img { filter: grayscale(.35) opacity(.82); }
.ref-quick { display: flex; flex-wrap: wrap; gap: 8px; }
.act-btn.ref-pinned { border-color: var(--amber); color: var(--amber); }
.tree-proj { margin-bottom: 2px; }
.tree-proj > a {
  display: flex; align-items: center; gap: 8px; padding: 7px 8px;
  border-radius: var(--r-sm); color: var(--text-2); font-size: 13px; font-weight: 500;
  transition: background .15s, color .15s;
}
.tree-proj > a:hover { background: var(--bg-hover); color: var(--text); }
.tree-proj > a.active { color: var(--amber); background: var(--bg-hover); }
.tree-chapters { margin: 1px 0 4px 24px; border-left: 1px solid var(--line); padding-left: 10px; }
.tree-ch {
  display: flex; align-items: center; gap: 7px; padding: 4.5px 7px;
  border-radius: 6px; color: var(--text-3); font-size: 12.5px;
  transition: background .15s, color .15s;
  white-space: nowrap; overflow: hidden;
}
.tree-ch:hover { background: var(--bg-hover); color: var(--text-2); }
.tree-ch.active { color: var(--text); background: var(--bg-hover); }
.tree-ch .dot { width: 5px; height: 5px; border-radius: 50%; flex: none; background: #3a4150; }
.tree-ch .dot.rendered { background: var(--green); box-shadow: 0 0 6px rgba(92, 158, 232, .5); }
.tree-ch .dot.scripted { background: var(--blue); }
.tree-ch span { overflow: hidden; text-overflow: ellipsis; }

/* 页脚（作者签 + 出品签成一个整体）：负 margin 吃掉 .rail 的 12px 底 padding，
   区块从分隔线贯到窗口底，两行经 flex 在其中垂直居中（上下留白对称） */
.rail-foot { border-top: 1px solid var(--line); margin-bottom: -12px;
  padding: 7px 8px; display: flex; flex-direction: column;
  justify-content: center; gap: 3px; }
/* 出品签 + 许可签：同一行两个落点（前者跳官网、后者开声明弹层）。
   极小号 mono 大写，克制存在感——它们是署名与合规件，不该抢导航的注意力。 */
/* 作者签（单行居中）：AUTHOR 小标 + 名字 + ↗，hover 纯文字特效（无背景块） */
.rail-author { display: flex; align-items: baseline; justify-content: center;
  gap: 9px; padding: 2px 9px; white-space: nowrap; }
.ra-k { font: 600 8.5px/1 var(--font-mono); letter-spacing: .24em; color: var(--text-3);
  transition: color .15s; }
.rail-author b { font-size: 12.5px; font-weight: 600; color: var(--text-2);
  transition: color .15s, letter-spacing .18s; }
.rail-author i { font-style: normal; font-size: 11px; color: var(--text-3);
  transition: color .15s, transform .15s; }
.rail-author:hover b, .rail-author:hover i { color: var(--amber); }
.rail-author:hover .ra-k { color: var(--amber); opacity: .7; }
.rail-author:hover b { letter-spacing: .06em; }
.rail-author:hover i { transform: translate(1px, -1px); }
.rail-sign { display: flex; align-items: center; justify-content: center; gap: 5px;
  flex-wrap: nowrap; }
.rail-sep { font: 600 8px/1 var(--font-mono); color: var(--text-3); opacity: .45; }
.rail-power { display: inline-block; text-align: center;
  font: 600 8px/1 var(--font-mono); letter-spacing: .24em;
  color: var(--text-3); opacity: .55;
  transition: opacity .15s, transform .12s var(--ease); }
.rail-power b { font-weight: 700; color: var(--text-3); transition: color .15s; }
.rail-power:hover { opacity: 1; }
.rail-power:hover b { color: var(--amber); }
.rail-power:active { transform: scale(.94); }
.rail-legal { display: inline-block; background: none; border: 0; cursor: pointer;
  font: 600 8px/1 var(--font-mono); letter-spacing: .18em;
  color: var(--text-3); opacity: .55;
  transition: opacity .15s, color .15s, transform .12s var(--ease); }
.rail-legal:hover { opacity: 1; color: var(--amber); }
.rail-legal:active { transform: scale(.94); }
/* 法律声明弹层：产品签 → 协议正文 → 商业授权，只用两道发丝线与留白分层。
   **刻意不用色块/码片/彩色链接**：这类装饰会把一份声明读成营销页，且四处琥珀
   同时在场等于没有重点。全篇唯一的强调留给「不附带任何担保」。
   文本色令牌只有 `--text` / `--text-2` / `--text-3` 三档，**没有 `--text-1`**；
   未定义的自定义属性不报错也不回退，写错的那条会静默失效（加粗渲染成普通正文）。 */
.legal-note { display: flex; flex-direction: column; gap: 16px;
  font-size: 12px; line-height: 1.85; color: var(--text-2); }
.legal-note b { color: var(--text); font-weight: 600; }
.legal-note code { font: 500 11px/1.5 var(--font-mono); color: var(--text); }
/* 链接静态即正文色、只留一道极淡下划线，hover 才上琥珀——静态页面上没有一处彩字 */
.legal-note a { color: inherit; text-decoration: underline;
  text-decoration-color: var(--line-2); text-underline-offset: 3px;
  transition: color .15s var(--ease), text-decoration-color .15s var(--ease); }
.legal-note a:hover { color: var(--amber); text-decoration-color: var(--amber); }
.legal-note .sep { color: var(--text-3); margin: 0 3px; }
/* 抬头两行：「产品签 + 一句定位」同行，版权单独一行——版权属身份而非条款，
   故收在抬头里而不进正文。同行靠基线对齐，字签的字距已自带右侧余白，gap 取小 */
.legal-head { display: flex; flex-direction: column; gap: 7px; }
.legal-title { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.legal-brand { font: 600 12px/1 var(--font-mono); letter-spacing: .3em; color: var(--text); }
.legal-tag { font-size: 12px; color: var(--text-3); }
.legal-copy { font: 500 10px/1.6 var(--font-mono); letter-spacing: .02em; color: var(--text-3); }
/* 协议正文夹在两道发丝线之间：上接产品签、下接商业授权，无需任何底色 */
.legal-body { display: flex; flex-direction: column; gap: 13px; padding: 15px 0;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
/* 「一句引子（冒号收）+ 链接另起一行」的成对块：正文的许可证出处与下方的商业授权
   同用这一档行距，两处句式一致，间距也就该一致（比 legal-body 的段距 13px 紧） */
.legal-pair, .legal-comm { display: flex; flex-direction: column; gap: 7px; }
/* 商业授权与 AGPL 是两条并行的法律关系，故分区；小标题直接复用全站 `.k` 微标签。
   联系方式行**不另设字体色阶**——它与正文里 gnu.org 那条同为链接，treatment 必须一致 */
/* 运行环境卡（总览页尾）：原侧栏系统信息的新家 */
.sysinfo { padding: 14px 16px; display: flex; flex-direction: column; gap: 9px; }
.sys-row { display: flex; align-items: baseline; gap: 14px; }
.sys-row .k { flex: none; width: 88px; font: 600 9px/1 var(--font-mono);
  letter-spacing: .2em; color: var(--text-3); }
.sys-row code { font: 500 11px/1.5 var(--font-mono); color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ============================================================ 主区 */
/* 让位用 padding-top 而不是 margin-top 是**刻意的**：全局 `* { box-sizing: border-box }`
   下，`body:has(.view.view-stage) .main { height: 100vh }` 那条满幅规则可以一个字不改——
   边框盒仍是整屏，内容盒自动减去导航条的高度，3D 视口不会被挤出屏底。
   换成 margin-top（或再减一次 height）就会在视口底部留下一条导航条高的死带。 */
.main { margin-left: var(--shell-left); padding-top: var(--shell-top);
  position: relative; z-index: 1; min-height: 100vh; display: flex; flex-direction: column;
  /* 页顶一抹钨丝灯暖光洗：极淡、只在首屏上缘，给纯黑底一个光源方向 */
  background: radial-gradient(1100px 420px at 60% -160px, rgba(240, 166, 60, .05), transparent 72%); }
.topbar {
  position: sticky; top: var(--shell-top); z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 32px;
  background: rgba(11, 12, 15, .82); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}
.crumbs { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-3); min-height: 26px; }
.crumbs a { color: var(--text-2); transition: color .15s; }
.crumbs a:hover { color: var(--text); }
.crumbs .sep { color: var(--text-3); opacity: .6; }
.crumbs .here { color: var(--text); font-weight: 500; }
.topbar-right { display: flex; align-items: center; gap: 8px; }
.live { display: flex; align-items: center; gap: 7px; font: 600 10px/1 var(--font-mono); letter-spacing: .2em; color: var(--green); }
/* 引擎错配贴条（与 LIVE 同族的顶栏状态位）：琥珀=要人动手，但不是事故红——
   旧进程仍在正常服务，只是行为停在上一版 */
.engine-stale {
  display: flex; align-items: center; gap: 6px; cursor: pointer;
  font: 600 10px/1 var(--font-mono); letter-spacing: .12em; color: var(--amber);
  padding: 4px 9px; border-radius: var(--btn-r);
}
.engine-stale:hover { background: var(--amber-soft); }
.tally { width: 7px; height: 7px; border-radius: 50%; background: var(--green); animation: tally 1.4s infinite; }
@keyframes tally { 0%, 100% { opacity: 1; box-shadow: 0 0 8px rgba(92, 158, 232, .8); } 50% { opacity: .35; box-shadow: none; } }
/* 幽灵钮＝纯文字按钮：无边框，hover 才浮出底色。琥珀只留给状态与主行动，
   工具按钮的悬停不抢强调色。 */
.ghost-btn {
  display: flex; align-items: center; gap: 7px;
  padding: var(--btn-pad); border-radius: var(--btn-r);
  border: 1px solid transparent; color: var(--text-2); font-size: var(--btn-fs);
  transition: all .15s var(--ease);
}
.ghost-btn svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.5; }
.ghost-btn:hover { color: var(--text); background: var(--bg-hover); }
.ghost-btn:active { transform: scale(.97); }

/* 顶栏右侧控件组：比正文按钮**小一号**，且四件（形态开关 + 检索 / 指令集 / 刷新）
   统一 28px 行高——分段胶囊按内容算高（约 26px）、幽灵钮按 --btn-pad 算高
   （约 33px）时两者基线对不齐，右上角读起来是高低错落的一排；显式定高后
   只剩一条水平线。 */
.topbar-right .ghost-btn {
  height: 28px; padding: 0 11px; gap: 6px; border-radius: 7px;
  font-size: 11.5px;
}
.topbar-right .ghost-btn svg { width: 12px; height: 12px; }
.topbar-right .ghost-btn .kbd { font-size: 9px; padding: 1px 4px; border-bottom-width: 1px; }
.topbar-right .useg-sm { height: 28px; align-items: center; background: rgba(0, 0, 0, .18); }
.topbar-right .useg-sm .usegb { height: 22px; display: flex; align-items: center;
  padding: 0 10px; font-size: 11px; }

/* ══════════════════════════════════════════════════ 外壳形态 · 顶栏导航
   同一份 DOM 的第二种排布：竖列变横条。全部规则带 html[data-shell="top"] 前缀，
   特异性高于基线规则，故与源序无关；侧栏形态下这一段整体不参与级联。 */
html[data-shell="top"] .rail {
  inset: 0 0 auto 0; width: auto; height: var(--topnav-h);
  flex-direction: row; align-items: center; gap: 5px;
  padding: 0 18px;
  border-right: 0; border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, #12151a 0%, #0d0f13 100%);
  /* 条内塞不下时横滑，绝不把菜单项挤出视口——项目树浮层是 position:fixed，
     不受这层 overflow 裁切（.rail 未创建定位包含块）。 */
  overflow-x: auto; scrollbar-width: none;
}
html[data-shell="top"] .rail::-webkit-scrollbar { height: 0; }
/* 品牌区收成单行并竖线收边；52px 条内放不下两行，口号让位 */
html[data-shell="top"] .rail-brand { flex: none; height: 100%;
  padding: 0 16px 0 0; margin-right: 5px; border-right: 1px solid var(--line); }
html[data-shell="top"] .mark { width: 26px; height: 26px; border-radius: 7px; }
html[data-shell="top"] .mark span { border-left-width: 8px;
  border-top-width: 5px; border-bottom-width: 5px; }
html[data-shell="top"] .brand-txt b { font-size: 12px; }
html[data-shell="top"] .brand-txt i { display: none; }

html[data-shell="top"] .rail-nav { flex-direction: row; gap: 3px; flex: none; }
html[data-shell="top"] .nav-item { flex: none; padding: 7px 11px; white-space: nowrap; }
/* EN 小标靠 margin-left:auto 推到行尾，横排里会在名字与胶囊右缘间撑出一段断裂空白，
   故一律不显；唯独待审有数时保留——那是计数不是装饰。 */
html[data-shell="top"] .nav-item em { display: none; }
html[data-shell="top"] .nav-item em.qbadge.has { display: inline-flex; margin-left: 3px; }
/* 竖排的选中态是贴左缘的竖条（-12px 抵消 rail 左 padding）；横排换成底部下划线，
   与条的下边框贴合。四个方位全部重写，不残留竖条的几何。 */
html[data-shell="top"] .nav-item.active::before {
  left: 10px; right: 10px; top: auto; bottom: -1px;
  width: auto; height: 2px; border-radius: 2px 2px 0 0;
}
html[data-shell="top"] .nav-item.nav-sec { margin: 0; }
html[data-shell="top"] .nav-item.nav-sec::after {
  content: "▾"; font-size: 9px; color: var(--text-3); margin-left: 1px;
  transition: transform .15s var(--ease);
}
html[data-shell="top"] .rail.tree-open .nav-item.nav-sec::after { transform: rotate(180deg); }
/* 菜单开启中触发钮保持「按下」态：浮层与钮之间隔着 6px 缝，钮不亮着就认不出
   浮层是从它长出来的 */
html[data-shell="top"] .rail.tree-open .nav-item.nav-sec { background: var(--bg-hover); color: var(--text); }

/* 项目树：竖排里靠 flex:1 吃掉列的剩余高度，横排里没有"剩余高度"可吃，
   改成挂在导航条下沿的浮层。开合走 class 而**不是 hidden 属性**——hidden 是元素
   自身的状态，会跟着切回侧栏一起带走、把侧栏的树永久隐藏；而这条规则只在顶栏形态
   下存在，切回去必然恢复。 */
html[data-shell="top"] .rail-tree {
  /* 悬浮菜单形态：与触发钮拉开 6px、四角全圆、整圈玻璃边——「贴条挂下来」的
     直角+去顶边写法会与触发钮的圆角盒子打架，读作断成两截的一个控件。
     6px 缝不会断 hover：离开侧有 220ms 宽限计时（shell.js bindTreeFlyout）。 */
  position: fixed; top: calc(var(--topnav-h) + 6px); left: 18px; z-index: 31;
  /* 高度跟着视口给到底（留 20px 呼吸），而不是封在一个常数上——项目一多
     （本仓库真有 71 章的项目）封顶就会把列表切掉一半 */
  flex: none; width: min(360px, calc(100vw - 24px));
  max-height: calc(100vh - var(--topnav-h) - 26px);
  padding: 8px 4px 10px;
  /* 整块一起滚会让「全部项目」与筛选框跟着滚走，看起来就像被截断；
     改成头部钉住、只有下面的列表滚（见 .tree-list 那条） */
  display: flex; flex-direction: column; overflow: hidden;
  /* 磨砂玻璃（与 .dlg-card / #sys-tip 同族）：浮层透出底下页面的虚化光影 */
  background: rgba(22, 25, 33, .62);
  backdrop-filter: blur(24px) saturate(165%); -webkit-backdrop-filter: blur(24px) saturate(165%);
  border: 1px solid rgba(255, 255, 255, .13);
  border-radius: var(--r-md); box-shadow: var(--shadow-pop);
  visibility: hidden; opacity: 0; pointer-events: none; transform: translateY(-6px);
  transition: opacity .14s var(--ease), transform .14s var(--ease), visibility .14s;
}
html[data-shell="top"] .rail-tree > .rail-search { flex: none; }
html[data-shell="top"] .rail-tree > .tree-list {
  flex: 1; min-height: 0; overflow-y: auto; padding-right: 2px;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent;
}
html[data-shell="top"] .rail-tree > .tree-list::-webkit-scrollbar { width: 5px; }
html[data-shell="top"] .rail-tree > .tree-list::-webkit-scrollbar-thumb {
  background: var(--line-2); border-radius: 4px; }
html[data-shell="top"] .rail.tree-open .rail-tree {
  visibility: visible; opacity: 1; pointer-events: auto; transform: none;
}
/* 页脚三签收成右端一组。#rail-legal 是 AGPL 第 5(d) 条要求的显眼条目，
   两种形态下都必须在场——它不是装饰，省掉即界面本身不合规。 */
html[data-shell="top"] .rail-foot {
  flex-direction: row; align-items: center; gap: 14px; flex: none;
  margin: 0 0 0 auto; padding: 0 0 0 16px;
  border-top: 0; border-left: 1px solid var(--line);
}
html[data-shell="top"] .rail-author { padding: 0; gap: 7px; }
html[data-shell="top"] .rail-power,
html[data-shell="top"] .rail-legal { white-space: nowrap; }

/* 面包屑栏收紧并去掉分隔线：与上方导航条读作一条栏的上下两层，而不是两条工具栏。
   **背景不能真去掉**——它是 sticky 的，透明后滚动内容会从它下面穿过去；用与页面
   同色的近不透明底，既保住可读性又不自成一块。 */
html[data-shell="top"] .topbar {
  padding: 10px 32px; border-bottom: 0;
  background: rgba(11, 12, 15, .92);
}
/* 顶栏形态下这条面包屑栏本身就收紧了，控件跟着再矮 2px（26px），比例才不变 */
html[data-shell="top"] .topbar-right .ghost-btn,
html[data-shell="top"] .topbar-right .useg-sm { height: 26px; }
html[data-shell="top"] .topbar-right .useg-sm .usegb { height: 20px; }

/* 内容可读宽度上限对两种形态一体生效（规则本体在 .view 定义处）——顶栏形态
   全宽、侧栏形态 2560px 屏减去 244px 后同样会把卡片网格拉成超长行。 */

/* 外壳形态开关（顶栏右侧）：紧凑档分段器，与 ghost-btn 同高不撑开导航条 */
.lay-seg { display: flex; align-items: center; }

.view { padding: 28px 32px 72px; flex: 1; }
/* 可读宽度上限：**必须排除两个刻意满幅的视图**——3D 导演台与剧本工作台被居中
   裁到 1680px 就是两侧留大黑边，且它们的高度是 JS 实测的、发现不了。 */
.view:not(.view-stage):not(.view-app) { width: 100%; max-width: 1680px; margin-inline: auto; }
.view.enter > * { animation: rise .5s var(--ease) backwards; }
.view.enter > *:nth-child(2) { animation-delay: .05s; }
.view.enter > *:nth-child(3) { animation-delay: .1s; }
.view.enter > *:nth-child(4) { animation-delay: .15s; }
.view.enter > *:nth-child(5) { animation-delay: .2s; }
.view.enter > *:nth-child(6) { animation-delay: .25s; }
@keyframes rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
/* 遮罩层入场（us-menu / rf-overlay 共用）：纯淡入——不动 transform，
   不与任何底定位冲突（关键帧缺失会导致入场空转） */
@keyframes dlg-in { from { opacity: 0; } }

.loading { display: flex; align-items: center; gap: 12px; color: var(--text-3); padding: 60px 0; justify-content: center; font-size: 13px; }
.loading::before {
  content: ""; width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid var(--line-2); border-top-color: var(--amber);
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* 区块标题：序号 + 中文 + 英文 tracked + hairline */
.sec { margin: 34px 0 16px; display: flex; align-items: baseline; gap: 12px; }
.sec:first-child { margin-top: 0; }
.sec .no { font: 600 11px/1 var(--font-mono); color: var(--amber); letter-spacing: .1em; }
.sec h2 { font-size: 16px; font-weight: 600; letter-spacing: .01em; }
.sec .en { font: 500 9px/1 var(--font-mono); letter-spacing: .26em; color: var(--text-3); text-transform: uppercase; }
.sec .rule { flex: 1; height: 1px; background: var(--line); }
.sec .cnt { font: 500 11px/1 var(--font-mono); color: var(--text-3); }
/* 区块头右端「更多」：截断展示的区块领人去整页。与 .cnt 同字号同族，
   常态压在灰阶里不与标题抢，hover 才亮成琥珀 */
.sec .sec-more { display: inline-flex; align-items: center; gap: 5px;
  font: 500 11px/1 var(--font-mono); color: var(--text-3);
  transition: color .15s; }
.sec .sec-more i { font-style: normal; font-size: 10px; transition: transform .15s var(--ease); }
.sec .sec-more:hover { color: var(--amber); }
.sec .sec-more:hover i { transform: translateX(2px); }

/* ============================================================ 通用组件 */
/* chip＝软填标签：色由字与极淡底给出，边框恒透明（占位供 clickable/hover 态上色）——
   描边药丸叠三枚就是一排小盒子，软填叠三枚仍是一行字。 */
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3.5px 9px; border-radius: 999px;
  background: var(--fill-soft); border: 1px solid transparent;
  font-size: 11.5px; color: var(--text-2); white-space: nowrap;
  /* chip 常被塞进 display:flex 的行里（.src-row / .nv-arc / 各种头部）。flex 容器默认
     align-items:stretch，会把这枚药丸**拉成整行高的圆角大色块**——行里的正文一换行就
     立刻现形（实测卷规划里「✔ 已收卷」被拉成四行高）。这两条让它恒为内容高、不被拉伸。 */
  align-self: center; flex: none;
}
.chip.amber { background: var(--amber-soft); color: var(--amber); }
.chip.green { background: var(--green-soft); color: var(--green); }
.chip.blue  { background: var(--blue-soft); color: var(--blue); }
.chip.cyan  { background: var(--cyan-soft); color: var(--cyan); }
.chip.red   { background: var(--red-soft); color: var(--red); }
/* 中性待办位（「未生成/剧本待写」）：压暗一档，与缺省 chip 的「信息」层级区分 */
.chip.gray  { background: transparent; border-color: var(--line); color: var(--text-3); }

/* 合成特效选择器（章节头部 ✎ 特效 chip + 竖线分割 + 面板） */
.chip-sep { display: inline-block; width: 1px; height: 13px; background: var(--line-2);
  margin: 0 3px; align-self: center; }
button.chip { font-family: inherit; font-size: 11.5px; line-height: 1.3; cursor: pointer; transition: all .15s; }
.chip.efx-chip { background: var(--amber-soft); color: var(--amber); }
.chip.efx-chip:hover { border-color: rgba(240, 166, 60, .45); }
.chip.efx-chip.on { background: var(--amber); border-color: var(--amber); color: #1a1206; font-weight: 600; }
/* 特效弹框：卡片放宽、内容区可滚（12 特效分类多行时不撑爆弹层） */
.efx-dlg-card { width: min(560px, 92vw); }
.efx-dlg-body { display: flex; flex-direction: column; gap: 12px; max-height: 58vh;
  overflow-y: auto; margin: 4px 0 2px; }
.efx-cat { display: flex; align-items: flex-start; gap: 12px; }
.efx-cat-k { flex: 0 0 60px; font-size: 11px; color: var(--text-3); padding-top: 6px; letter-spacing: .04em; }
.efx-opts { display: flex; flex-wrap: wrap; gap: 7px; }
.efx-opt { font: inherit; font-size: 12px; padding: 4px 11px; border-radius: 999px; cursor: pointer;
  border: 1px solid transparent; background: var(--fill-soft); color: var(--text-2); transition: all .14s; }
.efx-opt:hover { background: var(--bg-hover); color: var(--text); }
.efx-opt.on { background: var(--amber-soft); color: var(--amber); font-weight: 600; }
.efx-warn { font-size: 11.5px; color: var(--amber); min-height: 14px; }
/* 无警告时整行收起（移出 flex 流·连同上下 gap 一并消除）——按钮上移，贴合角标/水印等同族弹窗 */
.efx-warn:empty { display: none; }

/* 放映区行动条：特效 + 水印（好看的动作按钮，取代原 chips 行小 chip） */
.screen-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.screen-act {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 15px; border-radius: var(--r-md); cursor: pointer;
  font-size: 12.5px; font-weight: 550; color: var(--text-2);
  border: 1px solid transparent; background: var(--fill-soft);
  transition: color .16s var(--ease), border-color .16s var(--ease), background .16s var(--ease);
}
.screen-act:hover { color: var(--text); background: var(--bg-hover); }
.screen-act .screen-act-ico { width: 15px; height: 15px; display: inline-flex; opacity: .92; }
.screen-act .screen-act-ico svg {
  width: 100%; height: 100%; fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
/* 已叠加特效：金色透明选中态（与水印 .wm-on 同制式，表示本集已带特效） */
.screen-act.fx-on { color: var(--amber); background: var(--amber-soft); }
.screen-act.fx-on:hover { border-color: rgba(240, 166, 60, .45); }
.screen-act.on { background: var(--amber); border-color: var(--amber); color: #1a1206; }
.screen-act.on .screen-act-ico { opacity: 1; }
.screen-act.wm-on { color: var(--blue); background: var(--blue-soft); }
.screen-act.wm-on:hover { border-color: rgba(92, 158, 232, .45); }
/* 重新构建：放映区「按当前设置重烧成片」的应用操作——琥珀点缀，区别于水印/特效 */
.screen-act.rebuild-act { color: var(--amber); }
.screen-act.rebuild-act:hover { color: var(--amber); background: var(--amber-soft); }

/* 固定角标水印：四角位置选择器（弹层内）——2×2 网格，各格一个角上的点示意落点 */
.corner-pick { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 12px 0 2px; }
.corner-cell {
  position: relative; height: 46px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: var(--bg-card);
  color: var(--text-3); cursor: pointer; font-size: 12px; font-weight: 550;
  display: flex; align-items: center; justify-content: center;
  transition: color .14s var(--ease), border-color .14s var(--ease), background .14s var(--ease);
}
.corner-cell:hover { color: var(--text-2); border-color: var(--text-3); }
.corner-cell.on { color: var(--blue); border-color: rgba(92, 158, 232, .5); background: var(--blue-soft); }
/* 角上的点＝该角标会落在哪——它是这个 2×2 网格唯一的语义信息，
   太小太淡就退化成四个空按钮，用户只能靠文字读位置 */
.corner-dot { position: absolute; width: 9px; height: 9px; border-radius: 2px;
  background: currentColor; opacity: 1;
  box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 16%, transparent); }
.c-tl .corner-dot { top: 6px; left: 6px; }
.c-tr .corner-dot { top: 6px; right: 6px; }
.c-bl .corner-dot { bottom: 6px; left: 6px; }
.c-br .corner-dot { bottom: 6px; right: 6px; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }

/* 按钮体系四级归级（audit · 沿用旧类名，不改名只对齐度量）：
   主   primary  — .dlg-btn.primary（弹层确认）/ .apill-btn（播放，全站唯一实心族）
   次   secondary— .act-btn(.ok/.no 为语义色) / .exp-btn / .aspect-tab / .fchip / .vroute-tab / .tr-add
   危险 danger   — .dlg-btn.danger / .act-btn.no / .tr-del / .cmt-act.del
   幽灵 ghost    — .ghost-btn / .lb-x / .lb-nav / .cmt-act / .clip-btn
   同级统一字号/内边距/圆角（--btn-* token）；按压/键盘焦点全站一致。 */
.act-btn:active, .exp-btn:active, .dlg-btn:active, .tr-add:active, .fchip:active,
.vroute-tab:active, .aspect-tab:active, .clip-btn:active,
.cmt-act:active { transform: scale(.97); }
button:focus-visible { outline: 2px solid rgba(240, 166, 60, .5); outline-offset: 2px; }

/* 运动模式徽章 A/B/C/D */
.mbadge {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  padding: 3px 8px 3px 4px; border-radius: 6px;
  border: 1px solid transparent; background: var(--fill-soft);
  font: 500 10.5px/1.5 var(--font-mono); letter-spacing: .05em; color: var(--text-2);
}
.mbadge b {
  width: 16px; height: 16px; border-radius: 4px; display: grid; place-items: center;
  font: 700 10px/1 var(--font-mono); color: #0b0c0f;
  background: #8b93a7;   /* 兜底底色：新增档位漏配专属色时字母仍可读（黑字压深底=1.13:1） */
}
.mbadge.m-a b { background: #8b93a7; }
.mbadge.m-b b { background: var(--cyan); }
.mbadge.m-c b { background: var(--amber); }
.mbadge.m-d b { background: var(--blue); }

/* 状态点 */
.st {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; color: var(--text-2);
}
.st::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: #3a4150; }
.st.rendered::before { background: var(--green); box-shadow: 0 0 7px rgba(92, 158, 232, .5); }
.st.rendered { color: var(--green); }
.st.scripted::before { background: var(--blue); }
.st.scripted { color: var(--blue); }
.st.draft { color: var(--text-3); }
.st.active::before { background: var(--green); }
.st.archived::before { background: var(--text-3); }
.st.missing::before, .st.error::before { background: var(--red); }

/* 卡片基底：hairline 定形 + 顶光 + 微影——「浮起的面」三件套 */
.card {
  background: linear-gradient(180deg, var(--bg-card) 0%, var(--bg-panel) 100%);
  border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--hi), var(--shadow-1);
}

/* 空状态 */
.empty {
  border: 1px dashed var(--line-2); border-radius: var(--r-lg);
  padding: 48px 32px; text-align: center; color: var(--text-3);
}
.empty h3 { color: var(--text-2); font-size: 15px; margin-bottom: 6px; font-weight: 600; }
/* 空态的「下一步」槽：放的一律是一句话指令（对 AI 说：…），故居中并按内容收窄。
   text-align:left + 定宽是多行 CLI 命令的排法——代码块左对齐才读得顺，而一句话
   靠左躺在一个 560px 宽的居中框里，看着像没排版。 */
.empty pre {
  display: inline-block; margin: 18px auto 0; max-width: 560px; text-align: center;
  background: #0d0e12; border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 14px 18px; font: 12px/1.9 var(--font-mono); color: var(--text-2);
  white-space: pre-wrap;
}
.empty pre b { color: var(--amber); font-weight: 500; }

/* 音频胶囊播放器 */
.apill {
  display: flex; align-items: center; gap: 9px;
  background: #0d0f13; border: 1px solid var(--line); border-radius: 999px;
  padding: 5px 12px 5px 5px; min-width: 0;
}
.apill-btn {
  width: 26px; height: 26px; border-radius: 50%; flex: none;
  background: var(--amber); color: #14161b;
  display: grid; place-items: center; transition: transform .15s var(--ease), background .15s;
}
.apill-btn:hover { transform: scale(1.08); }
.apill-btn svg { width: 10px; height: 10px; fill: currentColor; stroke: none; }
.apill.playing .apill-btn { background: var(--text); }
.apill-track { flex: 1; height: 3px; border-radius: 2px; background: #262b35; position: relative; cursor: pointer; min-width: 40px; }
.apill-track i { position: absolute; inset: 0 auto 0 0; width: 0; border-radius: 2px; background: var(--amber); }
.apill-time { font: 500 10px/1 var(--font-mono); color: var(--text-3); flex: none; }
.apill-label { font-size: 11.5px; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ============================================================ 总览 */
.statband { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; margin-bottom: 24px; }
.stat {
  background: var(--bg-card); padding: 20px 22px 18px;
  display: flex; flex-direction: column; gap: 8px; position: relative; overflow: hidden;
}
.stat b { font: 600 30px/1 var(--font-mono); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.stat b small { font-size: 14px; color: var(--text-3); font-weight: 500; margin-left: 2px; }
.stat::after {
  content: ""; position: absolute; left: 22px; bottom: 0; width: 26px; height: 2px;
  background: var(--amber); opacity: 0; transition: opacity .2s;
}
.stat:hover::after { opacity: 1; }

/* 总览「最近成片」：只放最新 6 条，余量走区块头「更多」去片库——若做成
   `grid-auto-flow:column` 的横滑条，看第七条要横着拖，且滚动条常年横在区块下沿。
   列宽下限 230px 配 1680 的内容上限恰好排满六轨（首屏一行铺满、窄屏自然折行）；
   用 auto-fit 而非 auto-fill 是为了容器上限日后变宽时也不留空轨。 */
.recent-grid { display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }

/* profile 表 */
/* 指令集（PLAYBOOK）：协作模型流程 / skill 入口 / 协作范式 / CLI 速查 / 实战步骤 */
.gd-flow { display: flex; align-items: stretch; gap: 10px; flex-wrap: wrap; }
.gd-flow .gd-node { flex: 1 1 200px; padding: 14px 16px; }
.gd-node p { margin: 8px 0 0; font-size: 12px; line-height: 1.75; color: var(--text-2); }
.gd-arrow { align-self: center; color: var(--text-3); font-size: 15px; }
.gd-card { padding: 15px 18px; display: flex; flex-direction: column; gap: 8px; }
.gd-lead { margin: 0 0 4px; font-size: 12.5px; line-height: 1.8; color: var(--text-2); }
.gd-note { margin: 4px 0 0; font-size: 11.5px; line-height: 1.7; color: var(--text-3); }
.gd-say, .gd-cmd { display: flex; align-items: center; gap: 10px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--bg-card-2); padding: 8px 12px; }
.gd-say code { font: 600 12px/1.6 var(--font-mono); color: var(--amber); }
.gd-cmd code { font: 500 11.5px/1.6 var(--font-mono); color: var(--text); }
.gd-say span, .gd-cmd span { margin-left: auto; font-size: 11px; color: var(--text-3);
  white-space: nowrap; }
.gd-say .cmt-act, .gd-cmd .cmt-act { flex: none; }
.gd-say span + .cmt-act, .gd-cmd span + .cmt-act { margin-left: 0; }
.gd-say code, .gd-cmd code { overflow-wrap: anywhere; }
/* 对话即生产：场景卡——「你说 / Claude」对仗两行（同构版式：小标签列 +
   竖色轨 + 内容），无底色块，靠色轨与字色分声部 */
.gd-talks { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: 12px; }
.gd-talk { padding: 15px 17px; display: flex; flex-direction: column; gap: 10px; }
.gd-talk-t { font-size: 13.5px; }
.gd-quote, .gd-resp { display: flex; align-items: flex-start; gap: 10px; }
.gd-quote i, .gd-resp i { flex: none; width: 46px; padding-top: 2px;
  font: 600 9.5px/1.6 var(--font-mono); letter-spacing: .14em;
  font-style: normal; text-align: right; }
.gd-quote i { color: var(--text-3); }
.gd-resp i { color: var(--amber); }                    /* Claude 声部标签 · 琥珀 */
.gd-quote code, .gd-resp p { flex: 1; min-width: 0; margin: 0;
  padding-left: 11px; border-left: 2px solid; }
.gd-quote code { font: 600 12px/1.7 var(--font-mono); color: var(--amber);
  border-color: rgba(240, 166, 60, .55); overflow-wrap: anywhere; }
.gd-resp p { font-size: 11.5px; line-height: 1.75; color: var(--text-2);
  border-color: var(--line-2); }
.gd-quote .cmt-act { flex: none; }

.gd-loops { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 12px; }
.gd-loop { padding: 15px 17px; }
.gd-loop b { font-size: 13.5px; }
.gd-loop p { margin: 8px 0 0; font-size: 12px; line-height: 1.8; color: var(--text-2); }
.gd-cli { display: flex; flex-direction: column; gap: 12px; }
.gd-steps { display: flex; flex-direction: column; gap: 10px; }
.gd-step { padding: 14px 17px; display: flex; flex-direction: column; gap: 8px; }
.gd-step-head { display: flex; align-items: center; gap: 10px; }
.gd-step-no { font: 700 15px/1 var(--font-mono); color: var(--amber); }
.gd-step-head b:last-child { font-size: 13.5px; }
.gd-step > p { margin: 0; font-size: 12px; line-height: 1.8; color: var(--text-2); }

/* 风格档 · skill 分组展示（总览 03）：组卡=入口 skill，组内画风网格 */
.sp-groups { display: flex; flex-direction: column; gap: 14px; }
.sp-group { padding: 16px 18px 15px; }
.sp-ghead { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.sp-gcmd { font: 600 12px/1 var(--font-mono); color: var(--amber);
  background: var(--amber-soft);
  padding: 4px 10px; border-radius: 8px; }
.sp-gzh { font-size: 14.5px; font-weight: 650; }
.sp-gen { font: 600 9px/1 var(--font-mono); letter-spacing: .22em; color: var(--text-3); }
.sp-gcnt { font: 600 10px/1 var(--font-mono); color: var(--text-3); margin-left: auto; }
.sp-gusage { flex-basis: 100%; font-size: 12px; line-height: 1.6;
  color: var(--text-2); margin: 3px 0 11px; }
.sp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(236px, 1fr));
  gap: 10px; }
.sp-card { border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--bg-card-2); padding: 11px 13px 10px;
  display: flex; flex-direction: column; gap: 7px;
  transition: border-color .15s, transform .12s var(--ease); }
.sp-card:hover { border-color: var(--line-2); transform: translateY(-1px); }
.sp-head { display: flex; align-items: center; gap: 7px; }
.sp-head b { font-size: 13px; }
.sp-head .chip { font-size: 9.5px; padding: 1px 7px; }
.sp-id { margin-left: auto; font: 500 10px/1 var(--font-mono); color: var(--text-3); }
.sp-desc { margin: 0; font-size: 11px; line-height: 1.72; color: var(--text-2); }
.sp-meta { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; margin-top: auto; }
.sp-meta .chip { font-size: 10px; padding: 2px 8px; }
.sp-cmd { font: 600 10.5px/1 var(--font-mono); color: var(--amber); }
.sp-note { margin: 0; font-size: 10.5px; line-height: 1.5; color: var(--text-3); }
.sp-card { cursor: pointer; }

/* SKILL 指挥层大屏（#/skill）：分组骨架复用 .sp-group，卡片自有 .sk-* ——
   卡片整体**不可点**（只读档案，点击语义只落在画风档 code 上），故不做 hover 抬升 */
.sk-catline { margin: -6px 0 14px; display: flex; flex-wrap: wrap; gap: 8px; }
.sk-catline code { font: 500 10.5px/1 var(--font-mono); color: var(--text-3);
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 4px 8px; }
.sk-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 10px; }
.sk-card { border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--bg-card-2); padding: 12px 14px 11px;
  display: flex; flex-direction: column; gap: 7px; }
.sk-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sk-head b { font-size: 13px; }
.sk-head .chip { font-size: 9.5px; padding: 1px 7px; }
.sk-cmd { font: 600 11.5px/1 var(--font-mono); color: var(--amber); }
.sk-en { font: 600 9px/1 var(--font-mono); letter-spacing: .18em; color: var(--text-3); }
.sk-desc { margin: 0; font-size: 11px; line-height: 1.72; color: var(--text-2); }
.sk-profs { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.sk-profk { font: 600 10px/1 var(--font-mono); color: var(--text-3); margin-right: 2px; }
.sk-prof { font: 500 10.5px/1.4 var(--font-mono); color: var(--text-2);
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 2px 7px;
  cursor: pointer; transition: border-color .15s, color .15s; }
.sk-prof:hover { border-color: var(--line-2); color: var(--text); }
.sk-prof.def { color: var(--amber); border-color: color-mix(in srgb, var(--amber) 45%, transparent); }
.sk-prof.off { cursor: default; color: var(--text-3); border-style: dashed; }
.sk-meta { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; margin-top: auto; }
.sk-meta .chip { font-size: 10px; padding: 2px 8px; }
.sk-src { margin-left: auto; font: 500 9.5px/1.4 var(--font-mono); color: var(--text-3);
  overflow-wrap: anywhere; }
/* 02 区「落地命令」面板内的命令列：行体复用 .gd-cmd/.gd-say，只负责竖排间距——
   不借 .gd-card，那份自带内边距，套进门牌面板会叠成两层 */
.sk-cmds { display: flex; flex-direction: column; gap: 8px; }

/* 指令集弹层（顶栏直开·不跳路由）：与画风详情弹窗同制式，只是幅面大得多——
   装的是整页 PLAYBOOK（六段：协作模型 / 对话即生产 / skill 入口 / 协作范式 /
   命令速查 / 实战步骤）。**宽度必须给到 1180**：gd-talks 与 gd-loops 是
   minmax(340px, 1fr) / minmax(300px, 1fr) 的 auto-fit 网格，弹层一窄就整列塌成
   单列，六张对话卡拉成一根要滚半天的长条。高度取定值而非 max-height：内容远高于
   视口，定高才能让「头固定 + 体滚动 + 足提示」三段稳住不随内容跳。
   滚动容器**保持块级**（不是 flex）——viewGuide 的段间距由 .sec 的 34px 外边距
   给，套上 flex + gap 会两份叠加。 */
.gdm-wrap { position: relative; width: min(1180px, 94vw); height: min(88vh, 1040px);
  background: var(--bg-panel); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 18px 22px 14px; display: flex; flex-direction: column; gap: 12px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, .5); animation: pop .16s var(--ease); }
.gdm-title { font-size: 15px; }
.gdm-en { margin-left: 10px; font: 600 9px/1 var(--font-mono); letter-spacing: .22em;
  font-style: normal; color: var(--text-3); }
.gdm-scroll { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  padding-right: 10px; scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.gdm-wrap .rf-foot { border-top: 1px solid var(--line); padding-top: 11px; }

/* 画风详情弹窗：头固定 · 体滚动 · 基因/参数/对话三段 */
.stm-wrap { position: relative; width: min(680px, 94vw); max-height: 84vh;
  background: var(--bg-panel); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 18px 20px 14px; display: flex; flex-direction: column; gap: 12px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, .5); animation: pop .16s var(--ease); }
.stm-title { font-size: 15px; }
.stm-id { margin-left: 10px; font: 500 11px/1 var(--font-mono); color: var(--text-3); }
.stm-scroll { overflow-y: auto; overscroll-behavior: contain; min-height: 0;
  display: flex; flex-direction: column; gap: 9px; padding-right: 6px;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.stm-k { font: 600 9.5px/1 var(--font-mono); letter-spacing: .2em;
  color: var(--text-3); margin-top: 7px; }
.stm-k:first-child { margin-top: 0; }
.stm-dna { margin: 0; font-size: 12.5px; line-height: 1.9; color: var(--text); }
.stm-en { margin: 0; font: 500 10.5px/1.8 var(--font-mono); color: var(--text-3); }
.stm-rows { display: flex; flex-direction: column; gap: 5px; }
.stm-row { display: flex; align-items: baseline; gap: 12px; font-size: 12px; }
.stm-row span { flex: none; width: 60px; color: var(--text-3); }
.stm-row b { font-weight: 500; color: var(--text-2); }
.stm-say { padding: 2px 0; }

.ptable { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.ptable th {
  text-align: left; padding: 9px 14px; font: 600 9.5px/1 var(--font-mono);
  letter-spacing: .18em; text-transform: uppercase; color: var(--text-3);
  border-bottom: 1px solid var(--line-2); white-space: nowrap;
}
.ptable td { padding: 10px 14px; border-bottom: 1px solid var(--line); color: var(--text-2); vertical-align: top; }
.ptable tr:last-child td { border-bottom: 0; }
.ptable tbody tr { transition: background .12s; }
.ptable tbody tr:hover { background: rgba(255, 255, 255, .02); }
.ptable .pname { font: 500 12px/1.6 var(--font-mono); color: var(--text); }
.ptable .pfx { color: var(--text-3); font-size: 11.5px; max-width: 320px; }

/* ============================================================ 项目卡片 */
.proj-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: 18px; }
/* will-change:transform 把卡片常驻为独立合成层——圆角裁剪蒙版只栅格一次、烘进图层纹理，
   悬停上浮是纯合成位移（不逐帧重栅格裁剪），消除残余的边缘白线 */
.pcard { overflow: hidden; cursor: pointer; will-change: transform;
  transition: transform .25s var(--ease), border-color .2s, box-shadow .25s; }
.pcard:hover { transform: translateY(-3px); border-color: var(--line-2); box-shadow: var(--hi), var(--shadow-2); }
.pcard-cover { aspect-ratio: 21/9; background: #0d0f13; position: relative; overflow: hidden; }
/* 悬停不缩放封面图——图片相对卡片体的缩放运动会扰动「图片底缘 ↔ 卡片体」这条高对比
   接缝，过渡期间把明亮的图片底边抗锯齿糊成一道白线（缩放是相对运动，卡片整体上浮是同步运动
   故不闪）。用纯 opacity 提亮做悬停反馈：不动几何、不碰接缝，零白边闪烁 */
.pcard-cover img { width: 100%; height: 100%; object-fit: cover; opacity: .9; transition: opacity .3s var(--ease); }
.pcard:hover .pcard-cover img { opacity: 1; }
.pcard-cover .noimg {
  position: absolute; inset: 0; display: grid; place-items: center;
  color: var(--text-3); font: 500 10px/1 var(--font-mono); letter-spacing: .3em;
  background:
    repeating-linear-gradient(-45deg, transparent 0 14px, rgba(255,255,255,.018) 14px 28px),
    radial-gradient(ellipse at 30% 20%, rgba(240,166,60,.05), transparent 60%);
}
.pcard-cover::after { content: ""; position: absolute; inset: auto 0 0 0; height: 60%; background: linear-gradient(transparent, rgba(11,12,15,.9)); }
/* 真封面缺位标：兜底图源顶上来后横幅看着「有图」，不点名封面这步就一直欠着。
   兜底图源常是高亮度分镜图，纯灰字会糊在里面——压一层局部暗角保证可读，
   不做成盒子（药丸标签会跟画风 chip 抢视线） */
.pcard-nocover { position: absolute; top: 0; right: 0; z-index: 2; padding: 10px 12px 16px 26px;
  font: 500 9.5px/1 var(--font-mono); letter-spacing: .18em; color: rgba(255,255,255,.66);
  text-shadow: 0 1px 6px rgba(0,0,0,.9);
  background: radial-gradient(ellipse at 90% 0%, rgba(0,0,0,.55), transparent 72%); }
.pcard-over { position: absolute; left: 16px; bottom: 12px; right: 16px; z-index: 2; display: flex; align-items: flex-end; justify-content: space-between; gap: 10px; }
.pcard-over h3 { font-size: 16.5px; font-weight: 650; letter-spacing: .01em; text-shadow: 0 2px 8px rgba(0,0,0,.6); }
.pcard-over .pid { font: 500 10px/1 var(--font-mono); letter-spacing: .12em; color: var(--text-2); margin-top: 4px; }
.pcard-body { padding: 14px 16px 16px; display: flex; flex-direction: column; gap: 12px; }
.pcard-theme { font-size: 12.5px; color: var(--text-2); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.segbar { display: flex; gap: 3px; height: 5px; }
.segbar i { flex: 1; border-radius: 3px; background: #262b35; }
.segbar i.rendered { background: var(--green); }
.segbar i.scripted { background: var(--blue); }
.pcard-stats { display: flex; gap: 20px; }
.pcard-stat b { display: block; font: 600 15px/1.2 var(--font-mono); }
.pcard-stat span { font-size: 10.5px; color: var(--text-3); }

/* ============================================================ 项目详情 */
.head-hero { display: flex; flex-direction: column; gap: 12px; margin-bottom: 22px;
  position: relative; }   /* 右上角挂「删除项目」绝对定位按钮 */

/* 软删（逻辑删除）：回收站横幅 / 项目删除钮 / 回收站清单 */
.recycle-banner { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  border: 1px solid rgba(239, 106, 90, .4); background: var(--red-soft);
  border-radius: var(--r-lg); padding: 12px 16px; margin-bottom: 14px; }
.recycle-banner b { color: var(--red); font-size: 13.5px; }
.recycle-banner span { flex: 1; min-width: 220px; font-size: 12px;
  line-height: 1.7; color: var(--text-2); }
/* 移至回收站的项目=只读冻结：容器内一切操作控件统一灰化禁用（视觉层）。
   点击层面另有捕获拦截器兜底（app.js），连 onclick 的 div 卡片也一并冻结；
   仅放行导航链接 / 章节行 / .ro-keep 恢复钮。 */
.ro-deleted button,
.ro-deleted input,
.ro-deleted select,
.ro-deleted textarea,
.ro-deleted .act-btn,
.ro-deleted .exp-btn,
.ro-deleted .fchip,
.ro-deleted .aspect-tab,
.ro-deleted .vroute-tab,
.ro-deleted .tr-add,
.ro-deleted .cmt-act {
  opacity: .45 !important; filter: grayscale(1);
  pointer-events: none !important; cursor: not-allowed;
}
.ro-deleted a[href],
.ro-deleted .chap-row,
.ro-deleted .ro-keep {
  opacity: 1 !important; filter: none;
  pointer-events: auto !important; cursor: pointer;
}
.recycle-list { padding: 4px 12px; display: flex; flex-direction: column; }
.recycle-row { display: flex; align-items: center; gap: 12px;
  padding: 10px 6px; border-bottom: 1px solid var(--line); font-size: 12.5px; }
.recycle-row:last-child { border-bottom: 0; }
.recycle-row b { font-size: 13px; }
.recycle-row code { font: 500 11px/1 var(--font-mono); color: var(--text-3); }
.recycle-row .rc-meta { margin-left: auto; color: var(--text-3); font-size: 11.5px; }
.head-hero h1 { font-size: 27px; font-weight: 700; letter-spacing: -.015em; }
.head-hero .sub { color: var(--text-2); font-size: 13.5px; max-width: 760px; }
/* 系列主视觉（cover 命令产物，3:4 竖版）——有封面时头部转横排 */
.head-hero.with-cover { flex-direction: row; align-items: flex-start; gap: 18px; }
.head-hero .head-hero-txt { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.series-cover { flex: 0 0 auto; width: 132px; aspect-ratio: 3 / 4; border-radius: var(--r-lg);
  overflow: hidden; border: 1px solid var(--line); cursor: zoom-in;
  box-shadow: 0 6px 22px rgba(0, 0, 0, .35); }
.series-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 封面未生成的占位：与真封面同尺寸同位，斜纹底 + 等宽小字，hover 出补做命令 */
.series-cover.ph { display: grid; place-items: center; cursor: help; box-shadow: none;
  color: var(--text-3); font: 500 9.5px/1 var(--font-mono); letter-spacing: .18em;
  background: repeating-linear-gradient(-45deg, transparent 0 14px, rgba(255,255,255,.018) 14px 28px); }
/* 设定格阵：flex 换行而非 grid 自动列——末行不满时余下的格自动伸展填平；
   grid 的空列会露出 1px 线底，读起来像整块掉了一格。 */
.design-grid { display: flex; flex-wrap: wrap; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; }
/* 格底取页面底色而非 --bg-card：本段上下相邻的都是无卡片的裸区块（参考库、场景俯视图），
   卡片灰在长页里自成一块浅色台面。格与格之间靠容器 1px 线底分隔，结构不丢。
   注意底色必须是不透明的 --bg：透明会让容器的半透明线底整片透上来，等于整块提亮。 */
.design-cell { flex: 1 1 190px; min-width: 0; background: var(--bg); padding: 16px 18px;
  display: flex; flex-direction: column; gap: 6px; }
.design-use { font-size: 10.5px; line-height: 1.6; color: var(--text-3); }
.design-cell.wide { flex-basis: 100%; }
/* 缺字段不靠底色区分（同处黑底），由字段名减淡 + 斜体「未填写」承担 */
.design-cell.miss .k { opacity: .6; }
.design-empty { color: var(--text-3); font-style: italic; opacity: .7; }
.bible-intro { margin: -4px 0 12px; font-size: 12px; line-height: 1.75;
  color: var(--text-2); }
.design-cell p { font-size: 13px; color: var(--text-2); margin-top: 7px; line-height: 1.7; }

/* ── 拆书圣经（剧本工作台「拆书」Tab）──
   与通用 .design-grid 的差别是**字段体量**：拆书的 world_bible 动辄数千字、名场面能到几十条，
   照通用格阵的 flex-basis:190px 会把六个长文字段挤成六条窄柱、全挤在一起看不全。
   故：① 每个字段整行铺开；② 正文按 column-width 报纸式分栏，保证每栏行宽落在可读区间；
   ③ 正文 pre-wrap——拆书文本靠 \n 分节，塌成一坨就没法读；
   ④ 爽点/名场面是**整句**，改列表渲染，绝不能再用 .chip（nowrap 会把句子横向裁断）。 */
.bible-grid .bible-cell { padding: 18px 20px 20px; }
.bible-prose { font-size: 13px; color: var(--text-2); line-height: 1.78; margin-top: 9px;
  white-space: pre-wrap; column-width: 33em; column-gap: 40px; column-rule: 1px solid var(--line);
  text-align: justify; hyphens: auto; }
.bible-list { margin-top: 10px; display: grid; gap: 7px;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); align-items: start; }
.bible-li { display: flex; gap: 9px; align-items: baseline; padding: 9px 12px; border-radius: 9px;
  background: var(--bg-card-2); border: 1px solid var(--line);
  font-size: 12.5px; line-height: 1.68; color: var(--text-2);
  transition: border-color .13s var(--ease), background .13s var(--ease); }
.bible-li:hover { background: var(--bg-hover); border-color: var(--line-2); }
.bible-li-n { flex: none; font: 600 10px/1.9 var(--font-mono); opacity: .8; letter-spacing: .04em; }
.bible-li-t { min-width: 0; word-break: break-word; }
.bible-li.amber { border-left: 2px solid rgba(240, 166, 60, .55); }
.bible-li.amber .bible-li-n { color: var(--amber); }
.bible-li.cyan { border-left: 2px solid rgba(76, 195, 217, .5); }
.bible-li.cyan .bible-li-n { color: var(--cyan); }

/* 角色设定卡 */
/* 340 宽容得下一行 3 个按钮（音色路线 tab + 试音/锁定按钮不挤成两行） */
/* 角色设定：**固定每行两张**（不用 auto-fill）——角色设定图是 16:9 三区 model sheet，
   一行里挤三四张后每张只剩三百多像素宽，三区里的正脸肖像与全身像全糊成一团，
   而这个区块存在的意义恰恰是"看清楚锚点"。两列 = 单张够大 + 仍能左右对照两个角色。 */
.char-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }
/* 带设定图的卡片（角色/道具/取景地/场景俯视）整块用 --bg-sheet：图与它下面的文字体
   同一层底，卡片由 1px hairline 定形而不是由两块深浅不同的色块拼出来。.card 缺省的
   渐变（--bg-card → --bg-panel）比图片承托面亮一档，图下方会突然亮起来，
   读作「文字块贴在图上」。渐变留给不带设定图的卡片（选角块、侧栏卡）。 */
.ccard { overflow: hidden; display: flex; flex-direction: column; will-change: transform;
  background: var(--bg-sheet); }
/* 容器比例必须**等于设定图本身的 16:9**：若用别的比例（如 3:2）配 `object-fit: cover`，
   16:9 的三区表会被左右各裁掉一截——最左区那张正脸肖像正好被切掉小半，
   而"锁死面部锚点"恰恰是这一区的全部意义。同比例 = 一像素不裁。 */
.ccard-sheet { aspect-ratio: 16/9; background: var(--bg-sheet); position: relative; cursor: zoom-in; overflow: hidden; }
/* 设定图版本徽章：sheet 右上角金色 vN 角标 → 点开版本谱系（与分镜版本徽章同义），归档≥1 才现 */
.ver-badge { position: absolute; top: 8px; right: 8px; z-index: 2;
  font: 600 11px/1 var(--font-mono); padding: 4px 8px; border-radius: 999px;
  background: rgba(8, 9, 11, .72); color: var(--amber); border: 1px solid transparent;
  cursor: pointer; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); transition: all .14s; }
.ver-badge:hover { background: var(--amber); color: #1a1205; }
/* 同项目卡：不缩放（相对运动会糊「设定图底缘↔卡片体」接缝白线），改 opacity 提亮做悬停反馈 */
.ccard-sheet img { width: 100%; height: 100%; object-fit: cover; opacity: .94; transition: opacity .3s var(--ease); }
.ccard-sheet:hover img { opacity: 1; }
.ccard-sheet .nosheet, .scene-fig .nosheet, .scene-plan .nosheet {
  position: absolute; inset: 0; display: flex; flex-direction: column; gap: 8px;
  align-items: center; justify-content: center; color: var(--text-3);
  background: repeating-linear-gradient(-45deg, transparent 0 14px, rgba(255,255,255,.018) 14px 28px);
  cursor: default;
}
.ccard-sheet .nosheet svg, .scene-fig .nosheet svg, .scene-plan .nosheet svg { width: 30px; height: 30px; stroke: currentColor; fill: none; stroke-width: 1; opacity: .55; }
.ccard-sheet .nosheet span, .scene-fig .nosheet span, .scene-plan .nosheet span { font: 500 9.5px/1 var(--font-mono); letter-spacing: .22em; }
.ccard-body { padding: 14px 15px 15px; display: flex; flex-direction: column; gap: 9px; }
.ccard-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
/* 名字恒不换行：设定文案长（角色定位长条）时被挤的是右侧 chip，不是名字——
   .ccard-name 一旦可收缩，「宁雀」会被压成一列竖字（实测）；超长名（取景地）截断出省略号 */
.ccard-head h4 { font-size: 15px; font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 名字 + ⧉ 调校设定 小按钮同排（不占整行）；按钮沿用 .act-btn 风格、更紧凑 */
.ccard-name { display: flex; align-items: center; gap: 8px; flex: none; max-width: 72%; }
.ccard-edit, .chap-edit { flex: none; padding: 2px 8px; font-size: 10.5px; white-space: nowrap; }
/* 章节标题后的「⧉ 打磨本集」：与标题基线对齐、间距舒展 */
.chap-edit { margin-left: 14px; vertical-align: middle; }
/* 角色定位 chip 是这一排唯一的弹性项：吃剩余宽度、内部自然换行 */
.ccard-role { font-size: 10.5px; color: var(--amber); background: var(--amber-soft); padding: 2.5px 8px; border-radius: 10px; flex: 0 1 auto; min-width: 0; line-height: 1.55; }
.ccard-desc { font-size: 12px; color: var(--text-2); line-height: 1.65; }
.ccard-attrs { display: flex; flex-direction: column; gap: 4px; }
.ccard-attr { display: flex; gap: 8px; font-size: 11.5px; }
.ccard-attr .k { padding-top: 3px; flex: none; width: 34px; }
.ccard-attr span { color: var(--text-2); }

/* 设定区「未生成」抽屉：大量无图空卡不平铺展示，收进按需展开的折叠段 */
.fold-sec { margin-top: 12px; }
.fold-sec .fold-toggle { width: 100%; text-align: left; padding: 8px 12px; color: var(--text-3); }
.fold-sec .fold-body { margin-top: 12px; }

/* 道具卡 */
/* 道具/取景地卡：**定量四列**而非 auto-fill——auto-fill 在宽屏上会挤到一行五六个，
   每张缩到 190px 时物件细节与取景地全貌都看不清（设定图是拿来核对细节的）。
   四列在 1440px 下每张约 340px，与「角色设定图一行两张」的疏密节奏也对得上。 */
.prop-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.prcard { overflow: hidden; container-type: inline-size; display: flex; flex-direction: column;
  background: var(--bg-sheet); }
/* 头图按**生成规格**显示（CSS 变量由卡片按 kind 注入：道具 1/1 方图、
   取景地跟项目比例）——统一成一个框就必然裁掉一边，而设定图正是拿来看全貌的 */
.prcard .ccard-sheet { aspect-ratio: var(--sheet-ar, 4/3); }
.prcard-body { padding: 11px 13px 13px; }
/* 名字恒不换行（与 .ccard-head h4 同规则）：取景地长名（「陆昭的十二平米（母亲的画室）」）
   在 190px 卡里会折成两三行——名字截断出省略号，类型 chip 与 ⧉ 调校按钮恒完整靠右 */
/* 与角色卡 .ccard-head 同版式：[名字 + ⧉ 调校设定] 成一组靠左，类型 chip 靠右。
   名字恒不换行（长取景地名截断出省略号），可收缩的是 chip 不是名字。 */
/* 道具/取景地卡头：名字 / 动作组（素材直供+调校+类型标签）/ 描述 三段 grid。
   宽卡：名字一行截断出省略号、动作组靠右恒完整；窄卡（容器查询按卡宽判，不看视口）：
   名字整行完整展示，动作组沉到卡底——按钮文字任何宽度下绝不折行 */
.prcard-body { display: grid; grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "name actions" "desc desc"; align-items: center; column-gap: 8px;
  flex: 1; }   /* 卡体拉满剩余高度——窄卡下动作组才有"底"可钉 */
.prcard-title { grid-area: name; font-size: 13px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.prcard-actions { grid-area: actions; display: flex; align-items: center; gap: 7px;
  justify-content: flex-end; }
.prcard-actions .act-btn, .prcard-actions .chip, .ccard-name .act-btn { white-space: nowrap; }
.prcard-body p { grid-area: desc; font-size: 11.5px; color: var(--text-3); margin-top: 4px; }
@container (max-width: 340px) {
  /* 340px = 动作组（素材直供+调校+标签 ≈240px）+ 最短名字 + 卡内边距的临界值：
     名字与按钮真的挤不进一行才沉底；描述行 1fr 吃掉剩余高度，并排卡的
     按钮与类型标签自动对齐在同一条底线上 */
  .prcard-body { grid-template-columns: minmax(0, 1fr); row-gap: 7px;
    grid-template-areas: "name" "desc" "actions";
    grid-template-rows: auto 1fr auto; }
  .prcard-title { white-space: normal; overflow: visible; text-overflow: clip; }
  .prcard-body p { align-self: start; }
  .prcard-actions { justify-content: flex-start; flex-wrap: wrap; align-self: end; }
}

/* 场景设定 */
/* 固定场景：**整行一张**。场景设定图是 16:9 的定场画面，塞进 380px 侧栏等于
   把"这一集的世界长什么样"缩成缩略图；改为通栏大图 + 提示词压在下方，
   与全站卡片语言一致（图上不压字，文字另起一块，读图与读词互不打扰）。 */
.scene-wrap { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; align-items: start;
  border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden;
  background: var(--bg-sheet); }
.scene-fig { position: relative; overflow: hidden; cursor: zoom-in; background: var(--bg-sheet);
  aspect-ratio: 16/9; }
.scene-fig img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 一个场景两张图：基准图说「看上去什么样」、俯视图说「空间怎么摆」，同区成对呈现
   （拆到两个区去，读者得自己把它们配起来）。**但两格不等分**——基准图是全片的光线与
   陈设基准，通栏大图那份分量要留住；俯视图是图纸，作附图与 SCENE PROMPT 同排即可。
   等分并排试过：缺俯视图时右半屏是一堵灰墙，而基准图被腰斩成半宽缩略。 */
.scene-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(200px, 28%);
  gap: 1px; background: var(--line); border-top: 1px solid var(--line); }
.scene-body .scene-txt { border-top: 0; background: var(--bg-sheet); }
.scene-plan { position: relative; overflow: hidden; background: var(--bg-sheet); min-height: 128px; }
/* 图纸用 contain 不用 cover：平面图被裁掉一角就读不出空间边界了，
   留边反而像「图纸贴在版面上」，与编辑部版面语言一致 */
.scene-plan img { width: 100%; height: 100%; object-fit: contain; display: block; cursor: zoom-in; }
.scene-cap { position: absolute; left: 10px; bottom: 8px; z-index: 2; pointer-events: none;
  font: 500 9.5px/1 var(--font-mono); letter-spacing: .2em; color: var(--text-3);
  text-shadow: 0 1px 3px rgba(0, 0, 0, .85); }
@media (max-width: 900px) { .scene-body { grid-template-columns: minmax(0, 1fr); } }
.scene-txt { font-size: 13px; color: var(--text-2); line-height: 1.85;
  padding: 14px 18px 16px; border-top: 1px solid var(--line); }
.scene-txt .k { display: block; margin-bottom: 6px; }
/* 固定场景的 SCENE PROMPT 头排：标签靠左 · ⧉ 调校设定靠右（与设定卡同制度） */
.scene-txt-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.scene-txt-head .k { margin-bottom: 0; }

/* 章节表 */
.chap-table { border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; }
/* 行底透明、只靠 hairline 分行：表格不由一摞色块拼成，行是「纸上的行」，
   hover 整行洗亮即是全部的交互反馈 */
.chap-row {
  display: grid; grid-template-columns: 84px 40px minmax(200px, 1.4fr) 104px 128px repeat(3, minmax(64px, .55fr)) 88px;
  gap: 14px; align-items: center; padding: 12px 18px;
  border-bottom: 1px solid var(--line);
  cursor: pointer; transition: background .15s;
}
.chap-row:last-child { border-bottom: 0; }
.chap-row:hover { background: var(--bg-hover); }
.chap-row.hdr { cursor: default; padding: 9px 18px; }
.chap-row.hdr:hover { background: transparent; }
.chap-row.hdr span { font: 600 9.5px/1 var(--font-mono); letter-spacing: .18em; text-transform: uppercase; color: var(--text-3); }
.chap-thumb { width: 84px; aspect-ratio: 16/9; border-radius: 6px; overflow: hidden; background: #0d0f13; position: relative; }
.chap-thumb img { width: 100%; height: 100%; object-fit: cover; }
.chap-thumb .ph { position: absolute; inset: 0; display: grid; place-items: center; color: var(--text-3); font-size: 12px; }
.chap-ord { font: 600 12px/1 var(--font-mono); color: var(--text-3); }
.chap-title { font-size: 14px; font-weight: 550; overflow: hidden; }
.chap-title b { display: block; font-weight: 550; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chap-title small { display: block; font: 400 10px/1.7 var(--font-mono); color: var(--text-3); }
.chap-num { font: 500 12.5px/1.4 var(--font-mono); color: var(--text-2); }
.chap-num .u { color: var(--text-3); font-size: 10.5px; }

/* ============================================================ 章节制作台 */
/* 阶段带走编辑部语言：上下两道 hairline 夹一条透明带，格间不立竖墙——
   进度光条（.stage-prog）贴住下缘 hairline，读作「这条流水线亮到哪了」 */
.stagebar { display: flex; align-items: stretch; border-block: 1px solid var(--line); overflow: hidden; margin-bottom: 22px; }
.stage {
  flex: 1; display: flex; align-items: center; gap: 11px; padding: 14px 18px;
  position: relative;
  cursor: pointer; transition: background .14s;   /* 格子即页内锚点 */
}
.stage:hover { background: rgba(255, 255, 255, .03); }
.stage-ico {
  width: 26px; height: 26px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  border: 1.5px solid var(--line-2); color: var(--text-3);
  font: 600 11px/1 var(--font-mono);
}
.stage.done .stage-ico { border-color: var(--green); background: var(--green-soft); color: var(--green); }
.stage.part .stage-ico { border-color: var(--amber); color: var(--amber); animation: pulse-a 2s infinite; }
.stage.skip .stage-ico { border-style: dashed; opacity: .55; }
@keyframes pulse-a { 0%, 100% { box-shadow: 0 0 0 0 rgba(240,166,60,.28); } 50% { box-shadow: 0 0 0 5px rgba(240,166,60,0); } }
.stage-txt b { display: block; font-size: 12.5px; font-weight: 600; }
.stage-txt span { font: 500 10px/1.6 var(--font-mono); color: var(--text-3); }
.stage.done .stage-txt span { color: var(--green); }
.stage.part .stage-txt span { color: var(--amber); }
/* 阶段格：EN 小标 + 步进箭头 + 底部进度细条（纯展示，不可点） */
.stage-en { margin-left: 7px; font: 500 8.5px/1 var(--font-mono);
  letter-spacing: .18em; color: var(--text-3); font-style: normal; }
.stage-arrow { margin-left: auto; color: var(--text-3); opacity: .45;
  font-size: 13px; flex: none; padding-left: 6px; }
.stage-prog { position: absolute; left: 0; bottom: 0; height: 2px;
  background: var(--green); opacity: .9; transition: width .3s var(--ease); }
.stage.part .stage-prog { background: var(--amber); }
.stage.todo .stage-prog, .stage.skip .stage-prog { display: none; }

.console { display: grid; grid-template-columns: minmax(300px, 380px) minmax(0, 1fr); gap: 22px; align-items: start; margin-top: 22px; }
/* 左栏检查器范式：sticky 钉在顶栏下 + 视口限高 + 自带内滚——
   右侧滚动时左栏固定；鼠标移到左栏滚轮只滚它自己（断滚动链，到边不带走页面） */
.console-side { display: flex; flex-direction: column; gap: 16px;
  position: sticky; top: calc(var(--chrome-h) + 21px);
  max-height: calc(100vh - var(--chrome-h) - 41px); overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent;
  padding-right: 5px; margin-right: -5px; }
.console-side::-webkit-scrollbar { width: 5px; }
.console-side::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 4px; }
.console-side::-webkit-scrollbar-track { background: transparent; }
.console-side > * { flex: none; }   /* 卡片不被压缩，超出走内滚 */
/* 侧栏区块头只靠 flex gap(16px) 定间距，不叠加 .sec 的 34/16 外边距——
   否则 抬头→视频 与 视频→抬头 会双倍留白；与 SB 分镜卡抬头上下间隔看齐 */
.console-side > .sec { margin: 0; }
.side-card { padding: 16px 17px; display: flex; flex-direction: column; gap: 12px; }
/* ═══ 陪伴面板三件套：放映合卡 / 成本迷你行 / 一致性健康条 ═══ */
.screen-wrap { display: flex; flex-direction: column; gap: 10px; }
.scr-tabs { display: flex; gap: 6px; }
.scr-tab { flex: 1; padding: 6px 0; border-radius: 8px; text-align: center;
  border: 1px solid transparent; background: var(--fill-soft); color: var(--text-3);
  font: 600 10.5px/1.6 var(--font-mono); letter-spacing: .08em; transition: all .15s; }
.scr-tab:hover { color: var(--text); background: var(--bg-hover); }
.scr-tab.on { background: var(--amber-soft); color: var(--amber); }
.cost-strip { display: flex; align-items: baseline; gap: 9px; padding: 11px 15px;
  border: 1px solid var(--line); border-radius: var(--r-md); background: var(--bg-panel);
  transition: border-color .15s; }
.cost-strip b { font: 600 16px/1 var(--font-mono); color: var(--amber);
  font-variant-numeric: tabular-nums; }
.cost-strip span { font-size: 11px; color: var(--text-2); }
.cost-strip i { font: 500 10px/1.4 var(--font-mono); color: var(--text-3);
  font-style: normal; }
.cost-strip em { margin-left: auto; font: 500 10px/1.4 var(--font-mono);
  color: var(--text-3); font-style: normal; transition: color .15s; }
.cost-strip:hover { border-color: var(--line-2); }
.cost-strip:hover em { color: var(--amber); }
.cons-strip { border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--bg-panel); overflow: hidden; }
.cons-line { display: flex; align-items: baseline; gap: 9px; padding: 11px 15px; }
.cons-line b { font-size: 11.5px; color: var(--green); flex: none; }
.cons-strip.warn .cons-line b { color: var(--amber); }
.cons-line span { font: 500 10px/1.6 var(--font-mono); color: var(--text-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 右栏叙事线：下沉区块的呼吸与双列 */
.shots-col + .sec, .flow-grid + .sec, .sb-card + .sec { margin-top: 36px; }
.flow-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 16px; align-items: start; }
/* 右栏顶部状态带：成本 × 一致性并排等高，一瞥可知 */
.status-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 14px; align-items: stretch; margin-bottom: 22px; }
.status-row .cost-strip { align-items: center; }
.status-row .cons-strip .cons-line { height: 100%; align-items: center; }
.side-card > .k { display: flex; justify-content: space-between; align-items: baseline; }
.side-card > .k .sub { letter-spacing: 0; text-transform: none; font-size: 10px; color: var(--text-3); }

.final-player { position: relative; border-radius: var(--r-md); overflow: hidden;
  background: #000; border: 1px solid var(--line); }
/* 画布放大 + 比例自关联：竖屏给足高度、横屏/方形按各自比例锁画布，避免小窗看片 */
.final-player video { width: 100%; max-height: min(74vh, 920px); display: block; background: #000; }
.final-player[data-aspect="16x9"] video { aspect-ratio: 16/9; object-fit: contain; }
.final-player[data-aspect="9x16"] video { aspect-ratio: 9/16; object-fit: contain; max-height: min(78vh, 960px); }
.final-player[data-aspect="1x1"] video { aspect-ratio: 1/1; object-fit: contain; }

/* 转场镜瓦片：黑场光带小卡（fade_white 反白）——时间线/列表里的过场占位，拒绝空图 */
.tr-thumb { position: relative; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 3px; overflow: hidden; color: #e8eaf0;
  background: radial-gradient(130% 95% at 50% 45%, #262b36 0%, #0b0d12 78%);
  border: 1px solid var(--line-2); border-radius: 8px; }
.tr-thumb::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 32%, rgba(255, 255, 255, .08) 50%, transparent 68%); }
.tr-thumb-ico { font-size: 13px; opacity: .7; line-height: 1; }
.tr-thumb-txt { font: 500 9.5px/1.2 var(--font-mono); letter-spacing: .3em; margin-right: -.3em;
  max-width: 90%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; opacity: .92; }
.tr-thumb.white { color: #30343b;
  background: radial-gradient(130% 95% at 50% 45%, #ffffff 0%, #d8dce5 82%); }
.ln-node .tr-thumb { width: 84px; aspect-ratio: var(--ln-aspect, 16/9); height: auto; max-height: 118px; }
.ln-node.hot .tr-thumb { border-color: var(--amber); }
/* 放映卡头行：比例页签靠左、「历史」靠右。单比例时左侧为空，右侧照常在位——
   故这一行恒渲染（页签数不决定行的存在），否则单比例章节没地方挂历史入口。 */
.fc-head { display: flex; align-items: center; gap: 8px; min-height: 24px; }
.fc-head-right { margin-left: auto; display: flex; gap: 6px; flex: none; }
.fc-hist { color: var(--text-3); }        /* 档案入口比"看哪个比例"轻一档 */
.fc-hist:hover { color: var(--amber); background: var(--amber-soft); }
.aspect-tabs { display: flex; gap: 6px; flex-wrap: wrap; }
.aspect-tab {
  padding: 4px 11px; border-radius: 999px; border: 1px solid transparent;
  font: 500 11px/1.6 var(--font-mono); color: var(--text-3); transition: all .15s;
}
.aspect-tab:hover { color: var(--text); background: var(--bg-hover); }
.aspect-tab.active { background: var(--amber-soft); color: var(--amber); }
.aspect-tab.wm.active { background: var(--blue-soft); color: var(--blue); }
.out-meta { display: flex; gap: 12px; flex-wrap: wrap; font: 500 10.5px/1.6 var(--font-mono); color: var(--text-3); }
.out-meta .wm-tag { color: var(--blue); font-weight: 700; letter-spacing: .04em; }

.script-block { display: flex; flex-direction: column; gap: 10px; }
.script-item { border-left: 2px solid var(--line-2); padding: 2px 0 2px 12px; }
.script-item.hook { border-color: var(--amber); }
.script-item.cta { border-color: var(--green); }
.script-item p { font-size: 12.5px; color: var(--text-2); line-height: 1.7; margin-top: 4px; }

.kv { display: flex; flex-direction: column; gap: 8px; }
.kv-row { display: flex; gap: 10px; font-size: 12px; align-items: baseline; }
.kv-row .k { flex: none; width: 58px; padding-top: 2px; }
.kv-row div { color: var(--text-2); line-height: 1.65; min-width: 0; overflow-wrap: anywhere; }
.kv-row code.val { font-size: 11px; color: var(--cyan); }

.voice-line { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-2); flex-wrap: wrap; }
.voice-line b { font-weight: 600; color: var(--text); }
.voice-line .arrow { color: var(--text-3); }
.voice-line code { font-size: 10px; color: var(--text-3); }

.cost-rows { display: flex; flex-direction: column; gap: 6px; }
.cost-row { display: flex; align-items: baseline; gap: 8px; font-size: 12px; }
.cost-row .lbl { color: var(--text-2); text-transform: capitalize; }
.cost-row .dots { flex: 1; border-bottom: 1px dotted var(--line-2); transform: translateY(-3px); }
.cost-row .val { font: 500 12px/1 var(--font-mono); }
.cost-row.total { padding-top: 7px; border-top: 1px solid var(--line); }
.cost-row.total .lbl { color: var(--text); font-weight: 600; }
.cost-row.total .val { color: var(--amber); font-size: 14px; }

/* 分镜（场记板卡） */
.shots-col { display: flex; flex-direction: column; gap: 14px; }
.shot-card { display: grid; grid-template-columns: minmax(150px, 208px) minmax(0, 1fr); overflow: hidden; }
/* ============================================================ 转场镜 */
.transition-card { display: flex; grid-template-columns: none; background: #0b0d12;
  border-style: dashed; }
.transition-card.white { background: #f4f2ee; }
.transition-card.white .tr-txt b { color: #30343b; }
.transition-card.white .tr-txt small { color: #8a8f98; }
.tr-body { display: flex; align-items: center; gap: 14px; padding: 14px 18px; width: 100%; }
.tr-icon { font-size: 20px; opacity: .7; }
.tr-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.tr-txt b { font-size: 15px; letter-spacing: .18em; }
.tr-txt small { color: var(--text-2); font-size: 11.5px; letter-spacing: .04em; }
.tr-del { border: 1px solid transparent; background: var(--fill-soft); color: var(--text-2);
  border-radius: 8px; width: 26px; height: 26px; cursor: pointer; }
.tr-del:hover { color: var(--red); background: var(--red-soft); }
.tr-slot { display: flex; justify-content: center; margin: -6px 0; opacity: 0;
  transition: opacity .15s; }
.shots-col:hover .tr-slot { opacity: .55; }
.tr-slot:hover { opacity: 1 !important; }
.tr-add { border: 1px dashed var(--line); background: var(--bg-2, transparent);
  color: var(--text-2); border-radius: 999px; padding: 3px 14px; font-size: 11.5px;
  cursor: pointer; letter-spacing: .08em; }
.tr-add:hover { color: var(--accent, #ffd45e); border-color: var(--accent, #ffd45e); }
.shot-visual { position: relative; background: #0d0f13; cursor: zoom-in; min-height: 150px; }
.shot-visual img, .shot-visual video { width: 100%; height: 100%; object-fit: cover; position: absolute; inset: 0; }
.shot-visual .ph {
  position: absolute; inset: 0; display: flex; flex-direction: column; gap: 8px;
  align-items: center; justify-content: center; color: var(--text-3);
  font: 500 9.5px/1 var(--font-mono); letter-spacing: .2em;
  background: repeating-linear-gradient(-45deg, transparent 0 14px, rgba(255,255,255,.02) 14px 28px);
  cursor: default;
}
.slate {
  position: absolute; top: 0; left: 0; z-index: 2;
  background: rgba(8, 9, 11, .88); border-right: 1px solid var(--line-2); border-bottom: 1px solid var(--line-2);
  border-radius: 0 0 9px 0;
  padding: 5px 10px 5px 9px;
  font: 700 10.5px/1 var(--font-mono); letter-spacing: .1em; color: var(--amber);
}
/* ▸ CLIP 角标：与左上 .slate 同一套贴角版式（右上镜像·青色区分「有成片素材」）——
   胶囊浮签会读成第三种视觉语言，SHOT/CLIP 是同级的「本镜身份牌」 */
.shot-visual .clipmark {
  position: absolute; top: 0; right: 0; z-index: 2;
  background: rgba(8, 9, 11, .88); border-left: 1px solid var(--line-2); border-bottom: 1px solid var(--line-2);
  border-radius: 0 0 0 9px;
  padding: 5px 9px 5px 10px;
  font: 700 10.5px/1 var(--font-mono); letter-spacing: .1em; color: var(--cyan);
}
/* 直供徽标与 CLIP 角标同侧共存时下移让位（clipmark 在 DOM 前位） */
.shot-visual .dur-tag {
  position: absolute; right: 8px; bottom: 8px; z-index: 2;
  background: rgba(8,9,11,.85); border-radius: 5px; padding: 3px 7px;
  font: 500 10px/1 var(--font-mono); color: var(--text-2);
}
.shot-card.omitted { opacity: .45; filter: grayscale(.5); }
.shot-card.omitted:hover { opacity: .8; }
.slate.omt { color: var(--red); }
.shot-main { padding: 13px 16px 14px; display: flex; flex-direction: column; gap: 9px; min-width: 0; }
.shot-meta { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.shot-meta .spk { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--text); }
.shot-meta .spk i { font-style: normal; font-size: 10.5px; color: var(--amber); font-weight: 500; }
.shot-narr { font-size: 13.5px; line-height: 1.7; color: var(--text); }
.shot-cap { font-size: 11.5px; color: var(--text-3); }
.shot-media { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.shot-media .apill { flex: 1 1 200px; max-width: 320px; }
.prompt-fold { border-top: 1px dashed var(--line); padding-top: 8px; }
.prompt-fold summary {
  cursor: pointer; list-style: none; display: flex; align-items: center; gap: 7px;
  font: 500 10px/1 var(--font-mono); letter-spacing: .16em; color: var(--text-3);
  text-transform: uppercase; user-select: none;
}
.prompt-fold summary::-webkit-details-marker { display: none; }
.prompt-fold summary::before { content: "›"; transition: transform .2s; font-size: 12px; }
.prompt-fold[open] summary::before { transform: rotate(90deg); }
.prompt-fold summary:hover { color: var(--text-2); }
.prompt-rows { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
/* 实发提示词预览：编辑部式节奏——mono 眉行压 hairline（TAG 琥珀、模型小字右对齐）、
   正文深底块、负面串独立 AVOID 块（琥珀左缘 + 极淡底色，同一强调色不另起红）。 */
.pv-sec { margin-top: 4px; }   /* 容器 .prompt-rows 自带 8px gap，合计 12px */
.pv-sec:first-child { margin-top: 2px; }
.pv-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  border-bottom: 1px solid var(--line); padding-bottom: 5px; margin-bottom: 7px;
}
.pv-head .tag {
  font: 600 9px/1.8 var(--font-mono); letter-spacing: .14em; color: var(--amber);
}
.pv-meta { font: 10px/1.8 var(--font-mono); color: var(--text-3); letter-spacing: .04em; }
.pv-note { font-size: 11px; color: var(--text-3); line-height: 1.7; margin: 0 0 6px; }
.pv-prompt {
  white-space: pre-wrap; word-break: break-word; font-family: inherit;
  font-size: 12px; line-height: 1.75; color: var(--text-2);
  background: #0d0f13; border: 1px solid var(--line); border-radius: 7px;
  padding: 9px 12px; margin: 0; max-height: 40vh; overflow: auto;
}
.pv-neg {
  display: flex; gap: 10px; align-items: baseline;
  margin-top: 7px; padding: 6px 11px 6px 9px;
  border-left: 2px solid var(--amber-deep);
  background: rgba(240, 166, 60, .05);
  border-radius: 0 7px 7px 0;
}
.pv-neg-tag {
  flex: none; font: 600 10px/1.7 var(--font-mono);
  letter-spacing: .06em; color: var(--amber-deep);
}
.pv-neg-txt { font-size: 11.5px; line-height: 1.7; color: var(--text-3); }
/* 音色锚定注记：与上方正文/AVOID 块留出呼吸位（负面块在 bodyHost 容器内，
   相邻兄弟选择器够不着，走专属类） */
.pv-anchor-note { margin-top: 10px; }
/* 实发稿内的引用记号（@图片N/@视频N/参考音频N）：琥珀虚线底可点，点开即看/即听。
   记号不许在行尾折断：折成两行的行内元素外接矩形横跨整行，悬浮提示按它居中就落到
   面板正中而不是记号旁 */
.pv-ref {
  color: var(--amber); cursor: pointer; text-decoration: none; white-space: nowrap;
  border-bottom: 1px dashed rgba(240, 166, 60, .4);
}
.pv-ref:hover { border-bottom-color: var(--amber); filter: brightness(1.15); }
.pv-ref-dim { color: var(--amber-deep); cursor: default; border-bottom: none; opacity: .8; }
img.pv-peek {
  display: block; max-width: 100%; max-height: 78vh; object-fit: contain;
  border: 1px solid var(--line); border-radius: 8px; margin: 6px 0;
}
/* @图片 弹框加宽：参考图要看清细节。复合选择器提权——同权重时表尾的
   .skb-dlg(560px) 会按书写顺序反压回去 */
.dlg-card.pv-peek-dlg { width: min(1400px, 96vw); }
.pv-peek-dlg img.pv-peek { max-height: 82vh; width: 100%; }
/* 中英对照切换（pv-head 右侧 mono 小字，当前语种琥珀点亮） */
.pv-head-r { display: flex; align-items: baseline; gap: 12px; }
.pv-langs { font: 600 9px/1.8 var(--font-mono); color: var(--text-3); letter-spacing: .08em; }
.pv-lang { color: var(--text-3); cursor: pointer; }
.pv-lang:hover { color: var(--text-2); }
.pv-lang.on { color: var(--amber); }
/* 审阅锁（紧随 MOTION TAG）：徽记已审蓝/审后有变琥珀；「通过」主操作蓝色无下划线，
   「撤销」弱化为灰、悬停才亮 */
.pv-head-l { display: inline-flex; align-items: baseline; gap: 14px; }
.pv-appr-box { display: inline-flex; align-items: baseline; gap: 10px; }
.pv-appr { font: 600 10px/1.8 var(--font-mono); letter-spacing: .08em; }
.pv-appr.ok { color: var(--blue); }
.pv-appr.stale { color: var(--amber); }
.pv-appr-act {
  font: 600 10px/1.8 var(--font-mono); letter-spacing: .08em;
  color: var(--blue); cursor: pointer;
}
.pv-appr-act:hover { filter: brightness(1.2); }
.pv-appr-act.dim { color: var(--text-3); }
.pv-appr-act.dim:hover { color: var(--text-2); filter: none; }
.pv-peek-audio { margin: 8px 0; }
/* 放映窗信息栏里的实发稿：宿主是 rowk 的 <code>，字体要拉回正文栈 */
.pv-cin { display: block; }
.pv-cin .pv-prompt { font-family: var(--font-ui); max-height: 34vh; }
.pv-cin .pv-neg { margin-top: 6px; }
.prompt-row { display: flex; gap: 10px; }
.prompt-row .tag {
  flex: none; font: 600 9px/1.8 var(--font-mono); letter-spacing: .1em;
  color: var(--text-3); width: 44px; text-align: right;
}
.prompt-row p {
  font-size: 12px; color: var(--text-2); line-height: 1.7;
  background: #0d0f13; border: 1px solid var(--line); border-radius: 7px; padding: 7px 11px; flex: 1;
}
.prompt-row .p-en {
  display: block; margin-top: 5px; padding-top: 5px; border-top: 1px dashed var(--line);
  color: var(--text-3); font-size: 11px; font-style: italic;
}
.prompt-row.neg p { border-color: rgba(239,106,90,.25); color: var(--text-3); }
.prompt-row.neg .tag { color: var(--red); }

/* ============================================================ 成片库 */
.filter-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 18px; }
/* 左＝新建项目主行动；右组（检索 + 筛选 chip）margin-left:auto 整体靠右对齐 */
.filter-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  justify-content: flex-end; margin-left: auto; }
[hidden] { display: none !important; }
.fsearch { min-width: 260px; padding: 8px 12px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: var(--bg-card-2); color: var(--text);
  font-size: 12.5px; line-height: 1.4; outline: none;
  transition: border-color .15s; margin-bottom: 2px; }
.filter-right .fsearch { flex: 0 1 360px; max-width: 420px; }
.fsearch:focus { border-color: var(--amber); }
.fsearch::placeholder { color: var(--text-3); }
.stat.amber b { color: var(--amber); }
.stat.red b { color: var(--red); }
.ledger tbody tr:nth-child(even) td { background: rgba(255, 255, 255, .015); }
.ledger tbody tr:hover td { background: var(--bg-hover); }
.ledger tfoot td { font-weight: 700; border-top: 1px solid var(--line-2); border-bottom: none; }
.fchip {
  padding: 5px 13px; border-radius: 999px; border: 1px solid transparent;
  font-size: 11.5px; color: var(--text-3); transition: all .15s;
}
.fchip:hover { color: var(--text); background: var(--bg-hover); }
.fchip.active { background: var(--amber-soft); color: var(--amber); }
.fsep { width: 1px; height: 18px; background: var(--line-2); margin: 0 4px; }
/* 片库工具条：项目下拉定宽（`.us` 本体 width:100%，不定宽会被 flex 拉走）。 */
.lib-bar .us { width: 210px; flex: none; }
/* 检索框度量是**跨页同一条**（片库 / 待审队列 / 看板）：这三处搜的东西同量级
   （标题＋项目＋章节＋镜号＋阶段），420 基准 / 620 上限——框再短就
   看不全自己打的字。分两条写就必然只改一处，三个页面的同一个框长短不一。
   `.kb-toolbar` 不换行，故它额外保留 min-width:0（见下：窄屏要能缩）。 */
.lib-bar .fsearch, .kb-toolbar .fsearch { flex: 1 1 420px; max-width: 620px; }
.lib-bar .fsearch { min-width: 320px; }

.gal-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 16px; }
.vcard { overflow: hidden; cursor: pointer; transition: transform .25s var(--ease), border-color .2s, box-shadow .25s; }
.vcard:hover { transform: translateY(-3px); border-color: var(--line-2); box-shadow: var(--hi), var(--shadow-2); }
.vposter { position: relative; aspect-ratio: 16/10; background: #0d0f13; overflow: hidden; }
.vposter img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s var(--ease); }
.vcard:hover .vposter img { transform: scale(1.05); }
.vposter .playhint {
  position: absolute; inset: 0; display: grid; place-items: center;
  background: rgba(8,9,11,.25); opacity: 0; transition: opacity .2s;
}
.vcard:hover .playhint { opacity: 1; }
.playhint span {
  width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(240,166,60,.92); color: #14161b; font-size: 15px; padding-left: 3px;
  box-shadow: 0 6px 24px rgba(0,0,0,.5);
}
.vposter .tc {
  position: absolute; right: 8px; bottom: 8px;
  background: rgba(8,9,11,.85); border-radius: 5px; padding: 3px 8px;
  font: 500 10.5px/1 var(--font-mono); color: var(--text);
}
.vposter .asp {
  position: absolute; left: 8px; bottom: 8px;
  background: rgba(8,9,11,.85); border-radius: 5px; padding: 3px 8px;
  font: 500 10px/1 var(--font-mono); color: var(--text-2);
}
.vcard-body { padding: 12px 14px 13px; display: flex; flex-direction: column; gap: 8px; }
.vcard-body h4 { font-size: 13.5px; font-weight: 600; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.vcard-sub { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.vcard-sub .src { font-size: 11px; color: var(--text-3); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

/* ============================================================ 灯箱 / 放映厅 */
.cinema { position: fixed; inset: 0; z-index: 100; display: grid; place-items: center; }
/* 灯箱与版本谱系(.vpanel)互为上下层，末次打开者置顶（JS raiseModal 动态切 120/121）：
   谱系里点缩略图→灯箱盖上；灯箱里点「版本谱系」→谱系盖上。z 基值仅首开生效，之后由内联覆盖 */
.lightbox { position: fixed; inset: 0; z-index: 120; display: grid;
  grid-template-columns: minmax(0, 1fr) 360px; }
.lightbox[hidden], .cinema[hidden] { display: none; }
.lb-backdrop, .cin-backdrop { position: absolute; inset: 0; background: var(--scrim);
  backdrop-filter: var(--scrim-blur); -webkit-backdrop-filter: var(--scrim-blur); }
.lb-stage { position: relative; z-index: 2; display: grid; place-items: center;
  padding: 30px 34px; min-width: 0; max-height: 100vh; margin: 0;
  animation: pop .3s var(--ease); }
@keyframes pop { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }
.lb-canvas { position: relative; }
.lb-stage img { max-width: 100%; max-height: calc(100vh - 60px); object-fit: contain;
  border-radius: var(--r-md); box-shadow: var(--shadow-pop); display: block; }

/* 右侧全高操作面板（inspector 制式：头部/信息/操作/评论/元信息） */
.lb-side { position: relative; z-index: 2; height: 100vh; display: flex;
  flex-direction: column; background: var(--bg-panel); border-left: 1px solid var(--line); }
.lb-side-head { display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 15px 18px; border-bottom: 1px solid var(--line); flex: none; }
.lb-side-title { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.lb-side-title b { font: 600 12px/1.4 var(--font-mono); letter-spacing: .1em;
  color: var(--amber); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lb-side-title i { font: 500 10px/1 var(--font-mono); color: var(--text-3);
  font-style: normal; flex: none; }
.lb-side-body { flex: 1; min-height: 0; overflow-y: auto; padding: 16px 18px;
  display: flex; flex-direction: column; gap: 20px;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
/* 段头一行两件事：左标题、右动作。四个段共用这条 flex（其余三段没有右件，
   纯文本 h5 在 flex 容器里的观感与块级一致，不必为 INFO 单开一个类）。 */
.lbs h5 { margin: 0 0 9px; font: 600 9.5px/1 var(--font-mono); letter-spacing: .22em;
  color: var(--text-3); text-transform: uppercase;
  display: flex; align-items: center; gap: 10px; min-height: 20px; }
/* 段头动作：**纯文字形态**，无框无底——它是段落标题的附属动作，画成按钮就在
   面板里多出一个与「操作 · ACTIONS」区那三块实心钮抢层级的视觉块。`font: inherit`
   直接继承 h5 的等宽微型字，读起来是标题行的一部分；只靠颜色区分可点与否。 */
.lb-copy { margin-left: auto; flex: none; padding: 0; border: 0; background: none;
  font: inherit; letter-spacing: .1em; color: var(--text-3);
  transition: color .15s var(--ease); }
.lb-copy:hover { color: var(--amber); }
.lb-copy:active { opacity: .65; }
/* 复制成功的瞬时态：文字转琥珀钉住 1.4s 再退回——toast 在屏幕另一头，
   手指还在这儿，反馈就该落在按下去的那个点上。 */
.lb-copy.ok { color: var(--amber); }
.lb-cap { font-size: 12.5px; color: var(--text-2); line-height: 1.8;
  white-space: pre-line; }   /* 简笔板灯箱的逐拍对照表按行排（其余单行文案不受影响） */
.lb-act { display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  width: 100%; padding: 10px 13px; margin-bottom: 8px; text-align: left;
  border-radius: var(--r-sm); border: 1px solid transparent;
  background: var(--fill-soft); transition: all .15s var(--ease); }
.lb-act b { font-size: 12.5px; font-weight: 600; color: var(--text); }
.lb-act span { font: 500 10px/1.5 var(--font-mono); color: var(--text-3); }
.lb-act:hover { border-color: var(--amber); transform: translateY(-1px); }
.lb-act.on { border-color: rgba(240, 166, 60, .5); background: var(--amber-soft); }
.lb-act.on b { color: var(--amber); }
/* 重新生成 + 垫图参考 同排各半 */
.lb-act-row { display: flex; gap: 8px; }
.lb-act-row .lb-act { flex: 1; width: auto; min-width: 0; }
/* 双模式分段选择器（提意见｜局部改造）：并排等分，激活琥珀 */
.lb-segbar { display: flex; gap: 8px; margin-bottom: 10px; }
.lb-seg { flex: 1; display: flex; flex-direction: column; align-items: flex-start;
  gap: 3px; padding: 9px 12px; text-align: left; border-radius: var(--r-sm);
  border: 1px solid transparent; background: var(--fill-soft);
  transition: all .15s var(--ease); }
.lb-seg b { font-size: 12.5px; font-weight: 600; color: var(--text); }
.lb-seg span { font: 500 9.5px/1.5 var(--font-mono); color: var(--text-3); }
.lb-seg:hover { border-color: var(--text-3); }
.lb-seg.on { border-color: rgba(240, 166, 60, .55); background: var(--amber-soft); }
.lb-seg.on b { color: var(--amber); }
#lb-strokes { position: absolute; inset: 0; pointer-events: none; z-index: 1; }
#lb-pins { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
#lb-pins .lb-pin { pointer-events: auto; }
.lb-side-meta { flex: none; padding: 12px 18px; border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: 6px 14px;
  font: 500 10px/1.6 var(--font-mono); color: var(--text-3); }
@media (max-width: 900px) {
  .lightbox { grid-template-columns: 1fr; grid-template-rows: minmax(0, 1fr) auto; }
  .lb-side { height: auto; max-height: 46vh; border-left: none;
    border-top: 1px solid var(--line); }
  .lb-stage img { max-height: 50vh; }
}
.vp-sheet .lb-x, .cin-panel .lb-x { position: absolute; top: 18px; right: 20px;
  z-index: 3; width: 34px; height: 34px; border-radius: 50%; }
.lb-x {
  flex: none; width: 30px; height: 30px; border-radius: 9px;
  background: rgba(255,255,255,.06); border: 1px solid transparent;
  color: var(--text-2); font-size: 13px; transition: all .15s;
}
.lb-x:hover { color: var(--text); background: rgba(255,255,255,.12); }
.lb-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 3;
  width: 44px; height: 44px; border-radius: 50%;
  background: rgba(255,255,255,.05); border: 1px solid transparent;
  color: var(--text-2); font-size: 22px; line-height: 1; transition: all .15s;
}
.lb-nav:hover { color: var(--amber); border-color: rgba(240,166,60,.5); }
.lb-prev { left: 24px; } .lb-next { right: 384px; }

.cin-panel {
  position: relative; z-index: 2; width: min(1400px, 94vw);
  background: var(--bg-panel); border: 1px solid var(--line-2); border-radius: 16px;
  overflow: hidden; box-shadow: var(--shadow-pop); animation: pop .3s var(--ease);
  display: grid; grid-template-columns: minmax(0, 1fr) 380px;
}
.cin-player { background: #000; display: grid; place-items: center; }
.cin-player video { width: 100%; max-height: 82vh; }
.cin-meta { padding: 22px 20px; display: flex; flex-direction: column; gap: 14px; border-left: 1px solid var(--line); overflow-y: auto; max-height: 82vh; }
.cin-meta h3 { font-size: 16px; font-weight: 650; line-height: 1.45; }
.cin-meta .rowk { display: flex; justify-content: space-between; gap: 10px; font-size: 12px; }
/* 标签列不参与换行收缩，换行发生在内容侧 */
.cin-meta .rowk span { color: var(--text-3); white-space: nowrap; flex-shrink: 0; }
.cin-meta .rowk code { color: var(--text-2); font-size: 11px; text-align: right; }
/* 长文本行（openCinema 按值长度加 .stack）：标签在上，内容整宽左对齐换行 */
.cin-meta .rowk.stack { flex-direction: column; align-items: stretch; gap: 6px; }
.cin-meta .rowk.stack code { text-align: left; white-space: pre-wrap;
  line-height: 1.75; }
/* 信息栏内的入口按钮（版本谱系）用紧凑档——台账行字号 11px，标准按钮档过大 */
.cin-meta .rowk .ghost-btn { padding: 3px 8px; font-size: 11px; gap: 5px; }
.cin-open { margin-top: auto; justify-content: center; text-align: center; }
.cin-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: -4px; }
/* 时间码：琥珀 mono 等宽数字，随播放跳动的机房仪表 */
.cin-meta .rowk code.cin-tc { color: var(--amber);
  font-variant-numeric: tabular-nums; }

/* ============================================================ 审阅交互 */
/* 待审角标 */
.qbadge { margin-left: auto; font: 500 8.5px/1 var(--font-mono);
  letter-spacing: .2em; color: var(--text-3); font-style: normal; }
.qbadge.has {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 18px; padding: 0 6px; letter-spacing: 0;
  border-radius: 999px; background: var(--amber); color: #14161b;
  font: 700 10.5px/1 var(--font-mono);
  box-shadow: 0 0 10px rgba(240, 166, 60, .35);
}
.nav-item.active .qbadge.has { color: #14161b; }

/* 表态按钮 */
.stage-cell { display: inline-flex; align-items: center; gap: 3px; }
.chip.clickable { cursor: pointer; }
.chip.clickable:hover { border-color: var(--line-2); }
/* 次级动作钮＝软填静默钮：无描边（边框占位透明，供 ref-pinned 等选中态上色），
   hover 提亮底色。一行六个描边 chip 是盒子墙，一行六个软填钮是一条安静的工具行。 */
.act-btn {
  border: 1px solid transparent; border-radius: 6px; padding: var(--btn-pad-sm);
  font-size: var(--btn-fs-sm); color: var(--text-2); transition: all .15s; line-height: 1.5;
  background: var(--fill-soft);
}
.act-btn:hover { color: var(--text); background: var(--bg-hover); }
.act-btn.ok { color: var(--green); }
.act-btn.ok:hover { background: var(--green-soft); }
.act-btn.no { color: var(--red); }
.act-btn.no:hover { background: var(--red-soft); }
/* 状态位：与同排动作钮同度量，只是不可点（如候选行的「已入档」——它与「选定」
   同宽同高，一列按钮才不会因为一条已入档就参差） */
.act-btn.state { color: var(--amber); background: var(--amber-soft);
  cursor: default; }
.act-btn.big { padding: var(--btn-pad); font-size: var(--btn-fs); border-radius: var(--btn-r); white-space: nowrap; }
.act-btn.sm { padding: 3px 10px; font-size: 11px; border-radius: 5px; }
.act-btn:disabled { opacity: .5; cursor: default; }

/* 剧本改编（ADAPTATION）页：上传投放区 + 源文本指针 + 分集大纲卡 */
.adapt-drop {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 36px 24px; text-align: center; cursor: pointer;
  border: 1.5px dashed var(--line-2); border-radius: var(--r-lg);
  background: linear-gradient(180deg, var(--bg-card), var(--bg-panel));
  transition: border-color .18s var(--ease), background .18s var(--ease), transform .12s var(--ease);
}
.adapt-drop:hover, .adapt-drop:focus-visible {
  border-color: var(--amber); outline: none;
  background: linear-gradient(180deg, var(--amber-soft), var(--bg-panel));
}
.adapt-drop.drag { border-color: var(--amber); background: var(--amber-soft); transform: scale(.996); }
.adapt-drop-ico { width: 38px; height: 38px; color: var(--amber); }
.adapt-drop-ico svg {
  width: 100%; height: 100%; fill: none; stroke: currentColor;
  stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
}
.adapt-drop-title { font-size: 15px; font-weight: 650; color: var(--text); }
.adapt-drop-sub { font-size: 12.5px; color: var(--text-2); }
.adapt-drop-hint { font-size: 11px; color: var(--text-3); margin-top: 2px; }
.adapt-reup { margin-left: 8px; }
.adapt-src { padding: 14px 16px; margin-bottom: 12px; }
.adapt-src > .k { display: block; margin-bottom: 8px; }
.adapt-src-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.adapt-src-row b { font-size: 13px; color: var(--text); }
.adapt-src-row code { font-size: 11.5px; color: var(--text-2); font-family: var(--font-mono);
  background: var(--bg-card-2); padding: 2px 7px; border-radius: 5px; }
.adapt-sha { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-3); margin-left: auto; }
/* 集卡最小宽 360：每张要放 logline + 四条钩子（开场/核心/爽点/尾钩），
   300px 时四条钩子各自折成三四行，整列变成一堵字墙。 */
.adapt-eps { display: grid; grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: 12px; }
.adapt-ep { background: var(--bg-card); border: 1px solid var(--line);
  border-left: 3px solid var(--line-2); border-radius: var(--r-md); padding: 13px 15px;
  display: flex; flex-direction: column; gap: 7px; transition: border-color .2s var(--ease); }
.adapt-ep:hover { border-color: var(--line-2); }
.adapt-ep.built { border-left-color: var(--green); }
.adapt-ep-hd { display: flex; align-items: center; gap: 9px; }
.adapt-ep-hd b { font-size: 13.5px; color: var(--text); flex: 1; }
.adapt-ep-hd a.chip { text-decoration: none; }
.adapt-no { font-family: var(--font-mono); font-size: 11px; font-weight: 700;
  color: var(--amber); letter-spacing: .3px; }
.adapt-log { font-size: 12.5px; color: var(--text-2); line-height: 1.65; margin: 0; }
.adapt-hooks { display: flex; flex-direction: column; gap: 4px; }
.adapt-hooks span { font-size: 11.5px; color: var(--text-3); line-height: 1.55; }
.adapt-hooks .hook-end { color: var(--amber); }
.adapt-dim { font-size: 10.5px; color: var(--text-3); }

/* 剧本工作台入口卡：hover 参照上传区——金边 + 顶部琥珀渐变（元素自身背景，内含不外溢、无发光） */
.studio-entry { display: flex; align-items: center; gap: 16px; padding: 15px 18px;
  cursor: pointer; border-radius: var(--r-lg); border: 1px solid var(--line);
  background: linear-gradient(180deg, var(--bg-card), var(--bg-panel));
  transition: border-color .18s var(--ease), background .18s var(--ease), transform .12s var(--ease); }
.studio-entry:hover, .studio-entry:focus-visible { outline: none; border-color: var(--amber);
  background: linear-gradient(180deg, var(--amber-soft), var(--bg-panel)); }
.studio-sub { flex: 1; min-width: 0; font-size: 12.5px; color: var(--text-2); line-height: 1.6; }
.studio-go { flex: none; display: inline-flex; align-items: center; gap: 6px; color: var(--amber);
  font: 600 12.5px/1 var(--font-ui); letter-spacing: .02em; white-space: nowrap; }
.studio-arrow { font-style: normal; transition: transform .18s var(--ease); }
.studio-entry:hover .studio-arrow { transform: translateX(4px); }

/* 剧本工作台：设定登记表 + 正文分段查看器 */
/* 风格垫图 MOODBOARD（项目级参考图）*/
/* 参考库整块：内部 .sec 作为首子会被 .sec:first-child 归零，故区块上间距挪到外层与其他模块一致 */
.mb-section { margin-top: 34px; }
.mb-wrap { display: flex; flex-direction: column; gap: 10px; }
.mb-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 12px; }
.mb-item { position: relative; aspect-ratio: 1; border-radius: var(--r-md); overflow: hidden;
  border: 1px solid var(--line); background: var(--bg-card); }
.mb-item img { width: 100%; height: 100%; object-fit: cover; cursor: zoom-in; display: block; }
.mb-del { position: absolute; top: 6px; right: 6px; width: 22px; height: 22px; padding: 0; border: none;
  border-radius: 6px; background: rgba(11, 12, 15, .66); color: #fff; font-size: 15px; line-height: 1;
  cursor: pointer; opacity: 0; transition: opacity .13s var(--ease); }
.mb-item:hover .mb-del { opacity: 1; }
.mb-del:hover { background: var(--red); }
/* 默认启用开关：✓ 蓝底=默认套用全局生成 / ○ 灰底=停用留库 */
.mb-tog { position: absolute; top: 6px; left: 6px; width: 22px; height: 22px; padding: 0; border: none;
  border-radius: 6px; background: var(--blue); color: #fff; font-size: 13px; font-weight: 700; line-height: 1;
  cursor: pointer; opacity: .92; transition: all .13s var(--ease); }
.mb-tog:hover { opacity: 1; transform: scale(1.08); }
.mb-item.mb-off .mb-tog { background: rgba(11, 12, 15, .66); color: var(--text-3); }
.mb-item.mb-off img { filter: grayscale(1) opacity(.5); }
.mb-item.mb-off { border-style: dashed; }
.mb-add { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  aspect-ratio: 1; border: 1px dashed var(--line-2); border-radius: var(--r-md); background: transparent;
  color: var(--text-3); font: 550 12px var(--font-ui); cursor: pointer; transition: all .14s var(--ease); }
.mb-add:hover { border-color: var(--amber); color: var(--amber); background: var(--amber-soft); }
.mb-add-ico { font-size: 22px; line-height: 1; }
.mb-hint { font-size: 11.5px; color: var(--text-3); line-height: 1.6; }

.ent-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 14px; }
.ent-card { display: flex; gap: 12px; background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 12px; }
.ent-thumb { width: 60px; height: 60px; flex: none; border-radius: var(--r-sm); overflow: hidden;
  background: #0d0f13; cursor: zoom-in; }
.ent-thumb img { width: 100%; height: 100%; object-fit: cover; }
.ent-nothumb { display: flex; align-items: center; justify-content: center; cursor: default;
  font-size: 10px; color: var(--text-3); letter-spacing: .05em; }
.ent-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.ent-name { font-size: 13.5px; font-weight: 600; color: var(--text); display: flex; align-items: center; gap: 7px; }
.ent-badge { font: 600 9px/1 var(--font-mono); letter-spacing: .1em; padding: 2px 6px; border-radius: 4px;
  background: var(--amber-soft); color: var(--amber); text-transform: uppercase; }
.ent-badge.prop { background: var(--cyan-soft); color: var(--cyan); }
.ent-sub { font-size: 11.5px; color: var(--text-2); line-height: 1.6; margin: 0;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.ent-voice { font-size: 10.5px; color: var(--text-3); }

.seg-list { display: flex; flex-direction: column; gap: 8px; }
.seg-item { border: 1px solid var(--line); border-radius: var(--r-md);
  background: linear-gradient(180deg, var(--bg-card), var(--bg-panel)); overflow: hidden; }
.seg-item.open { border-color: var(--line-2); }
.seg-head { display: flex; align-items: center; gap: 10px; padding: 11px 14px; cursor: pointer;
  transition: background .14s var(--ease); }
.seg-head:hover { background: var(--bg-hover); }
.seg-idx { font: 600 11px/1 var(--font-mono); color: var(--amber); flex: none; }
.seg-title { font-size: 13px; font-weight: 550; color: var(--text); flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.seg-range { font: 500 10.5px/1 var(--font-mono); color: var(--text-3); flex: none; }
.seg-cev { color: var(--text-3); transition: transform .15s var(--ease); flex: none; }
.seg-item.open .seg-cev { transform: rotate(90deg); }
.seg-prev { padding: 0 14px 11px 40px; font-size: 12px; color: var(--text-3); line-height: 1.6;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.seg-body { margin: 0; padding: 4px 16px 16px 40px; font-family: var(--font-ui); font-size: 13px;
  color: var(--text-2); line-height: 1.85; white-space: pre-wrap; word-break: break-word;
  max-height: 60vh; overflow-y: auto; }

/* ═══ 剧本工作台：全屏两栏「阅读工作台」（抬头可折叠 + 左目录/右Tab 各自独立滚动）═══ */
/* 全屏应用态：吃掉 .view 内边距，工作台以 flex 链占满视口剩余高度、内部各自滚动、页面不滚 */
.view.view-app { padding: 0; overflow: hidden; }
.view.view-app.enter > * { animation: none; }        /* 全屏态禁 rise 动画（避免裁切） */
/* 高度由 JS 按 app 距顶实测钉死（.main 用 min-height 不封顶，纯 CSS flex 链拿不到确定高度）*/
.script-app { display: flex; flex-direction: column; overflow: hidden; padding: 20px 32px 0; }

/* 抬头 · 书封题头（masthead）：书名做主角（衬线大字）+ 右侧数据带 + 下排指令行；
   阅读模式整块折叠吸顶让位正文（机制沿用：max-height 过渡 + pointer-events 摘除） */
.script-head { display: flex; flex-direction: column; gap: 13px; flex: none; overflow: hidden;
  max-height: 320px; margin-bottom: 16px;
  transition: max-height .3s var(--ease), opacity .22s var(--ease), margin-bottom .3s var(--ease); }
.script-app.reading .script-head { max-height: 0; opacity: 0; margin-bottom: 0; pointer-events: none; }
.script-mast { display: flex; align-items: flex-end; justify-content: space-between; gap: 30px;
  padding-bottom: 15px; border-bottom: 1px solid var(--line); }
.mast-main { min-width: 0; display: flex; flex-direction: column; gap: 9px; }
.mast-eyebrow { display: flex; align-items: baseline; gap: 11px;
  font: 600 10.5px/1 var(--font-mono); letter-spacing: .2em; color: var(--amber);
  text-transform: uppercase; }
.mast-eyebrow .dim { color: var(--text-3); letter-spacing: .14em; }
.mast-title { font: 700 30px/1.25 var(--font-serif); letter-spacing: .06em; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
/* 数据带：hairline 分隔的统计格——大数字是版面的第二主角（参考画册 KPI 带） */
.mast-stats { display: flex; align-items: stretch; flex: none; padding-bottom: 2px; }
.mast-stat { display: flex; flex-direction: column; gap: 6px; justify-content: flex-end;
  padding: 2px 22px; border-left: 1px solid var(--line); }
.mast-stat:first-child { border-left: 0; padding-left: 0; }
.mast-stat:last-child { padding-right: 4px; }
.mast-stat b { font: 600 21px/1 var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--text); white-space: nowrap; }
.mast-stat b small { font-size: 12px; font-weight: 600; color: var(--text-2); margin-left: 1px; }
.mast-stat.warn b { color: var(--amber); }
.mast-stat > span { font: 600 9.5px/1 var(--font-mono); letter-spacing: .16em; color: var(--text-3); }
/* 指令行：工作台的核心交互（复制指令给 AI）收成一排安静的文字按钮 */
.mast-tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.mast-tools .spring { flex: 1; }
.mast-act { display: inline-flex; align-items: center; gap: 6px; padding: 6px 13px;
  background: var(--fill-soft); border: 1px solid transparent; border-radius: 8px;
  color: var(--text-2); font: 550 12px/1.4 var(--font-ui); cursor: pointer;
  transition: all .13s var(--ease); }
.mast-act:hover { color: var(--text); background: var(--bg-hover); }
.act-btn.soft-off { opacity: .42; cursor: not-allowed; }   /* 软禁用：灰化但保留悬浮 tip + 点击 toast */

/* 两栏容器：占满抬头之下的剩余高度，各列独立滚动 */
.script-console { display: grid; grid-template-columns: minmax(260px, 340px) minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr); gap: 26px; flex: 1; min-height: 0; margin: 0; align-items: stretch; }

/* 左栏：目录标题(常驻) + 目录列表(独立滚)——不复用 ch01 的 sticky 滚动逻辑，独立处理 */
.console-side.script-side { position: static; max-height: none; display: flex; flex-direction: column;
  min-height: 0; gap: 0; padding: 0; margin: 0; overflow: hidden; }
.console-side.script-side > .sec { margin: 0 0 12px; flex: none; }
.script-side > .toc-scroll { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; padding-right: 5px; }
.script-side > .toc-scroll::-webkit-scrollbar { width: 6px; }
.script-side > .toc-scroll::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 4px; }
.toc-search { flex: none; width: 100%; height: 42px; margin: 0 0 12px; background: #0d0f13;
  border: 1px solid var(--line-2); border-radius: 10px; padding: 0 13px; color: var(--text);
  font: 12.5px var(--font-ui); outline: none; transition: border-color .13s var(--ease); }
.toc-search:focus { border-color: rgba(240, 166, 60, .5); }
.toc-search::placeholder { color: var(--text-3); }

/* 右栏：Tab 条(常驻) + 面板(各自独立滚) */
.script-pane { display: flex; flex-direction: column; gap: 12px; min-width: 0; min-height: 0; }
.script-pane > .sec { margin: 0; flex: none; }        /* 右栏「◨ 工作台」分区标题，与左「◧ 目录」对称 */
/* Tab 条 · 编辑部式编号页签：透明底 + 通栏 hairline + 琥珀下划指示（脱离按钮盒子感；
   基础 .scr-tabs 盒式样式仍服务章节页的成片/animatic 切换，此处仅在 .script-tabs 作用域覆写） */
.script-tabs { flex: none; height: auto; display: flex; gap: 25px; padding: 2px 2px 0;
  background: transparent; border: 0; border-bottom: 1px solid var(--line); border-radius: 0; }
.script-tabs .scr-tab { position: relative; flex: none; display: inline-flex; align-items: baseline;
  gap: 7px; background: transparent; border: 0; border-radius: 0; padding: 5px 1px 13px;
  font: 600 13px/1 var(--font-ui); letter-spacing: .02em; color: var(--text-3);
  transition: color .15s var(--ease); }
.script-tabs .scr-tab:hover { color: var(--text-2); background: transparent; border: 0; }
.script-tabs .scr-tab.on { color: var(--text); background: transparent; border: 0; }
.script-tabs .scr-tab::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px;
  height: 2px; background: var(--amber); transform: scaleX(0); transform-origin: left center;
  transition: transform .2s var(--ease); }
.script-tabs .scr-tab.on::after { transform: scaleX(1); }
.scr-tab-no { font: 600 10px/1 var(--font-mono); letter-spacing: .08em; color: var(--text-3);
  transition: color .15s var(--ease); }
.scr-tab.on .scr-tab-no { color: var(--amber); }
.scr-tab-txt { flex: none; }
.scr-tab-cnt { font: 500 10.5px/1 var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--text-3); }
.script-tabs .scr-tab.on .scr-tab-cnt { color: var(--amber); }
.script-panels { flex: 1; min-height: 0; min-width: 0; display: flex; flex-direction: column; }
.script-panel { flex: 1; min-height: 0; min-width: 0; }
.script-panel[hidden] { display: none; }
.reader-panel { display: flex; flex-direction: column; }
.scroll-panel { overflow-y: auto; overscroll-behavior: contain; padding-right: 6px;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.scroll-panel::-webkit-scrollbar { width: 6px; }
.scroll-panel::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 4px; }
.script-panel > .design-grid, .script-panel > .eps-wrap, .script-panel > .ent-grid,
.script-panel > .empty, .script-panel > .src-info, .script-panel > .adapt-drop { margin-top: 0; }

/* ▤ 单章阅读器 · 铅字排印：细工具条常驻 + 正文独立滚——衬线中栏、章扉题头、篇末翻章。
   顶部一抹钨丝灯暖光压住阅读区，正文是这个页面唯一的衬线场域（“暗房里摊开一页稿纸”） */
.reader { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.reader-head { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; padding: 2px 2px 12px; margin-bottom: 2px; border-bottom: 1px solid var(--line); }
.reader-head-l { display: flex; align-items: baseline; gap: 12px; min-width: 0; flex-wrap: wrap; }
.reader-title { font: 600 13.5px/1.4 var(--font-ui); color: var(--text-2); letter-spacing: .02em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.reader-meta { font: 500 11px/1 var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--text-3); flex: none; }
.reader-nav { display: flex; gap: 8px; flex: none; }
.reader-nav-btn { background: var(--fill-soft); border: 1px solid transparent; border-radius: 8px;
  padding: 6px 14px; color: var(--text-2); font: 550 12px/1 var(--font-ui); cursor: pointer;
  transition: all .13s var(--ease); }
.reader-nav-btn:hover:not(:disabled) { color: var(--text); background: var(--bg-hover); }
.reader-nav-btn:disabled { opacity: .32; cursor: not-allowed; }
.reader-scroll { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent;
  background: radial-gradient(46% 260px at 50% 0, rgba(240, 166, 60, .05), transparent 76%); }
.reader-scroll::-webkit-scrollbar { width: 8px; }
.reader-scroll::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 5px; border: 2px solid var(--bg); }
/* 可读行长：中文 46em ≈ 每行 40 余字——比通栏铺满更接近书页 */
.reader-body { max-width: 46em; margin: 0 auto; padding: 34px clamp(20px, 4%, 56px) 36px; }
/* 章扉：编号眉线 + 衬线大字章题 + 一枚琥珀短线——纸书扉页语言 */
.reader-chap { margin: 4px 0 36px; text-align: center; }
.reader-chap-no { font: 600 10.5px/1 var(--font-mono); letter-spacing: .34em; color: var(--amber);
  text-transform: uppercase; text-indent: .34em; }   /* text-indent 抵掉末字符 letter-spacing，视觉才居中 */
.reader-chap-t { font: 700 27px/1.45 var(--font-serif); letter-spacing: .1em; color: var(--text);
  margin: 13px 0 0; }
.reader-chap-rule { width: 36px; height: 1px; margin: 21px auto 0; border: 0;
  background: linear-gradient(90deg, transparent, rgba(240, 166, 60, .65), transparent); }
.reader-p { font: 400 17px/2.15 var(--font-serif); color: var(--text); letter-spacing: .02em;
  text-indent: 2em; margin: 0 0 .55em; text-align: justify; text-justify: inter-ideograph; }
.reader-note { font: italic 13px/1.7 var(--font-ui); color: var(--text-3); padding: 8px 0; text-indent: 0; }
/* 原创正文的 markdown 两件：`**加粗**`（面板/强调行）与 `---` 分隔线 */
.reader-p b { color: var(--text); font-weight: 700; }
.reader-hr { border: 0; margin: 2em auto; width: 100%; max-width: 220px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--line-2), transparent); }
/* 篇末翻章：读完顺手翻，不必滚回顶部 */
.reader-foot { display: flex; align-items: center; justify-content: center; gap: 16px;
  max-width: 46em; margin: 0 auto; padding: 6px clamp(20px, 4%, 56px) 84px; }
.reader-foot .reader-nav-btn { padding: 9px 26px; }
.reader-foot-mid { font: 500 10.5px/1 var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--text-3); letter-spacing: .18em; text-indent: .18em; }

/* ▤ 源文本信息表 */
.src-info { max-width: 640px; display: flex; flex-direction: column; }
.src-row { display: flex; align-items: flex-start; gap: 16px; padding: 13px 2px;
  border-bottom: 1px solid var(--line); }
.src-k { flex: none; width: 60px; color: var(--text-3); font-size: 12.5px; }
.src-v { min-width: 0; color: var(--text); font-size: 13px; word-break: break-all; font-family: var(--font-mono); }

/* 窄屏回落：解除全屏固定，恢复自然流式滚动 */
@media (max-width: 900px) {
  .view.view-app { display: block; overflow: visible; }
  /* !important 压过 fit() 写在行内的实测高度——窄屏回归自然流，高度不再钉死 */
  .script-app { height: auto !important; overflow: visible; padding: 16px; }
  /* 解除 1fr 行高：单列堆叠时左栏按内容长高，不再被压扁到只剩分区标题 */
  .script-console { grid-template-rows: none; }
  .script-app.reading .script-head { max-height: 480px; opacity: 1; margin-bottom: 20px; }
  .script-head { max-height: none; }
  .script-mast { flex-direction: column; align-items: stretch; gap: 14px; }
  .mast-title { white-space: normal; }
  .mast-stats { flex-wrap: wrap; gap: 10px 0; }
  .mast-stat { padding: 2px 18px 2px 0; border-left: 0; }
  .script-tabs { gap: 18px; overflow-x: auto; }
  .script-console { grid-template-columns: 1fr; }
  .console-side.script-side { overflow: visible; }
  .script-side > .toc-scroll { max-height: 42vh; }
  .stoc-vol { position: static; }
  .script-panels { display: block; }
  .script-panel, .reader { flex: none; height: auto; }
  .reader-scroll { overflow: visible; }
}
/* 左栏目录树：原创长篇按卷分组（卷头吸顶），章行走「琥珀左标线」而非整行药丸 */
.script-toc { display: flex; flex-direction: column; gap: 1px; }
.stoc-vol { position: sticky; top: 0; z-index: 2; display: flex; align-items: baseline; gap: 9px;
  padding: 12px 9px 7px 2px; margin-top: 8px; background: var(--bg);
  border-bottom: 1px solid var(--line); }
.stoc-vol:first-child { margin-top: 0; }
.stoc-vol-no { font: 600 9.5px/1 var(--font-mono); letter-spacing: .14em; color: var(--amber);
  flex: none; }
.stoc-vol-t { flex: 1; min-width: 0; font: 600 13px/1.35 var(--font-serif); letter-spacing: .05em;
  color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stoc-vol.now .stoc-vol-t { color: var(--text); }
.stoc-vol-m { font: 500 9.5px/1 var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--text-3); flex: none; }
.stoc-item { display: flex; align-items: center; gap: 9px; padding: 7px 9px 7px 10px;
  cursor: pointer; border: 0; border-left: 2px solid transparent;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  transition: background .13s var(--ease), border-color .13s var(--ease); }
.stoc-item:hover { background: var(--bg-hover); }
.stoc-item:focus-visible { outline: none; background: var(--bg-hover); }
.stoc-item.on { background: linear-gradient(90deg, var(--amber-soft), transparent 82%);
  border-left-color: var(--amber); }
.stoc-idx { font: 500 10.5px/1 var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--text-3); flex: none; min-width: 26px; text-align: right; }
.stoc-item.on .stoc-idx { color: var(--amber); font-weight: 700; }
.stoc-title { flex: 1; min-width: 0; font-size: 12.5px; color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stoc-item.on .stoc-title { color: var(--text); font-weight: 550; }
.stoc-meta { font: 500 10px/1 var(--font-mono); color: var(--text-3); flex: none; }

/* AI 问书内联面板 */
.ask-panel { display: flex; gap: 8px; align-items: center; margin: -4px 0 16px; }
.ask-panel[hidden] { display: none; }
.ask-input { flex: 1; min-width: 0; background: #0d0f13; border: 1px solid var(--line-2);
  border-radius: 8px; padding: 9px 13px; color: var(--text); font: 13px var(--font-ui); outline: none; }
.ask-input:focus { border-color: rgba(92, 158, 232, .55); }

/* 划词抽实体浮动工具条 */
.sel-tools { position: fixed; z-index: 60; display: flex; gap: 5px; padding: 5px;
  background: var(--bg-card-2); border: 1px solid var(--line-2); border-radius: 10px;
  box-shadow: 0 8px 22px rgba(0, 0, 0, .4); }
.sel-tools[hidden] { display: none; }
.sel-tool { background: transparent; border: 1px solid transparent; border-radius: 7px;
  padding: 5px 9px; color: var(--text-2); font: 550 11.5px/1 var(--font-ui); cursor: pointer;
  transition: all .12s var(--ease); }
.sel-tool:hover { background: var(--blue-soft); border-color: rgba(92, 158, 232, .4); color: var(--blue); }

/* 集级对照（原文侧 ↔ 分镜侧）*/
.cmp-host { margin: 12px 0 4px; }
.cmp-host[hidden] { display: none; }
.cmp-wrap { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 16px; padding: 16px; border: 1px solid var(--line-2); border-radius: var(--r-md);
  background: var(--bg-panel); }
.cmp-col { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.cmp-k { font: 600 10.5px/1.6 var(--font-mono); letter-spacing: .08em; color: var(--blue);
  text-transform: uppercase; }
.cmp-log { font-size: 13px; color: var(--text); line-height: 1.7; }
.cmp-src { font: 500 11.5px/1.6 var(--font-mono); color: var(--text-3); margin-top: 2px; }
.cmp-shots { display: flex; flex-direction: column; gap: 7px; max-height: 52vh; overflow-y: auto;
  overscroll-behavior: contain; padding-right: 4px; }
.cmp-shot { display: flex; gap: 9px; padding: 8px 10px; border: 1px solid var(--line);
  border-radius: var(--r-sm); background: var(--bg-card); }
.cmp-no { font: 600 11px/1.5 var(--font-mono); color: var(--amber); flex: none; }
.cmp-body { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.cmp-cam { font: 500 10.5px/1.4 var(--font-mono); color: var(--cyan); }
.cmp-body p { font-size: 12.5px; color: var(--text-2); line-height: 1.6; }
.cmp-close { position: absolute; top: 8px; right: 10px; width: 22px; height: 22px; padding: 0;
  background: transparent; border: none; color: var(--text-3); font-size: 18px; line-height: 1;
  cursor: pointer; border-radius: 6px; transition: all .12s var(--ease); }
.cmp-close:hover { background: var(--bg-hover); color: var(--text); }
.cmp-btn { align-self: flex-start; margin-top: 2px; background: transparent;
  border: 1px solid var(--line-2); border-radius: 7px; padding: 4px 10px; color: var(--text-2);
  font: 550 11px/1 var(--font-ui); cursor: pointer; transition: all .12s var(--ease); }
.cmp-btn:hover { border-color: rgba(92, 158, 232, .5); color: var(--blue); background: var(--blue-soft); }
@media (max-width: 760px) { .cmp-wrap { grid-template-columns: 1fr; } }

/* ============================================================================
   ❖ 关系图谱（剧本工作台「图谱」Tab）：力导向节点网 + 缩放/平移/拖拽 + 下方知识点
   ========================================================================== */
.kg-panel { display: flex; flex-direction: column; min-height: 0; }
.kg-mount { flex: 1; min-height: 0; display: flex; }        /* 整个模块即画布：只含铺满的舞台 */

/* 舞台：裁剪视口 + 电影级深空背景（银心柔光 + 边缘压暗晕影，晕影烘在底色里不碰节点亮度）；世界层承载缩放/平移 */
.kg-stage { flex: 1; min-height: 250px; position: relative; overflow: hidden;
  border: 1px solid var(--line-2); border-radius: 13px; cursor: grab; touch-action: none;
  user-select: none; -webkit-user-select: none;                /* 禁止点/拖时误选节点文字 */
  background:
    radial-gradient(58% 48% at 50% 44%, rgba(66, 98, 178, .22), transparent 70%),
    radial-gradient(120% 96% at 50% 46%, transparent 50%, rgba(3, 5, 11, .55) 100%),
    radial-gradient(132% 110% at 50% 4%, #131c38 0%, #0b1122 42%, #070b17 70%, #04060d 100%); }
.kg-stage.grab { cursor: grabbing; }
.kg-stage:fullscreen, .kg-stage.kg-full { border-radius: 0; border: none; }

/* 悬浮标题（左上）：标题 + 计数 + 重生成，浮于画布之上 */
.kg-title { position: absolute; top: 11px; left: 11px; z-index: 2; display: flex; align-items: center; gap: 10px;
  padding: 7px 12px; background: rgba(16, 18, 22, .5); backdrop-filter: blur(14px) saturate(150%);
  -webkit-backdrop-filter: blur(14px) saturate(150%); border: 1px solid rgba(255, 255, 255, .09); border-radius: 10px; }
.kg-title-t { font: 640 13px/1 var(--font-ui); color: var(--text); letter-spacing: .01em; }
.kg-title-sub { font: 500 11px/1 var(--font-mono); color: var(--text-3); }

/* 星海背景（电影级）：多团星云缓慢呼吸 + 两层视差星点（近层大而带光晕·远层细密，异速漂移+异相微闪）*/
.kg-stars { position: absolute; inset: -30%; z-index: 0; pointer-events: none;
  background:
    radial-gradient(46% 40% at 18% 20%, rgba(78, 138, 234, .20), transparent 68%),
    radial-gradient(42% 38% at 84% 26%, rgba(158, 116, 236, .17), transparent 70%),
    radial-gradient(52% 44% at 70% 84%, rgba(58, 190, 208, .13), transparent 72%),
    radial-gradient(36% 32% at 40% 60%, rgba(96, 132, 244, .10), transparent 68%),
    radial-gradient(30% 26% at 90% 68%, rgba(224, 148, 200, .07), transparent 70%);
  animation: kgDrift 220s linear infinite alternate, kgNebula 30s ease-in-out infinite; }
/* 星层放大留足余量：随缩放做「星际穿梭」推拉时(scale 0.5~2.4)仍铺满不露边 */
.kg-stars::before, .kg-stars::after { content: ""; position: absolute; inset: -45%; background-repeat: repeat;
  transform-origin: 50% 50%; }
.kg-stars::before {                                    /* 远层：细密星尘，慢速视差 + 6.5s 微闪 */
  background-image:
    radial-gradient(1px 1px at 20px 30px, rgba(255, 255, 255, .85), transparent),
    radial-gradient(1px 1px at 60px 120px, rgba(206, 224, 255, .6), transparent),
    radial-gradient(1px 1px at 110px 40px, rgba(255, 255, 255, .75), transparent),
    radial-gradient(1px 1px at 150px 200px, rgba(255, 255, 255, .55), transparent),
    radial-gradient(1px 1px at 190px 80px, rgba(224, 232, 255, .8), transparent),
    radial-gradient(1px 1px at 240px 160px, rgba(255, 255, 255, .5), transparent),
    radial-gradient(1px 1px at 280px 50px, rgba(255, 255, 255, .7), transparent),
    radial-gradient(1px 1px at 45px 220px, rgba(206, 224, 255, .55), transparent),
    radial-gradient(1px 1px at 130px 140px, rgba(255, 255, 255, .65), transparent),
    radial-gradient(1px 1px at 210px 260px, rgba(255, 255, 255, .55), transparent),
    radial-gradient(1px 1px at 30px 170px, rgba(255, 255, 255, .75), transparent),
    radial-gradient(1px 1px at 270px 230px, rgba(224, 232, 255, .5), transparent);
  background-size: 300px 300px;
  transform: scale(var(--warp-far, 1)) translateZ(0);   /* 远层：随缩放小幅推拉（穿梭视差·慢层）*/
  will-change: transform; backface-visibility: hidden;  /* 独立 GPU 图层 → warp 缩放走合成不重绘=顺滑 */
  animation: kgTwinkle 6.5s ease-in-out infinite, kgParA 260s linear infinite; }
.kg-stars::after {                                     /* 近层：亮星带柔光晕（略大·偏冷白暖白混），异速视差 + 9s 反相微闪 */
  background-image:
    radial-gradient(2.2px 2.2px at 70px 50px, #fff 34%, rgba(150, 190, 255, .35) 56%, transparent 76%),
    radial-gradient(2px 2px at 180px 130px, rgba(214, 230, 255, .95) 36%, rgba(150, 190, 255, .3) 58%, transparent 78%),
    radial-gradient(2.4px 2.4px at 300px 70px, #fff 32%, rgba(180, 205, 255, .32) 55%, transparent 75%),
    radial-gradient(1.9px 1.9px at 380px 210px, rgba(228, 218, 255, .92) 36%, rgba(190, 170, 255, .3) 58%, transparent 78%),
    radial-gradient(2.3px 2.3px at 120px 300px, #fff 33%, rgba(160, 195, 255, .32) 56%, transparent 76%),
    radial-gradient(2px 2px at 260px 360px, rgba(210, 228, 255, .9) 36%, rgba(150, 190, 255, .28) 58%, transparent 78%),
    radial-gradient(1.9px 1.9px at 40px 380px, rgba(255, 255, 255, .88) 36%, rgba(180, 205, 255, .28) 58%, transparent 78%),
    radial-gradient(2.4px 2.4px at 220px 240px, rgba(255, 246, 222, .9) 34%, rgba(255, 214, 160, .3) 56%, transparent 76%);
  background-size: 440px 440px;
  transform: scale(var(--warp-near, 1)) translateZ(0);  /* 近层：随缩放大幅推拉 → 星际穿梭前进后退感（快层）*/
  will-change: transform; backface-visibility: hidden;  /* 独立 GPU 图层 → warp 缩放走合成不重绘=顺滑 */
  animation: kgTwinkle 9s ease-in-out infinite reverse, kgParB 200s linear infinite; }
@keyframes kgTwinkle { 0%, 100% { opacity: .62; } 50% { opacity: 1; } }
@keyframes kgNebula { 0%, 100% { opacity: .78; } 50% { opacity: 1; } }
@keyframes kgDrift { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-40px, -26px, 0); } }
@keyframes kgParA { from { background-position: 0 0; } to { background-position: 300px 600px; } }        /* 远层：慢 */
@keyframes kgParB { from { background-position: 0 0; } to { background-position: -440px 880px; } }        /* 近层：快·反向 → 视差纵深 */
@media (prefers-reduced-motion: reduce) { .kg-stars, .kg-stars::before, .kg-stars::after { animation: none; } }
/* will-change 交由 JS 按交互态切换（缩放/平移中=transform 图层加速；稳定态=auto 让浏览器按当前比例重栅格→高清不糊）*/
.kg-world { position: absolute; top: 0; left: 0; transform-origin: 0 0; will-change: auto; }
.kg-edges { position: absolute; top: 0; left: 0; overflow: visible; pointer-events: none; }
.kg-edge { fill: none; stroke-width: 1.6; opacity: .62; transition: opacity .16s var(--ease), stroke-width .16s; }
.kg-edge.dashed { stroke-dasharray: 5 5; }
.kg-edge.hot { opacity: 1; stroke-width: 2.4; }
.kg-stage.sel .kg-edge.dim { opacity: .09; }
.kg-elabel { font: 500 10px var(--font-mono); fill: var(--text-2); opacity: 0; pointer-events: none;
  paint-order: stroke; stroke: var(--bg-panel); stroke-width: 3px; stroke-linejoin: round;
  transition: opacity .16s var(--ease); }
.kg-elabel.show { opacity: 1; }

/* 节点：圆盘（角色=设定图头像 / 其余=首字）+ 名牌，圆心恰在 (x,y) */
.kg-node { position: absolute; transform: translate(-50%, -50%); cursor: pointer;
  animation: kgIn .5s var(--ease) both; transition: opacity .16s var(--ease); }
.kg-disc { position: relative; border-radius: 50%; overflow: hidden; background: var(--bg-card-2);
  border: 2px solid var(--nc, var(--line-2)); box-shadow: 0 0 0 4px rgba(0, 0, 0, .25), 0 4px 14px rgba(0, 0, 0, .35);
  display: grid; place-items: center; animation: kgPop .55s var(--ease) both;
  transition: box-shadow .16s var(--ease), border-color .16s; }
.kg-disc img { width: 100%; height: 100%; object-fit: cover;
  -webkit-user-drag: none; user-drag: none; }   /* 禁原生图片拖拽：否则按住带图节点＝拖走图片而非搬节点 */
.kg-init { font: 640 14px/1 var(--font-ui); color: var(--nc, var(--text-2)); letter-spacing: -.02em; }
.kg-nlabel { position: absolute; top: calc(100% + 4px); left: 50%; transform: translateX(-50%);
  white-space: nowrap; font: 550 11.5px/1 var(--font-ui); color: var(--text-2); pointer-events: none;
  max-width: 118px; overflow: hidden; text-overflow: ellipsis; text-shadow: 0 1px 3px rgba(0, 0, 0, .6);
  transition: color .16s var(--ease); }
.kg-node:hover .kg-disc, .kg-node.hot .kg-disc { border-color: var(--nc); box-shadow: 0 0 0 4px rgba(0, 0, 0, .25), 0 0 16px -2px var(--nc); }
.kg-node.pick .kg-disc { box-shadow: 0 0 0 3px var(--nc), 0 0 20px -2px var(--nc); }
.kg-node.hot .kg-nlabel, .kg-node:hover .kg-nlabel { color: var(--text); }
.kg-stage.sel .kg-node.dim { opacity: .25; }
@keyframes kgIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes kgPop { from { transform: scale(.3); } to { transform: scale(1); } }

/* 工具条 / 图例（悬浮在舞台上） */
.kg-toolbar { position: absolute; top: 11px; right: 11px; z-index: 6; display: flex; align-items: center; gap: 3px;
  padding: 4px; background: rgba(16, 18, 22, .55); backdrop-filter: blur(16px) saturate(155%);
  -webkit-backdrop-filter: blur(16px) saturate(155%);
  border: 1px solid rgba(255, 255, 255, .1); border-radius: 10px; }
.kg-tool { width: 27px; height: 27px; display: grid; place-items: center; border-radius: 7px;
  background: transparent; border: none; color: var(--text-2); font-size: 15px; line-height: 1; cursor: pointer;
  transition: all .12s var(--ease); }
.kg-tool:hover { background: var(--amber-soft); color: var(--amber); }
.kg-tool.on { background: var(--amber-soft); color: var(--amber); }
.kg-zoom { min-width: 40px; text-align: center; font: 600 10.5px/1 var(--font-mono); color: var(--text-3); }
.kg-tool-sep { width: 1px; height: 16px; background: var(--line-2); margin: 0 2px; }
.kg-legend { position: absolute; left: 11px; bottom: 11px; z-index: 2; display: flex; flex-wrap: wrap; align-items: center;
  gap: 4px 11px; max-width: 70%; padding: 7px 11px; background: rgba(16, 18, 22, .55); backdrop-filter: blur(14px) saturate(150%);
  -webkit-backdrop-filter: blur(14px) saturate(150%); border: 1px solid rgba(255, 255, 255, .08); border-radius: 10px; pointer-events: none; }
.kg-leg { display: inline-flex; align-items: center; gap: 5px; font: 500 10.5px/1 var(--font-ui); color: var(--text-2); }
.kg-leg-dot { width: 8px; height: 8px; border-radius: 50%; }
.kg-leg-ln { width: 13px; height: 2.5px; border-radius: 2px; }
.kg-leg-sep { width: 1px; height: 12px; background: var(--line-2); }

/* 选中详情卡：默认左侧中间，可自由拖动 */
.kg-detail { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 312px;
  max-width: calc(100% - 24px); max-height: calc(100% - 24px); overflow-y: auto; padding: 14px; z-index: 4;
  cursor: grab; background: rgba(18, 21, 28, .55); backdrop-filter: blur(22px) saturate(165%);
  -webkit-backdrop-filter: blur(22px) saturate(165%); border: 1px solid rgba(255, 255, 255, .13);
  border-radius: 14px; box-shadow: 0 18px 50px rgba(0, 0, 0, .55); animation: kgDetailIn .2s var(--ease) both; }
.kg-detail[hidden] { display: none; }
.kg-detail.dragging { cursor: grabbing; animation: none; }
.kg-detail button, .kg-detail a, .kg-detail img, .kg-detail .kg-rel { cursor: pointer; }
@keyframes kgDetailIn { from { opacity: 0; transform: translate(-10px, -50%); } to { opacity: 1; transform: translate(0, -50%); } }
.kg-detail-x { position: absolute; top: 8px; right: 9px; width: 22px; height: 22px; padding: 0; background: transparent;
  border: none; color: var(--text-3); font-size: 17px; line-height: 1; cursor: pointer; border-radius: 6px; transition: all .12s var(--ease); }
.kg-detail-x:hover { background: var(--bg-hover); color: var(--text); }
.kg-detail-hd { display: flex; gap: 12px; align-items: center; padding-right: 20px; }
.kg-detail-img { width: 54px; height: 68px; object-fit: cover; border-radius: 8px; border: 1px solid var(--line-2);
  cursor: zoom-in; flex: none; transition: border-color .13s var(--ease); }
.kg-detail-img:hover { border-color: var(--amber); }
.kg-detail-meta { min-width: 0; }
.kg-detail-name { font-size: 15px; font-weight: 640; color: var(--text); margin-bottom: 6px; }
.kg-detail-tags { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.kg-badge { font: 600 10px/1 var(--font-ui); padding: 3px 7px; border: 1px solid; border-radius: 20px; }
.kg-detail-fac { font: 500 11px/1 var(--font-ui); color: var(--text-3); }
.kg-detail-desc { margin-top: 11px; font-size: 12.5px; line-height: 1.65; color: var(--text-2); }
.kg-detail-rels { margin-top: 11px; display: flex; flex-direction: column; gap: 2px; border-top: 1px solid var(--line); padding-top: 9px; }
.kg-rel { display: flex; align-items: center; gap: 7px; padding: 5px 6px; background: transparent; border: none;
  border-radius: 7px; cursor: pointer; text-align: left; transition: background .12s var(--ease); }
.kg-rel:hover { background: var(--bg-hover); }
.kg-rel-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.kg-rel-rel { font: 500 11.5px/1 var(--font-ui); color: var(--text-2); }
.kg-rel-ar { color: var(--text-3); font-size: 11px; }
.kg-rel b { font: 600 12px/1 var(--font-ui); color: var(--text); }
.kg-detail-hint { margin-top: 9px; font: 400 10.5px/1.4 var(--font-ui); color: var(--text-3); }

/* ── 节点英雄图（有设定图的节点点开即整行大图）──
   前景 contain：角色设定图是 16:9 三区 model sheet，cover 会裁掉正脸肖像或全身像的一半；
   底衬是同一张图放大 + 模糊 + 压暗做毛玻璃，把 contain 的留白填成同色系氛围（Apple Music 封面式），
   避免黑边或纯色底。整卡有图时去掉内边距，让图真正「占满一行」。 */
.kg-detail.has-hero { padding: 0; overflow: hidden; }
.kg-detail.has-hero .kg-detail-x { top: 10px; right: 10px; z-index: 3; color: rgba(255, 255, 255, .82);
  background: rgba(10, 12, 16, .42); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.kg-detail.has-hero .kg-detail-x:hover { background: rgba(10, 12, 16, .72); color: #fff; }
.kg-hero { position: relative; height: 156px; overflow: hidden; cursor: zoom-in;
  border-bottom: 1px solid rgba(255, 255, 255, .08); background: #0a0c10; }
.kg-hero-bg { position: absolute; inset: -18%; background-size: cover; background-position: center;
  filter: blur(20px) saturate(.75) brightness(.42); transform: scale(1.08); }
.kg-hero-img { position: relative; z-index: 1; width: 100%; height: 100%; object-fit: contain;
  -webkit-user-drag: none; user-drag: none;
  display: block; transition: transform .38s var(--ease); }
.kg-hero:hover .kg-hero-img { transform: scale(1.035); }
.kg-hero-scrim { position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(to top, rgba(8, 10, 14, .92) 0%, rgba(8, 10, 14, .55) 26%, rgba(8, 10, 14, 0) 54%); }
.kg-hero-zoom { position: absolute; z-index: 3; top: 10px; left: 10px; width: 24px; height: 24px;
  display: grid; place-items: center; border-radius: 7px; color: rgba(255, 255, 255, .8);
  background: rgba(10, 12, 16, .42); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  opacity: 0; transition: opacity .18s var(--ease); }
.kg-hero-zoom svg { width: 13px; height: 13px; }
.kg-hero:hover .kg-hero-zoom { opacity: 1; }
.kg-hero-cap { position: absolute; z-index: 3; left: 14px; right: 14px; bottom: 11px; pointer-events: none; }
.kg-hero-name { font: 660 16px/1.25 var(--font-ui); color: #fff; letter-spacing: .01em;
  text-shadow: 0 2px 10px rgba(0, 0, 0, .75); margin-bottom: 7px; }
.kg-hero-cap .kg-detail-tags { gap: 6px; }
.kg-hero-cap .kg-badge { background: rgba(10, 12, 16, .5); backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px); }
.kg-hero-cap .kg-detail-fac { color: rgba(255, 255, 255, .72); text-shadow: 0 1px 6px rgba(0, 0, 0, .7); }
.kg-detail.has-hero .kg-detail-body { padding: 13px 14px 14px; }
.kg-detail.has-hero .kg-detail-desc { margin-top: 0; }

/* 关系摘要侧栏（左侧滑入·磨砂）：摘要浮于画布左侧，工具条 ≡ 开合 */
.kg-side { position: absolute; top: 0; left: 0; bottom: 0; z-index: 5; width: min(340px, 82%);
  display: flex; flex-direction: column; background: rgba(15, 18, 25, .58);
  backdrop-filter: blur(30px) saturate(160%); -webkit-backdrop-filter: blur(30px) saturate(160%);
  border-right: 1px solid rgba(255, 255, 255, .12); box-shadow: 22px 0 60px rgba(0, 0, 0, .45);
  animation: kgSideIn .22s var(--ease); }
.kg-side[hidden] { display: none; }
@keyframes kgSideIn { from { transform: translateX(-18px); opacity: 0; } to { transform: none; opacity: 1; } }
.kg-side-hd { flex: none; display: flex; align-items: center; justify-content: space-between;
  padding: 12px 14px; border-bottom: 1px solid rgba(255, 255, 255, .08); }
.kg-side-t { display: inline-flex; align-items: baseline; gap: 8px; font: 640 13px/1 var(--font-ui); color: var(--text); }
.kg-side-t i { font: 600 9px/1 var(--font-mono); letter-spacing: .13em; color: var(--text-3); font-style: normal; }
.kg-side-x { width: 24px; height: 24px; border: none; background: transparent; color: var(--text-3);
  font-size: 18px; line-height: 1; border-radius: 7px; cursor: pointer; transition: all .12s var(--ease); }
.kg-side-x:hover { background: rgba(255, 255, 255, .09); color: var(--text); }
.kg-side-body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 14px;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.kg-side-body::-webkit-scrollbar { width: 6px; }
.kg-side-body::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 4px; }
.kg-summary { font-size: 13px; line-height: 1.75; color: var(--text); padding: 12px 14px; margin-bottom: 12px;
  background: var(--bg-card); border: 1px solid var(--line); border-left: 2px solid var(--amber); border-radius: 9px; }
.kg-dg-sec { margin-bottom: 14px; }
.kg-dg-h { display: block; font: 600 10.5px/1.6 var(--font-mono); letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-3); margin-bottom: 9px; }
.kg-dg-group { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 8px; }
.kg-dg-k { flex: none; width: 52px; font: 600 11.5px/1.9 var(--font-ui); }
.kg-dg-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.kg-dg-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 20px;
  background: var(--bg-card-2); border: 1px solid var(--line-2); color: var(--text); cursor: pointer;
  font: 550 12px/1 var(--font-ui); transition: all .12s var(--ease); }
.kg-dg-chip:hover { border-color: var(--nc); color: var(--nc); }
.kg-dg-deg { font: 600 9.5px/1.4 var(--font-mono); min-width: 15px; padding: 0 4px; border-radius: 10px;
  background: var(--line-2); color: var(--text-3); }
.kg-dg-rels { display: flex; flex-direction: column; gap: 1px; }
.kg-dg-rel { display: flex; align-items: center; gap: 9px; padding: 7px 9px; border-radius: 8px; cursor: pointer;
  background: transparent; border: 1px solid transparent; text-align: left; transition: all .12s var(--ease); }
.kg-dg-rel:hover { background: var(--bg-hover); border-color: var(--line); }
.kg-dg-rel b { font: 600 12.5px/1 var(--font-ui); color: var(--text); white-space: nowrap; }
.kg-dg-tag { font: 500 11px/1 var(--font-ui); padding: 3px 8px; border: 1px solid; border-radius: 20px; }
.kg-dg-ar { color: var(--text-3); font-size: 12px; }
.kg-dg-more { margin-top: 8px; font: 400 11px/1.5 var(--font-ui); color: var(--text-3); }

/* 统一空态：剧本工作台 拆书 / 分集 / 设定 / 图谱 四模块同款空态 */
.pane-empty { flex: 1; min-height: 100%; box-sizing: border-box; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center; gap: 9px; padding: 48px 24px; }
.pane-empty-ic { color: var(--text-3); opacity: .5; margin-bottom: 2px; }
.pane-empty-ic svg { width: 46px; height: 46px; }
.pane-empty h3 { font-size: 15.5px; font-weight: 640; color: var(--text-2); }
.pane-empty p { max-width: 430px; font-size: 12.5px; line-height: 1.75; color: var(--text-3); }
.pane-empty-act { margin-top: 8px; display: inline-flex; align-items: center; gap: 7px; padding: 9px 16px;
  background: var(--amber-soft); border: 1px solid transparent; color: var(--amber);
  border-radius: 9px; font: 600 12.5px/1 var(--font-ui); cursor: pointer; transition: all .13s var(--ease); }
.pane-empty-act:hover { background: var(--amber); border-color: var(--amber); color: #1a1205; }
.pane-empty-act-ic { display: inline-flex; }
.pane-empty-act-ic svg { width: 14px; height: 14px; }

/* 窄屏：图谱回落自然高度 */
@media (max-width: 900px) {
  .kg-panel { display: block; }
  .kg-mount { display: flex; min-height: 60vh; }
  .kg-stage { flex: none; height: 60vh; }
  .kg-side { width: min(300px, 88%); }
}

/* 重做意见输入 */
.retake-box { display: flex; gap: 8px; align-items: center; }
.retake-box[hidden] { display: none; }
.cmt-input {
  flex: 1; background: #0d0f13; border: 1px solid var(--line-2); border-radius: 8px;
  padding: 7px 12px; color: var(--text); font: 13px var(--font-ui); outline: none;
  min-width: 0;
}
.cmt-input:focus { border-color: rgba(240,166,60,.5); }
.cmt-form { display: flex; gap: 8px; margin-top: 8px; }

/* 待审队列 */
.queue-list { display: flex; flex-direction: column; gap: 14px; }
.qcard {
  display: grid; grid-template-columns: 190px minmax(0,1fr) auto;
  gap: 16px; padding: 14px 16px; align-items: start;
  transition: opacity .25s, transform .25s, border-color .15s;
}
.qcard.focus { border-color: rgba(240,166,60,.5); box-shadow: 0 0 0 1px rgba(240,166,60,.25); }
.qcard.gone { opacity: 0; transform: translateX(24px); }
.q-media img, .q-media video { width: 100%; max-height: 230px; object-fit: cover; border-radius: 8px; cursor: zoom-in; }
.q-media .ph { padding: 30px 0; text-align: center; color: var(--text-3); font: 500 10px/1 var(--font-mono); }
.q-info { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.q-src { font-size: 12px; color: var(--text-3); }
.q-src:hover { color: var(--amber); }
/* 表态钮并排贴右上角：两键同排读作一组对立选择，竖排会读成上下两级 */
.q-actions { display: flex; flex-direction: row; align-items: center;
  justify-content: flex-end; gap: 8px; flex-wrap: wrap; }

/* 灯箱钉点评论 */
.lb-canvas { position: relative; display: inline-block; cursor: crosshair; }
.lb-pin {
  position: absolute; transform: translate(-50%, -50%); z-index: 4;
  width: 22px; height: 22px; border-radius: 50% 50% 50% 4px;
  background: var(--amber); color: #14161b; font: 700 11px/22px var(--font-mono);
  text-align: center; box-shadow: 0 2px 10px rgba(0,0,0,.5); cursor: pointer;
}
.lb-pin.ok { background: var(--green); opacity: .55; }
/* 钉点的悬浮说明走系统级 #sys-tip（data-tip 委托），旧 ::after 私有提示已裁撤 */
.cmt-text.editable { cursor: text; }
.chip-link { background: none; border: none; padding: 0; cursor: pointer; }
.chip-link:hover .chip { border-color: var(--amber); color: var(--amber); }
.ts-wrap { position: relative; width: min(980px, 94vw); max-height: 84vh;
  display: flex; flex-direction: column; gap: 12px; overflow: hidden;
  background: var(--bg-panel); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 18px 20px 16px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, .5);
  animation: pop .16s var(--ease); }   /* 遮罩淡入 + 面板 pop，与对话框同层次 */
.ts-scroll { overflow: auto; border: 1px solid var(--line); border-radius: var(--r-md);
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.ts-scroll::-webkit-scrollbar { width: 5px; }
.ts-scroll::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 4px; }
/* 弹层表格：时间/编号列紧凑收窄，文本列吃满剩余宽度 */
.ts-wrap .sb-table th, .ts-wrap .sb-table td { padding: 6px 10px; }
.ts-wrap .sb-table td.mono { white-space: nowrap; width: 1%; }
.ts-wrap .sb-table th { white-space: nowrap; }
.ts-raw { margin: 0; padding: 12px 14px; font: 11px/1.7 var(--font-mono);
  color: var(--text-2); white-space: pre-wrap; word-break: break-all; }
.cmt-text.editable:hover { color: var(--text); text-decoration: underline dotted; }
.lb-pin.new { background: var(--red); animation: pinpop .3s var(--ease); }
@keyframes pinpop { from { transform: translate(-50%,-50%) scale(.4); } to { transform: translate(-50%,-50%) scale(1); } }
.lb-comments { display: flex; flex-direction: column; gap: 6px; }
.cmt-row {
  display: flex; align-items: center; gap: 9px;
  background: rgba(20,23,28,.9); border: 1px solid var(--line); border-radius: 9px;
  padding: 7px 12px; font-size: 12.5px; color: var(--text-2);
}
.cmt-row b {
  width: 18px; height: 18px; border-radius: 50% 50% 50% 3px; background: var(--amber);
  color: #14161b; font: 700 10px/18px var(--font-mono); text-align: center; flex: none;
}
.cmt-row.ok { opacity: .55; }
.cmt-row.ok .cmt-text { text-decoration: line-through; }
.cmt-text { flex: 1; min-width: 0; }
.cmt-act { color: var(--text-3); font-size: var(--btn-fs-sm); padding: var(--btn-pad-sm); border-radius: 5px; transition: all .15s; }
.cmt-act:hover { color: var(--green); background: var(--green-soft); }
.cmt-act.del:hover { color: var(--red); background: var(--red-soft); }
.screen-wrap .empty .act-btn { margin-top: 12px; }

/* 版本历史面板 */
.vpanel { position: fixed; inset: 0; z-index: 110; display: grid; place-items: center; }
.vpanel[hidden] { display: none; }
.vp-sheet {
  position: relative; z-index: 2; width: min(860px, 94vw); max-height: 86vh;
  background: var(--bg-panel); border: 1px solid var(--line-2); border-radius: 16px;
  box-shadow: var(--shadow-pop); animation: pop .3s var(--ease);
  overflow: hidden; display: flex; flex-direction: column;   /* 头固定，只滚正文 */
}
.vp-head { flex: none; display: flex; align-items: center; justify-content: space-between;
  padding: 20px 64px 14px 22px; border-bottom: 1px solid var(--line); }
.vp-body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  padding: 16px 22px 18px;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.vp-row {
  display: grid; grid-template-columns: 150px minmax(0,1fr) auto; gap: 14px;
  align-items: center; padding: 12px; border: 1px solid var(--line); border-radius: 12px;
  margin-bottom: 10px; background: var(--bg-card);
}
.vp-row.current { border-color: rgba(240,166,60,.4); }
.vp-thumb { width: 100%; border-radius: 8px; cursor: zoom-in; }
.vp-none { color: var(--text-3); font-size: 11px; text-align: center; padding: 20px 0; }
.vp-info { display: flex; flex-direction: column; gap: 6px; min-width: 0; font-size: 12.5px; }
.vp-info > b { font: 600 12px/1 var(--font-mono); }
.vp-reason { color: var(--red); }
.vp-params p { color: var(--text-3); font-size: 11.5px; line-height: 1.6; overflow-wrap: anywhere; }
.vp-params b { color: var(--text-3); font: 600 9px/1 var(--font-mono); letter-spacing: .1em; }

/* 选角卡：在用 / 候选 / 档案 三段 */
.vb { display: flex; flex-direction: column; gap: 10px; }
/* 在用那一行是卡片第一眼要回答的问题，字号比候选大半档、单行省略不换行 */
.vb-active-name { font-size: 12px; color: var(--text); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.vc-box { display: flex; flex-direction: column; gap: 7px; border-top: 1px dashed var(--line); padding-top: 9px; }
/* 候选行容器：生成后就地 replaceChildren 换掉这一层（不重绘整页）。
   自带行距并在空态零高度——否则没有候选时会在描述框与按钮之间多出一道空隙 */
.vc-rows { display: flex; flex-direction: column; gap: 7px; }
.vc-rows:empty { display: none; }
/* 试听是选角最高频操作：整行 hover 提亮给出「这一行是一个操作单元」的手感 */
.vc-row { display: flex; align-items: center; gap: 8px; padding: 3px 5px;
  border-radius: 6px; transition: background .14s; }
.vc-row:hover { background: rgba(255, 255, 255, .035); }
.vc-row .apill { flex: 1; min-width: 0; }
.vc-no {
  width: 20px; height: 20px; border-radius: 6px; flex: none; text-align: center;
  background: var(--bg-card-2); border: 1px solid var(--line-2);
  font: 700 11px/20px var(--font-mono); color: var(--text-2);
}

/* 音色档案：一条=一把用过的声音。在用那条挑出来（左侧竖标 + 底色），
   其余是历史——它们与候选行的差别必须一眼可见，否则「临时的」与「存下来的」
   两种东西长得一样，选中态到底在说什么就说不清了 */
.vb-casts { display: flex; flex-direction: column; gap: 8px; }
.vb-cast {
  display: flex; align-items: center; gap: 9px; padding: 8px 10px;
  border: 1px solid var(--line); border-left: 2px solid transparent; border-radius: 8px;
  background: var(--bg-card-2);
}
.vb-cast.on { border-left-color: var(--green); background: var(--green-soft); }
.vb-no { flex: none; font: 700 10px/1 var(--font-mono); color: var(--text-3); }
.vb-cast-m { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 150px; }
.vb-cast-name { display: flex; align-items: baseline; gap: 6px; font-size: 12px; color: var(--text-2);
  min-width: 0; }
.vb-cast-name i { flex: none; font: 600 9px/1 var(--font-mono); letter-spacing: .08em;
  color: var(--text-3); font-style: normal; }
/* 省略号挂在内层 span 上：`text-overflow` 对 flex 容器不生效，写在外层会把
   声线描述从中间硬切断（连个「…」都没有，读起来像数据坏了） */
.vb-cast-name > span { min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.vb-cast .apill { flex: 1 1 130px; min-width: 0; }
.vb-cast-acts { display: flex; gap: 6px; flex: none; }
/* 有引用的档案删不得：置灰而不隐藏——隐藏会被当成 bug，理由写在 tip 里 */
.vb-cast-acts .act-btn[disabled] { opacity: .38; cursor: not-allowed; }

/* 顶部轻提示 */
/* 消息条：宿主 flex 居中（无 transform 居中，入场关键帧不会顶掉定位），
   纵向堆叠 · 语义图标 · 入场下滑淡入 / 离场上浮淡出 */
/* 顶偏移跟随外壳形态：z-index 400 远高于导航条的 30，不让位就会整条压在菜单上 */
.toast-host { position: fixed; top: calc(var(--shell-top) + 16px); left: 0; right: 0; z-index: 400;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  pointer-events: none; }
.toast { display: flex; align-items: center; gap: 9px; pointer-events: auto;
  max-width: min(560px, calc(100vw - 32px));
  background: rgba(20, 23, 28, .96); border: 1px solid var(--line-2); color: var(--text);
  border-radius: 10px; padding: 8px 15px 8px 10px; font-size: 12.5px;
  box-shadow: var(--shadow-pop); cursor: default;
  animation: toast-in .22s var(--ease) backwards; }
.toast .t-ico { flex: none; width: 17px; height: 17px; border-radius: 50%;
  display: grid; place-items: center; font: 700 9px/1 var(--font-mono);
  background: var(--green-soft); color: var(--green);
  border: 1px solid rgba(92, 158, 232, .4); }
.toast.bad .t-ico { background: var(--red-soft); color: var(--red);
  border-color: rgba(239, 106, 90, .4); }
.toast .t-msg { line-height: 1.55; }
.toast.out { animation: toast-out .2s var(--ease) forwards; }
@keyframes toast-in { from { opacity: 0; transform: translateY(-8px) scale(.98); } }
@keyframes toast-out { to { opacity: 0; transform: translateY(-6px) scale(.98); } }
.pinmark {
  position: absolute; left: 8px; bottom: 8px; z-index: 2;
  background: rgba(8,9,11,.85); border-radius: 5px; padding: 3px 7px;
  font: 600 10px/1 var(--font-mono); color: var(--amber);
}

/* ============================================================ 响应式 */
@media (max-width: 1200px) {
  .statband { grid-template-columns: repeat(3, 1fr); }
  .console { grid-template-columns: 1fr; }
  .console-side { position: static; }
  .cin-panel { grid-template-columns: 1fr; }
  .cin-meta { border-left: 0; border-top: 1px solid var(--line); }
}
/* ============ 宫格候选：点选定稿 ============ */
.cand-wrap { display: flex; flex-direction: column; gap: 8px; }
.cand-wrap > .k { font-size: 10.5px; letter-spacing: .08em; color: var(--text-3); text-transform: uppercase; }
.cand-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 8px;
}
.cand-grid.q { grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); width: 100%; }
.cand {
  position: relative; border: 1px solid var(--line-2); border-radius: 8px;
  overflow: hidden; cursor: pointer; background: var(--bg-card-2);
  transition: border-color .15s, transform .12s;
}
.cand:hover { border-color: var(--amber); transform: translateY(-2px); }
.cand img { display: block; width: 100%; aspect-ratio: 3/4; object-fit: cover; }
.cand b {
  position: absolute; top: 5px; left: 5px; min-width: 18px; height: 18px;
  display: grid; place-items: center; border-radius: 5px; padding: 0 4px;
  font-size: 11px; background: rgba(0, 0, 0, .62); color: var(--text);
  border: 1px solid var(--line-2);
}
.cand.picked { border-color: var(--green); cursor: default; }
.cand.picked:hover { transform: none; }
.cand-ok {
  position: absolute; right: 5px; bottom: 5px; padding: 2px 7px;
  font-size: 10.5px; border-radius: 5px; background: var(--green-soft);
  color: var(--green); border: 1px solid rgba(92, 158, 232, .4);
  backdrop-filter: blur(3px);
}

/* ============ 时间线：分镜按时长横排 + 音轨 ============ */
.tl-card { padding: 14px 16px; margin-bottom: 18px; display: flex; flex-direction: column; gap: 8px; }
.tl-card > .k { font-size: 10.5px; letter-spacing: .08em; color: var(--text-3); text-transform: uppercase;
  display: flex; justify-content: space-between; }
.tl-card > .k .sub { color: var(--text-3); letter-spacing: 0; }
.tl-strip { display: flex; gap: 2px; height: 64px; }
.tl-block {
  position: relative; flex-basis: 0; min-width: 26px; border-radius: 6px; overflow: hidden;
  background: var(--bg-card-2) center/cover; cursor: pointer;
  border: 1px solid var(--line); transition: transform .12s, border-color .15s;
}
.tl-block:hover { transform: translateY(-2px); border-color: var(--amber); }
@keyframes tlpulse { 0%, 100% { opacity: 1; } 50% { opacity: .4; } }
.tl-tag {
  position: absolute; left: 4px; top: 6px; font-size: 10px; font-family: var(--font-mono);
  padding: 1px 5px; border-radius: 4px; background: rgba(0, 0, 0, .55); color: var(--text-2);
}
.tl-dur { position: absolute; right: 4px; bottom: 3px; font-size: 9.5px;
  font-family: var(--font-mono); color: var(--text-2); text-shadow: 0 1px 2px #000; }
/* 时间线上的转场格：黑场光带 + 居中字卡文案（fade_white 反白）——不留空白格 */
.tl-block.tl-tr { min-width: 52px; color: #e8eaf0;
  background: radial-gradient(130% 95% at 50% 45%, #262b36 0%, #0b0d12 78%); }
.tl-block.tl-tr::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 32%, rgba(255, 255, 255, .08) 50%, transparent 68%); }
.tl-tr-txt { position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 1px; padding: 0 6px;
  font: 500 10px/1.3 var(--font-mono); letter-spacing: .25em; margin-right: -.25em;
  text-align: center; overflow: hidden; }
.tl-tr-ico { font-style: normal; font-size: 12px; letter-spacing: 0; opacity: .7; }
.tl-block.tl-tr.white { color: #30343b;
  background: radial-gradient(130% 95% at 50% 45%, #ffffff 0%, #d8dce5 82%); }
.tl-block.tl-tr .tl-dur { color: inherit; opacity: .75; }
/* 直供徽标：素材直供画面（未走 AI 生图）——挂 shot-visual 右上 */
.tl-audio { display: flex; gap: 2px; height: 16px; }
.tl-ablock {
  flex-basis: 0; min-width: 26px; border-radius: 4px; background: var(--bg-card-2);
  border: 1px dashed var(--line); font-size: 9px; color: var(--text-3);
  display: grid; place-items: center;
}
/* 音轨块底色 = 镜审阅状态（取代缩略图角标）：通过蓝·待审琥珀·重做红·生成中蓝脉冲；todo 中性虚线 */
.tl-ablock.green { background: var(--green-soft); border: 1px solid transparent; color: var(--green); }
.tl-ablock.amber { background: var(--amber-soft); border: 1px solid transparent; color: var(--amber); }
.tl-ablock.red { background: var(--red-soft); border: 1px solid transparent; color: var(--red); }
.tl-ablock.blue { background: var(--blue-soft); border: 1px solid transparent; color: var(--blue); }
.tl-ablock.wip { animation: tlpulse 1.5s ease-in-out infinite; }
/* 转场无音轨：与缩略行转场格同宽(52px) 对齐，防后续整体错位；淡化表示无音 */
.tl-ablock.tl-tr { min-width: 52px; background: transparent; border-style: dotted; opacity: .5; }
.tl-bgm { display: flex; align-items: center; gap: 8px; font-size: 9.5px; color: var(--text-3);
  letter-spacing: .08em; }
.tl-bgm i { flex: 1; height: 4px; border-radius: 2px;
  background: repeating-linear-gradient(90deg, var(--cyan-soft) 0 8px, transparent 8px 12px); }

/* ============ 看板：状态列 · 热力 · 重roll榜 ============ */
.kanban { display: grid; grid-template-columns: repeat(5, 1fr); gap: 16px; margin-bottom: 26px; }
/* 列不立框：列头 + 卡片直接摆在版面上（Linear 式看板），描边留给拖放态点亮——
   描边列裝描边卡的双层套盒是盒子感重灾区 */
.kb-col { border: 1px dashed transparent; border-radius: var(--r-md);
  padding: 6px; margin: -6px; display: flex; flex-direction: column; gap: 10px; min-height: 120px;
  transition: border-color .15s, background .15s; }
.kb-head { display: flex; align-items: center; justify-content: space-between;
  padding-bottom: 7px; border-bottom: 1px solid var(--line); }
.kb-cnt { font-family: var(--font-mono); font-size: 12px; color: var(--text-3); }
.kb-list { display: flex; flex-direction: column; gap: 6px; max-height: 420px; overflow: auto; }
.kb-card {
  display: flex; align-items: center; gap: 8px; padding: 5px; border-radius: 7px;
  background: var(--bg-card); border: 1px solid var(--line); text-decoration: none;
  color: var(--text-2); box-shadow: var(--hi), var(--shadow-1);
  transition: border-color .15s, transform .15s var(--ease);
}
.kb-card:hover { border-color: var(--line-2); transform: translateY(-1px); }
.kb-card img { width: 34px; height: 44px; object-fit: cover; border-radius: 4px; flex: none; }
.kb-ph { width: 34px; height: 44px; border-radius: 4px; background: var(--bg-card-2);
  display: grid; place-items: center; font-size: 10px; color: var(--text-3); flex: none; }
.kb-meta { display: flex; flex-direction: column; min-width: 0; font-size: 11px; }
.kb-meta b { color: var(--text); font-weight: 600; }
.kb-meta i { font-style: normal; color: var(--text-3); white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }
.kb-meta em { font-style: normal; color: var(--amber); font-family: var(--font-mono); font-size: 10px; }
.kb-more { font-size: 10.5px; color: var(--text-3); text-align: center; }
.heat-row { cursor: pointer; }
.heat-row:hover td { background: var(--bg-hover); }
.heat-cell.amber { color: var(--amber); }
.heat-cell.red { color: var(--red); }
.heat-cell.green { color: var(--green); }
.mono.bad, .spec-val.bad, .spec-val .bad { color: var(--red); }
.reroll-list { display: flex; flex-direction: column; gap: 8px; }
.reroll-row {
  display: flex; align-items: center; gap: 12px; padding: 8px 12px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--r-md);
  text-decoration: none; color: var(--text-2); font-size: 12.5px;
}
.reroll-row:hover { border-color: var(--text-3); }
.reroll-row img { width: 36px; height: 46px; object-fit: cover; border-radius: 5px; }
.reroll-row b { font-family: var(--font-mono); color: var(--red); }
.reroll-row > span:not(.chip) { flex: 1; }

/* ============ 平台规格达标卡 ============ */
.spec-card { padding: 16px 18px; display: flex; flex-direction: column; gap: 9px; }
.spec-row { display: grid; grid-template-columns: 64px 1fr 140px; gap: 12px; align-items: center; }
.spec-ch { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3); }
.spec-bar { position: relative; height: 10px; border-radius: 5px; background: var(--bg-card-2);
  overflow: hidden; }
.spec-range { position: absolute; top: 0; bottom: 0; background: var(--green-soft);
  border-inline: 1px solid rgba(92, 158, 232, .35); }
.spec-fill { position: absolute; left: 0; top: 2px; bottom: 2px; border-radius: 3px;
  background: var(--amber); }
.spec-fill.bad { background: var(--red); }
.spec-val { font-size: 11.5px; color: var(--text-2); font-family: var(--font-mono);
  white-space: nowrap; }
.spec-val i { font-style: normal; color: var(--text-3); }
.spec-foot { display: flex; flex-wrap: wrap; gap: 14px; padding-top: 6px;
  border-top: 1px dashed var(--line); font-size: 11px; color: var(--text-3); }

/* ============ ⌘K 场记检索============ */
kbd.kbd, .pal-foot kbd {
  font: 600 10px/1 var(--font-mono); color: var(--text-2);
  background: var(--bg-card-2); border: 1px solid var(--line-2); border-bottom-width: 2px;
  border-radius: 5px; padding: 2px 5px;
}
.ghost-btn .kbd { margin-left: 2px; }
.palette { position: fixed; inset: 0; z-index: 90; }
.pal-sheet {
  position: relative; width: min(680px, calc(100vw - 48px)); margin: 12vh auto 0;
  background: linear-gradient(180deg, #16191f, #101216); border: 1px solid var(--line-2);
  border-radius: 16px; box-shadow: var(--shadow-pop); overflow: hidden;
  animation: pop .18s var(--ease);
}
.pal-head { display: flex; align-items: center; gap: 12px; padding: 15px 18px;
  border-bottom: 1px solid var(--line); }
.pal-head svg { width: 16px; height: 16px; stroke: var(--amber); fill: none;
  stroke-width: 1.6; stroke-linecap: round; flex: none; }
.pal-head input { flex: 1; background: none; border: none; outline: none;
  color: var(--text); font: 16px/1.4 var(--font-ui); }
.pal-head input::placeholder { color: var(--text-3); }
.pal-tag { font: 600 9px/1 var(--font-mono); letter-spacing: .3em; color: var(--text-3); }
.pal-body { max-height: 46vh; overflow: auto; padding: 8px; }
.pal-row {
  display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; gap: 12px; align-items: center;
  padding: 8px 10px 8px 14px; border-radius: 10px; cursor: pointer; position: relative;
  animation: rise .18s var(--ease) both;
}
.pal-row::before { content: ""; position: absolute; left: 2px; top: 22%; bottom: 22%;
  width: 2px; border-radius: 2px; background: transparent; transition: background .12s; }
.pal-row.sel { background: var(--bg-hover); }
.pal-row.sel::before { background: var(--amber); }
.pal-row img { width: 44px; height: 56px; object-fit: cover; border-radius: 6px; }
.pal-ph { width: 44px; height: 56px; border-radius: 6px; background: var(--bg-card-2);
  display: grid; place-items: center; font: 600 11px var(--font-mono); color: var(--text-3); }
.pal-snip { font-size: 13.5px; color: var(--text-2); white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }
.pal-snip mark { background: var(--amber-soft); color: var(--amber); border-radius: 3px;
  padding: 0 2px; }
.pal-where { font: 500 10.5px/1.8 var(--font-mono); color: var(--text-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pal-field { font: 600 9.5px/1 var(--font-mono); color: var(--text-3);
  background: var(--fill-soft); border-radius: 999px; padding: 3px 8px; white-space: nowrap; }
.pal-empty { padding: 34px 0 30px; text-align: center; color: var(--text-3); font-size: 12.5px; }
.pal-foot { display: flex; gap: 16px; align-items: center; padding: 10px 18px;
  border-top: 1px solid var(--line); color: var(--text-3); font-size: 11px; }
.pal-foot em { margin-left: auto; font: 500 10px var(--font-mono); font-style: normal; }
@keyframes shotflash {
  0%, 55% { box-shadow: 0 0 0 2px var(--amber), 0 12px 40px rgba(240, 166, 60, .18); }
  100% { box-shadow: none; }
}
.shot-card.flash { animation: shotflash 1.6s var(--ease) 1; }

/* ============ 生意页：制片账房 · 台账 + 估值测算单 ============ */
.biz-proj { margin-bottom: 30px; }
.biz-filter { display: flex; align-items: center; gap: 10px; margin-bottom: 18px; }
.biz-filter .us { width: 220px; }
.bf-k { font: 600 9.5px/1 var(--font-mono); letter-spacing: .22em; color: var(--text-3); }
.kb-toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 18px; }
.kb-toolbar .us { width: 240px; }
/* 长度走片库那条共用规则（见 `.lib-bar .fsearch, .kb-toolbar .fsearch`）；
   这里只留本工具条独有的两项：不换行故必须能缩到 0，且贴在统计带上不留下边距 */
.kb-toolbar .fsearch { min-width: 0; margin-bottom: 0; }
.biz-block > .sec { margin-top: 6px; }
.biz-block + .biz-block { margin-top: 4px; }
.val-card { padding: 16px 18px; display: flex; flex-direction: column; gap: 11px; }
.val-card > .k { font-size: 10.5px; letter-spacing: .08em; color: var(--text-3);
  text-transform: uppercase; display: flex; justify-content: space-between; align-items: center; }
.ledger { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.ledger th { font: 600 9.5px/1 var(--font-mono); letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-3); text-align: right; padding: 7px 9px; border-bottom: 1px solid var(--line-2); }
.ledger th:first-child, .ledger td:first-child { text-align: left; }
.ledger td { padding: 7px 9px; border-bottom: 1px solid var(--line); font-size: 12.5px;
  color: var(--text-2); text-align: right; font-family: var(--font-mono); }
.ledger td:first-child { font-family: var(--font-ui); color: var(--text); }
.ledger tbody tr { transition: background .12s; }
.ledger tbody tr:hover { background: var(--bg-hover); }
.ledger .red { color: var(--red); }
.ledger .dim { color: var(--text-3); }
.ledger tfoot td { border-top: 1px solid var(--line-2); border-bottom: none;
  color: var(--text); font-weight: 600; }
.burnwrap { position: relative; margin: 14px 2px 0; }
.burnbar { display: flex; height: 7px; border-radius: 4px; overflow: hidden;
  background: var(--bg-card-2); }
.burnbar .act { background: var(--amber); }
.burnbar .wst { background: var(--red); }
.burn-est { position: absolute; top: -3px; bottom: -3px; width: 2px;
  background: var(--cyan); border-radius: 1px; }
.burn-legend { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 12px;
  font-size: 10.5px; color: var(--text-3); }
.burn-legend i { display: inline-block; width: 8px; height: 8px; border-radius: 2px;
  margin-right: 5px; vertical-align: -1px; }

/* ============ 导出中心：出片单 ============ */
.exp-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
/* 导出卡：整卡可点触发导出（去掉右侧独立按钮），hover 提升 + 右侧动作文字 */
.exp-card { padding: 14px 16px; display: flex; flex-direction: column; gap: 8px; cursor: pointer;
  transition: border-color .18s var(--ease), transform .12s var(--ease), box-shadow .18s var(--ease); }
.exp-card:hover { border-color: var(--line-2); transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .22); }
.exp-card:focus-visible { outline: none; border-color: var(--line-2); }
.exp-card.working { pointer-events: none; opacity: .85; }
.exp-go { flex: none; font: 600 11.5px/1 var(--font-mono); color: var(--amber);
  letter-spacing: .03em; white-space: nowrap; transition: transform .16s var(--ease); }
.exp-card:hover .exp-go { transform: translateX(2px); }
.exp-head { display: flex; align-items: center; gap: 10px; }
.exp-tt { display: flex; align-items: baseline; gap: 9px; min-width: 0; flex: 1; }
.exp-tt b { font-size: 12.5px; font-weight: 600; white-space: nowrap; }
.exp-tt i { font: 500 8.5px/1 var(--font-mono); letter-spacing: .2em;
  color: var(--text-3); font-style: normal; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.exp-desc { color: var(--text-3); font-size: 11.5px; line-height: 1.65; }
.exp-btn { flex: none; position: relative; overflow: hidden; }
.exp-btn.working { color: var(--text-3); pointer-events: none; }
.exp-btn.working::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: repeating-linear-gradient(90deg, var(--amber) 0 14px, transparent 14px 24px);
  animation: spool .8s linear infinite;
}
@keyframes spool { to { background-position: 24px 0; } }
/* 导出结果：文件名主行（绿）+ 目录次行（灰）+ 提示行（琥珀），左缘绿条，点击复制 */
.exp-out { display: flex; flex-direction: column; gap: 2px; cursor: copy;
  background: var(--bg-card-2); border-left: 2px solid var(--green);
  border-radius: 7px; padding: 8px 11px; transition: background .15s; }
.exp-out:hover { background: var(--bg-hover); }
.exp-out b { font: 600 11px/1.5 var(--font-mono); color: var(--green); word-break: break-all; }
.exp-out span { font: 500 9.5px/1.5 var(--font-mono); color: var(--text-3); word-break: break-all; }
.exp-out i { font: 500 10px/1.6 var(--font-mono); color: var(--amber); font-style: normal; }

/* ============ 音色路线容器（vroutes 标签页）：模版生成 ｜ 定制生成 ============ */
.vroutes { display: flex; flex-direction: column; gap: 10px; }
.vroute-tabs { display: flex; gap: 6px; }
.vroute-tab {
  border: 1px solid transparent; background: none; color: var(--text-3);
  border-radius: 999px; padding: 5px 13px; font-size: 11.5px; cursor: pointer;
  transition: color .15s var(--ease), background .15s var(--ease);
}
.vroute-tab:hover { color: var(--text-2); background: var(--bg-hover); }
.vroute-tab.on { color: var(--amber); background: var(--amber-soft); }
.vc-input {
  background: var(--bg-card-2); border: 1px solid var(--line-2); color: var(--text);
  border-radius: 8px; padding: 7px 10px; font-size: 12px; outline: none;
  transition: border-color .15s var(--ease);
}
.vc-input:focus { border-color: var(--amber); }
.vc-input.wide { width: 100%; font-family: var(--font-mono); }
.vc-ack { display: flex; align-items: center; gap: 7px; font-size: 11px;
  color: var(--text-3); cursor: pointer; }
.vc-ack input { accent-color: var(--amber); }
/* 定制生成的声线描述输入框 */
/* 声线描述输入框：形态归 `.ta-field` 基座，这里只定高度 */
.vd-desc { min-height: 62px; }

/* ============ 设定图候选宫格：点选=定稿（旧稿备份 · 血缘传播 · 可换选）============ */
.refcand { display: grid; grid-template-columns: repeat(auto-fill, minmax(86px, 1fr));
  gap: 8px; padding: 10px 12px; border-top: 1px dashed var(--line); }
.refcand-cell {
  position: relative; border-radius: 8px; overflow: hidden; cursor: pointer;
  border: 2px solid transparent;
  transition: transform .12s var(--ease), border-color .15s var(--ease);
}
.refcand-cell:hover { transform: translateY(-2px); border-color: var(--line-2); }
.refcand-cell.picked { border-color: var(--green); }
.refcand-cell img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; }
.refcand-cell b { position: absolute; left: 5px; top: 5px; font: 700 10px/1 var(--font-mono);
  color: var(--text); background: rgba(0, 0, 0, .6); border-radius: 4px; padding: 3px 6px; }
.refcand-badge { position: absolute; right: 5px; bottom: 5px;
  font: 600 9.5px/1 var(--font-mono); color: var(--green);
  background: rgba(0, 0, 0, .65); border-radius: 4px; padding: 3px 6px; }

/* ============ 血缘画布：设定资产 ↔ 分镜（hover 联动 · 过期红线）============ */
.ln-card { padding: 14px 16px; margin-bottom: 18px; display: flex; flex-direction: column; gap: 12px; }
.ln-card > .k { font-size: 10.5px; letter-spacing: .08em; color: var(--text-3);
  text-transform: uppercase; display: flex; justify-content: space-between; }
.ln-card > .k .sub { letter-spacing: 0; }
.ln-stage { position: relative; padding: 2px 4px; }
.ln-svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.ln-row { display: flex; gap: 18px; flex-wrap: wrap; position: relative; z-index: 1;
  justify-content: center; }   /* 资产视图整体居中 */
.ln-assets { margin-bottom: 66px; }
.ln-node { display: flex; flex-direction: column; align-items: center; gap: 5px;
  cursor: pointer; transition: opacity .18s var(--ease), transform .15s var(--ease); }
.ln-node:hover { transform: translateY(-2px); }
.ln-node img, .ln-ph { width: 84px; aspect-ratio: var(--ln-aspect, 16/9); height: auto;
  max-height: 118px; object-fit: cover; border-radius: 8px;
  border: 1px solid var(--line-2); background: var(--bg-card-2); }
.ln-ph { display: grid; place-items: center; color: var(--text-3);
  font: 600 13px var(--font-mono); }
.ln-node i { font-style: normal; font-size: 10.5px; color: var(--text-3);
  max-width: 64px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ln-node.hot img, .ln-node.hot .ln-ph { border-color: var(--amber); }
.ln-node.hot i { color: var(--amber); }
.ln-shot.stale img { border-color: rgba(239, 106, 90, .65); }
.ln-stage.focus .ln-node:not(.hot) { opacity: .28; }
.ln-edge { fill: none; stroke: var(--line-2); stroke-width: 1.2;
  transition: stroke .15s, opacity .18s; }
.ln-edge.stale { stroke: rgba(239, 106, 90, .55); stroke-dasharray: 5 4; }
.ln-stage.focus .ln-edge:not(.hot) { opacity: .1; }
.ln-edge.hot { stroke: var(--amber); stroke-width: 1.8; }
.ln-edge.stale.hot { stroke: var(--red); }

/* ============ 看板拖拽表态 ============ */
.kb-card { cursor: grab; }
.kb-card:active { cursor: grabbing; }
.kb-col.dropping { border-color: var(--amber); background: rgba(240, 166, 60, .045); }

/* ============ 灯箱框选局部改造："只改这一处" ============ */
.lb-canvas.refining { cursor: crosshair; }
.lb-canvas.refining .lb-pin { pointer-events: none; opacity: .3; }
#lb-rect {
  position: absolute; border: 1.5px dashed var(--amber); border-radius: 4px;
  background: rgba(240, 166, 60, .07); pointer-events: none;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, .38);   /* 框外压暗：聚光在改造区域 */
}
#lb-rect::after {
  content: attr(data-label); position: absolute; top: -24px; left: -2px;
  font: 600 10px/1 var(--font-mono); color: var(--amber);
  background: rgba(0, 0, 0, .7); padding: 4px 7px; border-radius: 5px; white-space: nowrap;
}
.lb-refine { display: flex; gap: 8px; align-items: center; }
.lb-refine-tag {
  flex: none; font: 600 10px/1.4 var(--font-mono); color: var(--amber);
  background: var(--amber-soft); border-radius: 6px; padding: 6px 9px; letter-spacing: .05em;
}
/* 提交类按钮与「整体」标签完全同制式（软琥珀 chip），hover 转实底示可点 */
.lb-refine-go {
  flex: none; font: 600 10px/1.4 var(--font-mono); letter-spacing: .05em;
  padding: 6px 11px; border-radius: 6px; border: 1px solid rgba(240, 166, 60, .35);
  background: var(--amber-soft); color: var(--amber);
  transition: background .15s, color .15s, transform .12s; }
.lb-refine-go:hover { background: var(--amber); color: #16130c; }
.lb-refine-go:active { transform: scale(.96); }
.lb-refine-go:disabled { opacity: .38; cursor: not-allowed; transform: none; }
.lb-refine-go:disabled:hover { background: var(--amber-soft); color: var(--amber); }
.lb-foot-btns { display: flex; gap: 8px; }

/* ============ 统一弹层（uiConfirm / uiPrompt）：全站操作确认同一语言 ============ */
.dlg { position: fixed; inset: 0; z-index: 210; display: grid; place-items: center; }
.dlg-backdrop {
  position: absolute; inset: 0; background: var(--scrim);
  backdrop-filter: var(--scrim-blur); -webkit-backdrop-filter: var(--scrim-blur);
  animation: dlg-fade .15s var(--ease);
}
.dlg-card {   /* 磨砂透明（与 #sys-tip / 详情卡同族），透出背景虚化 */
  position: relative; z-index: 2; width: min(420px, calc(100vw - 48px));
  background: rgba(22, 25, 33, .62); backdrop-filter: blur(24px) saturate(165%);
  -webkit-backdrop-filter: blur(24px) saturate(165%);
  border: 1px solid rgba(255, 255, 255, .13); border-radius: 14px;
  box-shadow: var(--shadow-pop); padding: 20px 20px 16px;
  display: flex; flex-direction: column; gap: 12px;
  animation: pop .15s var(--ease);
}
.dlg.closing { pointer-events: none; }
.dlg.closing .dlg-backdrop, .dlg.closing .dlg-card { animation: dlg-out .14s var(--ease) forwards; }
@keyframes dlg-fade { from { opacity: 0; } }
@keyframes dlg-out { to { opacity: 0; } }
.dlg-msg { font-size: 13px; color: var(--text-2); line-height: 1.7; white-space: pre-wrap; }
/* 紧贴着下方列表的引导句：小一号、上下留白收窄，读作列表的标题而不是另一段说明 */
.dlg-msg.tight { margin: 12px 0 5px; font-size: 12px; }
.dlg-card .cmt-input { width: 100%; }
.dlg-acts { display: flex; justify-content: flex-end; gap: 8px; margin-top: 2px; }
.dlg-btn {
  border: 1px solid transparent; border-radius: var(--btn-r); padding: var(--btn-pad);
  font-size: var(--btn-fs); color: var(--text-2); transition: all .15s var(--ease);
  background: var(--fill-soft);
}
.dlg-btn:hover { color: var(--text); background: var(--bg-hover); }
.dlg-btn.primary { background: var(--amber); border-color: var(--amber); color: #14161b; font-weight: 600; }
.dlg-btn.primary:hover { background: var(--amber-deep); border-color: var(--amber-deep); color: #14161b; }
.dlg-btn.danger { background: var(--red); border-color: var(--red); color: #14161b; font-weight: 600; }
.dlg-btn.danger:hover { filter: brightness(1.08); color: #14161b; }

/* 分镜卡·镜内多段台词：一句一行 + 说话人签（多角色镜的「谁在说话」一眼可见） */
.shot-lines { display: flex; flex-direction: column; gap: 5px; }
.sl-row { display: flex; gap: 8px; align-items: baseline; }
.sl-who { flex: none; font: 600 10px/1.7 var(--font-mono); letter-spacing: .06em;
  color: var(--amber); opacity: .85; font-style: normal;
  min-width: 3.6em; text-align: right; }
.sl-row > span { flex: 1; min-width: 0; }

/* ══════════ 指令弹层（openDirectiveDialog）：全站「把指令交给 AI」同一张台面 ══════════
   编排语言与控制台一致：眉标 + 中文题 + 定位副行 → 编号分区（数字·中文·英文·发丝线）
   → 等宽指令原文（需求就地嵌进去、琥珀高亮）→ 需求输入 → 字数/快捷键/动作收口。
   卡顶一道琥珀 tally 细光——与分镜卡、导演台同一枚「通电了」的记号。 */
.dq-card { width: min(680px, calc(100vw - 40px)); max-height: 88vh;
  padding: 0; gap: 0; overflow: hidden; }
.dq-card::before {              /* tally 光：中间亮两端隐，压在磨砂卡的上缘内侧 */
  content: ""; position: absolute; inset: 0 0 auto; height: 2px; pointer-events: none;
  z-index: 3;
  background: linear-gradient(90deg, transparent, rgba(240, 166, 60, .5) 26%,
              var(--amber) 50%, rgba(240, 166, 60, .5) 74%, transparent);
  box-shadow: 0 0 14px rgba(240, 166, 60, .32);
}
.dq-hd { position: relative; padding: 20px 22px 15px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(240, 166, 60, .045), transparent); }
.dq-eyebrow { display: block; font-size: 9.5px; font-weight: 600; letter-spacing: .2em;
  text-transform: uppercase; color: var(--amber); opacity: .82; }
.dq-hd h3 { margin-top: 7px; font-size: 17px; font-weight: 600; letter-spacing: .01em;
  color: var(--text); }
.dq-meta { margin-top: 5px; font-size: 11.5px; line-height: 1.6; color: var(--text-3);
  font-family: var(--font-mono); }
.dq-x { position: absolute; right: 13px; top: 13px; width: 27px; height: 27px;
  border-radius: 8px; font-size: 12px; color: var(--text-3);
  display: grid; place-items: center; transition: all .15s var(--ease); }
.dq-x:hover { background: var(--bg-hover); color: var(--text); }

.dq-body { flex: 1 1 auto; min-height: 0; overflow-y: auto;
  padding: 16px 22px 18px; display: flex; flex-direction: column; gap: 9px; }
/* 分区标：01 · 指令原文 · BASE ————————— 发丝线吃掉剩余宽度（editorial 排法） */
.dq-seck { display: flex; align-items: center; gap: 8px; }
.dq-seck:not(:first-child) { margin-top: 7px; }
.dq-seck i { font-size: 9.5px; font-weight: 700; letter-spacing: .12em;
  color: var(--amber); opacity: .7; font-style: normal; }
.dq-seck b { font-size: 12px; font-weight: 600; color: var(--text-2); }
.dq-seck > span:not(.dq-rule) { font-size: 9px; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--text-3); opacity: .8; }
.dq-rule { flex: 1; height: 1px; background: var(--line); }

.dq-pre { position: relative; max-height: min(34vh, 300px); overflow-y: auto;
  background: #0a0c10; border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 12px 14px; font: 11.5px/1.85 var(--font-mono); color: var(--text-2);
  white-space: pre-wrap; overflow-wrap: anywhere;
  scrollbar-width: thin; animation: dq-rise .32s var(--ease) backwards; }
.dq-pre::-webkit-scrollbar { width: 7px; }
/* 高亮槽：未填=虚线待填位，填了=琥珀实底。多行时每行各自成块（clone） */
.dq-slot { border-radius: 5px; padding: 1px 5px; margin: 0 -1px;
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
  background: transparent; border: 1px dashed rgba(240, 166, 60, .38);
  color: var(--amber); opacity: .72; transition: all .18s var(--ease); }
.dq-slot.on { background: var(--amber-soft); border-color: rgba(240, 166, 60, .5);
  border-style: solid; color: var(--amber); opacity: 1;
  box-shadow: 0 0 0 3px rgba(240, 166, 60, .06); }

/* 只写差量：形态归 `.ta-field` 基座（见「长文输入基座」），这里补弹层入场动画与高度 */
.dq-ta { min-height: 96px; animation: dq-rise .32s .05s var(--ease) backwards; }
.dq-note { font-size: 11.5px; line-height: 1.65; color: var(--text-3); }
@keyframes dq-rise { from { opacity: 0; transform: translateY(6px); } }

.dq-ft { display: flex; align-items: center; gap: 10px;
  padding: 12px 22px; border-top: 1px solid var(--line);
  background: rgba(10, 12, 16, .42); }
.dq-stat { font-size: 10.5px; letter-spacing: .06em; color: var(--text-3); }
.dq-ft-acts { margin-left: auto; display: flex; gap: 8px; }
.dq-go { min-width: 108px; text-align: center; }
/* 复制成功的一瞬（收起前 460ms）：主钮换蓝、不再是「等你点」的琥珀 */
.dq-go.ok, .dq-go.ok:hover { background: var(--blue); border-color: var(--blue);
  color: #0b0f16; }
@media (prefers-reduced-motion: reduce) {
  .dq-pre, .dq-ta { animation: none; }
}

/* ============================================================ 新建项目 */
/* 「＋ 新建项目」主按钮（项目页头部右侧 / 空态）——琥珀主行动，与全站 amber 语汇一致 */
.np-open { align-self: center; display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; border-radius: var(--r-sm); cursor: pointer; white-space: nowrap;
  background: var(--amber-soft); border: 1px solid transparent; color: var(--amber);
  font-size: 12.5px; font-weight: 600; letter-spacing: .01em;
  transition: background .15s, border-color .15s, transform .12s var(--ease), box-shadow .15s; }
.np-open:hover { background: var(--amber); border-color: var(--amber); color: #14161b;
  box-shadow: 0 6px 18px rgba(240, 166, 60, .28); }
.np-open:active { transform: scale(.96); }
.np-open-ic { font-size: 14px; line-height: 1; font-weight: 400; }

/* 新建项目弹层：宽卡 + 分区表单（复用 dlg-card 磨砂底）
   卡片封顶 92vh，头/脚固定、**只有 np-body 一条滚动条**（去掉画风内框的第二层滚动，
   杜绝里外双滚 + 任何内容被遮挡） */
.np-card { width: min(720px, calc(100vw - 40px)); max-height: 92vh; gap: 14px; padding: 24px 24px 18px; }
.np-hd { display: flex; flex-direction: column; gap: 4px; }
.np-hd .k { font-size: 16px; font-weight: 700; color: var(--text); letter-spacing: .01em; }
.np-hd small { font-size: 11.5px; color: var(--text-3); }
.np-body { display: flex; flex-direction: column; gap: 14px;
  flex: 1 1 auto; min-height: 0; overflow-y: auto; margin: 2px -6px 0; padding: 2px 6px;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.np-body::-webkit-scrollbar { width: 7px; }
.np-body::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 4px; }
.np-field { display: flex; flex-direction: column; gap: 7px; }
.np-label { font-size: 11px; color: var(--text-3); letter-spacing: .06em; text-transform: uppercase;
  display: flex; align-items: baseline; gap: 8px; }
.np-label small { text-transform: none; letter-spacing: 0; font-size: 11px; color: var(--text-3); opacity: .8; }
.np-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.np-row > .np-field { min-width: 0; }   /* 栅格单元真正等宽（内容不撑破） */
/* 四个文本输入框统一尺寸：等宽（栅格 1fr）+ 等高（box-sizing + 固定 padding/行高） */
.np-inp { width: 100%; box-sizing: border-box; height: 38px; padding: 0 12px;
  border-radius: var(--r-sm, 8px);
  background: rgba(255, 255, 255, .04); border: 1px solid var(--line-2); color: var(--text);
  font: inherit; font-size: 13px; line-height: 38px;
  transition: border-color .15s, background .15s, box-shadow .15s; }
.np-inp::placeholder { color: var(--text-3); }
.np-inp-mono { font-family: var(--font-mono); font-size: 12px; letter-spacing: .02em; }
.np-inp:focus { border-color: var(--amber); background: rgba(255, 255, 255, .06);
  box-shadow: 0 0 0 3px rgba(240, 166, 60, .12); }
.np-inp.np-shake { animation: np-shake .4s cubic-bezier(.36, .07, .19, .97); border-color: var(--red); }
@keyframes np-shake { 10%, 90% { transform: translateX(-1px); } 20%, 80% { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-4px); } 40%, 60% { transform: translateX(4px); } }

/* 画风分组 chip 云——独立磨砂内框，分组标题 + 可选 chip；
   **不自带滚动**（随 np-body 一起滚），避免与外层构成双滚动条；
   默认只露前 3 组，「更多画风」展开其余（常态紧凑无滚动） */
.np-profiles { display: flex; flex-direction: column; gap: 12px;
  padding: 12px; border-radius: 10px; background: rgba(0, 0, 0, .18); border: 1px solid var(--line); }
.np-more-groups { display: flex; flex-direction: column; gap: 12px; }
.np-more { display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  align-self: center; margin-top: 2px; padding: 5px 16px; border-radius: 999px; cursor: pointer;
  background: transparent; border: 1px dashed var(--line-2); color: var(--text-2);
  font: inherit; font-size: 11.5px; transition: color .15s, border-color .15s, background .15s; }
.np-more:hover { color: var(--amber); border-color: rgba(240, 166, 60, .4); background: var(--amber-soft); }
.np-more-ic { font-size: 11px; line-height: 1; }
/* 组头 = skill：/kn-xxx cmd（青色 mono）+ 中文名 + EN + 用途，点明选画风即绑 skill */
.np-pgroup { display: flex; flex-direction: column; gap: 7px; }
.np-pglabel { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.np-pcmd { font: 600 10.5px/1 var(--font-mono); letter-spacing: .02em; color: var(--cyan);
  background: var(--cyan-soft);
  padding: 3px 7px; border-radius: 6px; }
.np-pglabel b { font-size: 12px; font-weight: 600; color: var(--text-2); }
.np-pglabel span { font: 500 8.5px/1 var(--font-mono); letter-spacing: .22em; color: var(--text-3); text-transform: uppercase; }
.np-pusage { font-size: 10.5px; color: var(--text-3); opacity: .85; }
.np-pchips { display: flex; flex-wrap: wrap; gap: 6px; }
.np-prof { font: inherit; font-size: 12px; padding: 5px 12px; border-radius: 999px; cursor: pointer;
  border: 1px solid transparent; background: var(--fill-soft); color: var(--text-2); transition: all .14s; }
.np-prof:hover { background: var(--bg-hover); color: var(--text); }
.np-prof.on { background: var(--amber); border-color: var(--amber); color: #14161b; font-weight: 600; }

/* 绑定 Skill 展示条：选画风后实时更新，青调高亮点明「已绑 skill · AI 凭项目名即可调」 */
.np-bind { display: flex; align-items: flex-start; gap: 10px; padding: 11px 14px;
  border-radius: 10px; background: var(--cyan-soft); }
.np-bind-ic { font-size: 16px; line-height: 1.3; flex: none; }
.np-bind-tx { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.np-bind-tx b { font-size: 12.5px; font-weight: 600; color: var(--text); display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.np-bind-tx code { font: 600 12px/1 var(--font-mono); color: var(--cyan); }
.np-bind-zh { color: var(--text-2); font-weight: 500; }
.np-bind-tx p { font-size: 11px; color: var(--text-3); line-height: 1.6; }

/* 分段控件（站内组件 uiSegment）——胶囊分段，选中琥珀。
   消费者：新建项目的比例与字幕语言、顶栏的外壳形态开关。 */
.useg { display: inline-flex; padding: 3px; gap: 3px; border-radius: 999px;
  background: rgba(0, 0, 0, .22); border: 1px solid var(--line); width: 100%; }
.usegb { flex: 1; font: inherit; font-size: 12px; padding: 6px 10px; border-radius: 999px; cursor: pointer;
  border: none; background: none; color: var(--text-2); white-space: nowrap; transition: all .15s var(--ease); }
.usegb:hover { color: var(--text); }
.usegb.on { background: var(--amber-soft); color: var(--amber); font-weight: 600;
  box-shadow: inset 0 0 0 1px rgba(240, 166, 60, .3); }
/* 紧凑档：嵌在顶栏里与 ghost-btn 同高，且按内容宽不占满 */
.useg-sm { width: auto; padding: 2px; }
.useg-sm .usegb { flex: none; padding: 4px 10px; font-size: 11.5px; }
.np-foot { font-size: 11.5px; color: var(--text-3); line-height: 1.6; }
.np-err { font-size: 12px; color: var(--red); min-height: 2px; }

/* 配置回退告警条：引擎缺 PyYAML / 无 models.yaml 回退内置精简配置时亮出（画风目录缩水） */
.np-cfgwarn { padding: 10px 14px; border-radius: 10px; font-size: 12px; line-height: 1.6;
  background: var(--amber-soft); border-left: 2px solid var(--amber); color: var(--text-2); }
.np-cfgwarn b { color: var(--amber); font-weight: 600; }

/* 无项目空态：网页新建引导 */
.np-empty { display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 12px; padding: 48px 24px; border: 1px dashed var(--line-2); border-radius: 14px;
  background: radial-gradient(120% 100% at 50% 0%, rgba(240, 166, 60, .05), transparent 60%); }
.np-empty-ic { font-size: 26px; color: var(--amber); opacity: .9; }
.np-empty h3 { font-size: 16px; font-weight: 600; color: var(--text); }
.np-empty p { font-size: 13px; color: var(--text-2); line-height: 1.7; max-width: 460px; }
.np-empty .np-open { margin: 4px 0 2px; padding: 9px 20px; font-size: 13px; }
.np-empty-say { font: 500 11px/1.5 var(--font-mono); color: var(--text-3); white-space: pre-wrap;
  word-break: break-all; max-width: 560px; opacity: .7; }

/* ============================================================ 危险区（项目页最底部删除模块） */
.danger-zone { display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  padding: 18px 20px; border-radius: 14px;
  background: linear-gradient(180deg, rgba(239, 106, 90, .05), rgba(239, 106, 90, .02));
  border: 1px solid rgba(239, 106, 90, .22); }
.dz-txt { flex: 1; min-width: 240px; display: flex; flex-direction: column; gap: 5px; }
.dz-txt b { font-size: 14px; font-weight: 600; color: var(--text); }
.dz-txt p { font-size: 12.5px; color: var(--text-3); line-height: 1.65; }
.dz-btn { display: inline-flex; align-items: center; gap: 8px; flex: none;
  padding: 9px 18px; border-radius: 999px; cursor: pointer;
  background: var(--red-soft); border: 1px solid rgba(239, 106, 90, .45); color: var(--red);
  font-size: 12.5px; font-weight: 600; letter-spacing: .02em;
  transition: background .15s, border-color .15s, color .15s, transform .12s var(--ease), box-shadow .15s; }
.dz-btn:hover { background: var(--red); border-color: var(--red); color: #14161b;
  box-shadow: 0 6px 18px rgba(239, 106, 90, .3); }
.dz-btn:active { transform: scale(.96); }
.dz-btn-ic { display: inline-flex; }
.dz-btn-ic svg { width: 14px; height: 14px; fill: none; stroke: currentColor;
  stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }

/* 转场类型选择弹层（类型网格 + 条件方向/主色 chip + 文案 + 音效）——沿用 efx 选择器语汇 */
.tr-dlg { width: min(472px, calc(100vw - 40px)); gap: 10px; }
.tr-sec-k { font-size: 11px; color: var(--text-3); letter-spacing: .06em; margin-top: 6px; }
.tr-types { display: flex; flex-wrap: wrap; gap: 7px; }
.tr-type { font: inherit; font-size: 12.5px; padding: 5px 13px; border-radius: 999px; cursor: pointer;
  border: 1px solid transparent; background: var(--fill-soft); color: var(--text-2);
  transition: all .15s var(--ease); }
.tr-type:hover { background: var(--bg-hover); color: var(--text); }
.tr-type.on { background: var(--amber-soft); color: var(--amber); font-weight: 600; }
.tr-desc { font-size: 12px; color: var(--text-3); line-height: 1.6; min-height: 1.15em; margin: -2px 0 0; }
.tr-opt-row { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.tr-opt-k { flex: 0 0 auto; font-size: 11px; color: var(--text-3); margin-right: 2px; }
.tr-chip { font: inherit; font-size: 11.5px; padding: 3px 11px; border-radius: 999px; cursor: pointer;
  border: 1px solid transparent; background: var(--fill-soft); color: var(--text-2);
  transition: all .15s var(--ease); }
.tr-chip:hover { background: var(--bg-hover); color: var(--text); }
.tr-chip.on { background: var(--amber-soft); color: var(--amber); font-weight: 600; }
.tr-text-sec { display: flex; flex-direction: column; gap: 10px; }
.tr-sound-row { display: flex; align-items: center; gap: 8px; }
.tr-sound-row .us { flex: 1; }

/* ============ 分镜脚本（镜头表）：施工图级专业视图 ============ */
.sb-card { padding: 0; overflow: hidden; }
/* 自适应高度：不设 max-height，纵向一次看全所有分镜（无竖滚动条）；表宽超容器时仅横向可滚 */
.sb-scroll { overflow-x: auto; overflow-y: hidden; }
.sb-table { width: 100%; min-width: 1180px; border-collapse: separate; border-spacing: 0; font-size: 12px; }
.sb-table th {
  position: sticky; top: 0; z-index: 2; background: var(--bg-panel);
  text-align: left; padding: 10px 12px; font: 600 9.5px/1 var(--font-mono);
  letter-spacing: .16em; text-transform: uppercase; color: var(--text-3);
  border-bottom: 1px solid var(--line-2); white-space: nowrap;
}
.sb-table td {
  padding: 9px 12px; border-bottom: 1px solid var(--line);
  color: var(--text-2); vertical-align: top; line-height: 1.6;
}
.sb-row.alt td { background: rgba(255, 255, 255, .016); }
.sb-row:hover td { background: var(--bg-hover); }
.sb-row.expandable { cursor: pointer; }
.sb-no { font: 600 11px/1.7 var(--font-mono); color: var(--amber); white-space: nowrap; }
.sb-no .cev { display: inline-block; margin-right: 5px; color: var(--text-3); transition: transform .15s var(--ease); }
.sb-row.open .cev { transform: rotate(90deg); }
.sb-num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
.sb-dim { color: var(--text-3); }
.sb-txt { min-width: 200px; max-width: 320px; color: var(--text); }
.sb-cap { min-width: 130px; max-width: 240px; color: var(--text-3); font-size: 11.5px; }
.sb-omt td { opacity: .45; }
.sb-omt-tag {
  font: 600 8.5px/1 var(--font-mono); font-style: normal; color: var(--red);
  margin-left: 6px; letter-spacing: .12em;
}
.sb-trrow td {
  background: repeating-linear-gradient(-45deg, transparent 0 12px, rgba(255, 255, 255, .016) 12px 24px);
}
/* 转场固定图标：占用与分镜 › 相同的图标槽（不旋转）→ 镜号列上下对齐 */
.sb-no .cev.cev-tr { color: var(--amber); transform: none; }
/* 转场文字与分镜台词同亮度同字号——偏暗偏小会在视觉上矮一等 */
.sb-tr-txt { color: var(--text); font-size: 12px; letter-spacing: .02em; }
.sb-x td { background: #0d0f13; padding: 12px 16px; }
.sb-x .prompt-rows { margin-top: 0; }

@media (max-width: 900px) {
  /* 窄屏恒顶栏（形态由 shell.js 强制）：侧栏不做整条 display:none——那会让
     五个主菜单与项目树在 900px 以下全部不可达，只能手敲 hash。 */
  html[data-shell="top"] .brand-txt { display: none; }
  html[data-shell="top"] .rail { padding: 0 12px; }
  html[data-shell="top"] .rail-tree { left: 12px; }
  /* 作者签与出品签让位，法律签保留——AGPL 第 5(d) 条不因屏幕窄而豁免 */
  html[data-shell="top"] .rail-author,
  html[data-shell="top"] .rail-power,
  html[data-shell="top"] .rail-sep { display: none; }
  .chap-row { grid-template-columns: 64px 1fr 90px; }
  .chap-row > :nth-child(n+4):not(:last-child) { display: none; }
  .shot-card { grid-template-columns: 1fr; }
  .shot-visual { aspect-ratio: 16/9; }
  /* 角色设定窄屏降到一列：两列在 900px 以下每张不足 430px，三区表又糊回去了 */
  .char-grid { grid-template-columns: minmax(0, 1fr); }
  /* 道具/取景地同步降到两列（四列在 900px 以下每张不足 210px，物件细节糊成一团） */
  .prop-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .kanban { grid-template-columns: repeat(2, 1fr); }
  .spec-row { grid-template-columns: 48px 1fr 100px; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001s !important; transition-duration: .001s !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   3D 导演控制台（#/stage/<pid>/<cid>）
   剪辑室外壳的延伸：同一套令牌、同一种 mono 微标签语言、同一组按钮度量。
   控制台不该看起来像"嵌进来的另一个软件"——它是 Studio 的一个视图。
   布局：满幅三栏（大纲 / 视口 / 检查器）+ 底部时间轴脊柱。
   ═══════════════════════════════════════════════════════════════════════════ */
.view.view-stage { padding: 0; overflow: hidden; display: flex; flex-direction: column;
  min-height: 0; height: calc(100vh - var(--chrome-h)); }
.view.view-stage.enter > * { animation: none; }     /* 满幅态禁 rise（会裁掉视口） */
/* :has 精修：让 .main 真正锁死一屏，视口高度不再依赖 topbar 的估算值 */
body:has(.view.view-stage) .main { height: 100vh; overflow: hidden; }
body:has(.view.view-stage) .view.view-stage { height: auto; flex: 1; }
/* 满幅视图下面包屑栏回归静态：.main 已 overflow:hidden、无滚动可言，sticky 无意义；
   且 overflow:hidden 让 .main 成为吸附容器后，浏览器把 sticky 偏移叠在 padding-top
   之上——面包屑栏被推下一条导航条的高度，正好压住满幅头部一整行（3D 导演台的
   返回按钮在顶栏形态下因此点不到）。 */
body:has(.view.view-stage) .topbar { position: static; }

/* ── 头部 ── */
/* 单行紧凑头（44px）：垂直居中，省下的每一行都还给视口 */
.dz-header { display: flex; align-items: center; gap: 11px; height: 44px; flex: none;
  padding: 0 16px; border-bottom: 1px solid var(--line);
  background: var(--bg); }   /* 与顶部导航同一块黑，别在两条横栏间夹出一段灰 */
.dz-header .k { flex: none; }
.dz-header h2 { font-size: 15px; font-weight: 650; letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dz-hsub { font: 500 11px/1 var(--font-mono); color: var(--text-3); font-style: normal;
  white-space: nowrap; }
.dz-header .dz-icobtn { width: 28px; height: 28px; font-size: 14px; }
/* 返回制作台：与头部 chip（16:9 / 8 正镜）同一套度量的可点胶囊——同排元素同尺度 */
.dz-back { display: inline-flex; align-items: center; gap: 6px; padding: 2px 10px;
  border-radius: 999px; border: 1px solid var(--line-2); background: var(--bg-card-2);
  font: 600 10.5px/1.6 var(--font-mono); letter-spacing: .04em;
  color: var(--text-2); white-space: nowrap;
  transition: color .15s, border-color .15s, background .15s, transform .12s var(--ease); }
.dz-back:hover { color: var(--amber); border-color: rgba(240, 166, 60, .5);
  background: var(--amber-soft); }
.dz-back:active { transform: scale(.97); }
.dz-back i { font-style: normal; font-size: 11px; line-height: 1;
  transition: transform .15s var(--ease); }
.dz-back:hover i { transform: translateX(-2px); }
/* 构图九宫格：主体在画面里的落点（Cinemachine Screen X/Y 的可视化） */
.dz-anchors { display: grid; grid-template-columns: repeat(3, 34px); gap: 4px;
  margin-top: 4px; justify-content: center; }
.dz-anchor { height: 24px; border-radius: 5px; border: 1px solid var(--line);
  background: var(--bg-card-2); display: flex; align-items: center; justify-content: center;
  transition: border-color .14s, background .14s; }
.dz-anchor i { width: 6px; height: 6px; border-radius: 50%; background: var(--text-3);
  font-style: normal; transition: background .14s; }
.dz-anchor:hover { border-color: var(--text-3); }
.dz-anchor.on { border-color: var(--amber); background: var(--amber-soft); }
.dz-anchor.on i { background: var(--amber); }
.dz-btn.dz-wide { width: 100%; margin-top: 8px; justify-content: center; }
/* 步进器（镜头块时长）：− 值 ＋ */
.dz-stepper { display: inline-flex; align-items: center; gap: 8px; }
.dz-stepper b { min-width: 34px; text-align: center; font-size: 12.5px; color: var(--text); }
.dz-stepper .dz-icobtn { width: 24px; height: 24px; font-size: 13px; }
/* 状态条：常态无文案即隐藏（教程收进 ⌨ 速查） */
.dz-hudtip:empty { display: none; }

/* ── 三栏骨架 ── */
/* position:relative 是忙态蒙版 `.dz-busy`（absolute inset:0）的定位上下文——
   没有它蒙版会挂到页面级祖先上，盖住整个 Studio 而不是这个工作台 */
.dz-stage { flex: 1; min-height: 0; display: flex; flex-direction: column; position: relative; }
.dz-main { flex: 1; min-height: 0; display: grid;
  grid-template-columns: 256px minmax(0, 1fr) 320px;
  transition: grid-template-columns .24s var(--ease); }
/* 栏收起：列宽归零 + 面板不可见——视口是这个工作台的主角，需要时应当能通栏 */
.dz-main.no-left { grid-template-columns: 0 minmax(0, 1fr) 320px; }
.dz-main.no-right { grid-template-columns: 256px minmax(0, 1fr) 0; }
.dz-main.no-left.no-right { grid-template-columns: 0 minmax(0, 1fr) 0; }
.dz-main.no-left .dz-outliner, .dz-main.no-right .dz-inspector {
  opacity: 0; pointer-events: none; padding-left: 0; padding-right: 0; }
.dz-outliner, .dz-inspector { min-height: 0; overflow-y: auto; padding: 14px 14px 26px;
  background: var(--bg-panel); scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.dz-outliner { border-right: 1px solid var(--line); }
.dz-inspector { border-left: 1px solid var(--line); }
.dz-viewport { position: relative; min-width: 0; min-height: 0; overflow: hidden;
  background: radial-gradient(120% 90% at 50% 0%, #14171d 0%, var(--bg) 72%); }
/* 光标语义（与视口手势对齐）：默认抓手=可平移 · 悬停可选对象=pointer ·
   落位/画线=十字准星 · 拖路点针=move。光标就是「现在点下去会发生什么」的预告。
   **只作用于主画布（直子）**——监视器的内嵌画布（.dz-pipcv）是点按互换视角的按钮 */
.dz-viewport > canvas { display: block; width: 100%; height: 100%; outline: none; cursor: grab; }
.dz-viewport > canvas:active { cursor: grabbing; }
.dz-viewport.pick > canvas { cursor: pointer; }
.dz-viewport.aim > canvas, .dz-viewport.aim > canvas:active { cursor: crosshair; }
.dz-viewport.dragpin > canvas, .dz-viewport.dragpin > canvas:active { cursor: move; }
/* ↕ 手柄 / 垂直拖：ns-resize——光标即操作说明（写在 dragpin 之后，垂直拖时赢） */
.dz-viewport.lift > canvas, .dz-viewport.lift > canvas:active { cursor: ns-resize; }
/* 视口内暗角：把注意力收进画面中心。**必须克制**——120px 模糊 + 24px 扩散会把
   近处的地面网格整片压黑，导演就量不出「这个人离那堵墙几米」，而那正是走位编排
   的全部依据。收到 76px/0 扩散、透明度 .42，只压边缘不吃工作区。 */
.dz-viewport::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  box-shadow: inset 0 0 76px 0 rgba(0, 0, 0, .42); }

/* ── 通用控件（控制台内自足；下拉/勾选/档位一律复用站内组件 .us / .us-check / .efx-opt） ── */
.view-stage .dz-btn { display: inline-flex; align-items: center; justify-content: center;
  gap: 7px; padding: var(--btn-pad); border-radius: var(--btn-r);
  font-size: var(--btn-fs); font-weight: 600; color: var(--text-2);
  border: 1px solid var(--line-2); background: var(--bg-card-2);
  transition: background .15s, color .15s, border-color .15s, transform .12s var(--ease); }
/* hover 与顶栏 ghost-btn（检索/指令集）同语：琥珀描边+软底，不加投影不发光 */
.view-stage .dz-btn:hover { background: var(--amber-soft); color: var(--amber);
  border-color: var(--amber); }
/* 内联 SVG 图标（emoji 在不同系统渲染不一致且廉价感重） */
.dz-svgi { display: inline-flex; align-items: center; font-style: normal; }
.dz-svgi svg { width: 13px; height: 13px; fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; }
.view-stage .dz-btn:active { transform: scale(.97); }
.view-stage .dz-btn.on { color: var(--amber); border-color: rgba(240, 166, 60, .45);
  background: var(--amber-soft); }
/* 重点动作（渲染 previz / 交给 Seedance）：描边+软填，与全站唯一的实心琥珀主按钮区分 */
.dz-cta { width: 100%; margin-top: 10px; padding: 10px 14px; border-radius: var(--r-md);
  font-size: 12.5px; font-weight: 620; color: var(--amber);
  border: 1px solid rgba(240, 166, 60, .38);
  background: linear-gradient(180deg, rgba(240, 166, 60, .16), rgba(240, 166, 60, .05));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06);
  transition: border-color .18s var(--ease), background .18s var(--ease),
              box-shadow .2s, transform .12s var(--ease); }
.dz-cta:hover { color: #ffdda6; border-color: rgba(240, 166, 60, .8);
  background: linear-gradient(180deg, rgba(240, 166, 60, .27), rgba(240, 166, 60, .1));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); }   /* 不外发光——与顶栏同纪律 */
.dz-cta:active { transform: scale(.985); }
.dz-cta:disabled { opacity: .42; pointer-events: none; }
.dz-cta.sm { width: auto; margin: 0; padding: 7px 15px; font-size: 12px; }
.dz-icobtn { width: 30px; height: 30px; flex: none; border-radius: var(--btn-r);
  font-size: 12px; color: var(--text-3); border: 1px solid var(--line-2);
  background: var(--bg-card-2); transition: color .15s, border-color .15s, background .15s; }
.dz-icobtn:hover { color: var(--text); border-color: var(--text-3); background: var(--bg-hover); }

.dz-sec { display: flex; align-items: center; gap: 8px; margin: 15px 0 8px; }
.dz-sec:first-child { margin-top: 0; }
.dz-sec::after { content: ""; flex: 1; height: 1px; background: var(--line); }
/* 分组卡：检查器的一组相关控件收进一张软卡（顶级工具面板的通用式样） */
.dz-card { padding: 11px 12px 12px; margin-bottom: 10px; border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: linear-gradient(180deg, var(--bg-card) 0%, var(--bg-card-2) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .03); }
.dz-card .dz-sec { margin: 13px 0 8px; }
.dz-card .dz-sec:first-child { margin-top: 0; }
.dz-card .dz-cta { margin-top: 8px; }
.dz-inspector .dz-card:last-child { margin-bottom: 0; }
.dz-hint { font: 500 10px/1 var(--font-mono); color: var(--text-3); font-style: normal; }
.dz-row { display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 5px 0; font-size: 12.5px; color: var(--text-2); }
/* 标签**定宽成列**（60px·绝不换行竖排）：右侧控件才有全栏统一的左右缘——
   表单的「标签列 + 控件列」两列制（实测点名：全部 input/select 对齐表演段
   那种通栏宽度，而不是各行随标签长短犬牙交错） */
.dz-row > span:first-child { flex: none; width: 60px; white-space: nowrap;
  color: var(--text-3); }
.dz-row > div { flex: 1; display: flex; align-items: center; gap: 6px; min-width: 0;
  justify-content: flex-end; }
.dz-ro { font-size: 12px; color: var(--text); }
.dz-ro.bad { color: var(--red); }
/* 站内下拉在窄栏里的度量收敛（.us 本体样式来自全站）。
   行内控件一律**弹性充满**（flex:1）：标签列定宽后，input 与下拉的左右缘
   全栏统一——右栏只有一种控件宽度（实测点名对齐它） */
.dz-inspector .us-btn { font-size: 12px; padding: 5px 9px; }
.dz-row .us { flex: 1; width: auto; max-width: none; }
/* 文本输入与站内下拉（.us）同宽同位——同一栏里两种控件两种宽度会显乱。
   类名必须是 dz-in 而非 dz-txt——后者是 3D 导演台**入口卡文本块**的既有类
   （flex:1 + min-width:240px），撞名时 min-width 会把输入框撑到 240px、
   把「名称」标签挤到贴身（与 dz-seg 撞名同一失败形态） */
.dz-in { flex: 1; width: auto; min-width: 0; padding: 5px 9px; font-size: 12px; }
.dz-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }
/* 药丸等宽伸展：整行整齐的格栅感，不一行长一行短地犬牙交错 */
.dz-pills .efx-opt { font-size: 11.5px; padding: 4px 8px; flex: 1 0 auto;
  min-width: 46px; text-align: center; }
.dz-chip { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 999px;
  font: 600 10.5px/1.6 var(--font-mono); letter-spacing: .04em;
  color: var(--text-2); background: var(--bg-card-2); border: 1px solid var(--line-2); }
.dz-chip.amber { color: var(--amber); background: var(--amber-soft); border-color: rgba(240,166,60,.3); }
.dz-chip.blue { color: var(--blue); background: var(--blue-soft); border-color: rgba(92,158,232,.3); }
.dz-chip.red { color: var(--red); background: var(--red-soft); border-color: rgba(239,106,90,.3); }
.dz-note { margin: 7px 0 2px; font-size: 11.5px; line-height: 1.7; color: var(--text-3); }
.dz-note.warn { color: var(--amber); }
.dz-empty { padding: 14px 10px; font-size: 12px; line-height: 1.7; color: var(--text-3);
  border: 1px dashed var(--line-2); border-radius: var(--r-md); text-align: center; }
.dz-btns { display: flex; gap: 8px; margin: 6px 0 2px; }
/* KPI 小格（统计 / 步态）——比一行行 label:value 更快读 */
.dz-kpis { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; margin-top: 4px; }
.dz-kpis.two { grid-template-columns: 1fr 1fr; }
.dz-kpi { padding: 9px 10px; border-radius: var(--r-md); text-align: center;
  border: 1px solid var(--line); background: var(--bg); }
.dz-kpi b { display: block; font: 650 14px/1.3 var(--font-mono); color: var(--text); }
.dz-kpi span { display: block; margin-top: 3px; font-size: 10px; color: var(--text-3);
  letter-spacing: .02em; }
.dz-kpi.bad b { color: var(--red); }
/* 卡内小节标题微提亮 + 走位按钮组等宽 */
.dz-card .dz-sec .k { color: var(--text-2); }
.dz-btns .dz-btn { flex: 1; justify-content: center; }

/* ── 大纲：工具条固定在栏顶，树单独滚动（树一长「添加」被卷走就等于没有）── */
.dz-outliner { padding: 0; display: flex; flex-direction: column; overflow: hidden; }
.dz-otree { flex: 1; min-height: 0; overflow-y: auto; padding: 10px 14px 26px;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.dz-obar { display: flex; align-items: center; gap: 7px; flex: none;
  padding: 12px 14px 10px; border-bottom: 1px solid var(--line); background: var(--bg-panel); }
.dz-add-btn { flex: 1; height: 30px; display: inline-flex; align-items: center;
  justify-content: center; gap: 6px; padding: 0 12px; border-radius: var(--btn-r);
  font-size: 12.5px; font-weight: 600; color: var(--text-2);
  border: 1px dashed var(--line-2); background: transparent;
  transition: color .15s, border-color .15s, background .15s; }
.dz-add-btn:hover { color: var(--amber); border-color: var(--amber);
  background: var(--amber-soft); border-style: solid; }
.dz-add-btn i { font-style: normal; font-size: 13px; line-height: 1; }
.dz-group { margin-bottom: 4px; }
.dz-fold { display: flex; align-items: center; gap: 7px; width: 100%;
  padding: 6px 7px; border-radius: var(--r-sm); background: transparent;
  transition: background .14s; }
.dz-fold:hover { background: var(--bg-hover); }
.dz-fold-caret { font-style: normal; font-size: 12px; color: var(--text-3);
  transition: transform .18s var(--ease); }
.dz-fold.open .dz-fold-caret { transform: rotate(90deg); }
.dz-fold-ico { font-size: 11px; color: var(--text-3); width: 12px; text-align: center; }
.dz-fold b { flex: 1; text-align: left; font: 600 10px/1 var(--font-mono);
  letter-spacing: .14em; color: var(--text-2); }
.dz-fold em { font: 600 10px/1 var(--font-mono); font-style: normal; color: var(--text-3);
  padding: 2px 6px; border-radius: 999px; background: var(--bg-card-2); }
.dz-foldbody { display: flex; flex-direction: column; gap: 2px; padding: 3px 0 6px 6px; }
.dz-group.closed .dz-foldbody { display: none; }
.dz-node { display: flex; align-items: center; gap: 9px; padding: 6px 8px; cursor: pointer;
  border-radius: var(--r-sm); border: 1px solid transparent;
  transition: background .14s, border-color .14s; }
.dz-node:hover { background: var(--bg-hover); }
.dz-node.on { background: var(--amber-soft); border-color: rgba(240, 166, 60, .32);
  box-shadow: inset 2px 0 0 var(--amber); }
/* 播放头正在这一镜（青=在播，琥珀=手选，两态可叠） */
.dz-node.now { border-color: rgba(76, 195, 217, .35);
  box-shadow: inset 2px 0 0 var(--cyan); }
.dz-node.on.now { box-shadow: inset 2px 0 0 var(--amber), inset -2px 0 0 var(--cyan); }
/* 节点图标入小方格：类型一眼可辨，行与行之间有了「锚点」——裸字符会飘 */
.dz-node i { font-style: normal; font-size: 10px; color: var(--text-3);
  width: 20px; height: 20px; flex: none; display: flex; align-items: center;
  justify-content: center; border-radius: 5px;
  border: 1px solid var(--line); background: var(--bg-card-2);
  transition: color .14s, border-color .14s, background .14s; }
.dz-node.on i { color: var(--amber); border-color: rgba(240, 166, 60, .4);
  background: var(--amber-soft); }
.dz-node b { flex: 1; font-size: 12.5px; font-weight: 550; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dz-node em { font: 500 10px/1 var(--font-mono); color: var(--text-3); font-style: normal;
  max-width: 74px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dz-x { font-size: 11px; color: var(--text-3); padding: 0 2px; opacity: 0;
  transition: opacity .14s, color .14s; }
.dz-node:hover .dz-x, .dz-track:hover .dz-x { opacity: 1; }
.dz-x:hover { color: var(--red); }

/* ── 资产缩略图（动作 / 体型 / 道具共用的一格画布）──
   底色比卡面再深一档：灰模是浅色体块，压深底色才有「取景框里的一件东西」的
   分离感；透明底由渲染器给出，这里只负责画框。 */
.dz-thumb { display: block; flex: none; border-radius: var(--r-sm);
  background: linear-gradient(180deg, rgba(255, 255, 255, .035), rgba(0, 0, 0, .22));
  box-shadow: inset 0 0 0 1px var(--line); }

/* ── 资产浮层（＋添加）── */
.dz-pop { position: fixed; z-index: 300; width: 268px; padding: 11px;
  border-radius: var(--r-lg); border: 1px solid var(--line-2);
  background: var(--bg-panel); box-shadow: var(--shadow-pop);
  animation: pop .16s var(--ease); }
.dz-pop-sec { margin: 4px 0 7px; }
.dz-pop-sec:not(:first-child) { margin-top: 12px; padding-top: 11px;
  border-top: 1px solid var(--line); }

/* ── 检查器：运镜当前卡（点开选择器）── */
.dz-presetcard { display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 10px 12px; text-align: left; border-radius: var(--r-md);
  border: 1px solid var(--line-2); background: var(--bg-card-2);
  transition: border-color .16s, background .16s; }
.dz-presetcard:hover { border-color: var(--amber); background: var(--amber-soft); }
.dz-presetcard > div { flex: 1; min-width: 0; }
.dz-presetcard b { display: block; font-size: 13px; font-weight: 600; color: var(--text); }
.dz-presetcard em { display: block; margin-top: 2px; font: 500 10px/1.5 var(--font-mono);
  font-style: normal; color: var(--text-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dz-presetcard i { font-style: normal; font-size: 13px; color: var(--text-3); }
.dz-presetcard:hover i { color: var(--amber); }
.dz-phrase { margin: 8px 0 2px; padding: 9px 11px; border-radius: var(--r-md);
  border: 1px solid var(--line); border-left: 2px solid var(--amber);
  background: var(--bg-card-2); font-size: 12px; line-height: 1.75; color: var(--text-2); }

/* ── 运镜选择器弹层（36 个运镜从侧栏搬进这里）── */
.dz-pkcard { width: min(940px, calc(100vw - 48px)); max-height: min(78vh, 760px);
  display: flex; flex-direction: column; }
.dz-pkhead { display: flex; align-items: center; gap: 12px; padding-bottom: 11px;
  border-bottom: 1px solid var(--line); }
.dz-pkhead .k { flex: none; }
.dz-pkhead .fsearch { flex: 1; }
.dz-pkbody { flex: 1; min-height: 0; overflow-y: auto; padding: 4px 2px 2px;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.dz-pkgroup { display: flex; align-items: center; gap: 8px; margin: 14px 0 8px; }
.dz-pkgroup:first-child { margin-top: 6px; }
.dz-pkgroup em { font: 600 10px/1 var(--font-mono); font-style: normal; color: var(--text-3); }
.dz-pkgroup::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.dz-pkgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 7px; }
.dz-preset { position: relative; display: grid;
  grid-template-columns: 14px 1fr auto; grid-template-rows: auto auto;
  align-items: baseline; gap: 2px 6px; padding: 9px 11px 9px 14px; text-align: left;
  border-radius: var(--r-md); border: 1px solid var(--line);
  background: var(--bg-card-2); overflow: hidden;
  transition: background .14s, border-color .14s, transform .12s var(--ease); }
.dz-preset::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--text-3); opacity: .6; }
.dz-preset.t-blue::before { background: var(--blue); }
.dz-preset.t-amber::before { background: var(--amber); }
.dz-preset.t-red::before { background: var(--red); }
.dz-preset:hover { background: var(--bg-hover); transform: translateY(-1px); }
.dz-preset.on { border-color: var(--amber); background: var(--amber-soft); }
.dz-preset-t { font-size: 9px; color: var(--text-3); }
.dz-preset b { font-size: 12.5px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dz-preset em { font: 500 9.5px/1 var(--font-mono); color: var(--text-3); font-style: normal; }
.dz-preset-d { grid-column: 2 / -1; font-size: 10.5px; line-height: 1.5; color: var(--text-3);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.dz-pkfoot { margin: 11px 0 0; padding-top: 11px; border-top: 1px solid var(--line);
  font-size: 11.5px; color: var(--text-3); }

/* ── 检查器：体型格（四种人偶共用取景，格与格之间身高差直接可读）── */
.dz-modelgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-top: 2px; }
.dz-modeltile { display: flex; align-items: center; gap: 8px; padding: 6px 8px; text-align: left;
  border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--bg-card-2);
  font-size: 11.5px; color: var(--text-2);
  transition: color .14s, border-color .14s, background .14s; }
.dz-modeltile:hover { color: var(--amber); border-color: rgba(240, 166, 60, .45); }
.dz-modeltile.on { color: var(--amber); border-color: var(--amber); background: var(--amber-soft); }
.dz-modeltile span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── 动作选择器弹层（每格实时演一遍）── */
.dz-pkgnote { font-style: normal; font-size: 10.5px; color: var(--text-3); flex: none; }
/* 组头的分隔线由 ::after 撑开，说明文字必须排在它之前才不会被推到行尾之外 */
.dz-pkgroup .dz-pkgnote { order: 2; }
.dz-pkgroup::after { order: 3; }
.dz-actgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(272px, 1fr)); gap: 8px; }
.dz-actcell { position: relative; display: flex; align-items: stretch; gap: 10px;
  padding: 9px; text-align: left; border-radius: var(--r-md);
  border: 1px solid var(--line); background: var(--bg-card-2); overflow: hidden;
  transition: background .14s, border-color .14s, transform .12s var(--ease); }
.dz-actcell::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--text-3); opacity: .6; }
.dz-actcell.k-move::before { background: var(--cyan); }
.dz-actcell.k-loop::before { background: var(--blue); }
.dz-actcell.k-once::before { background: var(--amber); }
.dz-actcell:hover { background: var(--bg-hover); transform: translateY(-1px); }
.dz-actcell.on { border-color: var(--amber); background: var(--amber-soft); }
.dz-actinfo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.dz-actname { display: flex; align-items: baseline; gap: 7px; }
.dz-actname b { font-size: 13px; font-weight: 600; color: var(--text); }
.dz-actname em { font: 500 9.5px/1 var(--font-mono); font-style: normal; color: var(--text-3); }
.dz-actmeta { display: flex; flex-wrap: wrap; gap: 5px; }
.dz-actmeta .dz-chip { padding: 1px 7px; font-size: 9.5px; }

/* ── 动作轨（角色检查器）── */
.dz-tracks { display: flex; flex-direction: column; gap: 5px; }
/* 当前动作卡：缩略图 + 名称 + 展开记号，与运镜那张当前卡同一语汇 */
.dz-actbtn { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px;
  padding: 4px 8px 4px 4px; text-align: left; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: var(--bg-card-2);
  transition: border-color .16s, background .16s; }
.dz-actbtn:hover { border-color: var(--amber); background: var(--amber-soft); }
.dz-actbtn b { flex: 1; min-width: 0; font-size: 12px; font-weight: 550; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dz-actbtn i { font-style: normal; font-size: 11px; color: var(--text-3); }
.dz-actbtn:hover i { color: var(--amber); }
/* 时间标签与属性行的标签**同列宽**（60px + 10px 间距）——表演段的动作卡与
   名称等行内控件左右缘逐像素对齐，右栏只有一种控件宽度 */
.dz-track { display: flex; align-items: center; gap: 10px; }
.dz-at { flex: none; width: 60px; font-size: 10.5px; color: var(--text-3); }
.dz-add { align-self: stretch; margin-top: 2px; font-size: 11.5px; color: var(--text-3);
  padding: 6px 9px; border-radius: var(--r-sm); border: 1px dashed var(--line-2);
  transition: color .14s, border-color .14s; }
.dz-add:hover { color: var(--amber); border-color: var(--amber); }

/* ── 时间轴：Shot-Cuts 脊柱 + 播放头 + 动作轨 ── */
.dz-timeline { border-top: 1px solid var(--line); background: var(--bg-panel);
  padding: 9px 16px 12px; display: flex; flex-direction: column; gap: 7px; }
.dz-tbar { display: flex; align-items: center; gap: 10px; }
.dz-spacer { flex: 1; }

/* ── 忙态蒙版（渲完一镜 → 引擎编码登记的那段等待）──
   为什么要盖住：那段里画面从洁净渲染切回带 gizmo 的编辑视图、而时间轴是暂停的，
   看上去就是「突然跳回初始画面并卡住」。毛玻璃把这次切换整个盖住，并明说在做什么。
   `pointer-events: auto` 是刻意的——这段里场景绝不能被改动（后续镜要照同一份编排渲）。*/
.dz-busy { position: absolute; inset: 0; z-index: 60; display: grid; place-items: center;
  background: rgba(10, 12, 16, .5); backdrop-filter: blur(16px) saturate(.7);
  -webkit-backdrop-filter: blur(16px) saturate(.7);
  opacity: 0; transition: opacity .13s var(--ease); }
.dz-busy.on { opacity: 1; }
.dz-busy-card { display: flex; flex-direction: column; align-items: center; gap: 12px;
  padding: 26px 34px; border-radius: var(--r-lg); border: 1px solid var(--line-2);
  background: rgba(20, 22, 27, .82); box-shadow: 0 22px 60px rgba(0, 0, 0, .5);
  transform: translateY(5px) scale(.985); transition: transform .13s var(--ease); }
.dz-busy.on .dz-busy-card { transform: none; }
.dz-busy-ring { width: 30px; height: 30px; border-radius: 50%;
  border: 2px solid rgba(240, 166, 60, .18); border-top-color: var(--amber);
  animation: dz-spin .82s linear infinite; }
@keyframes dz-spin { to { transform: rotate(360deg); } }
.dz-busy-title { font-size: 13.5px; font-weight: 600; color: var(--text); letter-spacing: .02em; }
.dz-busy-sub { font-size: 11.5px; font-style: normal; color: var(--text-3); }
/* 动效敏感者只保留静态蒙版（转圈会诱发不适），信息一个字不少 */
@media (prefers-reduced-motion: reduce) {
  .dz-busy, .dz-busy-card { transition: none; }
  .dz-busy-ring { animation: none; border-top-color: var(--amber); }
}

/* ── 悬停下拉（工具条的次级动作组）──
   主干动作留在台面，次级动作收进菜单：工具条已经很挤，三个平铺按钮会把
   「排戏 → 渲染 → 出片」的主干淹掉。**向上弹**——工具条下方紧挨着镜头脊柱，
   向下弹会盖住正在看的分镜条。悬停即现移开即收，比点击展开少一次交互，
   也不必处理「点别处收起」。`padding-bottom` 是悬停通路：菜单与触发器之间
   留缝的话，鼠标移过去的半路上菜单就收了。 */
.dz-mwrap { position: relative; display: inline-flex; padding-bottom: 0; }
.dz-menu { position: absolute; bottom: calc(100% + 8px); right: 0; z-index: 40;
  min-width: 208px; padding: 5px; display: flex; flex-direction: column; gap: 2px;
  border-radius: var(--r-md); border: 1px solid var(--line-2);
  background: var(--bg-panel); box-shadow: 0 14px 34px rgba(0, 0, 0, .55);
  opacity: 0; visibility: hidden; transform: translateY(4px);
  transition: opacity .14s var(--ease), transform .14s var(--ease), visibility .14s; }
.dz-mwrap:hover .dz-menu, .dz-mwrap:focus-within .dz-menu {
  opacity: 1; visibility: visible; transform: translateY(0); }
/* 触发器与菜单之间的悬停桥（透明），不然 8px 的缝会让菜单在半路收起 */
.dz-menu::after { content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 10px; }
.dz-menu-item { display: flex; align-items: baseline; gap: 8px; text-align: left;
  padding: 7px 10px; border-radius: var(--r-sm); border: 1px solid transparent;
  background: none; color: var(--text-2); font-family: inherit; font-size: 12px;
  cursor: pointer; text-decoration: none; transition: background .12s, color .12s; }
.dz-menu-item b { font-weight: 500; white-space: nowrap; }
.dz-menu-item em { margin-left: auto; font-style: normal; font-size: 11px; color: var(--text-3); }
.dz-menu-item:hover { background: var(--bg-card-2); color: var(--amber); }
.dz-menu-item:hover em { color: var(--text-2); }
.dz-mtrig { font-variant-numeric: tabular-nums; }
.dz-play { width: 30px; height: 30px; border-radius: 50%; font-size: 11px; color: var(--text);
  border: 1px solid var(--line-2); background: var(--bg-card-2);
  transition: background .14s, border-color .14s, transform .12s var(--ease); }
.dz-play:hover { background: var(--amber-soft); border-color: var(--amber); color: var(--amber); }
.dz-play:active { transform: scale(.93); }
.dz-time { font-size: 12.5px; color: var(--text); font-variant-numeric: tabular-nums; }
.dz-now { font-size: 11.5px; color: var(--text-3); }
.dz-scrub { position: relative; height: 14px; cursor: ew-resize;
  border-radius: 3px; background: var(--bg-card-2); border: 1px solid var(--line); }
.dz-playhead { position: absolute; top: -3px; bottom: -3px; width: 2px; margin-left: -1px;
  background: var(--amber); box-shadow: 0 0 8px rgba(240, 166, 60, .75); pointer-events: none; }
.dz-playhead::before { content: ""; position: absolute; top: -3px; left: -3px;
  border: 4px solid transparent; border-top-color: var(--amber); }

/* ── 分镜卡的「◈ 预演」角标（与 ▸ CLIP / ⇪ 直供 同族） ── */
/* ── 分镜卡画面左下的角标堆栈 .vmarks（◉意见/◈预演/▸动态片段/▦简笔 从上到下）：
   堆叠由 flex 列容器管，不靠 .pzmark ~ .skmark 兄弟偏移逐组合手排——
   四件任意组合都不重叠不悬空 ── */
.vmarks { position: absolute; left: 8px; bottom: 8px; z-index: 2;
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.vmarks .pinmark { position: static; }
.pzmark { cursor: pointer;
  padding: 2px 7px; border-radius: 999px;
  font: 600 9.5px/1.6 var(--font-mono); letter-spacing: .04em;
  color: var(--cyan); background: rgba(10, 12, 16, .82); border: 1px solid rgba(76, 195, 217, .35);
  transition: background .14s, color .14s; }
.pzmark:hover { background: var(--cyan-soft); color: #fff; }

/* ── 分镜卡的「◆ 深度」角标（与 ◈ 预演 / ▦ 简笔 同族·紫色区分第三条运动路径） ── */
.cvmark { cursor: pointer;
  padding: 2px 7px; border-radius: 999px;
  font: 600 9.5px/1.6 var(--font-mono); letter-spacing: .04em;
  color: #b79bff; background: rgba(10, 12, 16, .82); border: 1px solid rgba(150, 122, 255, .38);
  transition: background .14s, color .14s; }
.cvmark:hover { background: rgba(150, 122, 255, .25); color: #fff; }

/* ▸ 视频：画面内的播放入口（成片素材位），紧贴「▦ 简笔」上方——
   版式与 .skmark **逐值一致**（padding/字号/圆角全同），只用青色区分 */
.clip-play { cursor: pointer;
  padding: 2px 7px; border-radius: 999px;
  font: 600 9.5px/1.6 var(--font-mono); letter-spacing: .04em;
  color: var(--cyan); background: rgba(10, 12, 16, .82); border: 1px solid rgba(76, 195, 217, .35);
  transition: background .14s, color .14s; }
.clip-play:hover { background: var(--cyan-soft); color: #fff; }

/* ── 分镜卡的「▦ 简笔」角标（与 ◈ 预演 同族·琥珀系区分两条预演路径） ── */
.skmark { cursor: pointer;
  padding: 2px 7px; border-radius: 999px;
  font: 600 9.5px/1.6 var(--font-mono); letter-spacing: .04em;
  color: var(--amber); background: rgba(10, 12, 16, .82); border: 1px solid rgba(230, 176, 92, .35);
  transition: background .14s, color .14s; }
.skmark:hover { background: rgba(230, 176, 92, .25); color: #fff; }

/* ── 工作台区块卡（简笔分镜 .skb-* / 深度捕捉 .cvc-*）──
   两张卡是同一类东西的两个实例，故**共用这一段样式**而不是各存一份：
   三个工作台的视觉语言（网格底纹 + 描边软填主钮 + 读数瓦片 + 缩略条）
   已经在 .dzc-* 与这里各写过一遍，第三份拷贝只会让它们慢慢长歪。 */
/* 原注：简笔分镜台区块卡（与 3D 导演台入口卡 .dzc 同一套视觉语言：
   网格渐变底纹 + 描边软填主按钮；琥珀调区分两条预演路径） ── */
.skb-card, .cvc-card { position: relative; overflow: hidden; padding: 0; margin-bottom: 10px; }
.skb-grid, .cvc-grid {
  position: absolute; inset: 0; pointer-events: none; opacity: .5;
  background-image:
    linear-gradient(to right, rgba(230, 176, 92, .09) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(230, 176, 92, .09) 1px, transparent 1px);
  background-size: 26px 26px;
  mask-image: radial-gradient(150% 108% at 50% 0%, #000 0%, transparent 74%);
  -webkit-mask-image: radial-gradient(150% 108% at 50% 0%, #000 0%, transparent 74%);
}
.skb-body, .cvc-body { position: relative; padding: 15px 16px 14px; }
/* 主按钮：描边+软填+掠光 hover（.dzc-go 的对位形态，绝不再造实心强调）。

   色相走 `--go` / `--go-hi` 两个变量而不是复制整段规则：三个工作台的主按钮是
   同一件东西的三次出场，配方复制一遍就是下次改 hover 或圆角只改到其中一处。
   分色按**这颗按钮属于哪一类活儿**：画面预演（3D 导演台 / 简笔分镜）取青，
   与 `.dzc-go` 同值；声音（音频剧本）留琥珀。 */
.skb-go, .cvc-go {
  --go: 230, 176, 92;                    /* 琥珀：音频剧本台 */
  --go-hi: #ffe9c4;
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; gap: 9px;
  padding: 10px 18px; border-radius: var(--r-md);
  font-size: 12.5px; letter-spacing: .01em; color: rgb(var(--go));
  border: 1px solid rgba(var(--go), .34);
  background: linear-gradient(180deg, rgba(var(--go), .15), rgba(var(--go), .05));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06);
  transition: border-color .18s var(--ease), background .18s var(--ease),
              box-shadow .2s var(--ease), transform .12s var(--ease);
}
/* 青：与 3D 导演台「进入导演台」逐值同色——两条预演路径的主行动看起来是一类事 */
.skb-go.cy, .cvc-go.cy { --go: 76, 195, 217; --go-hi: #d8f6fb; }
.skb-go::after, .cvc-go::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 32%,
    rgba(var(--go), .22) 48%, transparent 64%);
  transform: translateX(-110%);
  transition: transform .62s var(--ease);
}
.skb-go:hover, .cvc-go:hover { color: var(--go-hi); border-color: rgba(var(--go), .72);
  background: linear-gradient(180deg, rgba(var(--go), .25), rgba(var(--go), .1));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08), 0 4px 18px rgba(var(--go), .16); }
.skb-go:hover::after, .cvc-go:hover::after { transform: translateX(110%); }
.skb-go b, .cvc-go b { font-weight: 650; }
.skb-go-ico, .cvc-go-ico { font-size: 13px; }
.skb-go-arw, .cvc-go-arw { font-style: normal; opacity: .7; transition: transform .18s var(--ease); }
.skb-go:hover .skb-go-arw, .cvc-go:hover .cvc-go-arw { transform: translateX(3px); }
/* 工作台骨架：说明在左、动作与读数在右，与 3D 导演台 `.dzc-mid`/`.dzc-foot` 同形。
   右栏纵向两层——主钮一排在上、读数瓦片在下，与 3D 卡同节奏。 */
.skb-main, .cvc-main { display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 14px 32px; align-items: start; margin-bottom: 12px; }
.skb-lead, .cvc-lead { min-width: 0; display: flex; flex-direction: column; gap: 10px; }
/* 卡头：图标 + 名字 + 一句话，与 3D 导演台 `.dzc-head` 同制式 */
.skb-head, .cvc-head { display: flex; align-items: center; gap: 11px; }
/* 与 3D 导演台 `.dzc-ico` 同色（青）：三个工作台是同一类东西，共用一个色标 */
.skb-ico, .cvc-ico { width: 30px; height: 30px; flex: none; display: inline-flex; color: var(--cyan); }
.skb-ico svg, .cvc-ico svg { width: 100%; height: 100%; fill: none; stroke: currentColor;
  stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.skb-head b, .cvc-head b { display: block; font-size: 14.5px; font-weight: 650; letter-spacing: -.01em; }
.skb-head em, .cvc-head em { display: block; margin-top: 2px; font-style: normal;
  font-size: 11.5px; color: var(--text-3); }
/* 正文限宽与 3D 同口径。`ch` 按数字「0」宽度计，中文一个字约占 2ch——
   88ch ≈ 44 个汉字（62ch 只有 ~31 字，行行折出孤字尾行）；
   text-wrap:pretty 让末行不剩单字（不支持的浏览器静默忽略） */
.skb-desc, .cvc-desc { margin: 0; max-width: 88ch; text-wrap: pretty;
  font-size: 12px; line-height: 1.75; color: var(--text-2); }
.skb-desc strong, .cvc-desc strong { color: var(--text); font-weight: 600; }
.skb-side, .cvc-side { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
/* 读数瓦片：形态与 3D 导演台 `.dzc-stat` 同源，三张卡的读数保持同一外观 */
.skb-stats, .cvc-stats { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.skb-stat, .cvc-stat { min-width: 104px; padding: 8px 11px; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--bg-card-2); text-align: center; }
.skb-stat b, .cvc-stat b { display: block; font: 650 14px/1.25 var(--font-mono); color: var(--text-3); }
.skb-stat span, .cvc-stat span { display: block; margin-top: 3px; font-size: 10.5px; color: var(--text-3); }
.skb-stat.amber b, .cvc-stat.amber b { color: var(--amber); }
.skb-stat.amber, .cvc-stat.amber { border-color: rgba(240, 166, 60, .3); background: var(--amber-soft); }
.skb-stat.clickable, .cvc-stat.clickable { cursor: pointer;
  transition: border-color .15s var(--ease), transform .12s var(--ease); }
.skb-stat.clickable:hover, .cvc-stat.clickable:hover { border-color: var(--amber); transform: translateY(-1px); }
/* 告警条：左侧竖标的提示条（语汇同 `.dzc-note`）。分段超限是**提醒**不是报错，
   用琥珀不用红——红色留给真正失败的路径 */
.skb-alert, .cvc-alert { display: flex; flex-direction: column; gap: 5px;
  padding: 9px 12px 9px 13px; border-radius: var(--r-sm);
  border: 1px solid rgba(240, 166, 60, .22); border-left: 2px solid var(--amber);
  background: var(--amber-soft); }
.skb-alert span, .cvc-alert span { font-size: 11.5px; line-height: 1.7; color: var(--amber); }
/* 工作台动作条：主钮之外一律 ghost 档，按主钮高度重定一档度量。
   `.act-btn` 缺省的 2px/7px·11px 是给卡片角落小操作定的，与 40px 高的主钮并排时
   高度差过大。此处不画描边盒，hover 才浮起边线与微光。 */
.skb-acts, .cvc-acts { display: flex; align-items: stretch; gap: 6px; flex-wrap: wrap; }
.skb-acts .act-btn, .cvc-acts .act-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 10px 15px; border-radius: var(--r-md); line-height: 1;
  /* 软键而非描边盒：静息只有一层几乎察觉不到的提亮当底，没有硬边框。
     同一排里主钮是唯一带描边的那个，层级一眼可读 */
  border: 1px solid transparent; background: rgba(255, 255, 255, .035);
  color: var(--text-2); font-size: 12px; letter-spacing: .01em;
  transition: color .16s var(--ease), border-color .16s var(--ease),
              background .16s var(--ease);
}
.skb-acts .act-btn:hover, .cvc-acts .act-btn:hover {
  color: var(--text); border-color: var(--line-2);
  background: rgba(255, 255, 255, .07);
}
.skb-strip, .cvc-strip { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; }
.skb-cell, .cvc-cell { position: relative; flex: none; border-radius: 6px; overflow: hidden;
  border: 1px solid var(--line); cursor: zoom-in; transition: border-color .14s; }
.skb-cell:hover, .cvc-cell:hover { border-color: var(--amber); }
.skb-cell img, .cvc-cell img { display: block; height: 84px; }
.skb-tag, .cvc-tag { position: absolute; top: 4px; left: 4px; padding: 1px 6px; border-radius: 4px;
  font: 700 8.5px/1.7 var(--font-mono); letter-spacing: .08em;
  color: var(--text-2); background: rgba(10, 12, 16, .78);
  cursor: pointer; transition: color .14s; }
.skb-tag:hover, .cvc-tag:hover { color: var(--amber); }
/* 漂移角点（时长/拍序列已变）：84px 缩略里放不下两行警示文字，收成一枚角点，
   详情走 tip；cursor:help 提示它有话要说 */
.skb-stale, .cvc-stale { position: absolute; bottom: 5px; left: 5px; width: 9px; height: 9px;
  border-radius: 50%; cursor: help; background: #ff8a66;
  border: 2px solid rgba(10, 12, 16, .9);
  box-shadow: 0 0 6px rgba(255, 120, 90, .55); }
.skb-warn, .cvc-warn { font-style: normal; color: var(--amber); cursor: help; }
/* SHOT 签跳转的落点高亮（分镜卡闪一下琥珀描边） */
.sb-flash { animation: sb-flash 1.6s var(--ease) 1; }
@keyframes sb-flash {
  0%, 60% { box-shadow: 0 0 0 2px rgba(230, 176, 92, .75); }
  100% { box-shadow: 0 0 0 2px transparent; }
}
/* 右上角「改板指令」小签（与 SHOT 编号签同族·常显——hover 触发的入口可达性差）*/
.skb-copy, .cvc-copy { position: absolute; top: 4px; right: 4px; z-index: 1;
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 5px; cursor: pointer;
  color: var(--amber); background: rgba(10, 12, 16, .82);
  border: 1px solid rgba(230, 176, 92, .35);
  transition: background .14s, color .14s, transform .12s; }
.skb-copy:hover, .cvc-copy:hover { background: rgba(230, 176, 92, .25); color: #ffe9c4;
  transform: scale(1.08); }
.skb-copy svg, .cvc-copy svg { display: block; }
/* 生成中的格子：无图=虚线占位盒；重生（已有旧图）=旧图压暗、转圈盖在上面 */
.skb-cell.gen, .cvc-cell.gen { cursor: default; min-width: 150px; height: 86px;
  border-style: dashed; display: flex; align-items: center; justify-content: center;
  gap: 7px; background: rgba(240, 166, 60, .04); }
.skb-cell.gen img, .cvc-cell.gen img { position: absolute; inset: 0; height: 100%; width: 100%;
  object-fit: cover; opacity: .28; }
.skb-cell.gen .gw-ring, .cvc-cell.gen .gw-ring { width: 20px; height: 20px; border-width: 2px; z-index: 1; }
.skb-cell.gen i, .cvc-cell.gen i { font: 500 10px/1.6 var(--font-mono); color: var(--text-3);
  font-style: normal; z-index: 1; }
.skb-empty, .cvc-empty { font-size: 12px; color: var(--text-2); margin: 2px 0 6px; }
/* 卡底状态行与 3D 导演台 `.dzc-note` 同制式（分割线 + 琥珀）：三张工作台的
   「当前这一集这套东西生不生效」用同一制式呈现 */
.skb-note, .cvc-note { margin: 12px 0 0; padding-top: 11px; border-top: 1px solid var(--line);
  font-size: 11.5px; line-height: 1.7; color: var(--amber); }
/* ═══════════════════════════════════════════════════════════════════════════
   运动预演折叠条（PV）：kenburns 章节里 3D 导演台与简笔分镜收成的一行。
   刻意**不用**那两张卡的网格底纹与青色主调——底纹与彩色是「这里可以干活」的
   邀请，而这一档下它们不参与出片。收起态走中性灰、hover 才回青，读起来就是
   「在，但此刻不当班」。展开后原样长出那两张卡，条本身变成收起控件。
   ═══════════════════════════════════════════════════════════════════════════ */
.pvz-fold { display: flex; align-items: center; gap: 13px; width: 100%;
  padding: 13px 16px; text-align: left; cursor: pointer;
  transition: border-color .18s var(--ease), background .18s var(--ease); }
.pvz-fold:hover { border-color: var(--line-2); background: var(--bg-card-2); }
/* 展开态仍是一张完整的卡：下面接的是两个带区块头的独立段落，去掉下边框想「焊」
   在一起只会留出一道断口。展开的信号交给图标回青 + 箭头翻面 */
.pvz-fold.open { border-color: var(--line-2); }
.pvz-ico { width: 26px; height: 26px; flex: none; display: inline-flex;
  color: var(--text-3); transition: color .18s var(--ease); }
.pvz-ico svg { width: 100%; height: 100%; fill: none; stroke: currentColor;
  stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.pvz-fold:hover .pvz-ico, .pvz-fold.open .pvz-ico { color: var(--cyan); }
/* 文案吃掉全部余量：读数与展开控件才靠得住地贴在右端。
   用 auto margin 推右在「有读数/无读数」两种组合下要写两条规则，且两个 auto
   会平分余量把读数推到中间 */
.pvz-txt { flex: 1 1 auto; min-width: 0; }
.pvz-txt b { display: block; font-size: 13px; font-weight: 620; color: var(--text-2);
  letter-spacing: -.01em; transition: color .18s var(--ease); }
.pvz-fold:hover .pvz-txt b, .pvz-fold.open .pvz-txt b { color: var(--text); }
.pvz-txt em { display: block; margin-top: 3px; font-style: normal;
  font-size: 11.5px; line-height: 1.55; color: var(--text-3); }
/* 破折号两侧留白：模式名与结论是两句话，挤在一起会读成一句 */
.pvz-sep { margin: 0 6px; opacity: .55; }
/* 留存产物读数：这一档下它是「这里还有东西」的唯一线索，故给琥珀而非灰 */
.pvz-kept { flex: none; padding: 3px 10px; border-radius: 999px;
  font: 500 10.5px/1.7 var(--font-mono); color: var(--amber);
  border: 1px solid rgba(240, 166, 60, .28); background: var(--amber-soft); }
.pvz-act { display: inline-flex; align-items: center; gap: 6px; flex: none;
  font-size: 11.5px; color: var(--text-3); transition: color .18s var(--ease); }
.pvz-fold:hover .pvz-act { color: var(--cyan); }
.pvz-caret { font-style: normal; font-size: 10px; line-height: 1;
  transition: transform .22s var(--ease); }
.pvz-fold.open .pvz-caret { transform: rotate(180deg); }
/* 展开容器：空时不占位；首个区块头收窄上边距（条已经交代了这是什么） */
.pvz-slot:empty { display: none; }
.pvz-slot > .sec:first-child { margin-top: 20px; }
.pvz-slot.in > * { animation: pvzIn .22s var(--ease) both; }
.pvz-slot.in > *:nth-child(2) { animation-delay: .03s; }
.pvz-slot.in > *:nth-child(3) { animation-delay: .06s; }
.pvz-slot.in > *:nth-child(4) { animation-delay: .09s; }
@keyframes pvzIn { from { opacity: 0; transform: translateY(-5px); }
                   to   { opacity: 1; transform: none; } }

/* 选镜弹层 */
.skb-dlg { width: min(560px, 92vw); }
.skb-list { max-height: 46vh; overflow-y: auto; display: grid;
  grid-template-columns: 1fr 1fr; gap: 4px 14px; margin: 10px 0; }
.skb-row { display: flex; align-items: center; gap: 8px; padding: 3px 4px;
  font-size: 12px; cursor: pointer; border-radius: 6px; }
.skb-row:hover { background: var(--bg-hover); }
.skb-row.off { opacity: .5; }
.skb-row b { font: 600 11px/1.4 var(--font-mono); min-width: 44px; }
.skb-row span { color: var(--text-2); }
.skb-tools { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.skb-force { display: flex; align-items: center; gap: 6px; font-size: 12px;
  color: var(--text-2); cursor: pointer; margin-left: auto; }

/* ── 音频剧本台（AU）：复用简笔台的卡壳与主按钮，只补逐段编辑区自己的件 ── */
/* 未切到本路线时主按钮压暗但**不隐藏**——保持可见以标示该路线的入口 */
.skb-go.off, .skb-go:disabled { opacity: .45; cursor: not-allowed; }
.skb-go.off:hover::after, .skb-go:disabled:hover::after { transform: none; }
.aus-play { margin: 2px 0 10px; }
/* 逐段编辑区的工具条：起草与存稿都是「对着下面这些框做的事」，
   放顶行动作条里离它们操作的对象隔了半张卡 */
.aus-tools { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.aus-tools-k { margin-right: auto; font: 600 10px/1 var(--font-mono);
  letter-spacing: .18em; color: var(--text-3); text-transform: uppercase; }
.aus-tools .act-btn { padding: 6px 12px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: transparent; font-size: 11.5px;
  color: var(--text-2); line-height: 1.5; }
.aus-tools .act-btn:hover { color: var(--text); border-color: var(--text-3);
  background: rgba(255, 255, 255, .04); }
/* 存稿的"该点我了"态：框里的 ≠ 盘上的，而生成发的是盘上那份 */
.aus-tools .act-btn.hot { color: var(--amber); border-color: rgba(240, 166, 60, .5);
  background: var(--amber-soft); }
.aus-dirty { font: 600 10.5px/1 var(--font-mono); color: var(--amber);
  letter-spacing: .04em; }
/* 整轨生成期间锁框：此刻改的是"下一版"、跑的是"上一版"，回来分不清谁对应谁 */
.aus-seg.locked { opacity: .72; }
.aus-seg.locked .aus-ta { cursor: not-allowed; background: #08090c; }
/* 段谱系弹层：逐版试听 + 切回（互换，来回切不丢版） */
.aus-vers { display: flex; flex-direction: column; gap: 6px; margin: 10px 0 4px;
  max-height: 46vh; overflow-y: auto; }
.aus-ver { display: flex; align-items: center; gap: 9px; padding: 7px 9px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--bg-card-2); }
.aus-ver.cur { border-color: rgba(92, 158, 232, .38); }
.aus-ver b { font: 700 11px/1.4 var(--font-mono); color: var(--text-2); min-width: 40px; }
.aus-ver .apill { flex: 1; min-width: 0; }
.aus-list { display: grid; gap: 10px; }
.aus-seg { border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px 10px;
  background: rgba(255, 255, 255, .015); }
/* 段缺省收起：头行即开关，收起态只留头行 + 一行摘要——分段一多列表才立得住 */
.aus-seg .aus-head { cursor: pointer; user-select: none; }
.aus-caret { flex: none; width: 0; height: 0; font-size: 0;
  border-left: 4px solid var(--text-3);
  border-top: 3.5px solid transparent; border-bottom: 3.5px solid transparent;
  transition: transform .16s var(--ease); }
.aus-seg:not(.fold) .aus-caret { transform: rotate(90deg); }
.aus-seg.fold .aus-ta { display: none; }
.aus-seg.fold { padding-bottom: 9px;
  transition: border-color .14s var(--ease), background .14s var(--ease); }
.aus-seg.fold:hover { border-color: var(--line-2); background: rgba(255, 255, 255, .03); }
.aus-seg.fold .aus-head { margin-bottom: 4px; }
.aus-peek { display: none; margin: 0 0 0 13px; font-size: 12px; line-height: 1.6;
  color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.aus-seg.fold .aus-peek { display: block; }
.aus-head { display: flex; align-items: center; gap: 9px; margin-bottom: 6px;
  flex-wrap: wrap; }
.aus-head b { font: 700 11px/1.4 var(--font-mono); color: var(--amber);
  letter-spacing: .04em; }
.aus-head span { font-size: 11px; color: var(--text-2); }
.aus-count { margin-left: auto; font: 500 10px/1 var(--font-mono);
  font-style: normal; color: var(--text-3); }
.aus-count.over { color: var(--red); }     /* 接口硬上限 3000 字符，超了服务端直接拒 */
/* 逐段剧本输入框：形态归 `.ta-field` 基座，这里只压字号（一屏要摊开好几段） */
.aus-ta { font-size: 12.5px; min-height: 96px; }
/* 聚焦段左缘竖标：一屏摊开好几段时，「我正在改第几段」要一眼可辨 */
.aus-seg:focus-within { border-color: rgba(240, 166, 60, .4);
  box-shadow: inset 2px 0 0 var(--amber); }
/* 未存改动的吸底工具条：hairline 一条，不做实底横幅 */
.aus-dock { position: sticky; bottom: 10px; z-index: 2;
  display: flex; align-items: center; gap: 10px; margin-top: 10px;
  padding: 7px 12px; border-radius: var(--r-md);
  border: 1px solid rgba(240, 166, 60, .35);
  background: rgba(14, 12, 8, .92); backdrop-filter: blur(6px); }
.aus-dock[hidden] { display: none; }
.aus-dock-k { font: 600 10.5px/1 var(--font-mono); color: var(--amber);
  letter-spacing: .04em; }
.aus-dock i { font-style: normal; font-size: 11px; color: var(--text-2);
  margin-right: auto; }
/* 参考音频对应关系弹层：逐条 = 编号 / 说话人 / 试听 + 提交时自动附加的对应语句 */
.aus-anchor { display: flex; flex-direction: column; gap: 6px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--bg-card-2); }
.aus-anchor-top { display: flex; align-items: center; gap: 10px; }
.aus-anchor-top b { font: 700 11px/1.4 var(--font-mono); color: var(--amber);
  min-width: 52px; }
.aus-anchor-top .apill { flex: 1; min-width: 0; }
.aus-anchor-bind { font-style: normal; font: 500 11px/1.6 var(--font-mono);
  color: var(--text-3); }
.aus-pick { display: flex; align-items: center; gap: 8px; padding: 3px 4px;
  font-size: 12px; cursor: pointer; border-radius: 6px; }
.aus-pick:hover { background: var(--bg-hover); }
.aus-pick.off { opacity: .5; }
.aus-pick b { font: 600 11px/1.4 var(--font-mono); min-width: 52px; }
.aus-pick span { color: var(--text-2); }

@media (max-width: 1180px) {
  .dz-main { grid-template-columns: 208px minmax(0, 1fr) 264px; }
}

/* ── 视口浮层：状态条 + 机位监视器（纯 DOM，pointer-events:none） ── */
.dz-hud { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.dz-hudbar { position: absolute; top: 12px; left: 14px; display: flex; align-items: center; gap: 10px; }
.dz-hudk { font: 600 9.5px/1 var(--font-mono); letter-spacing: .18em; color: var(--amber);
  padding: 3px 7px; border-radius: 4px; background: rgba(10, 12, 16, .68);
  border: 1px solid rgba(240, 166, 60, .3); }
.dz-hudtip { font-size: 10.5px; color: var(--text-3); background: rgba(10, 12, 16, .5);
  padding: 3px 8px; border-radius: 4px; }
/* 监视器：画面走内嵌画布（stage.js 每帧从主画布拷贝），圆角由容器裁切。
   可点击（互换视角）——header 实底条 + REC 灯让它读作「一台监视器」而非装饰框 */
.dz-pip { position: absolute; right: 1.4%; bottom: 1.4%; width: 26%;
  pointer-events: auto; cursor: pointer; overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .22); border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .55);
  transition: border-color .16s, box-shadow .2s; }
.dz-pip:hover { border-color: rgba(240, 166, 60, .6);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .55), 0 0 0 3px rgba(240, 166, 60, .12); }
.dz-pip[hidden] { display: none; }
/* 竖幅画幅（stage.js 按 canvas 高>宽挂 .tall）：改按视口高度定尺寸，宽度由
   inline aspect-ratio 反推——沿用 width:26% 时 9:16 的高是宽的 1.78 倍，会盖满视口 */
.dz-pip.tall { width: auto; height: 44%; }
/* 监视器内嵌画布：画面在圆角容器**里**（与左下参考面板同构），四角不露方角 */
.dz-pipcv { display: block; width: 100%; height: 100%; }
/* 监视器三分构图线：专业监视器标配，与检查器构图九宫格同一套语义；
   只在「机位画面」上显示（导演全局不是构图对象，stage 按视角切 hidden） */
.dz-thirds { position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background-image:
    linear-gradient(to right, transparent calc(33.33% - .5px),
      rgba(255, 255, 255, .13) calc(33.33% - .5px), rgba(255, 255, 255, .13) calc(33.33% + .5px),
      transparent calc(33.33% + .5px)),
    linear-gradient(to right, transparent calc(66.66% - .5px),
      rgba(255, 255, 255, .13) calc(66.66% - .5px), rgba(255, 255, 255, .13) calc(66.66% + .5px),
      transparent calc(66.66% + .5px)),
    linear-gradient(to bottom, transparent calc(33.33% - .5px),
      rgba(255, 255, 255, .13) calc(33.33% - .5px), rgba(255, 255, 255, .13) calc(33.33% + .5px),
      transparent calc(33.33% + .5px)),
    linear-gradient(to bottom, transparent calc(66.66% - .5px),
      rgba(255, 255, 255, .13) calc(66.66% - .5px), rgba(255, 255, 255, .13) calc(66.66% + .5px),
      transparent calc(66.66% + .5px)); }
.dz-thirds[hidden] { display: none; }
/* 机位名牌：跟随机身的浮签（镜号+运镜名+轨道态）——Cinemachine 相机头顶那块牌。
   pointer-events:none 不抢视口手势；DOM 不进画布，导出与监视器天然干净 */
.dz-camtag { position: absolute; z-index: 5; pointer-events: none;
  transform: translate(-50%, calc(-100% - 10px)); white-space: nowrap;
  font: 600 9.5px/1 var(--font-mono); letter-spacing: .05em; color: rgba(191, 233, 242, .88);
  background: rgba(10, 13, 17, .6); border: 1px solid rgba(76, 195, 217, .26);
  border-radius: 5px; padding: 3px 6px; backdrop-filter: blur(5px); }
.dz-camtag[hidden] { display: none; }
/* 视口玻璃件通用语汇（对标 Spline / Previs Pro 的悬浮工具簇） */
.dz-viewseg { position: absolute; top: 10px; left: 50%; transform: translateX(-50%);
  display: flex; gap: 2px; padding: 3px; border-radius: 999px; pointer-events: auto;
  background: rgba(13, 15, 19, .74); border: 1px solid rgba(255, 255, 255, .08);
  backdrop-filter: blur(10px); box-shadow: 0 8px 24px rgba(0, 0, 0, .35); }
.dz-vseg { padding: 5px 14px; border-radius: 999px; font-size: 11.5px; font-weight: 600;
  color: var(--text-3); transition: color .15s, background .15s; }
.dz-vseg:hover { color: var(--text); }
.dz-vseg.on { color: var(--amber); background: var(--amber-soft); }
/* 监视模式提示：贴在视角胶囊正下方居中——模式说明跟着模式开关走 */
.dz-modehint { position: absolute; top: 52px; left: 50%; transform: translateX(-50%);
  padding: 5px 13px; border-radius: 999px; white-space: nowrap;
  font-size: 11px; color: var(--text-3);
  background: rgba(13, 15, 19, .66); border: 1px solid rgba(255, 255, 255, .06);
  backdrop-filter: blur(8px); pointer-events: none; }
.dz-modehint[hidden] { display: none; }
/* 拖拽读数：同槽位（视角胶囊正下方），数字用等宽+青色调——它是「量具」不是提示 */
.dz-draghint { font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  color: #bfe9f2; border-color: rgba(76, 195, 217, .28); }
/* 分镜参考面板（左下）：照着分镜图摆位的对照物；点按放大 */
.dz-refpanel { position: absolute; left: 1.4%; bottom: 1.4%; width: 21%; pointer-events: auto;
  cursor: zoom-in; border-radius: 8px; overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .12); background: rgba(13, 15, 19, .74);
  backdrop-filter: blur(10px); box-shadow: 0 10px 30px rgba(0, 0, 0, .5);
  transition: width .22s var(--ease), height .22s var(--ease), border-color .16s; }
.dz-refpanel:hover { border-color: rgba(255, 255, 255, .3); }
.dz-refpanel.big { width: 44%; cursor: zoom-out; }
.dz-refpanel[hidden] { display: none; }
/* 竖幅画幅：与监视器同规则按视口高度定尺寸，宽度由 img 的 inline aspect-ratio 反推；
   noimg 占位条不跟画幅走，维持 min-height 小条 */
.dz-refpanel.tall:not(.noimg) { width: auto; height: 36%; }
.dz-refpanel.tall.big:not(.noimg) { width: auto; height: 72%; }
.dz-refpanel.tall:not(.noimg) img { width: auto; height: 100%; }
.dz-refpanel img { display: block; width: 100%; object-fit: cover; }
.dz-refpanel img[hidden] { display: none; }
.dz-refpanel .dz-reflbl { position: absolute; left: 0; right: 0; top: 0; z-index: 1;
  padding: 5px 9px; font: 600 9.5px/1 var(--font-mono); letter-spacing: .08em;
  color: var(--text-2);
  background: rgba(10, 12, 16, .92); border-bottom: 1px solid rgba(255, 255, 255, .07); }
.dz-refpanel.noimg { min-height: 58px; cursor: default; }
.dz-refpanel.noimg::after { content: "尚无分镜图"; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; color: var(--text-3); }
/* 交给 Seedance · 选镜弹层 */
.dz-sdcard { width: min(560px, calc(100vw - 48px)); max-height: min(72vh, 640px);
  display: flex; flex-direction: column; }
.dz-sdlist { flex: 1; min-height: 0; overflow-y: auto; margin-top: 8px;
  display: flex; flex-direction: column; gap: 4px;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.dz-shotrow { display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border-radius: var(--r-sm); border: 1px solid var(--line);
  background: var(--bg-card-2); cursor: pointer; transition: border-color .14s; }
.dz-shotrow:hover { border-color: var(--line-2); }
.dz-shotrow b { font-size: 12.5px; color: var(--text); flex: none; }
.dz-shotrow em { font: 500 10.5px/1 var(--font-mono); color: var(--text-3);
  font-style: normal; flex: none; }
.dz-shotrow-t { flex: 1; min-width: 0; font-size: 11.5px; color: var(--text-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: right; }
/* 操作速查弹层 */
.dz-pop-keys { width: 336px; }
.dz-keys { display: grid; grid-template-columns: auto 1fr; gap: 6px 12px; padding: 2px 3px; }
.dz-keys b { font: 600 10px/1.8 var(--font-mono); color: var(--amber); white-space: nowrap; }
.dz-keys span { font-size: 11.5px; color: var(--text-2); line-height: 1.8; }
/* 收栏按钮：贴在视口两侧中线，只在鼠标进视口时显形——常驻会碍事 */
.dz-pane { position: absolute; top: 50%; transform: translateY(-50%); pointer-events: auto;
  width: 16px; height: 46px; font-size: 12px; color: var(--text-3);
  border: 1px solid var(--line-2); background: rgba(16, 18, 22, .88);
  opacity: 0; transition: opacity .18s var(--ease), color .15s, background .15s; }
.dz-viewport:hover .dz-pane { opacity: 1; }
.dz-pane:hover { color: var(--amber); background: var(--bg-hover); }
.dz-pane-left { left: 0; border-left: 0; border-radius: 0 var(--r-sm) var(--r-sm) 0; }
.dz-pane-right { right: 0; border-right: 0; border-radius: var(--r-sm) 0 0 var(--r-sm); }
/* 监视器 header：实底短条而非长渐变——半透明渐变糊在画面上会被读成「灰色阴影」 */
.dz-piplabel { position: absolute; left: 0; right: 0; top: 0; z-index: 1; padding: 5px 9px;
  font: 600 9.5px/1 var(--font-mono); letter-spacing: .08em; color: var(--text-2);
  background: rgba(10, 12, 16, .92); border-bottom: 1px solid rgba(255, 255, 255, .07); }
.dz-piprec { position: absolute; right: 6px; top: 6px; width: 6px; height: 6px; border-radius: 50%;
  background: var(--red); box-shadow: 0 0 7px var(--red); animation: tally 1.9s infinite; }

/* ═══════════════════════════════════════════════════════════════════════════
   3D 导演台入口卡（放映区 · 「3D 导演台」区块，落在「后期」之上）
   它不是又一个后期开关，而是一整个工作台的门——所以给它分量：网格底纹点题、
   青色主调与后期区的琥珀拉开阶段感、统计三格让人一眼知道排到哪了。
   ═══════════════════════════════════════════════════════════════════════════ */
.dzc { position: relative; overflow: hidden; padding: 0; }
/* 舞台网格底纹：与控制台地面同一套语言（1m 细格），透视感靠上疏下密的渐隐 */
.dzc-grid {
  position: absolute; inset: 0; pointer-events: none; opacity: .5;
  background-image:
    linear-gradient(to right, rgba(76, 195, 217, .10) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(76, 195, 217, .10) 1px, transparent 1px);
  background-size: 26px 26px;
  mask-image: radial-gradient(150% 108% at 50% 0%, #000 0%, transparent 74%);
  -webkit-mask-image: radial-gradient(150% 108% at 50% 0%, #000 0%, transparent 74%);
}
.dzc-body { position: relative; padding: 17px 18px 16px; }
/* 顶行：标题与主按钮分居两端（窄容器下自动换行堆叠） */
.dzc-top { display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; }
.dzc-head { display: flex; align-items: center; gap: 11px; }
.dzc-ico { width: 30px; height: 30px; flex: none; display: inline-flex; color: var(--cyan); }
.dzc-ico svg { width: 100%; height: 100%; fill: none; stroke: currentColor;
  stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.dzc-head b { display: block; font-size: 14.5px; font-weight: 650; letter-spacing: -.01em; }
.dzc-head em { display: block; margin-top: 2px; font-style: normal;
  font-size: 11.5px; color: var(--text-3); }
/* 中段：左说明 / 右状态，窄容器下自动堆叠回上下 */
.dzc-mid { display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 14px 30px; margin-top: 12px; }
/* 正文限宽：通栏卡里一行拉到 1200px 会读不下去（每行 ≤ 62 字符是长文的舒适带） */
.dzc-desc { flex: 1 1 380px; margin: 0; max-width: 88ch; text-wrap: pretty;
  font-size: 12px; line-height: 1.75; color: var(--text-2); }

/* 状态组：统计三格与已排镜 pill 并排 */
.dzc-foot { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 16px; }
.dzc-stats { display: flex; gap: 8px; }
.dzc-stat { min-width: 108px; padding: 8px 11px; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--bg-card-2); text-align: center; }
.dzc-stat b { display: block; font: 650 14px/1.25 var(--font-mono); color: var(--text-3); }
.dzc-stat span { display: block; margin-top: 3px; font-size: 10.5px; color: var(--text-3); }
.dzc-stat.cyan b { color: var(--cyan); }
.dzc-stat.cyan { border-color: rgba(76, 195, 217, .3); background: var(--cyan-soft); }
.dzc-stat.amber b { color: var(--amber); }
.dzc-stat.amber { border-color: rgba(240, 166, 60, .3); background: var(--amber-soft); }

.dzc-shots { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.dzc-pill { padding: 3px 9px; border-radius: 999px; cursor: pointer;
  font: 600 10.5px/1.7 var(--font-mono); color: var(--cyan);
  border: 1px solid rgba(76, 195, 217, .32); background: var(--cyan-soft);
  transition: background .14s var(--ease), color .14s, transform .12s var(--ease); }
.dzc-pill:hover { background: var(--cyan); color: #08181c; transform: translateY(-1px); }

.dzc-acts { display: flex; align-items: center; gap: 11px; }
/* 主按钮：**描边 + 软填**而不是实心色块。
   全站只有一个实心强调按钮体系（琥珀 .btn-primary，代表"提交/确认"这类终局动作），
   再来一块实心青色会跟它抢主次、也与四周 hairline + soft-fill 的克制语汇打架。
   这里要的是"重点但不喧宾夺主"：软填底 + 青色描边 + 内高光一线，hover 才点亮。 */
.dzc-go {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; gap: 9px;
  padding: 10px 18px; border-radius: var(--r-md);
  font-size: 12.5px; letter-spacing: .01em; color: var(--cyan);
  border: 1px solid rgba(76, 195, 217, .34);
  background: linear-gradient(180deg, rgba(76, 195, 217, .16), rgba(76, 195, 217, .055));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06);
  transition: border-color .18s var(--ease), background .18s var(--ease),
              box-shadow .2s var(--ease), transform .12s var(--ease);
}
/* 掠光：hover 时一道柔光扫过——克制的"可以进去"的邀请感，不用动色块 */
.dzc-go::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 32%,
    rgba(76, 195, 217, .22) 48%, transparent 64%);
  transform: translateX(-110%);
  transition: transform .62s var(--ease);
}
.dzc-go:hover { color: #d8f6fb; border-color: rgba(76, 195, 217, .72);
  background: linear-gradient(180deg, rgba(76, 195, 217, .26), rgba(76, 195, 217, .1));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 6px 20px rgba(76, 195, 217, .17); }
.dzc-go:hover::after { transform: translateX(110%); }
.dzc-go:active { transform: scale(.975); }
.dzc-go b { font-weight: 620; }
.dzc-go-ico { font-size: 12.5px; line-height: 1; opacity: .95; }
.dzc-go-arw { font-style: normal; font-size: 12px; opacity: .6; margin-left: -2px;
  transition: transform .2s var(--ease), opacity .2s; }
.dzc-go:hover .dzc-go-arw { transform: translateX(3px); opacity: 1; }
.dzc-saved { font-size: 11px; color: var(--text-3); }
.dzc-note { margin: 12px 0 0; padding-top: 11px; border-top: 1px solid var(--line);
  font-size: 11.5px; line-height: 1.7; color: var(--amber); }

/* ═══ 合并放映外观弹层：四段独立开关（漂移 / 底部 / 角标 / 字幕样式），一次提交 ═══ */
/* 卡片封顶视口高（与 .np-card 同款）：头/脚固定，四个分段在 .wm-scroll 一条滚动条里——
   分段全开超出浏览器高度时内部滚动，「应用/取消」永远够得着 */
.wm-card { width: min(600px, calc(100vw - 40px)); max-height: 92vh; }
.wm-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  margin: 0 -6px; padding: 0 6px;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.wm-scroll::-webkit-scrollbar { width: 7px; }
.wm-scroll::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 4px; }
.wm-sec { margin-top: 11px; border-radius: var(--r-md); overflow: hidden;
  border: 1px solid var(--line); background: var(--bg-card-2);
  transition: border-color .18s var(--ease), background .18s var(--ease); }
/* 选中态：两段同用蓝色——水印是一族功能（按钮 .screen-act.wm-on 也是蓝），
   两段各用一色等于宣告它们是两种不同性质的东西 */
.wm-sec.on.t-blue { border-color: rgba(92, 158, 232, .38); background: var(--blue-soft); }
.wm-sec-head { display: flex; align-items: center; gap: 8px; cursor: pointer;
  padding: 10px 12px; border-bottom: 1px solid transparent; }
.wm-sec.on .wm-sec-head { border-bottom-color: var(--line); }
.wm-sec-head b { font-size: 13px; font-weight: 600; color: var(--text-2); }
.wm-sec.on .wm-sec-head b { color: var(--text); }
.wm-sec-head em { font: 600 9.5px/1.7 var(--font-mono); letter-spacing: .1em;
  font-style: normal; padding: 1px 7px; border-radius: 999px; color: var(--text-3);
  border: 1px solid var(--line-2); }
.wm-sec.on.t-blue .wm-sec-head em { color: var(--blue); border-color: rgba(92,158,232,.35); }
.wm-spacer { flex: 1; }
/* 分段开关：与控制台 .dz-check 同款，色随分段主调 */
.wm-sw { width: 34px; height: 19px; appearance: none; border-radius: 999px; cursor: pointer;
  background: var(--bg-card); border: 1px solid var(--line-2); position: relative; flex: none;
  transition: background .18s var(--ease), border-color .18s; }
.wm-sw::after { content: ""; position: absolute; top: 2px; left: 2px; width: 13px; height: 13px;
  border-radius: 50%; background: var(--text-3);
  transition: transform .18s var(--ease), background .18s; }
.wm-sw:checked::after { transform: translateX(15px); }
.t-blue .wm-sw:checked { background: var(--blue-soft); border-color: var(--blue); }
.t-blue .wm-sw:checked::after { background: var(--blue); }
/* 关闭态收起正文：只留标题行，弹层不会被两段表单撑长 */
.wm-sec-body { padding: 0 12px; max-height: 0; opacity: 0; overflow: hidden;
  transition: max-height .22s var(--ease), opacity .18s, padding .22s var(--ease); }
.wm-sec.on .wm-sec-body { padding: 11px 12px 12px; max-height: 260px; opacity: 1; }
.wm-sec-body .cmt-input { width: 100%; }
.wm-desc { margin: 9px 0 0; font-size: 11.5px; line-height: 1.7; color: var(--text-3); }
.wm-sec-body .corner-pick { margin: 10px 0 0; }
/* 字幕样式段比水印段高（预设 chips + 三行控件 + 说明），展开上限单独放宽 */
.wm-sec.wm-tall.on .wm-sec-body { max-height: 460px; }   /* 预设行 + 三行控件 + 说明，留窄屏换行余量 */
.wm-presets { display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 10px; }
/* flex:1 弹性等分——整行正好撑满，右侧不留缺口；万一换行也各自铺满所在行 */
.wm-preset { font: 500 11px/1 var(--font-ui); color: var(--text-2); cursor: pointer;
  flex: 1 1 auto; text-align: center; white-space: nowrap;
  padding: 5px 9px; border-radius: 999px; border: 1px solid var(--line);
  background: transparent; transition: color .15s, border-color .15s; }
.wm-preset:hover { color: var(--text); border-color: rgba(92, 158, 232, .45); }
.wm-row { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; }
.wm-row-l { font-size: 11.5px; color: var(--text-3); min-width: 44px; }
.wm-sec-body .wm-num { width: 82px; flex: none; }
.wm-color { width: 40px; height: 26px; padding: 2px; flex: none; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-sm); background: transparent; }
.wm-row-h { font-size: 10.5px; font-style: normal; color: var(--text-3); }
/* 水印按钮上的启用类型计数（0 不显示） */
.screen-act-n { font: 650 9.5px/1 var(--font-mono); font-style: normal;
  min-width: 15px; height: 15px; padding: 0 4px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  color: #0b1420; background: var(--blue); }

/* ── 视口右上工具组（聚焦主体 / 全屏）── */
.dz-vptools { position: absolute; top: 10px; right: 10px; display: flex; gap: 6px;
  pointer-events: auto; }
.dz-vpbtn { width: 28px; height: 28px; border-radius: var(--r-sm); font-size: 13px;
  color: var(--text-2); border: 1px solid var(--line-2);
  background: rgba(16, 18, 22, .82); backdrop-filter: blur(6px);
  transition: color .15s, border-color .15s, background .15s, transform .12s var(--ease); }
.dz-vpbtn:hover { color: var(--amber); border-color: var(--amber); background: var(--bg-hover); }
.dz-vpbtn:active { transform: scale(.93); }
.dz-vpbtn.on { color: var(--amber); border-color: rgba(240, 166, 60, .55); background: var(--amber-soft); }
/* 全屏态：整块工作台铺满，底色补上（fullscreen 元素默认白底） */
.dz-stage.full { background: var(--bg); height: 100vh; }

/* ── 时间轴：秒刻度尺 ── */
.dz-ruler { position: relative; height: 13px; margin: 2px 0 1px; }
.dz-tick { position: absolute; bottom: 0; width: 1px; height: 4px; background: var(--line-2);
  font: 500 9px/1 var(--font-mono); color: var(--text-3); white-space: nowrap; }
.dz-tick.major { height: 7px; background: var(--text-3); padding-left: 3px; }
.dz-tick.major::after { content: ""; }

/* ── Shot-Cuts 脊柱：默认显示分镜图缩略 ── */
.dz-cuts { display: flex; gap: 3px; height: 54px; }
.dz-cut { position: relative; display: flex; flex-direction: column; justify-content: flex-end;
  gap: 0; padding: 0 8px 6px; min-width: 0; cursor: pointer; overflow: hidden;
  border-radius: var(--r-sm); border: 1px solid var(--line);
  background: linear-gradient(180deg, var(--bg-card) 0%, var(--bg-card-2) 100%);
  background-size: cover; background-position: center;
  transition: border-color .14s, transform .12s var(--ease); }
.dz-cut.has-img { background-color: #000; }
/* 图上压一层渐变——不压的话白底分镜图上的白字直接读不出来。
   **顶部也要近实的暗帽（.84，18% 处回落）**：分镜图上沿常是天窗/白墙的亮部，
   顶端只压 .44 时每块的上边缘都透出一条亮带（齿孔白点叠上去更亮）——实测
   被点名「边缘比较亮，遮罩没弄完全」；暗帽同时给齿孔条一个胶片底色。
   底部必须压到近实（.97）：白色场景图在 .86 时会于块底边透出一条亮线。
   非当前镜整体压重、**当前镜减淡**——「其余沉下去、正拍的亮着」，
   既把白底图彻底盖住，又免费得到一层「现在在哪一镜」的指示 */
.dz-cut-grad { position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(11,12,15,.84) 0%, rgba(11,12,15,.5) 18%,
    rgba(11,12,15,.64) 52%, rgba(11,12,15,.97) 100%); }
.dz-cut.on .dz-cut-grad {
  background: linear-gradient(180deg, rgba(11,12,15,.7) 0%, rgba(11,12,15,.26) 18%,
    rgba(11,12,15,.46) 52%, rgba(11,12,15,.96) 100%); }
.dz-cut:not(.has-img) .dz-cut-grad { display: none; }
.dz-cut::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 4px; z-index: 1;
  background: repeating-linear-gradient(90deg, rgba(255,255,255,.16) 0 3px, transparent 3px 8px); }
.dz-cut:hover { transform: translateY(-1px); border-color: var(--line-2); }
.dz-cut.on { border-color: var(--amber); box-shadow: inset 0 0 0 1px rgba(240,166,60,.45); }
.dz-cut > b, .dz-cut > em, .dz-cut > .dz-cutcam { position: relative; z-index: 1; }
.dz-cut b { font-size: 11.5px; font-weight: 600; color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.8); }
.dz-cut.on b { color: var(--amber); }
.dz-cut em { font: 500 9.5px/1.4 var(--font-mono); color: rgba(255,255,255,.72);
  font-style: normal; text-shadow: 0 1px 3px rgba(0,0,0,.8); }
.dz-cutcam { font-size: 10px; color: rgba(255,255,255,.62); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; text-shadow: 0 1px 3px rgba(0,0,0,.8); }

/* 分镜块 ◈ 角标：这一镜已渲 previz（点击即播），青=预演族语义色 */
.dz-cutpz { position: absolute; right: 5px; top: 7px; z-index: 2; cursor: pointer;
  font-size: 10px; color: var(--cyan); text-shadow: 0 1px 3px rgba(0, 0, 0, .8);
  transition: transform .12s var(--ease); }
.dz-cutpz:hover { transform: scale(1.25); }

/* ── 分镜块悬浮大图 ── */
.dz-cutpop { position: fixed; z-index: 320; width: 262px; padding: 8px;
  border-radius: var(--r-md); border: 1px solid var(--line-2);
  background: var(--bg-panel); box-shadow: var(--shadow-pop);
  opacity: 0; transform: translateY(4px); pointer-events: none;
  transition: opacity .14s var(--ease), transform .14s var(--ease); }
.dz-cutpop.on { opacity: 1; transform: none; }
.dz-cutpop img { width: 100%; border-radius: var(--r-sm); display: block; }
.dz-cutpop-ph { height: 128px; display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-sm); border: 1px dashed var(--line-2);
  font-size: 11.5px; color: var(--text-3); }
.dz-cutpop-t { display: flex; align-items: baseline; gap: 8px; margin-top: 7px; }
.dz-cutpop-t b { font-size: 12.5px; color: var(--text); }
.dz-cutpop-t em { font: 500 10px/1 var(--font-mono); font-style: normal; color: var(--text-3); }
.dz-cutpop p { margin: 5px 0 1px; font-size: 11px; line-height: 1.6; color: var(--text-3);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }

/* ── 角色动作轨：名牌 + 按动作族着色的时间段 ── */
.dz-lanes { display: flex; flex-direction: column; gap: 4px; max-height: 104px;
  overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.dz-lane { display: flex; align-items: center; gap: 8px; height: 24px; }
.dz-laneid { display: flex; align-items: center; gap: 6px; width: 116px; flex: 0 0 116px;
  height: 100%; padding: 0 8px; cursor: pointer; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--bg-card-2);
  transition: border-color .14s, background .14s; }
.dz-laneid:hover { background: var(--bg-hover); }
.dz-laneid.on { border-color: rgba(240,166,60,.4); background: var(--amber-soft); }
.dz-laneid i { font-style: normal; font-size: 10px; color: var(--text-3); }
.dz-laneid.on i { color: var(--amber); }
.dz-laneid b { flex: 1; font-size: 11.5px; font-weight: 550; color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dz-lanepath { font-size: 11px; color: var(--cyan); }
.dz-strip { position: relative; flex: 1; height: 100%; border-radius: var(--r-sm);
  background: var(--bg-card-2); border: 1px solid var(--line); overflow: hidden; }
/* 动作族配色：位移=青（要配走位）· 一次性=琥珀（有明确落点）· 循环原地=中性 */
.dz-seg { position: absolute; top: 0; bottom: 0; display: flex; align-items: center;
  padding: 0 8px; overflow: hidden; border-right: 1px solid rgba(0,0,0,.35);
  background: rgba(255,255,255,.05); cursor: pointer;
  transition: background .14s, box-shadow .14s; }
/* 段是换动作的入口，悬停要有可点的回应——内描边而不是外阴影，段与段紧邻不留缝 */
.dz-seg:hover { box-shadow: inset 0 0 0 1px var(--amber); }
.dz-seg span { font-size: 10px; color: var(--text-2); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.dz-seg.move { background: var(--cyan-soft); }
.dz-seg.move span { color: var(--cyan); }
.dz-seg.once { background: var(--amber-soft); }
.dz-seg.once span { color: var(--amber); }

/* ═ 剧本工作台 · ✎ 创作 Tab（原创小说层）：数据带 / 卷轴时间线 / 档案模块 / 伏笔总账 ═ */
.nv-wrap { display: flex; flex-direction: column; gap: 16px; }
/* 数据带：hairline 分格的大数字统计 + 右端本批次指令（与题头数据带同一门语言） */
.nv-kpis { display: flex; align-items: stretch; flex-wrap: wrap;
  border: 1px solid var(--line); border-radius: var(--r-lg);
  background: linear-gradient(180deg, var(--bg-card) 0%, var(--bg-panel) 100%); overflow: hidden; }
.nv-kpi { display: flex; flex-direction: column; gap: 6px; justify-content: center;
  padding: 14px 20px; border-right: 1px solid var(--line); min-width: 100px; }
.nv-kpi b { font: 600 20px/1 var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--text); white-space: nowrap; }
.nv-kpi b small { font-size: 11.5px; font-weight: 600; color: var(--text-2); margin-left: 1px; }
.nv-kpi > span { font: 600 9.5px/1 var(--font-mono); letter-spacing: .14em; color: var(--text-3); }
.nv-kpi.due b, .nv-kpi.due > span { color: var(--amber); }
.nv-kpi.bad b { color: var(--red); }
.nv-kpi-acts { flex: 1; display: flex; align-items: center; justify-content: flex-end;
  gap: 8px; padding: 12px 16px; flex-wrap: wrap; min-width: 220px; }
.nv-pips { display: flex; gap: 3px; }
.nv-pip { width: 12px; height: 5px; border-radius: 3px; background: var(--bg-card-2);
  border: 1px solid var(--line); }
.nv-pip.on { background: var(--amber); border-color: var(--amber); }
.nv-dim { font-size: 11.5px; color: var(--text-3); line-height: 1.55; }
.nv-due { color: var(--amber); font-weight: 600; }
/* 档案模块：眉题走「mono 小字 + hairline 延长线」的编辑部语言 */
.nv-style { background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 14px 16px; display: flex; flex-direction: column; gap: 10px; }
.nv-style > .k { display: flex; align-items: center; gap: 10px;
  font: 700 10.5px/1.5 var(--font-mono); color: var(--text-3); letter-spacing: .1em; }
.nv-style > .k::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.nv-style-rows { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 4px 18px; }
/* 卷轴时间线：一条按各卷章数等比分段的进度带——已收卷实、在写发光、未开写虚 */
.arc-track { display: flex; gap: 2px; height: 10px; margin: 2px 0; }
.arc-seg { position: relative; border-radius: 3px; min-width: 5px;
  background: var(--bg-card-2); border: 1px solid var(--line); }
.arc-seg.done { background: rgba(240, 166, 60, .32); border-color: rgba(240, 166, 60, .2); }
.arc-seg.writing { background: var(--amber); border-color: var(--amber);
  box-shadow: 0 0 10px rgba(240, 166, 60, .5); }
.arc-caption { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  font: 500 10.5px/1.6 var(--font-mono); font-variant-numeric: tabular-nums; color: var(--text-3); }
.arc-caption b { color: var(--amber); font-weight: 600; }
/* 卷/幕规划行——刻意不复用 .src-row：那是「键 60px + 等宽值」的档案行，装不下
   「卷12 第 311~345 章」，也不该拿 font-mono + break-all 去排中文正文。三列固定语义：
   卷号段 / 卷名·目标 / 状态。长篇有三十几卷，所以默认只展开当前卷附近（见 app 侧）。 */
.nv-arcs { display: flex; flex-direction: column; }
.nv-arc { display: grid; grid-template-columns: 118px minmax(0, 1fr) auto;
  align-items: center; gap: 14px; padding: 9px 2px; border-bottom: 1px solid var(--line); }
.nv-arc:last-child { border-bottom: 0; }
.nv-arc-no { font: 600 11.5px var(--font-mono); color: var(--text-3); white-space: nowrap; }
.nv-arc-main { min-width: 0; display: flex; align-items: baseline; gap: 8px; }
.nv-arc-t { font-size: 13px; color: var(--text); font-weight: 600; white-space: nowrap; }
.nv-arc-g { min-width: 0; font-size: 12px; color: var(--text-3); line-height: 1.5;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nv-arc.now { background: var(--bg-card-2); }
.nv-arc.now .nv-arc-no, .nv-arc.now .nv-arc-t { color: var(--amber); }
.nv-arc.now .nv-arc-g { white-space: normal; }        /* 只有正在写的那一卷摊开目标 */
.nv-arc-more { align-self: flex-start; margin-top: 2px; }

/* 章节稿/伏笔的分区题：编号眉线 + hairline 延长线（与档案模块眉题同款，位阶更高） */
.nv-sec-h { display: flex; align-items: center; gap: 10px; margin-top: 6px;
  font: 700 11px/1.5 var(--font-mono); color: var(--text-3); letter-spacing: .1em; }
.nv-sec-h::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.nv-list { display: flex; flex-direction: column; gap: 10px; }
.nv-ch { background: var(--bg-card); border: 1px solid var(--line); border-left: 2px solid var(--line-2);
  border-radius: var(--r-md); padding: 12px 15px; display: flex; flex-direction: column; gap: 7px;
  transition: border-color .2s var(--ease); }
.nv-ch:hover { border-color: var(--line-2); border-left-color: rgba(240, 166, 60, .5); }
.nv-ch-hd { display: flex; align-items: center; gap: 9px; cursor: pointer; flex-wrap: wrap; }
.nv-ch-hd b { font: 600 13.5px/1.5 var(--font-serif); letter-spacing: .03em; color: var(--text);
  flex: 1; min-width: 120px; }
.nv-digest { font-size: 12.5px; color: var(--text-2); line-height: 1.65; margin: 0; }
.nv-digest.miss { color: var(--text-3); font-style: italic; }
.nv-ents { display: flex; gap: 6px; flex-wrap: wrap; }
.nv-read { border-top: 1px dashed var(--line); padding-top: 10px; }
.nv-read-text { white-space: pre-wrap; font-size: 13px; line-height: 1.9; color: var(--text-2);
  max-height: 420px; overflow: auto; overscroll-behavior: contain; }
/* 伏笔总账：一张 hairline 分行的账本（不做一条一卡），状态点是唯一的颜色发声处 */
.nv-threads { display: flex; flex-direction: column; border: 1px solid var(--line);
  border-radius: var(--r-md); background: var(--bg-card); overflow: hidden; }
.nv-th { display: flex; align-items: flex-start; gap: 10px; padding: 10px 14px;
  border-bottom: 1px solid var(--line); }
.nv-th:last-child { border-bottom: 0; }
.nv-th.expired { box-shadow: inset 2px 0 0 var(--red); }
.nv-th.paid { opacity: .62; }
.nv-th.off { opacity: .42; }
.nv-th-dot { color: var(--amber); font-size: 13px; line-height: 1.4; }
.nv-th.paid .nv-th-dot { color: var(--green); }
.nv-th-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.nv-th-main b { font-size: 12.5px; color: var(--text); }
.nv-th-acts { display: flex; gap: 6px; flex: none; }
.ent-badge.scene { background: var(--green-soft); color: var(--green); }

/* ═══════════════════════════════════════════════════════════════════════════
   模型配置中心（#/model）
   两层：上层「能力路由」四张牌回答"这台机器现在用谁"，下层「服务商」是凭据货架，
   编辑一律收进右侧抽屉。状态用一颗点表达（就绪/本机已改/缺密钥/未接入），
   颜色只在既有令牌里取——这套设计系统是无绿的琥珀·蓝·青三色体系。
   ═══════════════════════════════════════════════════════════════════════════ */
.cfg-page { display: flex; flex-direction: column; gap: 22px; }

/* ── 页头 + 统计条 ── */
.cfg-head h1 { font-size: 25px; font-weight: 600; letter-spacing: -.01em; }
/* 导语走单行：抬头独占通栏，它有整屏可用，不限宽折行 */
.cfg-head p { margin-top: 7px; font-size: 12.5px; line-height: 1.75;
  color: var(--text-3); }
.cfg-head code { font-size: 11.5px; color: var(--text-2); }
/* 通栏统计带（压在「能力路由」之上）：左侧三格计数定宽，右侧路径块吃掉剩余宽度 */
.cfg-bar { display: flex; align-items: stretch; gap: 0;
  border: 1px solid var(--line); border-radius: var(--r-lg);
  background: linear-gradient(180deg, var(--bg-card) 0%, var(--bg-panel) 100%);
  overflow: hidden; }
.cfg-stat { padding: 13px 20px; display: flex; flex-direction: column; gap: 6px;
  border-right: 1px solid var(--line); min-width: 112px; }
.cfg-stat b { font: 600 20px/1 var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--text); }
.cfg-bar-p { padding: 11px 18px; display: flex; flex-direction: column; gap: 6px;
  justify-content: center; flex: 1; min-width: 0; }
.cfg-bar-p > div { display: flex; align-items: baseline; gap: 10px; }
.cfg-bar-p .k { width: 68px; flex: none; }
/* 路径按剩余宽度自适应，仍留省略号兜住极长的工作区路径 */
.cfg-bar-p code { font-size: 10.5px; color: var(--text-3); flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── 能力路由：一能力一张牌。列数由页面按后端能力清单写进 --caps，桌面宽度恒一行看完 ── */
.cfg-tiles { display: grid; grid-template-columns: repeat(var(--caps, 4), minmax(0, 1fr)); gap: 14px; }
.cfg-tile { text-align: left; display: flex; flex-direction: column; gap: 11px;
  padding: 15px 17px 14px; border-radius: var(--r-lg);
  border: 1px solid var(--line); background: var(--bg-card);
  box-shadow: var(--hi), var(--shadow-1);
  transition: border-color .18s var(--ease), background .18s, transform .18s var(--ease);
  position: relative; overflow: hidden; }
/* 顶部一条极细的高光：本机激活时点亮成琥珀，是"这一档被我改过"的第一眼信号 */
.cfg-tile::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 2px;
  background: var(--line-2); transition: background .18s; }
.cfg-tile:hover { border-color: var(--line-2); background: var(--bg-card-2);
  transform: translateY(-1px); }
.cfg-tile.on::before { background: var(--amber); box-shadow: 0 0 10px rgba(240,166,60,.5); }
.cfg-tile-h { display: flex; align-items: center; gap: 8px; }
.cfg-tile-h b { font-size: 13.5px; font-weight: 600; color: var(--text); }
.cfg-tile-h i { font: 500 8.5px/1 var(--font-mono); letter-spacing: .2em;
  color: var(--text-3); font-style: normal; }
.cfg-tile-h .cfg-pin { margin-left: auto; font-size: 7px; color: var(--amber); }
.cfg-ico { display: inline-flex; }
.cfg-ico svg { width: 14px; height: 14px; fill: none; stroke: currentColor;
  stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.cfg-tile-h .cfg-ico { color: var(--text-2); }
.cfg-tile-m { display: flex; align-items: baseline; gap: 9px; min-width: 0; }
.cfg-tile-m code { font: 600 15px/1.2 var(--font-mono); color: var(--amber);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cfg-tile-m small { font-size: 11px; color: var(--text-3); flex: none; }
.cfg-tile-f { display: flex; align-items: center; gap: 7px; font-size: 11.5px;
  color: var(--text-3); }
.cfg-tile-f em { margin-left: auto; font-style: normal; font-size: 10.5px;
  color: var(--amber); opacity: .8; }

/* ── 状态点：全页唯一的状态语汇 ── */
.cfg-dot { width: 6px; height: 6px; border-radius: 50%; flex: none;
  background: var(--text-3); }
.cfg-dot.ok { background: var(--blue); box-shadow: 0 0 7px rgba(92,158,232,.6); }
.cfg-dot.warn { background: var(--amber); box-shadow: 0 0 7px rgba(240,166,60,.55); }
.cfg-dot.bad { background: var(--red); box-shadow: 0 0 7px rgba(239,106,90,.5); }
.cfg-dot.off, .cfg-dot.muted { background: var(--text-3); box-shadow: none; }
.cfg-state { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px;
  color: var(--text-2); white-space: nowrap; }
.cfg-state.bad { color: var(--red); }
.cfg-state.warn { color: var(--amber); }
.cfg-state.muted, .cfg-state.off { color: var(--text-3); }

/* ── 筛选条 ── */
.cfg-filbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.cfg-fils { display: flex; gap: 5px; }
.cfg-fil { display: inline-flex; align-items: center; gap: 7px; padding: 5px 12px;
  border-radius: 999px; border: 1px solid transparent; color: var(--text-3);
  font-size: 12px; transition: all .15s var(--ease); }
.cfg-fil i { font-style: normal; font: 500 9.5px/1 var(--font-mono); color: var(--text-3); }
.cfg-fil:hover { background: var(--bg-hover); color: var(--text); }
.cfg-fil.on { background: var(--amber-soft); color: var(--amber); font-weight: 600; }
.cfg-fil.on i { color: var(--amber); opacity: .75; }
.cfg-search { flex: 1; min-width: 180px; max-width: 320px; margin-left: auto;
  padding: 6px 12px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--bg-card-2); color: var(--text); font-size: 12px; outline: none;
  transition: border-color .15s; }
.cfg-search:focus { border-color: var(--amber); }
.cfg-search::placeholder { color: var(--text-3); }

/* ── 服务商卡 ── */
.cfg-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.cfg-pv { display: flex; align-items: center; gap: 13px; text-align: left;
  padding: 13px 15px; border-radius: var(--r-lg);
  border: 1px solid var(--line); background: var(--bg-card); min-width: 0;
  box-shadow: var(--hi), var(--shadow-1);
  transition: border-color .18s var(--ease), background .18s, transform .18s var(--ease); }
.cfg-pv:hover { border-color: var(--line-2); background: var(--bg-card-2);
  transform: translateY(-1px); }
.cfg-pv:active { transform: translateY(0); }
.cfg-pv[data-state="bad"] { border-color: rgba(239, 106, 90, .22); }
.cfg-pv-b { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.cfg-pv-t { display: flex; align-items: center; gap: 7px; min-width: 0; }
.cfg-pv-t b { font: 600 13px/1.2 var(--font-mono); letter-spacing: .01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cfg-tag { flex: none; font: 600 8.5px/1 var(--font-mono); letter-spacing: .12em;
  padding: 3px 6px; border-radius: 4px; color: var(--amber);
  background: var(--amber-soft); }
.cfg-pv-s { font-size: 11.5px; color: var(--text-2); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.cfg-pv-u { font: 500 10px/1.4 var(--font-mono); color: var(--text-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cfg-pv-r { flex: none; display: flex; flex-direction: column; align-items: flex-end;
  gap: 5px; }
.cfg-price { font: 500 10.5px/1 var(--font-mono); color: var(--text-3); }
/* 服务商标：品牌标带自己的品牌色（`--brand` 由 brands.js 逐个注入），
   底色与描边由同一个色相按低透明度调出来——同一家的几个别名因此自然成组。 */
.cfg-mark { flex: none; width: 38px; height: 38px; border-radius: 11px;
  display: grid; place-items: center; font: 600 15px/1 var(--font-ui);
  color: var(--text-2); background: var(--bg-hover);
  border: 1px solid var(--line-2); }
.cfg-mark.brand { color: var(--brand);
  /* color-mix 不被支持时这两条整体作废、回落到上面的中性底，无需 @supports 兜 */
  background: color-mix(in srgb, var(--brand) 13%, transparent);
  border-color: color-mix(in srgb, var(--brand) 30%, transparent); }
.cfg-mark.brand svg { display: block; width: 19px; height: 19px; fill: currentColor; }
/* 自绘的线框标（本地曲库）走描边，与侧栏导航同一套图形语汇 */
.cfg-mark.brand.line svg { fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round; }
.cfg-mark .cfg-ico svg { width: 17px; height: 17px; stroke-width: 1.5; }
/* 行内品牌小标：跟在厂商名前面，随文字基线走 */
.cfg-bmk { display: inline-block; width: 12px; height: 12px; margin-right: 5px;
  vertical-align: -1.5px; color: var(--brand); }
.cfg-bmk svg { display: block; width: 100%; height: 100%; fill: currentColor; }
.cfg-bmk.line svg { fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round; }
.cfg-add { border-style: dashed; background: none; }
.cfg-add:hover { border-color: var(--amber); }
.cfg-add .cfg-mark { background: none; border-style: dashed; }
.cfg-empty { grid-column: 1 / -1; padding: 26px; text-align: center;
  color: var(--text-3); font-size: 12.5px; }

/* ── 右侧抽屉（openShell 的 .dlg-card 变体：backdrop/Escape/退场沿用同一份）── */
.dlg:has(> .cfg-drawer) { place-items: stretch; justify-items: end; }
.cfg-drawer { width: min(560px, 100vw); height: 100vh; max-height: 100vh;
  border-radius: 0; border-right: 0; border-top: 0; border-bottom: 0;
  padding: 0; gap: 0; animation: cfg-slide .22s var(--ease); }
@keyframes cfg-slide { from { transform: translateX(28px); opacity: 0; } }
.dlg.closing .cfg-drawer { animation: dlg-out .14s var(--ease) forwards; }
.cfg-dh { flex: none; display: flex; align-items: center; gap: 13px;
  padding: 18px 20px; border-bottom: 1px solid var(--line); }
.cfg-dh-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.cfg-dh-t b { font: 600 15px/1.2 var(--font-mono); }
.cfg-dh-t small { font-size: 11.5px; color: var(--text-3); }
.cfg-dh-b { display: flex; align-items: center; gap: 7px; flex: none; }
.cfg-db { flex: 1; overflow-y: auto; overscroll-behavior: contain;
  padding: 18px 20px 24px; display: flex; flex-direction: column; gap: 22px;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.cfg-db::-webkit-scrollbar { width: 6px; }
.cfg-db::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 4px; }
/* 动作一律靠右收口（与 .dlg-acts 同一条规矩）。靠各调用点自插 .cfg-sp 撑开的话，
   漏插的抽屉会把保存/取消甩到左下角——默认值定在这里，新开的抽屉不插撑子
   也落在该在的位置。 */
.cfg-df { flex: none; display: flex; align-items: center; justify-content: flex-end;
  gap: 8px; padding: 13px 20px; border-top: 1px solid var(--line);
  background: rgba(11, 12, 15, .45); }
/* 撑子仍然有用：把「恢复默认」这类反向动作顶到最左，与右侧主动作拉开对峙 */
.cfg-sp { flex: 1; }
.cfg-note { font-size: 12px; line-height: 1.75; color: var(--text-3); }

/* 抽屉内分节 */
.cfg-sec { display: flex; flex-direction: column; gap: 11px; }
.cfg-sec-h { display: flex; align-items: baseline; gap: 9px; }
.cfg-sec-h b { font-size: 12.5px; font-weight: 600; color: var(--text); }
.cfg-sec-h i { font: 500 8.5px/1 var(--font-mono); letter-spacing: .2em;
  color: var(--text-3); font-style: normal; }
.cfg-sec-f { font-size: 11px; line-height: 1.6; color: var(--text-3); }

/* 表单 */
.cfg-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 11px 13px; }
/* 字段数不定的小节按实际条数分栏（`--cols` 由渲染时给），单条即铺满整行 */
.cfg-form.cfg-cols { grid-template-columns: repeat(var(--cols, 2), minmax(0, 1fr)); }
.cfg-f { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.cfg-f.wide { grid-column: 1 / -1; }
.cfg-f label { display: flex; align-items: baseline; gap: 8px; font-size: 11px;
  color: var(--text-3); letter-spacing: .04em; }
.cfg-f label i { font-style: normal; font-size: 10.5px; color: var(--text-3);
  opacity: .72; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cfg-in { width: 100%; padding: 8px 12px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: var(--bg-card-2); color: var(--text);
  font: 500 12px/1.5 var(--font-mono); outline: none; transition: border-color .15s; }
.cfg-in:focus { border-color: var(--amber); }
.cfg-in::placeholder { color: var(--text-3); font-family: var(--font-ui); }
.cfg-slot { width: 100%; }

/* 密钥行（多凭证厂商一行一把钥匙） */
.cfg-keys { display: flex; flex-direction: column; gap: 7px; }
.cfg-key { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 6px 6px 6px 12px; border-radius: var(--r-md);
  border: 1px solid var(--line); background: var(--bg-card-2); }
.cfg-key .dlg-btn { padding: 4px 11px; font-size: 12px; }
.cfg-key code { font: 500 11.5px/1 var(--font-mono); color: var(--text-2); }
.cfg-key .dlg-btn { margin-left: auto; }

/* 路由抽屉的候选列表 */
.cfg-opts { display: flex; flex-direction: column; gap: 7px; }
.cfg-opt { display: flex; align-items: center; gap: 11px; text-align: left;
  padding: 11px 13px; border-radius: var(--r-md);
  border: 1px solid var(--line); background: var(--bg-card);
  transition: border-color .15s var(--ease), background .15s; }
.cfg-opt:hover { border-color: var(--line-2); background: var(--bg-card-2); }
.cfg-opt > div { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cfg-opt b { font: 600 12.5px/1.3 var(--font-mono); }
.cfg-opt small { font-size: 11px; color: var(--text-3); }
.cfg-opt-r { flex: none; width: 15px; height: 15px; border-radius: 50%;
  border: 1.5px solid var(--line-2); transition: all .15s var(--ease); }
.cfg-opt.on { border-color: rgba(240,166,60,.45); background: var(--amber-soft); }
.cfg-opt.on .cfg-opt-r { border-color: var(--amber); background: var(--amber);
  box-shadow: inset 0 0 0 3px var(--bg-card); }
.cfg-opt-x { flex: none; display: flex; align-items: center; gap: 9px; }
.cfg-opt-x small { font: 500 10.5px/1 var(--font-mono); color: var(--text-3); }

/* 画风例外提醒：解析链第一跳优先于全局激活项，不写出来则界面上的全局开关与实际生效值对不上 */
.cfg-warn { padding: 11px 13px; border-radius: var(--r-md);
  background: rgba(240, 166, 60, .07); border-left: 2px solid var(--amber); }
.cfg-warn b { display: block; font-size: 12px; color: var(--amber); margin-bottom: 5px; }
.cfg-warn p { font-size: 11.5px; line-height: 1.65; color: var(--text-3); }

/* 自检结果就地展开（而不是再套一层弹层） */
.cfg-probe-acts { display: flex; align-items: center; gap: 8px; }
/* 链接借用 .dlg-btn 的按钮制式时要抹掉 <a> 的默认链路样式，否则带下划线蓝字 */
a.cfg-console { display: inline-block; text-decoration: none; }
.cfg-console-a { color: var(--amber); text-decoration: none; margin: 0 3px; }
.cfg-console-a:hover { text-decoration: underline; }
.cfg-probe:not(:empty) { margin-top: 11px; }
.cfg-probe-l { display: flex; flex-direction: column; gap: 2px; }
.cfg-chk { display: flex; align-items: baseline; gap: 9px; padding: 5px 0;
  font-size: 11.5px; color: var(--text-2); }
.cfg-chk-i { flex: none; width: 13px; color: var(--blue); font-size: 10px; }
.cfg-chk.bad { color: var(--red); }
.cfg-chk.bad .cfg-chk-i { color: var(--red); }
.cfg-chk-n { flex: none; }
.cfg-chk small { color: var(--text-3); font-size: 10.5px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }

@media (max-width: 1500px) { .cfg-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 1200px) { .cfg-tiles { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); } }
@media (max-width: 900px) {
  .cfg-grid, .cfg-tiles { grid-template-columns: minmax(0, 1fr); }
  .cfg-form, .cfg-form.cfg-cols { grid-template-columns: minmax(0, 1fr); }
  .cfg-bar { flex-wrap: wrap; }
  .cfg-drawer { width: 100vw; }
}

/* 放映卡的两个出口：并列的二选一（图片合成 / 模型合成），居中呈现比左对齐更贴合语义 */
.shot-ops.fc-outlets { justify-content: center; flex-wrap: wrap; margin-top: 12px; }

/* 设定图素材直供：按钮与隐藏的 file input 同壳。**不复用 .sup-wrap**——那是直供
   弹层的外壳（固定宽度 820px），按钮沿用它会把卡片头撑开。 */
.sheet-supply { display: inline-flex; }


/* ═══════════════════════════════════════════════════════════════════════════
   深度捕捉（工作台卡 .cvc-*）
   卡的骨架与简笔分镜共用上面那一段规则（同一条选择器上并列），这里只放两处
   本台独有的东西：素材格的删除角标，以及两个弹层的内容排版。
   ═══════════════════════════════════════════════════════════════════════════ */
/* 素材格右上角的删除位——与 .skb-copy 同一处角落、同一种「hover 才显形」 */
/* 深度素材格比简笔板格高一档：两格竖屏对照图在 84px 高只有 95px 宽，
   素材名（用户自己的文件名，不像 SHOT 01 那样短）根本铺不开 */
.cvc-cell img { height: 112px; }
.cvc-cell.gen { min-width: 132px; height: 114px; }
/* 绑定去向：一条素材可以切给多个镜，格子上不标的话，几条摆在一起就分不出
   哪条已经用上、哪条还白放着。已绑的格子换青色边，扫一眼就分得开两类 */
.cvc-cell.bound { border-color: rgba(94, 214, 242, .45); }
.cvc-cell.bound .cvc-tag { color: var(--cyan); }
/* 还没绑上的签不可点，压暗以示区别（简笔板那边每格恒有镜号，不存在这一态） */
.cvc-tag.idle { color: var(--text-3); cursor: default; }
.cvc-tag.idle:hover { color: var(--text-3); }

.cvc-del { position: absolute; top: 4px; right: 4px; width: 18px; height: 18px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 4px; font-size: 11px; line-height: 1; cursor: pointer;
  color: var(--text-3); background: rgba(10, 12, 16, .78);
  opacity: 0; transition: opacity .14s, color .14s; }
.cvc-cell:hover .cvc-del { opacity: 1; }
.cvc-del:hover { color: var(--red); }
.cvc-cell.gen i { font: 600 10.5px/1 var(--font-mono); color: var(--amber); }

/* 未就绪时印在卡上的安装命令：可整段复制，不折行 */
.cvc-cmd { margin: 10px 0 0; padding: 9px 11px; border-radius: 8px;
  background: rgba(10, 12, 16, .7); border: 1px solid var(--line);
  font: 500 11px/1.75 var(--font-mono); color: var(--cyan);
  overflow-x: auto; user-select: all; }

/* ── 两个弹层（.cvc-dlg）：与 .skb-dlg 同宽同骨架 ── */
.cvc-dlg { width: min(620px, 94vw); }
.cvc-tips { margin: 10px 0; padding: 10px 12px; border-radius: 8px;
  background: var(--bg-card-2); border: 1px solid var(--line); }
.cvc-tips b { font-size: 11.5px; }
.cvc-tips ul { margin: 6px 0 0; padding-left: 17px; }
.cvc-tips li { font-size: 11.5px; line-height: 1.75; color: var(--text-2); }

/* 拖放区：与剧本工作台的素材投放区同款反馈（.drag 高亮 / .busy 压暗） */
.cvc-drop { padding: 22px 12px; border-radius: 10px; cursor: pointer; text-align: center;
  border: 1px dashed var(--line-2); transition: border-color .14s, background .14s; }
.cvc-drop:hover, .cvc-drop.drag { border-color: var(--cyan); background: var(--cyan-soft); }
.cvc-drop.busy { opacity: .55; pointer-events: none; }
.cvc-drop b { display: block; font-size: 12.5px; }
.cvc-drop em { display: block; margin-top: 4px; font-style: normal;
  font: 500 10.5px/1.6 var(--font-mono); color: var(--text-3); }
.cvc-file { display: none; }

/* 素材条：封面卡横排。几条素材常常都叫 IMG_0421.mp4，只印文件名等于让人凭记忆选；
   封面用处理时留下的对照图（左源片右深度），一眼认得出是哪条表演。
   横向滚动而不换行——素材多起来时换行会把下面的选段器挤出屏幕。 */
.cvc-pick-wrap { display: flex; align-items: center; gap: 9px; margin-bottom: 9px; }
.cvc-pick-k { font: 600 10.5px/1 var(--font-mono); color: var(--text-3); }
.cvc-pick { display: flex; gap: 8px; min-width: 0; overflow-x: auto; padding-bottom: 2px; }
.cvc-ast { position: relative; flex: none; width: 116px; padding: 0 0 6px;
  cursor: pointer; text-align: left; border-radius: 8px; overflow: hidden;
  border: 1px solid var(--line); background: var(--bg-card-2);
  transition: border-color .14s, transform .14s var(--ease); }
.cvc-ast img, .cvc-ast-none { display: block; width: 100%; height: 44px;
  object-fit: cover; background: #000; }
.cvc-ast b { display: block; margin: 5px 7px 0; font: 600 10.5px/1.3 var(--font-mono);
  color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cvc-ast i { display: block; margin: 1px 7px 0; font-style: normal;
  font: 500 9.5px/1.4 var(--font-mono); color: var(--text-3); }
/* 已绑镜数压在封面右上角：与缩略格上的 SHOT 签同一处位置，两处说的是同一件事 */
.cvc-ast em { position: absolute; top: 4px; right: 4px; font-style: normal;
  padding: 1px 6px; border-radius: 999px; font: 600 9px/1.6 var(--font-mono);
  color: var(--cyan); background: rgba(10, 12, 16, .82); }
.cvc-ast:hover { border-color: var(--line-2); transform: translateY(-1px); }
.cvc-ast.on { border-color: var(--cyan); box-shadow: inset 0 0 0 1px var(--cyan); }
.cvc-ast.on b { color: var(--text); }

/* 绑定行：与 .skb-row 同骨架，右侧是状态与解绑位 */
.cvc-list { max-height: 30vh; overflow-y: auto; display: flex; flex-direction: column;
  gap: 2px; margin: 10px 0; }
/* 行骨架与 .skb-row 同度量（扁平 flex、镜号定宽、状态走 chip）：两个台子是同一类
   东西的两个实例，各长一套版式会让人每开一个弹层都要重新认一遍。
   本台多出的一格是分镜图缩略——外观真源就在那一帧，选镜时看得见才判得准。 */
.cvc-row { position: relative; overflow: hidden;
  display: flex; align-items: center; gap: 8px; padding: 3px 5px;
  font-size: 12px; cursor: pointer; border-radius: 6px; }
/* 悬停底色**扫入**：一列等宽扁平行只靠变色很难看出指针停在哪一行，
   自左向右扫过的一层底把当前行推到前面来。扫入层在内容之下，故行内元素各自定位。
   选中行的扫入层换成选中色本身——不然悬停时那层不透明的底会把选中态整个盖掉。 */
.cvc-row::before { content: ""; position: absolute; inset: 0;
  background: var(--bg-hover); transform: scaleX(0); transform-origin: left center;
  transition: transform .2s var(--ease); }
.cvc-row:hover::before { transform: scaleX(1); }
.cvc-row > * { position: relative; }
.cvc-row.on { background: var(--cyan-soft); }
.cvc-row.on::before { background: var(--cyan-soft); }
/* 不可选的行（已绑别的素材）：内容压暗、不给悬停暗示，但「解绑」保持全亮——
   那颗按钮正是这一行的出口，连它一起压暗就成了死路 */
.cvc-row.off { cursor: default; }
.cvc-row.off::before { content: none; }
.cvc-row.off > :not(.cvc-un) { opacity: .42; }
.cvc-row b { font: 600 11px/1.4 var(--font-mono); min-width: 44px; }
.cvc-row > span:not(.cvc-radio):not(.chip) { color: var(--text-2); }
/* 单选点：与站内勾选件 .us-check 同尺寸同配色，只把方角换成圆角——
   一次只绑一镜，圆形是这件事的既有读法 */
.cvc-radio { flex: none; width: 16px; height: 16px; border-radius: 50%;
  border: 1px solid var(--line-2); background: var(--bg-card-2);
  display: inline-grid; place-items: center; transition: all .15s; }
.cvc-radio i { font-style: normal; font-size: 9px; line-height: 1; color: transparent;
  transition: color .12s; }
.cvc-radio.on { background: var(--amber); border-color: var(--amber); }
.cvc-radio.on i { color: #14161b; }
.cvc-row:not(.off):hover .cvc-radio { border-color: var(--amber); }
/* 行内的 chip 收一档：站内默认尺寸会把行撑到 33px，而简笔板那边是 25px。
   两张卡摆在一起时行高差一档比配色差一档更显眼 */
.cvc-row .chip { padding: 1.5px 7px; font-size: 10.5px; }
.cvc-thumb { flex: none; width: 28px; height: 16px; border-radius: 3px; object-fit: cover;
  background: var(--bg-card-2); border: 1px solid var(--line); }
.cvc-thumb.none { display: block; }
.cvc-un { margin-left: auto; padding: 2px 9px; border-radius: 999px; cursor: pointer;
  font: 600 10px/1.6 var(--font-mono); color: var(--amber);
  background: rgba(240, 166, 60, .12); border: 1px solid transparent;
  transition: border-color .12s, background .12s; }
.cvc-un:hover { border-color: var(--amber); background: rgba(240, 166, 60, .2); }
.cvc-bad { font-style: normal; font-size: 10px; padding: 1px 6px; border-radius: 999px;
  color: var(--amber); background: rgba(240, 166, 60, .14); cursor: help; }

/* ── 区间选择：二合一预览 + 缩略条上的双把手窗 ──
   时间轴语言对齐 3D 导演台（.dz-scrub / .dz-playhead / .dz-tick）：琥珀色播放头带
   三角帽与辉光、刻度小字压在条下。两个台子都是「在一条时间线上取一段」，
   长成两套读法只会让人每次都要重新认一遍。 */
.cvc-dlg.wide { width: min(880px, 96vw); }
.cvc-stage:empty { display: none; }
.cvc-range { margin-top: 12px; }

/* 预览幕：黑底裱框 + 左下角悬浮的播放控件，与灯箱同一套观感 */
.cvc-screen { position: relative; border-radius: 10px; overflow: hidden;
  background: #000; border: 1px solid var(--line); }
.cvc-prev { display: block; width: 100%; height: 32vh; object-fit: contain; }
.cvc-noprev { position: absolute; left: 0; right: 0; top: 10px; margin: 0;
  text-align: center; font-size: 10.5px; color: var(--text-3);
  text-shadow: 0 1px 3px rgba(0, 0, 0, .9); pointer-events: none; }
.cvc-hud { position: absolute; left: 10px; bottom: 10px; display: flex;
  align-items: center; gap: 9px; padding: 5px 11px 5px 6px; border-radius: 999px;
  background: rgba(10, 12, 16, .72); backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, .08); }
.cvc-play { width: 22px; height: 22px; border-radius: 50%; cursor: pointer; flex: none;
  display: grid; place-items: center; border: none; background: var(--cyan);
  color: #05070a; font-size: 9px; line-height: 1;
  transition: transform .12s var(--ease), background .12s; }
.cvc-play::before { content: "▶"; margin-left: 1px; }
.cvc-play.on::before { content: "❚❚"; margin-left: 0; letter-spacing: -1px; }
.cvc-play:hover { transform: scale(1.08); }
.cvc-clock { font: 500 10.5px/1 var(--font-mono); color: var(--text-2); }

/* 缩略条：整条即素材全长，选区外压暗——一眼看出「用了哪一段、丢了哪一段」 */
.cvc-track { margin-top: 10px; }
.cvc-bar { position: relative; height: 52px; border-radius: 6px;
  background: var(--bg-card-2) center / 100% 100% no-repeat;
  border: 1px solid var(--line); cursor: crosshair;
  touch-action: none; overflow: hidden; }
.cvc-win { position: absolute; inset-block: 0; cursor: grab; touch-action: none;
  background: linear-gradient(180deg, rgba(94, 214, 242, .10), rgba(94, 214, 242, .18));
  border-inline: 1px solid var(--cyan);
  box-shadow: 0 0 0 9999px rgba(4, 6, 9, .62); }
.cvc-win.drag { cursor: grabbing; }
/* 把手：命中区 14px（拖得住），可见宽 4px（不挡画面）；中间两道竖纹是抓握暗示。
   **贴选区内侧而不是骑在边线上**——条为了压暗选区外要 overflow:hidden，
   骑出去的那一半会在两端被整齐切掉，正好是最常拖的两个位置。 */
.cvc-h { position: absolute; inset-block: 0; width: 14px; cursor: ew-resize;
  touch-action: none; display: grid; align-items: center; }
.cvc-h.l { left: 0; justify-items: start; }
.cvc-h.r { right: 0; justify-items: end; }
.cvc-h::before { content: ""; width: 4px; height: 100%; border-radius: 2px;
  background: var(--cyan); transition: box-shadow .12s, width .12s var(--ease); }
.cvc-h:hover::before, .cvc-h.drag::before { width: 6px;
  box-shadow: 0 0 10px rgba(94, 214, 242, .75); }
.cvc-h::after { content: ""; position: absolute; width: 1px; height: 12px;
  background: rgba(5, 7, 10, .55); box-shadow: 2px 0 0 rgba(5, 7, 10, .55); }
/* 把手上的读数：平时压暗，拖动时点亮并抬起——拖的时候眼睛在把手上，不在下面的输入框 */
.cvc-h-t { position: absolute; top: -19px; font-style: normal; padding: 1px 5px;
  border-radius: 4px; font-size: 9.5px; white-space: nowrap; pointer-events: none;
  color: var(--text-3); background: var(--bg-card); border: 1px solid var(--line);
  opacity: 0; transition: opacity .12s; }
.cvc-h:hover .cvc-h-t, .cvc-h.drag .cvc-h-t { opacity: 1; color: var(--cyan); }
.cvc-head-l { position: absolute; inset-block: 0; width: 2px; margin-left: -1px;
  background: var(--amber); box-shadow: 0 0 8px rgba(240, 166, 60, .75);
  pointer-events: none; }
.cvc-head-l::before { content: ""; position: absolute; top: 0; left: -3px;
  border: 4px solid transparent; border-top-color: var(--amber); }
.cvc-ruler { position: relative; height: 12px; margin-top: 3px; }
.cvc-tick { position: absolute; transform: translateX(-50%); font-style: normal;
  font: 500 9px/1 var(--font-mono); color: var(--text-3); }
.cvc-tick.first { transform: none; }
.cvc-tick.last { transform: translateX(-100%); }

/* 参数条：起点/终点在左（改数字的地方），段长徽章在右（读结果的地方） */
.cvc-nums { display: flex; align-items: center; gap: 12px; margin-top: 10px; }
.cvc-nums label { display: inline-flex; align-items: center; gap: 5px;
  font: 500 10.5px/1 var(--font-mono); color: var(--text-3); }
.cvc-nums label i { font-style: normal; }
.cvc-num { width: 84px; padding: 5px 9px; border-radius: 6px; text-align: right;
  font: 500 11px/1.4 var(--font-mono); color: var(--text);
  background: var(--bg); border: 1px solid var(--line-2);
  transition: border-color .12s; }
.cvc-num:focus { outline: none; border-color: var(--cyan); }
.cvc-hint { margin-left: auto; font-size: 10.5px; color: var(--text-3); }
.cvc-lab { font: 500 10.5px/1 var(--font-mono); color: var(--text-3); }
.cvc-span { padding: 3px 9px; border-radius: 999px; font: 600 11px/1.3 var(--font-mono);
  color: var(--cyan); background: var(--cyan-soft);
  border: 1px solid rgba(94, 214, 242, .3); }
.cvc-span.bad { color: var(--amber); background: rgba(240, 166, 60, .14);
  border-color: rgba(240, 166, 60, .35); }
.cvc-tools { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.cvc-sum { min-width: 0; font-size: 12px; color: var(--text-2); }
.cvc-sum.bad { color: var(--amber); }
