/* css/beat-table.css · 场级分镜板（镜头清单页）
   ⚠ .beat-* 指**分镜**（b01）；.beat-sb-* 才是**节拍**（sb01）——字段名冻结，靠前缀分。
   设计层真源＝ui.css 的变量；这里只写本组件的排版，禁引任何外部框架。
   2026-09-04 改版：五列矩阵 → 四页签（分镜 / 故事板 / 动态分镜 / 正片）。 */

:root { --beat-tint: rgba(201, 162, 39, .12); --beat-tint-2: rgba(201, 162, 39, .28); }
:root:not([data-theme="light"]) { --beat-tint: rgba(201, 162, 39, .12); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --beat-tint: rgba(201, 162, 39, .16); }
}
:root[data-theme="dark"] { --beat-tint: rgba(201, 162, 39, .16); }

.beat-table-box { margin: 4px 0 10px; }
.beat-dim { color: var(--b-text-dim); }
.beat-spacer { flex: 1 1 auto; }

/* ── 页签条 ─────────────────────────────────────────────────── */
.beat-tabs {
  display: flex; align-items: center; gap: 2px; flex-wrap: wrap;
  border-bottom: 1px solid var(--b-line-2); margin-bottom: 8px;
}
.beat-tab {
  font-size: 12px; padding: 5px 12px; border: 0; background: transparent;
  color: var(--b-text-dim); cursor: pointer; border-bottom: 2px solid transparent;
  transition: color var(--mo-fast), border-color var(--mo-fast);
}
.beat-tab:hover { color: var(--b-text); }
.beat-tab.is-active { color: var(--b-gold-deep); border-bottom-color: var(--b-gold); font-weight: 600; }
.beat-tools { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; padding-bottom: 4px; }

.beat-inline-btn, .beat-primary-btn {
  font-size: 11px; padding: 3px 10px; border-radius: 999px; cursor: pointer;
  border: 1px dashed var(--b-line-2); background: transparent; color: var(--b-text-2);
  transition: background var(--mo-fast), color var(--mo-fast), border-color var(--mo-fast);
}
.beat-inline-btn:hover { border-color: var(--b-gold); color: var(--b-gold-deep); }
.beat-primary-btn {
  border-style: solid; border-color: var(--b-gold); background: var(--b-gold); color: #fff;
}
.beat-primary-btn:hover { filter: brightness(1.08); }

