/* 审核台样式 —— 深色作战室质感。
 *
 * 硬约束：不加载任何外部资源（无 Google Fonts、无 CDN）。服务器与国内网络
 * 访问外部 CDN 都不稳，加载失败会同时破坏观感与可用性。层次全靠字号、
 * 字距、留白、边框与单一强调色做出来。
 */

:root {
  --bg:        #0b0d11;
  --bg-panel:  #13161c;
  --bg-sunken: #0e1116;
  --line:      #262b34;
  --line-soft: #1c212a;

  --text:      #d5dae2;
  --text-dim:  #8d97a5;
  --text-faint:#5c6673;

  /* 单一强调色：暖琥珀。在近黑底上作唯一的高饱和点。 */
  --accent:    #d98b3a;
  --accent-dim:#8a5722;

  --ok:   #63b37a;
  --warn: #d9b03a;
  --bad:  #d46a5e;

  --sans:  -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB",
           "Microsoft YaHei", "Source Han Sans SC", sans-serif;
  --serif: "Songti SC", "STSong", "Source Han Serif SC", "Noto Serif CJK SC", serif;
  --mono:  ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas,
           "Liberation Mono", monospace;

  --r: 6px;
  --r-lg: 10px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.muted { color: var(--text-dim); }
.small { font-size: 12px; }
.num { text-align: right; }

/* —— 顶栏 —— */

.topbar {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 16px 28px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-sunken);
  position: sticky;
  top: 0;
  z-index: 10;
}
.brand {
  font-family: var(--serif);
  font-size: 20px;
  letter-spacing: .08em;
  color: var(--text);
}
.brand-sub {
  font-size: 11px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.logout-form { margin-left: auto; }

/* 免密模式标记。与「退出」按钮同一个位置（都是 margin-left:auto 挤到右侧），
   所以两种形态下顶栏的布局完全一样，不会因为少一个表单而跳一下。 */
.pill.noauth {
  margin-left: auto;
  border-color: var(--bad);
  color: var(--bad);
  letter-spacing: .1em;
}

.wrap {
  max-width: 1240px;
  margin: 0 auto;
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 28px;
}

/* —— 面板 —— */

.panel {
  background: var(--bg-panel);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}

.panel-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--line-soft);
}
.panel-head h2 {
  margin: 0;
  font-family: var(--serif);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: .06em;
}
.count {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--accent);
  border: 1px solid var(--accent-dim);
  border-radius: 999px;
  padding: 1px 9px;
}
.filter { margin-left: auto; display: flex; gap: 8px; align-items: center; }

select, input[type=text], input[type=password], input:not([type]) {
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--r);
  color: var(--text);
  padding: 6px 10px;
  font-family: var(--sans);
  font-size: 13px;
  outline: none;
}
select:focus, input:focus { border-color: var(--accent-dim); }

/* —— 按钮 —— */

