# script-report.html 设计约定

与 novel-characters / novel-outline / novel-art 的报告同一套视觉语言。改样式前先读这份，别凭感觉发挥。

## 基调

- 冷灰印张 + 铁锈红印记：`--paper:#eceded` `--panel:#f5f6f5` `--seal:#8a3324` `--seal-2:#c56a4e` `--ok:#3d6b4f`。这套配色跑过可视化验证器，别私自换色
- 页宽 1600，衬线标题（宋体系）+ 无衬线正文，克制的分区排版，像一份业内评审文件
- **零外部依赖**：全部样式内联、图形是纯 CSS/SVG，离线双击能开
- 模型产出的每一个字都要过 `esc()`；内嵌 JSON 的 `<` 转成 `<` 防 `</script` 截断

## 区块顺序

KPI 带 → 01 时长仪表 → 02 分集剧本 → 03 场次总表 → 04 台词本 → 05 质量门。时长是钱，仪表放最前；台词本是 TTS 的工作清单，放表格之后。

## 时长仪表

- 每集一行：`E01 | 轨道 | 数值`，轨道里三层——目标区间带（`--band`，半透明绿）、台词段（`--seal`）、动作段（`--seal-2`）
- 横轴比例尺全局统一（取全部集的最大值 × 1.08），行与行可以直接比长短
- 达标的数值用 `--ok` 绿，超欠用 `--seal` 红加粗并写明差多少秒——病灶要点名，不许只变个颜色

## 分集剧本

- **一排两集**：`.eps{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}`，单集加 `.solo` 单列，窄屏降一列
- 每集卡片里**场次区默认最多 300px**（`.scenes.clip{max-height:300px}` + 底部渐隐），集头/钩子/悬念永远可见；「展开全部场次 / 收起场次」是**开关**，收起时滚回卡片位置。页面加载后不超高的集自动放开并移除按钮（`scrollHeight` 判断）
- 台词行是三列网格 `150px minmax(0,1fr) auto`：说话人（名字 + delivery 竖排）、台词、悬停出现的复制按钮。**滚动/网格容器一律 `minmax(0,1fr)`**，防中文长词把列挤成一字一行
- 场头 chips：场景 id+名、光照（seal-2 描边）、人物、道具（seal 描边）。给了 `--outline` / `--art` 才显示名字，否则裸 ID——不猜

## 台词本

- **一排两个**（`.casts` 网格，同 `.eps` 规则），按角色一组一卡，组头带句数/字数/约合秒数 + 「复制全部台词」（整组台词换行拼接，直接喂 TTS）
- 列表**最多 6 行高**（`max-height:186px`）纵向滚动，细滚动条；打印时放开滚动全展开
- VO 单独成组，显示为「画外音」

## 质量门

- 页眉徽章 `✓ 质量门 n / n`；有未过项时 KPI 带下方挂病灶横幅（`.galert`），逐条列出未过的门和细节
- 对账门在缺上游文件时显示「跳过（视为通过）」的小字——**跳过要明说，静默通过和撒谎只差一步**

## 交互与打印

- 复制按钮统一 `.copy[data-copy]` 事件委托，成功换字 1.6 秒后还原；失败也要有反馈
- `@media print`：折叠全展开、按钮全隐藏、白底
- `prefers-reduced-motion` 关掉全部动效
- 导出 JSON：数据内嵌在 `<script type="application/json">`，导出包 Blob 下载，`revokeObjectURL` 延迟 10 秒（Safari 会抢在下载前撤 blob）