.beat-track-chip {
  font-size: 11px; padding: 2px 8px; border-radius: 999px;
  border: 1px solid var(--b-line-2); background: transparent; color: var(--b-text-2);
  cursor: pointer; transition: background var(--mo-fast), color var(--mo-fast);
}
.beat-track-chip:hover { background: var(--b-surface-3); color: var(--b-text); }
.beat-track-chip.is-active { background: var(--b-gold); border-color: var(--b-gold); color: #fff; }

/* ── 场级四段阶段进度 ────────────────────────────────────────── */
.beat-stages { display: flex; gap: 10px; margin-bottom: 10px; }
.beat-stage { flex: 1 1 0; min-width: 0; }
.beat-stage-track {
  height: 4px; border-radius: 2px; background: var(--b-surface-3);
  border: 1px solid var(--b-line-2); overflow: hidden;
}
.beat-stage-fill {
  height: 100%; background: var(--b-gold); transition: width var(--mo-base, 240ms);
}
.beat-stage-fill.is-full { background: var(--b-green); }
.beat-stage-label {
  font-size: 10px; color: var(--b-text-dim); margin-top: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.beat-stage-num { color: var(--b-text-2); }

/* ── 进度芯片 ○●●○ ─────────────────────────────────────────── */
.beat-dots { display: inline-flex; gap: 3px; align-items: center; cursor: help; }
.beat-dot {
  width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto;
  border: 1px solid var(--b-line-2); background: transparent;
}
.beat-dot.is-on { background: var(--b-gold); border-color: var(--b-gold); }

/* ── 表格（分镜 / 正片）────────────────────────────────────── */
.beat-table-box { overflow-x: auto; }
.beat-table, .beat-lanes {
  width: 100%; border-collapse: collapse; font-size: 12px; background: var(--b-surface);
}
.beat-table th, .beat-lanes th {
  text-align: left; font-weight: 600; font-size: 11px; color: var(--b-text-dim);
  padding: 6px 8px; border-bottom: 1px solid var(--b-line-2);
  background: var(--b-surface-2); position: sticky; top: 0; z-index: 1;
}
.beat-table td, .beat-lanes td {
  padding: 6px 8px; border-bottom: 1px solid var(--b-line); vertical-align: top;
}
.beat-row { cursor: pointer; }
.beat-row:hover td { background: var(--b-surface-2); }
.beat-row.is-active td { background: var(--beat-tint); }

/* 拖拽排序（2026-09-06）：手柄＝行首 id 那格，落点用一条金线画在行的上/下边 */
.beat-table.is-shotlist .c-id[draggable="true"] { cursor: grab; }
.beat-table.is-shotlist .c-id[draggable="true"]:active { cursor: grabbing; }
.beat-row.is-dragging td { opacity: .45; }
.beat-row.drop-before td { box-shadow: inset 0 2px 0 0 rgba(201, 162, 39, .95); }
.beat-row.drop-after td { box-shadow: inset 0 -2px 0 0 rgba(201, 162, 39, .95); }

.beat-table .c-id { white-space: nowrap; display: flex; align-items: center; gap: 6px; }
.beat-table .c-chars, .beat-table .c-size { color: var(--b-text-2); }
/* 时长：等宽右对齐，一列数字扫下来才看得出节奏（哪几拍偏长） */
.beat-table .c-dur {
  color: var(--b-text-2); white-space: nowrap; text-align: right;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-variant-numeric: tabular-nums;
}
.beat-table .c-shot, .beat-table .c-prog { white-space: nowrap; }
/* 一个分镜可以挂多条正片镜，chip 横排、挤不下就换行（列宽已按 1% 收到最窄）*/
.beat-table .beat-owners { display: inline-flex; flex-wrap: wrap; gap: 2px; }
.beat-table .c-prog { display: flex; align-items: center; gap: 6px; }

/* ── 分镜表列宽自适应 ─────────────────────────────────────────
   短列 `width:1%` + 不换行 ＝ 收到内容宽度（table-layout:auto 的惯用写法）；
   剩下的宽度由浏览器按 max-content 比例分给动作与台词两列——它们才是要读的正文。
   ⚠ 别给这两列写死百分比：百分比会连短列一起挤，「分镜」「进度」会被压成一条。 */
.beat-table.is-shotlist { table-layout: auto; }
.beat-table.is-shotlist .c-size,
.beat-table.is-shotlist .c-cam,
.beat-table.is-shotlist .c-dur,
.beat-table.is-shotlist .c-shot { width: 1%; white-space: nowrap; }
/* 人物也必须 nowrap：`width:1%` 收的是 **min-content**，可换行的中文列会被压成一字一行 */
.beat-table.is-shotlist .c-chars { width: 1%; white-space: nowrap; color: var(--b-text-2); }
/* 这两列是 display:flex 的格——flex 容器不给表格贡献 min-content，不写 min-width 会塌成一条 */
.beat-table.is-shotlist .c-id { width: 1%; min-width: 4.5em; }
.beat-table.is-shotlist .c-prog { width: 1%; min-width: 5.5em; }
.beat-table.is-shotlist .c-cam { color: var(--b-text-2); font-size: 11px; }
.beat-table.is-shotlist .c-act { min-width: 260px; }
.beat-table.is-shotlist .c-dx { min-width: 150px; }

/* ── 就地编辑的格 ─────────────────────────────────────────── */
.beat-cell { min-height: 18px; line-height: 1.5; }
.beat-cell.is-editable { cursor: text; border-radius: 3px; }
.beat-cell.is-editable:hover {
  box-shadow: inset 0 -1px 0 var(--b-gold);
  background: color-mix(in srgb, var(--b-gold) 6%, transparent);
}
.beat-input {
  width: 100%; box-sizing: border-box; font: inherit; line-height: 1.5;
  padding: 2px 4px; border: 1px solid var(--b-gold); border-radius: 4px;
  background: var(--b-surface); color: var(--b-text);
}
.beat-input:focus { outline: none; box-shadow: 0 0 0 2px color-mix(in srgb, var(--b-gold) 30%, transparent); }
.beat-input.is-area { resize: vertical; min-height: 3.6em; }

.beat-bar { width: 4px; height: 18px; border-radius: 2px; border: 0; padding: 0; }
.beat-bar.is-clickable { cursor: pointer; }
.beat-bar.is-clickable:hover { outline: 2px solid var(--b-gold); outline-offset: 1px; }

.beat-act {
  border: 0; background: transparent; padding: 0; text-align: left; color: var(--b-text);
  font: inherit; line-height: 1.5;
}
.beat-act.is-editable { cursor: text; border-bottom: 1px dotted transparent; }
.beat-act.is-editable:hover { border-bottom-color: var(--b-gold); }
.beat-dialogue { color: var(--b-text-2); font-size: 11px; margin-top: 2px; }
.beat-exempt { color: var(--b-text-dim); font-size: 11px; margin-top: 2px; }
.beat-uncovered { color: var(--b-red); }
.beat-todo {
  font-size: 10px; padding: 0 4px; border-radius: 3px; margin-left: 6px;
  color: var(--b-text-dim); background: var(--b-surface-3); border: 1px dashed var(--b-line-2);
}

.beat-chip {
  font-size: 11px; padding: 1px 7px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--b-line-2); background: var(--b-surface-2); color: var(--b-text-2);
}
.beat-chip:hover { border-color: var(--b-gold); color: var(--b-gold-deep); }
.beat-chip.is-film { border-color: var(--b-gold); color: var(--b-gold-deep); }
.beat-chip.is-none { border-style: dashed; color: var(--b-text-dim); }
.beat-chip.is-tiny { font-size: 10px; padding: 0 5px; margin-left: 3px; }
.beat-chip.is-active { background: var(--b-gold); border-color: var(--b-gold); color: #fff; }

.beat-more {
  border: 0; background: transparent; color: var(--b-text-dim); cursor: pointer;
  font-size: 13px; line-height: 1; padding: 0 3px; opacity: 0; transition: opacity var(--mo-fast);
}
.beat-row:hover .beat-more, .beat-more:focus { opacity: 1; }
.beat-more:hover { color: var(--b-text); }

.beat-empty { font-size: 12px; color: var(--b-text-dim); padding: 14px 4px; }

/* ── 行尾 / 色条弹出的小菜单 ───────────────────────────────── */
.beat-menu {
  position: fixed; z-index: 60; min-width: 180px; padding: 4px;
  background: var(--b-surface); border: 1px solid var(--b-line-2);
  border-radius: var(--b-radius); box-shadow: 0 6px 24px rgba(0, 0, 0, .18);
}
.beat-menu-title { font-size: 10px; color: var(--b-text-dim); padding: 3px 8px 5px; }
.beat-menu-item {
  display: flex; align-items: center; gap: 6px; width: 100%;
  font-size: 12px; text-align: left; padding: 5px 8px; border: 0; border-radius: 4px;
  background: transparent; color: var(--b-text); cursor: pointer;
}
.beat-menu-item:hover { background: var(--b-surface-2); }
.beat-menu-item.is-cur { color: var(--b-gold-deep); font-weight: 600; }
.beat-menu-item.is-danger { color: var(--b-red); }
.beat-menu-dot { width: 8px; height: 8px; border-radius: 2px; display: inline-block; }

/* ── 故事板：胶片条 ─────────────────────────────────────────── */
.beat-strip {
  display: flex; gap: 8px; overflow-x: auto; padding: 4px 2px 10px;
  scroll-snap-type: x proximity;
}
.strip-cell {
  flex: 0 0 132px; margin: 0; cursor: pointer; scroll-snap-align: start;
  border: 1px solid var(--b-line-2); border-radius: var(--b-radius);
  background: var(--b-surface); padding: 4px; position: relative;
}
.strip-cell.is-active { border-color: var(--b-gold); box-shadow: 0 0 0 2px var(--beat-tint-2); }
.strip-art {
  display: block; width: 100%; height: 74px; object-fit: cover; border-radius: 3px;
  background: var(--b-surface-3); border: 0;
}
.strip-art.is-empty {
  border: 1px dashed var(--b-line-2); color: var(--b-text-dim); font-size: 11px; cursor: pointer;
}
.strip-badge {
  position: absolute; top: 7px; right: 7px; font-size: 9px; padding: 0 4px;
  border-radius: 3px; color: #fff; background: var(--b-gold);
}
.strip-badge.is-sketch { background: var(--b-text-dim); }
.strip-cell figcaption { font-size: 10px; margin-top: 4px; line-height: 1.4; }
.strip-text { display: block; color: var(--b-text-dim); }

.beat-thumb {
  height: 42px; border-radius: 3px; object-fit: cover; cursor: zoom-in;
  border: 1px solid var(--b-line-2);
}
.beat-thumb.is-missing {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 74px; font-size: 10px; color: var(--b-text-dim);
  border: 1px dashed var(--b-line-2); border-radius: 3px; cursor: default;
  background: repeating-linear-gradient(45deg, transparent, transparent 5px,
              var(--b-surface-3) 5px, var(--b-surface-3) 10px);
}
/* 动态分镜的胶片条（.bt-dyn-lanes / .bt-strip / .bt-cut / .bt-prev-*）已于 2026-09-06 撤销：
   动态分镜页签改成与故事板同一套格子网格（css/scene-board.css 的 .sb-grid），
   UI/UX 完全一样，只是格里挂切片视频而不是图。 */

/* ── 多轨并排时间线 ────────────────────────────────────────── */
.beat-lanes .lane-order { color: var(--b-text-dim); font-size: 10px; width: 28px; }
.beat-lanes .lane-cell { border-left: 3px solid var(--beat-track-color); cursor: pointer; }
.beat-lanes .lane-cell.is-active { background: var(--beat-tint); }
.beat-lanes .lane-empty { background: var(--b-surface-2); }
.beat-lanes .lane-head { display: flex; align-items: center; gap: 6px; margin-bottom: 2px; }
.beat-lanes th { border-bottom: 2px solid var(--beat-track-color); }

/* ── 旧场：还没建分镜 ──────────────────────────────────────── */
.beat-legacy {
  padding: 16px; border: 1px dashed var(--b-line-2); border-radius: var(--b-radius);
  background: var(--b-surface-2); font-size: 12px; color: var(--b-text-2);
}
.beat-legacy-title { font-size: 13px; color: var(--b-text); font-weight: 600; margin-bottom: 4px; }
.beat-legacy p { margin: 0 0 10px; line-height: 1.6; }
.beat-legacy .beat-primary-btn { margin-right: 6px; }

/* ── 镜头卡上的分镜角标（shots.js 装饰）──────────────────────── */
.shot-card-beats {
  display: flex; align-items: center; gap: 5px; font-size: 10px;
  color: var(--b-text-dim); padding: 2px 8px 6px;
}
.beat-menu.is-scroll { max-height: 320px; overflow-y: auto; }
.beat-menu-item code { color: var(--b-gold-deep); font-size: 11px; }
.beat-menu-text { color: var(--b-text-dim); font-size: 11px; }

/* ── 并进故事板 overlay 之后（2026-09-04）─────────────────────────
   页签条现在是 scene-board-root 的一条横栏（贴顶栏下沿），正文在 .sb-main 里滚。
   .sb-beats 是「分镜 / 动态分镜 / 正片」三个页签的容器，与 .sb-grid 互斥显示。 */
.sb-tabs {
  flex-shrink: 0;
  gap: 2px;
  margin-bottom: 0;
  padding: 0 .9rem;
  border-bottom: 1px solid var(--b-line-2);
  position: relative;
  z-index: 20;          /* 顶栏的「工具」下拉是 30，这里只要压住主区即可 */
}
.sb-tabs .beat-tab { padding: 7px 14px; font-size: 12.5px; }
.sb-beats { padding-bottom: .5rem; }
.sb-beats .beat-table-box { margin: 0; }
/* 动态分镜格的 <video> 缩略样式在 css/dynboard.css 的 .dyn-vthumb —— 本文件不再有 */

/* ── 编译设定弹窗（features/beat-table/compose-settings.js）────────
   两个页签（本场 / 全局），每签内的项**全部直接展开**，没有折叠。说明只做 tooltip，
   不在每行下面挂小字——26 行灰字正是「太复杂」的来源。 */
.cs-modal { max-height: 62vh; overflow-y: auto; padding-right: 4px; }
.cs-layer { margin-bottom: 14px; }
.cs-layer:last-child { margin-bottom: 0; }
.cs-layer-head {
  display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
  padding-bottom: 3px; margin-bottom: 6px; border-bottom: 1px solid var(--b-line-2);
}
.cs-layer-title { font-size: .84rem; font-weight: 600; color: var(--b-text); }
.cs-scope { font-size: .7rem; color: var(--b-text-dim); }
.cs-scope.is-wide { color: var(--b-gold-deep); font-weight: 600; }
.cs-path { display: block; font-size: .66rem; color: var(--b-text-dim); margin-bottom: 4px; }

.cs-row {
  display: grid; grid-template-columns: 7.5rem 1fr; gap: .6rem;
  align-items: start; padding: 3px 0;
}
.cs-key { font-size: .78rem; color: var(--b-text-2); padding-top: 3px; }
.cs-val {
  min-height: 1.6em; line-height: 1.55; font-size: .8rem;
  border-radius: 4px; padding: 1px 4px; margin: -1px -4px;
}
.cs-val.is-editable { cursor: text; }
.cs-val.is-editable:hover {
  box-shadow: inset 0 -1px 0 var(--b-gold);
  background: color-mix(in srgb, var(--b-gold) 6%, transparent);
}
.cs-text { white-space: pre-wrap; word-break: break-word; color: var(--b-text); }
.cs-empty { font-size: .76rem; color: var(--b-text-dim); }
.cs-input {
  width: 100%; box-sizing: border-box; font: inherit; font-size: .8rem; line-height: 1.55;
  padding: 2px 4px; border: 1px solid var(--b-gold); border-radius: 4px;
  background: var(--b-surface); color: var(--b-text);
}
.cs-input:focus {
  outline: none; box-shadow: 0 0 0 2px color-mix(in srgb, var(--b-gold) 30%, transparent);
}
.cs-input.is-area { resize: vertical; }

/* 页签条钉在滚动区顶部：这一签有十几项，滚下去还得看得见自己在哪一签。
   背景要跟 modal-card 一致（白 / 深），透明的话下面的行会从底下透出来。 */
.cs-tabs {
  position: sticky; top: 0; z-index: 2;
  /* 底边不留 margin：留了那道缝是透明的，滚上来的行会从页签条下面露出半截 */
  background: white; margin: -2px 0 0; padding-top: 2px;
}
.dark .cs-tabs { background: rgb(var(--ink-900)); }
.cs-pane { padding-top: 10px; }
/* 兜底值：这句话没写进配置、但编译器正拿它在用——灰字铺出来 + 一枚「默认」标 */
.cs-text.is-default { color: var(--b-text-dim); }
.cs-tag {
  display: inline-block; margin-right: .4rem; padding: 0 .3rem;
  font-size: .64rem; line-height: 1.5; border-radius: 3px;
  border: 1px solid var(--b-line-2); color: var(--b-text-dim); vertical-align: 1px;
}
/* 组小标题 / 「不常改的」都只是分隔提示，不是可点的开关——别做成 summary 的样子 */
.cs-sub {
  font-size: .7rem; color: var(--b-text-dim);
  margin: 8px 0 2px; padding-top: 4px; border-top: 1px dashed var(--b-line-2);
}

/* 一签之内再分子页签：本场＝场级四组 + 每个角色一签，全局＝六组话术，一次只铺一组
   （2026-09-10 用户点名「本场和全局的设置项太多，都要拆子 tab」）。
   子页签比顶部 .beat-tab 小一号、药丸形、不带底线条——它只切这一签里的一块。
   药丸条允许折行：本场有四组 + 三四个角色，窄栏（侧栏形态）一行排不下。 */
.cs-subtabs { display: flex; flex-wrap: wrap; gap: 3px 4px; margin-bottom: 8px; }
.cs-subtab {
  font: inherit; font-size: .72rem; line-height: 1.4; padding: 1px 8px;
  border: 1px solid var(--b-line-2); border-radius: 999px; background: transparent;
  color: var(--b-text-dim); cursor: pointer;
}
.cs-subtab:hover { color: var(--b-text); border-color: var(--b-line); }
.cs-subtab.is-active {
  color: var(--b-gold-deep); border-color: var(--b-gold); font-weight: 600;
  background: color-mix(in srgb, var(--b-gold) 10%, transparent);
}
.cs-subpane { padding-top: 2px; }

/* 选图型（scene_refs / prop_refs）：ref-picker 挑，不手打路径 */
.cs-refs { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; padding-top: 1px; }
.cs-ref {
  display: flex; align-items: center; gap: .3rem;
  padding: 2px 5px 2px 2px; border: 1px solid var(--b-line); border-radius: 6px;
  background: var(--b-surface-2); font-size: .74rem;
}
.cs-ref.is-missing { border-color: #d97706; }
.cs-ref-img {
  width: 30px; height: 30px; object-fit: cover; border-radius: 4px; flex: 0 0 auto;
  background: var(--b-surface);
}
.cs-ref-img.is-broken {
  display: flex; align-items: center; justify-content: center; color: #d97706;
}
.cs-ref-name { max-width: 12em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-ref-x {
  border: 0; background: transparent; cursor: pointer; padding: 0 1px;
  color: var(--b-text-dim); font-size: .9rem; line-height: 1;
}
.cs-ref-x:hover { color: #e11d48; }
.cs-ref-add {
  border: 1px dashed var(--b-line); background: transparent; cursor: pointer;
  border-radius: 6px; padding: 4px 8px; font-size: .74rem; color: var(--b-text-2);
}
.cs-ref-add:hover { border-color: var(--b-gold); color: var(--b-gold-deep); }

/* 角色变体：下拉，不手打变体名 */
.cs-variants { display: flex; flex-wrap: wrap; gap: .5rem; padding-top: 1px; }
.cs-variant { display: flex; align-items: center; gap: .3rem; font-size: .76rem; }
.cs-variant > span { color: var(--b-text-2); }
/* 没建变体的角色也占一行（不静默漏人），灰着写明原因 */
.cs-variant.is-none { color: var(--b-text-dim); }
.cs-variant.is-none em { font-style: normal; opacity: .8; }
.cs-sel {
  font: inherit; font-size: .76rem; padding: 1px 4px; border-radius: 4px;
  border: 1px solid var(--b-line); background: var(--b-surface); color: var(--b-text);
}

/* ── 重编提示词弹窗：左右两栏（2026-09-09）───────────────────────────
   左＝编译设定（与 ⚙ 那个弹窗同一份面板，compact 形态），右＝预览。
   两栏各自滚动：设定有三十几项、正文动辄上千字，共用一根滚动条就只能来回找。
   ★ 2026-09-10 用户点名**四六分**：左 4 右 6 按比例走，不再给左栏定死 26–32rem
   （窗越宽左栏越不该原地不动；两栏都 minmax(0, …) 否则 pre 长行会把比例撑破）。 */
.cp-cols {
  display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 6fr);
  gap: 0 18px; align-items: start;
}
.cp-side {
  border-right: 1px solid var(--b-line-2); padding-right: 14px;
  position: sticky; top: 0;
}
.cp-side-head {
  font-size: .78rem; font-weight: 600; color: var(--b-text);
  padding-bottom: 6px; border-bottom: 1px solid var(--b-line-2); margin-bottom: 6px;
}
.cp-side-head em { display: block; font-style: normal; font-weight: 400;
  font-size: .68rem; color: var(--b-text-dim); padding-top: 2px; }
/* min-width:0 —— 不给的话 pre 里的长行会把整个 grid 撑宽、左栏被挤没 */
.cp-main { min-width: 0; display: flex; flex-direction: column; gap: 12px; }
/* 窄栏形态的设定面板：标签压到值上面一行（7.5rem 的键列在 24rem 里只剩半行位置） */
.cs-modal.is-side { max-height: 70vh; }
.cs-modal.is-side .cs-row { grid-template-columns: 1fr; gap: .1rem; padding: 4px 0; }
.cs-modal.is-side .cs-key { font-size: .72rem; color: var(--b-text-dim); padding-top: 0; }
.cs-modal.is-side .cs-val { font-size: .76rem; }
.cs-modal.is-side .cs-layer-head { flex-direction: column; gap: 0; align-items: flex-start; }
/* 指哪一行、右边就刷哪一句：左边这一行也要跟着亮，不然不知道正在看的是哪一项 */
.cs-modal.is-side .cs-row:hover {
  background: color-mix(in srgb, var(--b-gold) 8%, transparent);
  border-radius: 4px; box-shadow: -4px 0 0 0 var(--b-gold);
}
/* 悬停高亮：指到左边哪一项，正文里那一句刷黄 */
.cp-hl {
  background: color-mix(in srgb, var(--b-gold) 34%, transparent);
  color: inherit; border-radius: 2px; box-shadow: 0 0 0 1px color-mix(in srgb, var(--b-gold) 45%, transparent);
}
.cp-hint { font-size: .72rem; min-height: 1.1em; }
.cp-hint-on { color: var(--b-gold-deep); }
.cp-hint-off { color: var(--b-text-dim); }
/* 「⟲ 默认」：只在这一项真落了盘时出现，删键回内置默认 */
.cs-reset {
  margin-left: .35rem; font-size: .64rem; line-height: 1.4; padding: 0 .25rem;
  border: 1px solid var(--b-line-2); border-radius: 3px; background: transparent;
  color: var(--b-text-dim); cursor: pointer;
}
.cs-reset:hover { border-color: var(--b-gold); color: var(--b-gold-deep); }
/* 显式留空：与「默认」是两种状态，标签也要看得出区别 */
.cs-tag.is-blank { border-style: dashed; }

@media (max-width: 1080px) {
  .cp-cols { grid-template-columns: 1fr; gap: 12px; }
  .cp-side { border-right: none; padding-right: 0; position: static;
             border-bottom: 1px solid var(--b-line-2); padding-bottom: 10px; }
  .cs-modal.is-side { max-height: 34vh; }
}

/* ── 重编提示词弹窗：那排「编哪些部件」的勾选框（2026-09-07）─────────── */
.cp-parts {
  display: flex; flex-wrap: wrap; gap: .25rem .7rem;
  padding: 7px 9px; border: 1px solid var(--b-line-2); border-radius: 6px;
  background: var(--b-surface-2);
}
.cp-part {
  display: flex; align-items: center; gap: .3rem;
  font-size: .78rem; color: var(--b-text); cursor: pointer; user-select: none;
}
.cp-part input { cursor: pointer; margin: 0; }
.cp-part.is-blocked { color: var(--b-text-dim); cursor: not-allowed; }
.cp-part.is-blocked input { cursor: not-allowed; }
.cp-sum { font-size: .76rem; color: var(--b-text-2); }
.cp-speech { display: flex; flex-wrap: wrap; align-items: center; gap: .2rem .45rem; }
.cp-refs { font-size: .72rem; color: var(--b-text-dim); line-height: 1.5; }
/* 参考图缩略图格：每张带 @图片N 角标与绑定对象（「难陀」「空间锚 · b08 第8格」），
   点开进 lightbox 看全图；断链的格子不放图，摆一句「不在盘上」 */
.cp-refs-head { font-size: .74rem; color: var(--b-text-2); margin: 6px 0 4px; }
.cp-ref-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 6px;
}
.cp-ref {
  position: relative; margin: 0; border: 1px solid var(--b-line-2); border-radius: 6px;
  overflow: hidden; background: var(--b-surface-2); cursor: zoom-in;
}
.cp-ref img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; background: #0c0c0c; }
.cp-ref.is-missing { border-color: #d97706; cursor: default; }
.cp-ref-broken {
  display: flex; align-items: center; justify-content: center; aspect-ratio: 4 / 3;
  color: #d97706; font-size: .7rem;
}
.cp-ref-no {
  position: absolute; left: 0; top: 0; padding: 0 .35rem; font-size: .66rem; font-weight: 700;
  background: rgba(255,255,255,.92); color: #000; border-bottom-right-radius: 4px;
}
.cp-ref figcaption {
  font-size: .68rem; color: var(--b-text-2); padding: .15rem .3rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cp-aud { display: flex; align-items: center; gap: .5rem; margin-top: 5px; font-size: .72rem; }
.cp-aud .cp-ref-no { position: static; border-radius: 4px; border: 1px solid var(--b-line-2); }
.cp-aud audio { height: 26px; max-width: 260px; }
.cp-aud-name { color: var(--b-text-2); }
.cp-ref-warn { color: #d97706; }
/* 换一组部件要重新问一次后端：正文淡下去，免得当成「已经是新的了」 */
.cp-text.is-loading { opacity: .45; transition: opacity .12s; }
/* 正文是 contenteditable：聚焦时描金边，让人知道这里能改 */
.cp-text[contenteditable]:focus { border-color: var(--b-gold); }
.cp-warn-more {
  font-size: .72rem; color: var(--b-text-dim); padding: 1px 6px; border-radius: 4px;
  border: 1px dashed var(--b-line-2); background: transparent; cursor: pointer;
}
.cp-warn-more:hover { color: var(--b-text-2); border-color: var(--b-line); }

/* 重编弹窗的逐拍时长行（2026-09-07）：拍与拍之间一眼看出谁长谁短、加起来够不够本镜 */
.cp-beats { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem .45rem; font-size: .74rem; }
.cp-beats-key { color: var(--b-text-dim); }
.cp-beat {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  padding: 0 .35rem; border-radius: 4px;
  background: var(--b-surface-2); color: var(--b-text-2);
}
.cp-beat.has-line { color: var(--b-text); box-shadow: inset 0 0 0 1px var(--b-line); }
.cp-beats-sum { margin-left: .3rem; color: var(--b-text-2); }
.cp-beats-sum.is-off { color: #d97706; }
.cp-beat.is-tight { color: #d97706; box-shadow: inset 0 0 0 1px #d9770655; }
.cp-beat.is-over  { color: #dc2626; box-shadow: inset 0 0 0 1px #dc262666; font-weight: 600; }
.cp-fix {
  margin-left: .35rem; font-size: .72rem; padding: 1px .5rem; border-radius: 999px;
  border: 1px solid var(--b-gold); color: var(--b-gold); background: transparent; cursor: pointer;
}
.cp-fix:hover { background: var(--b-gold); color: #fff; }
.cp-fix:disabled { opacity: .5; cursor: default; }
.cp-fix-beat {
  margin-left: .3rem; padding: 0 .35rem; font-size: .68rem; border-color: #dc2626; color: #dc2626;
}
.cp-fix-beat:hover { background: #dc2626; border-color: #dc2626; }

/* 「自动同步」那排 + 它的变更计划（2026-09-07）：勾了就在写盘时按分镜写正镜头清单 */
.cp-sync { background: transparent; border-style: dashed; }
.cp-plan {
  display: flex; flex-direction: column; gap: .1rem;
  font-size: .74rem; color: var(--b-text-2);
}
.cp-plan-row b { color: var(--b-text); font-weight: 600; }
.cp-plan-row.is-ok { color: var(--b-text-dim); }

.cp-anchor {
  font: inherit; font-size: .74rem; padding: 1px .3rem; border-radius: 4px; margin-left: auto;
  border: 1px solid var(--b-line); background: var(--b-surface); color: var(--b-text);
}

/* ── 空间锚拼板子窗口（compose-sheet.js，2026-09-07）───────────────────
   「这条镜会挂哪几格」先看图再定口径：口径四选一 + 格子网格 + 一行落点说明。 */
.cp-sheet-btn {
  font-size: .74rem; padding: 1px .5rem; border-radius: 4px; margin-left: .4rem;
  border: 1px solid var(--b-line); background: var(--b-surface); color: var(--b-text);
  cursor: pointer;
}
.cp-sheet-btn:hover { background: var(--b-surface-2); }
.cs-modes { display: flex; flex-wrap: wrap; gap: .4rem; }
.cs-mode {
  display: flex; align-items: flex-start; gap: .35rem; cursor: pointer;
  flex: 1 1 12rem; padding: .4rem .55rem; border-radius: 6px;
  border: 1px solid var(--b-line-2); background: var(--b-surface-2);
}
.cs-mode.is-on { border-color: var(--b-accent, #c99a2e); background: var(--b-surface); }
.cs-mode input { margin: .15rem 0 0; cursor: pointer; }
.cs-mode b { display: block; font-size: .8rem; font-weight: 600; }
.cs-mode i { display: block; font-style: normal; font-size: .7rem; color: var(--b-text-dim); }
.cs-body {
  display: grid; gap: 6px; max-height: 46vh; overflow: auto;
  grid-template-columns: repeat(var(--cs-cols, 3), minmax(0, 1fr));
}
.cs-body.is-loading { opacity: .45; transition: opacity .12s; }
.cs-cell { position: relative; background: #0c0c0c; border-radius: 4px; overflow: hidden; }
.cs-cell img { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.cs-no {
  position: absolute; left: 0; top: 0; padding: 0 .35rem;
  background: #fff; color: #000; font-weight: 700; font-size: .75rem;
}
.cs-cell em {
  display: block; font-style: normal; font-size: .68rem; color: var(--b-text-dim);
  padding: .15rem .3rem; background: var(--b-surface-2);
}
.cs-note { font-size: .74rem; color: var(--b-text-2); line-height: 1.6; }
.cs-note .cs-dim { color: var(--b-text-dim); }
.cs-note .cs-warn, .cs-body .cs-warn { color: #d97706; font-size: .74rem; }
/* 「这一项现在生不生效」的一句话（编译设定：场景归属 vs 场景参考图） */
.cs-note-inline { display: block; font-size: .68rem; color: var(--b-text-dim); padding-top: .2rem; }

/* ── 节拍条（story_beats[]，2026-09-20）────────────────────────
   分镜表上方的**故事层**。⚠ 本文件其余地方的 .beat-* 指的是分镜（b01），
   .beat-sb-* 才是节拍（sb01）——字段名冻结，靠前缀分。
   不做成分组行：节拍↔分镜多对多，按组摆会让横跨两拍的分镜重复出现两次。 */
.beat-sb-strip {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 8px 4px 10px; margin-bottom: 2px;
  border-bottom: 1px dashed var(--b-line);
}
.beat-sb-label {
  font-size: 11px; font-weight: 600; color: var(--b-text-dim);
  letter-spacing: .04em; margin-right: 2px;
}
.beat-sb-hint { font-size: 11.5px; color: var(--b-text-dim); line-height: 1.5; }

.beat-sb-chip {
  display: inline-flex; align-items: baseline; gap: 5px;
  font-size: 11.5px; padding: 3px 9px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--b-line-2); background: var(--b-surface-2); color: var(--b-text-2);
  transition: border-color var(--mo-fast), color var(--mo-fast);
}
.beat-sb-chip:hover { border-color: var(--b-gold); color: var(--b-gold-deep); }
.beat-sb-chip code { font-size: 10.5px; color: var(--b-text-dim); }
.beat-sb-chip .beat-sb-title { max-width: 13em; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.beat-sb-chip .beat-sb-dur { font-size: 10.5px; color: var(--b-text-dim); }
.beat-sb-chip .beat-sb-n { font-size: 10px; color: var(--b-text-dim); }
/* 没有任何分镜演它＝戏写了但没拍，是真缺口，标出来 */
.beat-sb-chip.is-naked { border-style: dashed; border-color: var(--b-red); }
.beat-sb-chip.is-naked .beat-sb-n { color: var(--b-red); }

.beat-sb-warn { font-size: 11px; color: var(--b-red); }
.beat-sb-add {
  font-size: 11.5px; padding: 3px 9px; border-radius: 999px; cursor: pointer;
  border: 1px dashed var(--b-line-2); background: transparent; color: var(--b-text-dim);
}
.beat-sb-add:hover { border-color: var(--b-gold); color: var(--b-gold-deep); }

/* 分镜行上的「节拍」列：并列 chip，不是单选 */
.beat-chip.is-sb { border-color: var(--b-blue); color: var(--b-blue); }
.beat-table .c-sb { white-space: nowrap; }
/* 老集没建节拍层：显示「—」不是缺陷态（把未回填当缺陷会让人对红色麻木） */
.beat-sb-na { color: var(--b-text-dim); font-size: 11px; }

/* ── 节拍页签（story，2026-09-20）──────────────────────────────────
   与分镜表上方那条 `.beat-sb-strip` 是两个用途：条是看分镜时的上下文与导航，
   这张表是编辑面——进点/出点/戏剧任务这些长文本在 chip 的 title 里塞不下。 */
.beat-table.is-story td { vertical-align: top; line-height: 1.5; }
.beat-table.is-story .c-sbid { width: 3.5rem; white-space: nowrap; }
.beat-table.is-story .c-sbtitle { width: 6rem; }
.beat-table.is-story .c-emo  { width: 8rem; }
/* 「时长」两字会被挤成两行——给它够站一行的宽 */
.beat-table.is-story .c-size { width: 3.5rem; white-space: nowrap; text-align: right; }
.beat-table.is-story .c-sbcov { width: 11rem; }
.beat-table.is-story .c-act  { width: 4.5rem; white-space: nowrap; text-align: right; }
/* 没有任何分镜演它的那一拍：左缘一道红，比整行染色克制 */
.beat-table.is-story tr.is-naked > td:first-child { box-shadow: inset 2px 0 0 var(--b-red); }
.beat-sb-dim { color: var(--b-ink-400, #9ca3af); }
.beat-sb-cov { display: flex; flex-wrap: wrap; gap: 3px; }
.beat-sb-ok  { font-size: 11px; color: var(--b-ink-400, #9ca3af); }
.beat-sb-foot {
  margin-top: 6px; padding: 4px 2px;
  font-size: 11px; color: var(--b-ink-500, #6b7280);
}
.beat-inline-btn.is-mini { padding: 1px 6px; font-size: 11px; }
.beat-empty-sub { margin-top: 4px; font-size: 11px; color: var(--b-ink-400, #9ca3af); }