.btn {
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--r);
  color: var(--text);
  padding: 6px 14px;
  font-family: var(--sans);
  font-size: 13px;
  cursor: pointer;
  transition: border-color .12s, background .12s, color .12s;
}
.btn:hover { border-color: var(--accent-dim); color: #fff; }
.btn-ghost { color: var(--text-dim); }
.btn-approve {
  border-color: var(--accent-dim);
  color: var(--accent);
  font-weight: 600;
}
.btn-approve:hover { background: var(--accent); color: #14100a; }
.btn-reject:hover  { border-color: #6b3a35; color: var(--bad); }
.btn-sent:hover    { border-color: #3d5f47; color: var(--ok); }

.flash {
  margin: 0;
  padding: 11px 18px;
  border: 1px solid var(--accent-dim);
  border-left: 3px solid var(--accent);
  border-radius: var(--r);
  background: rgba(217,139,58,.07);
  color: var(--text);
  font-size: 13px;
}

/* —— 线索表 / 被跳过表 —— */

table.leads, table.skipped, table.results { width: 100%; border-collapse: collapse; }
table.leads th, table.skipped th, table.results th {
  text-align: left;
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-faint);
  font-weight: 500;
  padding: 10px 20px;
  border-bottom: 1px solid var(--line-soft);
}
table.leads th.num { text-align: right; }
table.leads td, table.skipped td, table.results td {
  padding: 11px 20px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: top;
}
table.leads tr:last-child td, table.skipped tr:last-child td, table.results tr:last-child td { border-bottom: none; }
table.leads tr:hover td, table.skipped tr:hover td, table.results tr:hover td { background: rgba(255,255,255,.015); }

.company { max-width: 300px; }
.evidence {
  display: block;
  font-size: 11.5px;
  color: var(--text-faint);
  margin-top: 2px;
  line-height: 1.45;
}

.tier {
  display: inline-block;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  width: 22px; height: 22px;
  line-height: 22px;
  text-align: center;
  border-radius: var(--r);
  border: 1px solid var(--line);
}
.tier-A { color: var(--accent); border-color: var(--accent-dim); }
.tier-B { color: var(--text-dim); }
.tier-C { color: var(--text-faint); }

.score { font-family: var(--mono); font-size: 13px; }
.bar {
  display: inline-block;
  width: 52px; height: 3px;
  background: var(--line);
  border-radius: 2px;
  margin-left: 9px;
  vertical-align: middle;
  overflow: hidden;
}
.bar i { display: block; height: 100%; background: var(--accent); }

.empty { padding: 28px; text-align: center; color: var(--text-faint); }

/* —— 被跳过面板 ——
 *
 * 诊断视图，不是工作队列：视觉上比线索表/审核区**低一档**（沉底背景、
 * 字号收小），因为它回答的是"刚才那一轮丢了什么"，而不是"现在要做什么"。
 * 但它是两条 KPI 的分子，所以计数一定要显眼——kpi 速览那一行是整块的重点。
 */

.skip-counts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 14px 20px 2px;
}
/* 计数胶囊是全表口径，而下方表体是"当前页"——两者在同一块面板里，
   不点明就会被当成一回事（"筛完只剩 10 条了？"）。这行小字是那处歧义的解药。 */
.skip-counts-label { letter-spacing: .04em; }
.skip-pill { color: var(--warn); border-color: #6b5a20; }
.skip-pill b { font-weight: 600; }

/* 摘录是诊断时真正要读的东西（"这句话为什么被判定成竞品调研"），
   所以给等宽 + 收窄换行，但压低对比度避免抢走计数的注意力。 */
.skip-excerpt {
  max-width: 460px;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--text-dim);
  word-break: break-word;
}
table.skipped td { background: var(--bg-sunken); }
table.skipped tr:hover td { background: rgba(255,255,255,.015); }

/* 分页条。压在表体下方，与诊断视图的"低一档"基调一致：不抢眼，
   但翻页控件必须有足够点击面积（一页十条，翻页是高频动作）。 */
.pager {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 20px 14px;
  border-top: 1px solid var(--line-soft);
  flex-wrap: wrap;
}
.pager-info { font-size: 12px; color: var(--text-dim); }
.pager-info b { color: var(--text); }
/* 端点页的占位：仍占位、仍可读，但明确不是可点的链接——
   把"点了没反应"做成灰按钮，比干脆不渲染更能说明"到头了"。 */
.pager .is-disabled {
  opacity: .35;
  cursor: default;
  pointer-events: none;
}
.pager-jump { margin-left: auto; display: flex; gap: 6px; align-items: center; }
.pager-jump input { width: 68px; text-align: center; }

/* —— 审核卡片 —— */

.card {
  border-top: 1px solid var(--line-soft);
  padding: 18px 20px 20px;
  border-left: 3px solid transparent;
}
.card:first-of-type { border-top: none; }
.card.risk-high { border-left-color: var(--bad); }
.card.risk-mid  { border-left-color: var(--warn); }
.card.risk-low  { border-left-color: var(--ok); }
.card.state-rejected { opacity: .55; }

.card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}
.card-company {
  font-family: var(--serif);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: .03em;
}
.card-id {
  margin-left: auto;
  font-size: 11px;
  color: var(--text-faint);
}

.pill {
  font-size: 11px;
  font-family: var(--mono);
  color: var(--text-dim);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 1px 9px;
  white-space: nowrap;
}
.pill.status { color: var(--accent); border-color: var(--accent-dim); }
.pill.risk   { color: var(--text-dim); }

/* 联系方式（leads.contact_handle）：电话号 / TG 句柄 / LinkedIn 主页后缀。
   它与渠道 pill 成对出现，回答的是"这条放行之后我具体要拨什么、找谁"——
   requiresHandle 的渠道（当前只有 phone）缺了它就放不了行。所以给它比周围
   那排灰 pill 更高的对比度与更大的字号：它是要被抄下来用的，不是背景信息。
   不用强调色（—accent）：那是 status 与主按钮的语义，抢了会让人以为
   "有联系方式"是一种状态。 */
.pill.handle {
  color: var(--text);
  border-color: #3a4250;
  font-size: 12px;
  letter-spacing: .04em;
}

/* 规则引擎判定（六要素⑤）：pass/warn/block 三档各占一色。 */
.pill.verdict-pass  { color: var(--ok);   border-color: #3d5f47; }
.pill.verdict-warn  { color: var(--warn); border-color: #6b5a20; }
.pill.verdict-block { color: var(--bad);  border-color: #6b3a35; }

/* 违规明细：卡片上最可操作的信息——"风险 mid"只说有违规，
   具体是哪个极限词、哪个未验证数字全在这几句里。视觉上从属于草稿正文：
   沉底背景、字号收小，不抢草稿的注意力。 */
.violations {
  margin: 0 0 16px;
  padding: 12px 14px;
  background: var(--bg-sunken);
  border: 1px solid var(--line-soft);
  border-radius: var(--r);
}
.violations li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.violations blockquote {
  margin: 0;
  border-left-color: var(--warn);
  color: var(--text);
}
.vl-suggest { flex-basis: 100%; }

.draft {
  margin: 0 0 16px;
  padding: 14px 16px;
  background: var(--bg-sunken);
  border: 1px solid var(--line-soft);
  border-radius: var(--r);
  font-family: var(--sans);
  font-size: 13.5px;
  line-height: 1.7;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--text);
}

.warn, .needfact {
  margin: 0 0 12px;
  padding: 9px 14px;
  border-radius: var(--r);
  font-size: 12.5px;
  border-left: 3px solid var(--warn);
  background: rgba(217,176,58,.07);
  color: var(--text);
}
.warn { border-left-color: var(--bad); background: rgba(212,106,94,.08); }

.card-meta {
  display: grid;
  grid-template-columns: minmax(0,1fr) 210px;
  gap: 22px;
  margin-bottom: 16px;
}
@media (max-width: 780px) { .card-meta { grid-template-columns: 1fr; } }

.card-meta h3 {
  margin: 0 0 8px;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-faint);
  font-weight: 500;
}

.facts { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.facts li { font-size: 12px; }
.fact-topic { color: var(--text-dim); margin-left: 8px; }
.facts blockquote {
  margin: 5px 0 0;
  padding: 6px 11px;
  border-left: 2px solid var(--line);
  color: var(--text-dim);
  font-family: var(--mono);
  font-size: 11.5px;
  white-space: pre-wrap;
  word-break: break-word;
}

.checks { list-style: none; margin: 0; padding: 0; font-size: 12.5px; }
.checks li::before { content: "○ "; color: var(--text-faint); }
.checks li.ok::before  { content: "● "; color: var(--ok); }
.checks li.bad::before { content: "● "; color: var(--bad); }
.checks li.bad { color: var(--bad); }

/* —— 交付包 —— */

.handoff {
  border: 1px solid var(--accent-dim);
  border-radius: var(--r);
  padding: 14px 16px;
  margin-bottom: 16px;
  background: rgba(217,139,58,.04);
}
.handoff h3 {
  margin: 0 0 10px;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 500;
}
.handoff-target {
  display: grid;
  grid-template-columns: 68px minmax(0,1fr);
  gap: 3px 12px;
  margin: 0 0 12px;
  font-size: 12.5px;
}
.handoff-target dt { color: var(--text-faint); }
.handoff-target dd { margin: 0; word-break: break-word; }

.copytext {
  margin: 0;
  padding: 12px 14px;
  background: var(--bg-sunken);
  border: 1px solid var(--line-soft);
  border-radius: var(--r);
  font-family: var(--sans);
  font-size: 13.5px;
  line-height: 1.7;
  white-space: pre-wrap;
  word-break: break-word;
}

/* —— 动作区 —— */

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  padding-top: 4px;
}
.inline { display: inline-flex; gap: 8px; margin: 0; }
.reviewer { margin-left: auto; }

/* —— 登录页 —— */

.login-body {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(circle at 20% 0%, rgba(217,139,58,.07), transparent 55%),
    var(--bg);
}
.login-wrap { width: 100%; max-width: 400px; padding: 24px; }
.login-box {
  background: var(--bg-panel);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 34px 30px;
}
.login-eyebrow {
  margin: 0 0 20px;
  font-size: 10.5px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.login-box h1 {
  margin: 0 0 4px;
  font-family: var(--serif);
  font-size: 30px;
  font-weight: 600;
  letter-spacing: .12em;
  color: var(--text);
}
.login-sub { margin: 0 0 26px; font-size: 12.5px; color: var(--text-dim); }

.login-input { width: 100%; padding: 10px 12px; font-size: 15px; }
.login-btn {
  width: 100%;
  margin-top: 12px;
  padding: 10px;
  background: transparent;
  border: 1px solid var(--accent-dim);
  border-radius: var(--r);
  color: var(--accent);
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: .1em;
  cursor: pointer;
  transition: background .14s, color .14s;
}
.login-btn:hover:not(:disabled) { background: var(--accent); color: #14100a; }
.login-btn:disabled { opacity: .55; cursor: default; }
.login-err {
  min-height: 18px;
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--bad);
}
.login-note {
  margin: 22px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--line-soft);
  font-size: 11px;
  line-height: 1.65;
  color: var(--text-faint);
}

/* —— 分页签（Scout / Closer）——
 *
 * 用法：每个签回答一个问题，所以导航条是页面的**主结构**而不是装饰，
 * 视觉分量要给够：当前签用强调色下划线 + 提亮文字，未选中的压暗。
 * 角标（待起草数 / 待审数）一律显示，0 也显示——隐藏会被读成"没统计"。
 */
.tabs {
  display: flex;
  gap: 4px;
  margin: 18px 0 14px;
  border-bottom: 1px solid var(--line);
}
.tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  font-size: 13.5px;
  letter-spacing: .02em;
  color: var(--text-dim);
  text-decoration: none;
  border: 1px solid transparent;
  border-bottom: 2px solid transparent;
  border-radius: var(--r) var(--r) 0 0;
  margin-bottom: -1px;
}
.tab:hover { color: var(--text); background: rgba(255,255,255,.02); }
.tab.active {
  color: var(--text);
  border-bottom-color: var(--accent);
  background: var(--bg-panel);
}
.tab b {
  font-size: 12px;
  font-weight: 600;
  padding: 1px 7px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--text-dim);
}
.tab.active b { color: var(--accent); border-color: var(--accent-dim); }

/* —— 人工录入表单 ——
 * 默认展开（一个没人知道的入口等于不存在），但用 <details> 折叠而不是占满首屏：
 * 录入是"偶尔用一次"的动作，而线索表是"经常看"的。
 */
.entry {
  background: var(--bg-panel);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 0 16px;
  margin-bottom: 18px;
}
.entry > summary {
  cursor: pointer;
  padding: 13px 0;
  font-size: 13.5px;
  color: var(--text);
  letter-spacing: .02em;
  list-style: none;
}
.entry > summary::-webkit-details-marker { display: none; }
.entry > summary::before { content: "▸ "; color: var(--accent); }
.entry[open] > summary::before { content: "▾ "; }
.entry-form { padding-bottom: 16px; border-top: 1px solid var(--line-soft); padding-top: 14px; }
.entry-form .field { margin-bottom: 10px; }
.entry-form .field label { display: block; font-size: 12px; color: var(--text-dim); margin-bottom: 4px; }
.entry-form .field label b { color: var(--accent); font-weight: 600; }
.entry-form input,
.entry-form textarea,
.entry-form select {
  width: 100%;
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--r);
  color: var(--text);
  padding: 7px 9px;
  font-size: 13px;
  font-family: inherit;
}
.entry-form textarea { resize: vertical; line-height: 1.5; }
.entry-form input:focus,
.entry-form textarea:focus,
.entry-form select:focus { outline: none; border-color: var(--accent-dim); }
/* 紧凑字段排一行：渠道/等级/语言/国家 四个都是短选项，竖排会把表单拉得很长。
   窄屏自动折行（flex-wrap），不做媒体查询也能用。 */
.field-row { display: flex; gap: 10px; flex-wrap: wrap; }
.field-row .field { flex: 1 1 150px; }
.entry-form .btn { margin-top: 6px; }

/* —— 线索表新增的两类标记 —— */
/* 「待起草」= 还没有任何草稿（补扫的目标集合）；其他状态都是"已经有东西了"。 */
.pill.draft { color: var(--text-dim); }
.pill.draft-none { color: var(--warn); border-color: #6b5a20; }
/* 「人工」：这一行没有机器评分。用中性色而不是 0 分的空条，
   因为 0 分是一个评分结果，而这里是"没有可评的正文"。 */
.pill.manual { color: var(--text-faint); letter-spacing: .06em; }

/* —— 审核结果（终态台账）—— */
.pill.result-sent     { color: var(--ok);   border-color: #3d5f47; }
.pill.result-rejected { color: var(--bad);  border-color: #6b3a35; }
table.results td.company { white-space: normal; }

/* —— 第四签「Promoter · 内容」（M5）——
 *
 * 2026-09-25 版式重构：列表从「每条一张全展开的大卡片」改成**一行一条的
 * 紧凑表格**（table.content-list），六步流水线、正文、两闸原文与动作按钮
 * 全部移到内容详情页（.dsec 的「操作」区）——列表只回答"有什么、走到哪
 * 一步了"，详情页回答"这条到底怎么样、下一步做什么"。
 * 原来服务卡片的 .script / .content-card .rawjson / .content-card.state-published
 * 与族群折叠 <details>（.group）的规则随卡片一起删除；六步流水线（.steps）与
 * 双闸（.gate）的规则保留——详情页第 0 节与第 5 节还在用。
 */

/* 列表表格：与 table.leads 同一版式语言（细边框、行 hover、紧凑字号）。
   标题列给一个最大宽度 + 省略号：长文的 hook 动辄半句话，不截的话
   一行会被顶成三行，列表就成了另一面墙——完整标题在详情页第 1 节。 */
table.content-list { width: 100%; border-collapse: collapse; font-size: 12.5px; }
table.content-list th {
  text-align: left; padding: 6px 8px;
  color: var(--text-dim); font-weight: 500; font-size: 12px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
table.content-list td {
  padding: 7px 8px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: baseline;
}
table.content-list tr:last-child td { border-bottom: none; }
table.content-list tr:hover td { background: rgba(255,255,255,.015); }
table.content-list td.num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
table.content-list td.cl-title {
  max-width: 340px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
table.content-list .cl-link { color: var(--text); }
table.content-list td a { color: var(--accent); }
table.content-list td a.btn { color: var(--text-dim); }
/* 已发布的内容整行降一档对比度：它们是**账**，不再是待办
   （原 .content-card.state-published 的同一手法，换到行上）。 */
table.content-list tr.row-published { opacity: .78; }

/* 详情页的操作区：通过/驳回 + 理由框可能要折行（窄屏），
   与原列表卡片 .actions 的 wrap 同一条理由，作用域换到新区块。 */
.detail-actions .actions,
.detail-actions .inline { flex-wrap: wrap; }

/* 正文行：卡片上的一句说明（降级原因、驳回理由、UTM、素材链接……）。
   与 .warn 的区别是**语气**——.note 是中性陈述（"这条降级了，原因是 X"），
   .warn 是"请注意"（结论解析失败、门禁已关）。把中性事实写成 .warn
   会让真正需要注意的那几条淹没在黄色里。 */
.note {
  margin: 0 0 12px;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--text);
  word-break: break-word;
}
/* 与 .warn 同时用时（降级标注）保留告警的语气与左边条。 */
.note.warn { padding: 9px 14px; }

/* 脚本文本的 <details>（details.script）规则已随 2026-09-25 的列表重构删除：
   脚本全文移到了内容详情页（正文区的普通 <details> 与第 2 节的折叠副块），
   列表上不再出现。 */

/* —— 六步流水线（2026-09-21 新增；现渲染在详情页第 0 节）——
 *
 * 版式目标：**一条记录 = 一条流程**。每步一行、行首带序号，从上往下读一遍
 * 就知道这个 Agent 做了什么、每步结果是什么。
 *
 * 为什么从"两列并排"改成"逐行编号"：并排的布局丢掉的是**顺序**，而顺序恰恰
 * 是排障的第一手信息——内容被拦，是死在双闸还是死在发布？自检过了没有？
 * 列式版面上这两个问题都要靠人去脑补时间线。
 *
 * 为什么用 <ol> 而不用一堆 <div>：序号本身是信息。有了它，工单/聊天/复盘里
 * 才能说"卡在第④步"，而"卡在双闸那一步"在同一张卡片上有多个闸时是含糊的。
 * 浏览器默认的列表标记被关掉，序号由 .step-no 自己渲染（字号与配色要受控）。
 */
.steps { list-style: none; margin: 14px 0 12px; padding: 0; }
.step {
  position: relative;
  padding: 0 0 12px 34px;
  margin-left: 11px;
  border-left: 1px solid var(--line-soft);
}
/* 末步不画下方的连接线：线是用来"连到下一步"的，最后一步没有下一步，
   留着会像被截断（而"被截断"在这张卡上有具体含义——流程真的中断了）。 */
.step:last-child { padding-bottom: 2px; border-left-color: transparent; }

/* 序号圆点压在竖线上（width/2 向左偏移，让圆心落在 border-left 上）。 */
.step-no {
  position: absolute;
  left: -11px;
  top: 0;
  width: 22px;
  height: 22px;
  line-height: 22px;
  text-align: center;
  border-radius: 50%;
  font-size: 11px;
  font-family: var(--mono);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  color: var(--text-faint);
}
.step-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.step-name {
  font-size: 12px;
  letter-spacing: .06em;
  color: var(--text-dim);
  min-width: 2.5em;
}
.step-result { font-size: 12.5px; line-height: 1.6; color: var(--text); flex: 1 1 240px; word-break: break-word; }
.step-link { font-size: 11.5px; color: var(--accent); word-break: break-all; }

/* 状态上色**只给序号圆点**，不给整行：
   整行上色会让"这一步是重点"与"这一步有问题"混起来——四步正常一步红，
   读起来像整条流程都在报错。正文里只有 blocked 那一步的结论字变色
   （它是唯一"必须现在处理"的一步）。 */
.step-done    .step-no { color: var(--ok);   border-color: #3d5f47; }
.step-warn    .step-no { color: var(--warn); border-color: #6b5a20; }
.step-blocked .step-no { color: var(--bad);  border-color: #6b3a35; }
.step-blocked .step-result { color: var(--bad); }

/* 双闸明细：**每闸一行**（原来是一闸一列并排）。
   缩进在步骤正文之下，与"这一步的结果"形成一个从属关系。 */
.gate {
  margin: 8px 0 0;
  padding: 9px 12px;
  background: var(--bg-sunken);
  border: 1px solid var(--line-soft);
  border-radius: var(--r);
}
.gate + .gate { margin-top: 6px; }
.gate-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 6px; }
.gate-name { font-size: 12px; color: var(--text-dim); }
.gate .violations { margin-bottom: 0; }
.gate .rawjson { margin-bottom: 0; max-height: 160px; }

/* 解析失败的原始 JSON：等宽、限高滚动。它是坏结论唯一的证据，
   必须可读，但不能长到把版面撑开。
   ⚠️ 2026-09-25 起两闸明细只渲染在详情页第 5 节，那里用的是 .raw；
   `.content-card .rawjson` 规则随列表卡片一起删除。 */

/* 回收数据表（table.recycle）的规则已在 2026-09-21 删除：那张表被并进
   第⑥步「回填」的结果行（见 content_page.go 的 stepBackfill），
   页面上不再有 table.recycle 元素。留着一套没人引用的规则会让后来者
   以为还有一个页面的表格靠它排版。 */

/* 「已降级图文」的提示胶囊。与 .pill.skip-pill 同一色系：它是"需要你知道"
   而不是"出错了"（降级是正常路径，见 internal/media）。 */
.pill.warn-pill { color: var(--warn); border-color: #6b5a20; }

/* 已发布整行降一档的规则见 table.content-list tr.row-published（列表重构后
   状态色从卡片移到行上）。 */

/* 动作区可能要放下"通过/驳回 + 理由框"三件东西，窄屏必须能折行。
   规则见上方 .detail-actions（操作区移进详情页后的作用域）。 */

/* 回填表单：G2 半自动的最后一步，人从平台后台抄数据回来。
   竖排 + 一行三个短数字（与人工录入表单的 .field-row 同一手法：
   窄屏自动折行，不做媒体查询也能用）。
   ⚠️ input 必须显式给底色：浏览器的默认控件是白底黑字，在近黑界面上
   会变成三个刺眼的亮块（.entry-form 里那一段也是为同一件事写的）。 */
.backfill-form {
  padding-top: 12px;
  border-top: 1px solid var(--line-soft);
  margin-top: 4px;
  flex-basis: 100%;
}
.backfill-form .field { margin-bottom: 10px; }
.backfill-form .field label { display: block; font-size: 12px; color: var(--text-dim); margin-bottom: 4px; }
.backfill-form .field label b { color: var(--accent); font-weight: 600; }
.backfill-form input {
  width: 100%;
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--r);
  color: var(--text);
  padding: 7px 9px;
  font-size: 13px;
  font-family: inherit;
}
.backfill-form input:focus { outline: none; border-color: var(--accent-dim); }
.backfill-form .btn { margin-right: 10px; }

/* —— 详情页第 7 节「投递与发布」的两个写入口（2026-09-25）——
   编辑表单从「操作」区挪到这一节（要编辑的就是上面那张表里的字段），
   入口用 <details> 而不是 JS 弹层：没有 JS 也能开合，与 Scout 签的
   「人工录入线索」同一取舍。summary 直接复用 .btn 的样式（它是按钮的样子，
   而 list-style 要显式去掉，否则 Safari 会在胶囊里多印一个三角）。 */
.pubedit { margin-top: 12px; }
.pubedit > summary { display: inline-flex; width: auto; list-style: none; cursor: pointer; user-select: none; }
.pubedit > summary::-webkit-details-marker { display: none; }
.pubedit .backfill-form { padding-top: 12px; margin-top: 8px; }

/* 撤销发布：危险动作，单独一行、与编辑入口分开（挤在一行上容易点错）。
   定义在 .inline 之后：两个类同权重，靠顺序覆盖它的 inline-flex。 */
.unpublish-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line-soft);
}

/* 驳回理由：与两个动作按钮同处一行，所以给一个能伸缩的宽度
   （flex-basis 220px 是"够写一句话"的下限，窄屏折行到按钮下面）。 */
.reject-reason {
  flex: 1 1 220px;
  min-width: 0;
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--r);
  color: var(--text);
  padding: 6px 10px;
  font-size: 12.5px;
  font-family: inherit;
}
.reject-reason:focus { outline: none; border-color: var(--accent-dim); }

/* ═══════════ 第四签：题目来源 / 热点快照 / 族群折叠 / 内容详情页 ═══════════
 *
 * 2026-09-24 新增（docs/16 §11.2 的三个缺口 + §11.3 详情页）。
 * 全部沿用既有的层次手段（字号、字距、留白、边框、单一强调色），不引新色——
 * 强调色只有一个（暖琥珀），再引一个会让"哪个才是要点"变得要靠猜。
 */

/* 题目来源徽标：与「选题类型」并列，但要能一眼分开（两个维度） */
.pill.pill-source { color: var(--accent); border-color: var(--accent-dim); }

/* 已进草稿箱：这是"人只需点发布"的状态，比一般投递档更值得被看到 */
.pill.pill-draft { color: var(--ok); border-color: #3d5f47; }

/* 超字数上限：它正是人判断"要不要退回重写"的依据，所以必须刺眼 */
.over-limit { color: var(--bad); }

/* 卡片头上那个「详情」链接：不要抢动作按钮的视线，做成次要按钮 */
.btn-detail { padding: 2px 8px; font-size: 12px; }

/* —— 热点判定快照（hot_ref）—— */

.origin {
  margin: 8px 0;
  padding: 8px 10px;
  border-left: 2px solid var(--accent-dim);
  background: var(--bg-sunken);
  border-radius: 0 var(--r) var(--r) 0;
}
.origin .note { margin: 0 0 6px; }

.hotref summary { cursor: pointer; color: var(--text-dim); font-size: 12.5px; }
.hotref summary:hover { color: var(--text); }

/* 五维打分：做成一行小格子，顺序与打分公式一致（D1→D5，权重递减） */
.dims { display: flex; flex-wrap: wrap; gap: 10px; margin: 8px 0; }
.dim {
  display: inline-flex; align-items: baseline; gap: 5px;
  padding: 3px 9px; border: 1px solid var(--line-soft); border-radius: var(--r);
  font-size: 12px;
}
.dim-name { color: var(--text-dim); }

/* 三选一对照：胜出者整行高亮，落选者保持暗色——复核"选得对不对"靠的是差距 */
.cands { list-style: none; margin: 6px 0; padding: 0; font-size: 12.5px; }
.cands li { display: flex; align-items: baseline; gap: 10px; padding: 3px 0; color: var(--text-dim); }
.cands li.cand-winner { color: var(--text); }

/* —— 族群折叠（content_group_id）——
 *
 * 列表侧的折叠 <details>（.group / .group-members）已随 2026-09-25 的列表
 * 重构删除：同款扇出现在只占一行，用编号旁的「+N」徽标表达，渠道变体在
 * 详情页第 3 节（table.variants）看。 */

/* 折叠前后的规模说明（"本页 20 条 → 折叠为 12 张卡"）：
   它的邻居是对不上号的两个数（分页器说条数、列表显示行数），所以用一个
   分隔符把它从"标题那一排"里分出来，别读成标题的一部分。 */
.group-note { padding-left: 8px; border-left: 1px solid var(--line-soft); }

/* —— 内容详情页（docs/16 §11.3）—— */

/* 每一节之间的分隔：详情页有 9 节，没有明确的分隔会读成一片 */
.dsec {
  margin: 0 0 18px;
  padding: 0 0 14px;
  border-bottom: 1px solid var(--line-soft);
}
.dsec:last-child { border-bottom: none; padding-bottom: 0; }
.dsec h3 {
  margin: 0 0 8px;
  font-size: 13px;
  letter-spacing: .04em;
  color: var(--text-dim);
  text-transform: none;
}

.detail-title { font-size: 16px; line-height: 1.5; margin: 0 0 6px; }

/* 渠道变体对照表 */
.variants { width: 100%; border-collapse: collapse; font-size: 12.5px; margin: 6px 0 8px; }
.variants th, .variants td {
  text-align: left; padding: 6px 8px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: top;
}
.variants th { color: var(--text-dim); font-weight: 500; }
/* 当前正在看的那一条要能一眼认出来（否则要在同族里数行） */
.variants tr.self { background: rgba(217, 139, 58, .07); }
.variants td.promo { max-width: 320px; color: var(--text-dim); }

/* 键值表（投递与发布那一节） */
.kv { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.kv th {
  width: 160px; text-align: left; padding: 5px 8px 5px 0;
  color: var(--text-dim); font-weight: 500; vertical-align: top;
  border-bottom: 1px solid var(--line-soft);
}
.kv td { padding: 5px 0; border-bottom: 1px solid var(--line-soft); }

/* 审计痕迹：事件流是"一行一件事"，用它自己的等宽字体读数最省事 */
.events { list-style: none; margin: 0; padding: 0; }
.events li { padding: 6px 0; border-bottom: 1px solid var(--line-soft); }
.events li:last-child { border-bottom: none; }
.events .small { margin-top: 2px; word-break: break-all; }

.viol-text { flex: 1 1 320px; }

/* ── 「新增内容」折叠表单（2026-09-25）──
   与 .entry / .script / .hotref 同一折叠视觉：▸/▾ 前缀、dim 色摘要。
   表单本体复用 .entry-form 的字段网格（与人工录入线索同一套）。 */
.newcontent { margin: 12px 0 4px; }
.newcontent summary {
  cursor: pointer;
  color: var(--text-dim);
  font-size: 12.5px;
}
.newcontent summary:hover { color: var(--text); }
.newcontent summary::before { content: "▸ "; color: var(--accent); }
.newcontent[open] summary::before { content: "▾ "; }
.newcontent .entry-form {
  margin-top: 10px;
  padding-top: 12px;
  border-top: 1px dashed var(--line-soft);
}

/* ── 第五签「系统设置」（2026-09-25）──
   每个设置项一个表单，字段网格复用 .entry-form（与人工录入线索同一套），
   它自带的 border-top 正好把相邻设置项分开——不需要新的分隔元素。
   .setting-actions 只负责把「保存」与「恢复默认」排成一行：
   两个按钮各占一行会让人读成两个独立操作，而后者只是前者的一个快捷值。 */
.setting-form > p { margin: 2px 0 0; }
.setting-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.setting-actions .btn { margin-top: 6px; }
/* 数值输入框不铺满整行：它的内容最多三位数，铺满会让"要填多少"看起来
   很宽（与 backfill 那三个计数框同一条理由，见上面 .backfill-form 的注释）。 */
.setting-form input[type="number"] { max-width: 120px; }

/* ── 卡面 A：视频「生成前确认」（P4a-3，docs/17 §9.1）──
   它是内容详情页第 4 节「素材」里的一块，不是独立的一节：素材的**来源**
   就在这一节说清（第 5/6/7 节分别是两闸、自检、投递，编号被
   content_approved 的结果码文案按名引用过——"回第 7 节「投递与发布」"，
   所以不能往中间插一节把号挪了）。
   子标题用 h4 而不是 h3：h3 是本节的标题，同号会把这一块读成并列的一节。 */
.vconf {
  margin: 12px 0 0;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--bg-sunken);
}
.vconf-head {
  margin: 0 0 6px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.vconf p { margin: 4px 0; }

/* 分辨率选择器：每一档一张卡，**全部展开**（不是下拉）。
   必须全部可见——每档下面那句 Note 是这张卡最不能省的字（480p 买的是
   "画面一致"，不是省钱），而 <select> 会把没选中的那些藏起来，
   于是人会以为三档只差价格。 */
.vres-list { display: flex; gap: 8px; flex-wrap: wrap; margin: 8px 0; }
.vres {
  flex: 1 1 240px;
  padding: 8px 10px;
  border: 1px solid var(--line-soft);
  border-radius: var(--r);
  cursor: pointer;
  background: var(--bg-panel);
}
.vres:hover { border-color: var(--accent-dim); }
/* :has() 让"选中的那一档"整张卡亮起来，而不是只有那个小圆点。
   它不支持时的降级是可接受的：圆点仍然是勾上的，只是少了强调边框。 */
.vres:has(input:checked) { border-color: var(--accent); background: rgba(217, 139, 58, .06); }
.vres input { margin-right: 6px; }
.vres .vres-name { font-weight: 500; }
.vres .vres-path { color: var(--text-dim); font-size: 12px; }
.vres .vres-note { color: var(--text-dim); font-size: 12px; margin: 4px 0 0; }
.vres .vres-price { color: var(--accent); font-size: 12px; margin: 4px 0 0; }

/* 下单按钮旁的价格：人按下按钮前最后看到的那一眼。
   无 JS 页面里它不会跟着时长输入框变——所以紧挨着它必须说清"按哪个数算的"
   （specNote 的活），否则一个不会变的数字迟早被当成"总价"。 */
.vconf-submit { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 6px; }
.vconf-price { color: var(--accent); font-size: 13px; }

/* 时长输入框不铺满整行（最多两位数，与大屏设置项同一条理由）。 */
.vconf input[type="number"] { max-width: 120px; }
.vconf-dur { margin: 8px 0; }
.vconf-dur label { font-size: 12px; color: var(--text-dim); }

/* 样片/终版播放器：宽度**不铺满**面板。竖屏视频铺满会变成一屏高的黑边，
   把下面的说明与按钮全推到看不见的地方——而"看完了要不要升级"正是紧接着
   要做的事。max-width 让它在竖屏下也不过分追高。 */
.asset-video {
  display: block;
  width: 100%;
  max-width: 260px;
  max-height: 460px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: #000;
}
