/* ============================================================
   完整版安全评估报告：A4 版式 + 左表单/右预览布局 + 打印导出
   屏幕上 .report-doc 缩放预览；打印时仅保留报告本体、恢复 1:1
   ============================================================ */

/* ---------- 左右布局 ---------- */
.rv-split {
  display: grid;
  grid-template-columns: 360px minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}

.rv-form {
  position: sticky;
  top: 16px;
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - var(--kb-top-h, 64px) - 32px);
  background: var(--ink-50);
  border: var(--border-soft);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.rv-form__in {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: var(--sp-5);
}
.rv-form__foot {
  flex: none;
  padding: var(--sp-4) var(--sp-5);
  border-top: var(--border-soft);
  background: #fff;
}
.rv-form__group + .rv-form__group { margin-top: var(--sp-5); }
.rv-form__cap {
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  color: var(--ink-500);
  letter-spacing: 0.4px;
  margin-bottom: var(--sp-3);
  padding-bottom: var(--sp-2);
  border-bottom: 1px dashed var(--ink-150);
}
.rv-form__group .field + .field { margin-top: var(--sp-3); }
/* 2026-10-08 老板反馈「同行输入框错位」：上面那条会误伤 form-grid 两列格的第二列
   （DOM 相邻即命中），导致同一行左右输入框高低差 8px —— grid 布局里由 gap 负责间距，
   格内的堆叠 margin 必须清零，且选择器更长以稳压上面那条。 */
.rv-form__group .form-grid .field + .field { margin-top: 0; }
.rv-form__group .form-grid { margin-top: var(--sp-3); }
.rv-form .textarea { min-height: 200px; font-family: var(--font-mono); font-size: var(--fs-xs); line-height: var(--lh-loose); }

/* ---------- ② 补齐信息：自然语言 → AI 识别并填充（2026-10-07 老板定） ----------
   界面纪律：这块是「一句话填表」，与下面的逐格表单是一回事，
   所以用品牌浅底 + 左侧色条做「入口感」，不抢表单的视觉权重。
   状态行单独占一行 —— 识别结果可能很长（填了几项 / 跳过几项 / 哪几项没采用），
   挤在按钮右边会撑成一行巨长的字。 */
.rv-aifill {
  margin: 0 0 var(--sp-5);
  padding: var(--sp-4) var(--sp-5);
  background: linear-gradient(180deg, var(--brand-50), #fff);
  border: 1px solid var(--brand-100);
  border-left: 3px solid var(--brand-400);
  border-radius: var(--r-lg);
}
.rv-aifill__hd { display: flex; gap: 10px; align-items: flex-start; }
.rv-aifill__icon {
  flex: none; width: 26px; height: 26px; border-radius: var(--r-md);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--brand-500); color: #fff;
}
.rv-aifill__tx { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.rv-aifill__tx b { font-size: var(--fs-base); color: var(--ink-900); }
.rv-aifill__tx > span { font-size: var(--fs-xs); color: var(--ink-600); line-height: var(--lh-normal); }
.rv-aifill__tx > span b { font-size: inherit; font-weight: var(--fw-semibold); color: var(--ink-800); }

/* 覆盖 .rv-form .textarea 的 200px 高度 —— 这里是一句话输入，不是配方粘贴框 */
.rv-aifill .textarea {
  margin-top: var(--sp-3);
  min-height: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  line-height: var(--lh-normal);
  background: #fff;
}
.rv-aifill__foot { display: flex; align-items: center; gap: var(--sp-3); margin-top: var(--sp-3); flex-wrap: wrap; }
.rv-aifill__status { flex: 1 1 240px; min-width: 200px; font-size: var(--fs-xs); color: var(--ink-500); line-height: var(--lh-normal); }
.rv-aifill__status.is-ok { color: var(--ok-700); }
.rv-aifill__status.is-warn { color: var(--warn-700); }

/* 使用方式判定的状态行
   2026-10-08 老板三次反馈「还是不对」的教训：自动判定必须让人看得见依据与失败原因，
   否则既可能判错、又根本查不出错在哪。这里把「判成什么 / 凭什么 / 为什么没判成」摊开。
   2026-10-09 老板定「手动重判按钮没有必要」已撤除 —— 判不对直接改下拉框即可，
   状态行本身保留（它承载 AI 的判定依据）。 */
.rv-method { display: flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-2); flex-wrap: wrap; }
.rv-method__status {
  flex: 1 1 200px; min-width: 160px;
  font-size: var(--fs-xs); line-height: var(--lh-normal);
  color: var(--ink-500);
}
.rv-method__status.is-ok { color: var(--ok-700); }
.rv-method__status.is-warn { color: var(--warn-700); }
.rv-aifill__hint {
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px dashed var(--brand-100);
  font-size: var(--fs-2xs);
  color: var(--ink-500);
  line-height: var(--lh-loose);
}

/* field 内联文字按钮（如「评估人」格的「去维护名单」）：块级按钮会把格子撑高，
   让同行两列的输入框失去水平对齐 —— 改成文字链后高度与普通 hint 一致。 */
.rv-linklike {
  background: none;
  border: none;
  padding: 0 0 0 4px;
  font: inherit;
  color: var(--brand-600);
  cursor: pointer;
}
.rv-linklike:hover { color: var(--brand-700); text-decoration: underline; }

/* ---------- 右栏 A4 预览 ---------- */
.rv-doc-wrap {
  min-height: 60vh;
  background: var(--ink-100);
  border-radius: var(--r-lg);
  padding: var(--sp-5) var(--sp-4);
  overflow: auto;
}
.rv-preview { display: flex; justify-content: center; }

/* ---------- 右栏：报告正文阅读区（内容页，不模拟 A4 纸） ---------- */
.rv-split--report { grid-template-columns: 320px minmax(0, 1fr); }
.rv-reader-wrap {
  display: grid;
  grid-template-columns: 196px minmax(0, 1fr);
  gap: var(--sp-4);
  align-items: start;
  min-width: 0;
}
.rv-reader__toc {
  position: sticky;
  top: 16px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--sp-3);
  background: var(--ink-50);
  border: var(--border-soft);
  border-radius: var(--r-md);
}
.rv-reader__toc-hd {
  display: flex; align-items: center; gap: 6px;
  padding: 0 4px var(--sp-2);
  font-size: var(--fs-2xs); font-weight: var(--fw-semibold); color: var(--ink-500);
  letter-spacing: 0.3px;
}
.rv-reader__toc-item {
  display: block; width: 100%;
  padding: 4px 6px; text-align: left;
  font-family: inherit; font-size: var(--fs-xs); color: var(--ink-600);
  background: none; border: none; border-radius: var(--r-sm); cursor: pointer;
}
.rv-reader__toc-item:hover { background: #fff; color: var(--brand-700); }
.rv-reader__toc-foot { margin-top: var(--sp-2); padding: var(--sp-2) 4px 0; border-top: 1px dashed var(--ink-150); font-size: var(--fs-2xs); color: var(--ink-400); }
.rv-reader {
  min-width: 0;
  background: #fff;
  border: var(--border-soft);
  border-radius: var(--r-lg);
  padding: var(--sp-6) clamp(24px, 4vw, 64px) var(--sp-8);
}

/* ---------- 报告正文（网页阅读版式） ---------- */
.rpt-doc {
  color: var(--ink-900);
  font-size: var(--fs-sm);
  line-height: 1.95;
  /* 水印层要盖在正文之上、正文要能选中阅读 → 用相对定位做叠放上下文 */
  position: relative;
}

/* ---------- 自助版免责声明（2026-10-09 定稿第三节） ----------
   免费档预览的「三层锁 + 满屏水印」已整段作废（报告只有完整版一种形态）。
   换来的是这两块：**首页声明**与**页脚留档**。

   为什么页脚要有编号：报告流出后要能回溯是哪一张券出的（客服对账用），
   只靠水印做不到 —— 水印能裁，编号是文本、跟着截图一起走。 */
.rpt-disc {
  margin: var(--sp-5) auto 0;
  max-width: 640px;
  padding: var(--sp-4) var(--sp-5);
  text-align: left;
  border: 1px solid var(--warn-300);
  border-left: 3px solid var(--warn-600);
  border-radius: var(--r-md);
  background: var(--warn-100);
}
.rpt-disc__t {
  display: block;
  margin-bottom: var(--sp-2);
  font-weight: var(--fw-semibold);
  color: var(--warn-700);
}
.rpt-disc__b {
  margin: 0;
  line-height: var(--lh-loose);
  font-size: var(--fs-xs);
  color: var(--ink-700);
}
.rpt-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-top: var(--sp-8);
  padding-top: var(--sp-3);
  border-top: var(--border);
  font-size: var(--fs-2xs);
  color: var(--ink-500);
}
.rpt-foot__no { font-variant-numeric: tabular-nums; }
.rpt-upnote {
  margin-top: var(--sp-2);
  text-align: center;
  font-size: var(--fs-2xs);
  color: var(--ink-500);
}

.rpt-doc__cover {
  text-align: center;
  padding-bottom: var(--sp-5);
  margin-bottom: var(--sp-6);
  border-bottom: 1px solid var(--ink-150);
}
.rpt-doc__title { margin: 0 0 6px; font-size: var(--fs-2xl); font-weight: var(--fw-semibold); letter-spacing: 4px; }
.rpt-doc__sub { margin-bottom: var(--sp-4); font-size: var(--fs-sm); letter-spacing: 2px; color: var(--ink-500); }

.rpt-sec { scroll-margin-top: 16px; }
.rpt-sec + .rpt-sec { margin-top: var(--sp-7); padding-top: var(--sp-6); border-top: 1px dashed var(--ink-150); }
.rpt-sec__t {
  margin: 0 0 var(--sp-4);
  padding-bottom: 6px;
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--ink-900);
  border-bottom: 2px solid var(--brand-600);
}
.rpt-doc p { margin: 0 0 var(--sp-3); text-align: justify; }
.rpt-doc p.mt { margin-top: var(--sp-3); }
/* 表题对齐 Word 版（2026-10-08 原件口径）：宋体加粗居中；--small 为非编号小节标题（左对齐） */
.rpt-sub { font-weight: var(--fw-semibold); margin-top: var(--sp-4); text-align: center; }
.rpt-sub--small { text-align: left; }
/* 表题居中加粗（对齐已备案 Word 版：表1/表2/表3） */
.rpt-tblcap { margin-top: var(--sp-4); text-align: center; font-weight: var(--fw-semibold); }
/* 第四章复配组分的续评段首行缩进（对齐 Word 版样张） */
.rpt-indent { text-indent: 2em; }
/* 目录页（对齐 Word 版封面后的「目　　录」页） */
.rpt-toc { margin: 0 0 var(--sp-5); }
.rpt-toc__t { margin: 0 0 var(--sp-3); text-align: center; font-size: var(--fs-lg); font-weight: var(--fw-semibold); letter-spacing: 6px; }
.rpt-toc__list { margin: 0; padding-left: 2.5em; line-height: 2.1; color: var(--ink-700); }
.rpt-note { font-size: var(--fs-xs); color: var(--ink-500); line-height: 1.7; }
.rpt-formula {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  line-height: 1.8;
  background: var(--ink-50);
  border: var(--border-soft);
  border-radius: var(--r-sm);
  padding: 8px 12px;
}
.rpt-item__head { font-weight: var(--fw-semibold); }
.rpt-comp { margin-bottom: 4px !important; }

/* 章内标注（红 = 不符合 / 缺口，黄 = 需人工核对） */
.rpt-flag {
  padding: 5pt 8pt;
  border-radius: 2pt;
  font-size: var(--fs-sm);
  line-height: 1.6;
}
.rpt-flag--block { background: #fdecec; border: 1px solid #e5a3a3; color: #a02020; }
.rpt-flag--gap { background: #fdf3e6; border: 1px solid #e8c795; color: #9a5b10; }
.rpt-flag--warn { background: #fffbe8; border: 1px solid #e6d788; color: #7a6a10; }

/* 表格（网页正文里仍按内容尺寸，不做 A4 固定列宽） */
.rpt-tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-xs);
  line-height: 1.6;
  margin: var(--sp-2) 0 var(--sp-4);
}
.rpt-tbl th, .rpt-tbl td {
  border: 1px solid var(--ink-200);
  padding: 5px 8px;
  text-align: left;
  vertical-align: top;
  word-break: break-word;
}
.rpt-tbl th { background: var(--ink-50); font-weight: var(--fw-semibold); text-align: center; }
.rpt-tbl td.num { text-align: right; font-variant-numeric: tabular-nums; }
.rpt-tbl--kv .rpt-k { width: 132px; background: var(--ink-50); color: var(--ink-600); white-space: nowrap; }
/* 封面表：只保留横向分隔线（与 Word 导出口径一致），须排在 .rpt-tbl 之后并提高优先级 */
.rpt-doc .rpt-cover__tbl { width: auto; min-width: 460px; margin: 0 auto; font-size: var(--fs-xs); }
.rpt-doc .rpt-cover__tbl td,
.rpt-doc .rpt-cover__tbl .rpt-k {
  border: none;
  border-bottom: 1px solid var(--ink-150);
  background: transparent;
  padding: 5px 10px;
  text-align: left;
}
.rpt-doc .rpt-cover__tbl .rpt-k { width: 168px; text-align: right; color: var(--ink-500); white-space: nowrap; }
.rpt-fill { height: 52px; }
.rpt-sign { height: 44px; }

/* 列表与参考文献 */
.rpt-ol { margin: 0 0 var(--sp-3); padding-left: 0; list-style: none; }
.rpt-ol li { margin-bottom: 6px; text-align: justify; padding-left: 2em; text-indent: -2em; }
.rpt-refs { margin: 0; padding-left: 0; list-style: none; font-size: var(--fs-xs); line-height: 1.9; }
.rpt-gaps { margin: 0 0 var(--sp-3); padding-left: 18px; font-size: var(--fs-xs); }
.rpt-gaps li { margin-bottom: 5px; }
.rpt-gaps__block { color: var(--danger-700); }
.rpt-gaps__gap { color: var(--warn-700); }
.rpt-gaps__warn { color: var(--warn-800, var(--warn-700)); }

/* 参考文献上标编号 */
.rpt-ref { font-size: var(--fs-2xs); vertical-align: super; line-height: 0; color: var(--brand-700); }

/* ---------- 打印兜底：Ctrl+P 时只留报告正文（正常导出请用「导出 Word 报告」） ---------- */
@media print {
  @page { size: A4 portrait; margin: 16mm 14mm; }
  html, body { background: #fff !important; }

  .shell > .sidebar,
  .rv-form,
  .rv-aifill,       /* AI 识别填充入口：作业工具，不进打印 */
  .rv-reader__toc,
  .rv-actbar,       /* 常驻操作条：不进打印 */
  .kb-rail { display: none !important; }

  .shell, .main, #viewport, .page,
  .rv-main, .rv-main__in,   /* 主区自成一屏（定高 + 内滚）在打印时解开 */
  .rv-split, .rv-reader-wrap, .rv-reader, #rv-preview,
  .rv-docpaper {
    display: block !important;
    overflow: visible !important;
    height: auto !important;
    max-height: none !important;
    min-height: 0 !important;
    padding: 0 !important;
    margin: 0 !important;
    background: none !important;
    border: none !important;
    box-shadow: none !important;
  }

  .rpt-sec + .rpt-sec { break-before: page; border-top: none; margin-top: 0; padding-top: 0; }
  .rpt-sec__t { break-after: avoid; }
  .rpt-tbl th { break-inside: avoid; }
  .rpt-tbl tr { break-inside: avoid; }
}

/* ============================================================
   三步主线新增部件：导入门户 / 名称待确认 / 两层配方表 /
   生成前检查 / 原料生产商 / 附件勾选 / 报告摘要
   ============================================================ */

/* 步骤条：未导入配方时后两步不可点 */
.tab.is-disabled { color: var(--ink-300); cursor: not-allowed; }
.tab.is-disabled:hover { color: var(--ink-300); }

/* ---------- 导入门户 ---------- */
/* 2026-10-05 老板定：自适应铺满 —— 去掉 1000px 上限，原来宽屏下右侧会空出一大块 */
.rv-portal { max-width: none; }
.rv-portal__hd h2 { margin: 0 0 var(--sp-2); font-size: var(--fs-lg); font-weight: var(--fw-semibold); color: var(--ink-900); }
.rv-portal__hd p { margin: 0 0 var(--sp-5); font-size: var(--fs-sm); line-height: var(--lh-loose); color: var(--ink-600); }

.rv-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-8) var(--sp-5);
  background: #fff;
  border: 2px dashed var(--ink-200);
  border-radius: var(--r-lg);
  text-align: center;
  transition: border-color 0.15s, background 0.15s;
}
.rv-drop.is-over { border-color: var(--brand-500); background: var(--brand-50); }
.rv-drop__icon { color: var(--brand-600); }
.rv-drop__main { font-size: var(--fs-md); font-weight: var(--fw-semibold); color: var(--ink-900); }
.rv-drop__sub { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-xs); color: var(--ink-500); }
.rv-drop__hint { font-size: var(--fs-2xs); color: var(--ink-400); }

.rv-paste { margin-top: var(--sp-4); background: #fff; border: var(--border-soft); border-radius: var(--r-md); padding: var(--sp-3) var(--sp-4); }
.rv-paste > summary { cursor: pointer; font-size: var(--fs-xs); color: var(--ink-700); font-weight: var(--fw-medium); }
.rv-paste .textarea { margin-top: var(--sp-3); font-family: var(--font-mono); font-size: var(--fs-xs); }
.rv-paste__foot { display: flex; align-items: center; gap: var(--sp-3); margin-top: var(--sp-3); }

.rv-cols { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); margin-top: var(--sp-5); }
.rv-col { background: var(--ink-50); border: var(--border-soft); border-radius: var(--r-md); padding: var(--sp-4); }
.rv-col__hd { display: flex; align-items: center; gap: 6px; font-size: var(--fs-xs); font-weight: var(--fw-semibold); color: var(--ink-800); margin-bottom: var(--sp-3); }
.rv-col__row { display: flex; gap: var(--sp-3); padding: 5px 0; border-top: 1px dashed var(--ink-150); font-size: var(--fs-xs); line-height: var(--lh-normal); }
.rv-col__row:first-of-type { border-top: none; }
.rv-col__row > b { flex: none; width: 168px; color: var(--ink-800); font-weight: var(--fw-medium); }
.rv-col__row > span { color: var(--ink-500); }
/* 长标签行改上下排，避免把说明压成窄条 */
.rv-col__row--wide { flex-direction: column; gap: 2px; }
.rv-col__row--wide > b { width: auto; }

/* ---------- 来源条 ---------- */
.rv-src {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 10px var(--sp-4);
  background: var(--brand-50);
  border: 1px solid var(--brand-200, var(--ink-150));
  border-radius: var(--r-md);
  font-size: var(--fs-xs);
}
.rv-src__main { display: flex; align-items: center; gap: var(--sp-2); color: var(--ink-800); min-width: 0; }
.rv-src__main b { font-weight: var(--fw-semibold); }
.rv-src__sheet { padding: 1px 6px; background: #fff; border: var(--border-soft); border-radius: var(--r-sm); font-size: var(--fs-2xs); color: var(--ink-600); }
.rv-src__acts { margin-left: auto; display: flex; gap: var(--sp-2); }

/* ---------- 名称待确认（置顶，候选横排） ---------- */
.rv-pick {
  margin-top: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  background: var(--warn-50, #fdf8ec);
  border: 1px solid var(--warn-200, var(--warn-300));
  border-radius: var(--r-md);
}
.rv-pick__hd { display: flex; align-items: center; gap: 6px; font-size: var(--fs-xs); color: var(--warn-800, var(--ink-800)); margin-bottom: var(--sp-2); }
.rv-pick__row { display: flex; gap: var(--sp-3); align-items: flex-start; padding: var(--sp-2) 0; border-top: 1px dashed var(--ink-150); }
.rv-pick__src { flex: none; width: 180px; font-size: var(--fs-xs); color: var(--ink-700); }
.rv-pick__cands { display: flex; flex-wrap: wrap; gap: 6px; }
.rv-pick__item {
  display: inline-flex; flex-direction: column; align-items: flex-start;
  padding: 4px 8px; font-size: var(--fs-xs);
  background: #fff; border: 1px solid var(--ink-200); border-radius: var(--r-sm);
  cursor: pointer; text-align: left; font-family: inherit;
}
.rv-pick__item:hover { border-color: var(--brand-500); color: var(--brand-700); }
.rv-pick__inci { font-size: var(--fs-2xs); color: var(--ink-400); font-family: var(--font-mono); }
.rv-pick__skip { padding: 4px 8px; font-size: var(--fs-2xs); color: var(--ink-500); background: none; border: none; cursor: pointer; text-decoration: underline; font-family: inherit; }

/* 选定即点亮（2026-10-07 老板三次定）：只变色 —— 不加对勾、不改字重，块尺寸与位置零变化；
   已指定行整体不再可点（改选请重新导入）。 */
.rv-pick__item.is-on {
  border-color: var(--brand-600); background: var(--brand-50); color: var(--brand-700);
  cursor: default;
}
.rv-pick__item.is-on:hover { border-color: var(--brand-600); }
.rv-pick__item.is-on .rv-pick__inci { color: var(--brand-600); }
.rv-pick__row.is-done .rv-pick__src { color: var(--ink-500); }
.rv-pick__row.is-done .rv-pick__item { cursor: default; }
.rv-pick__row.is-done .rv-pick__item:hover { border-color: var(--ink-200); }

/* ---------- 两层配方表 ---------- */
.rv-tbl-group > td { border-top: 1px solid var(--ink-200); }

/* ---------- 序号组之间的视觉分界（2026-10-08 老板定）
   老板反馈「希望不同序号原料之间的分界线明显一些，一眼就能区分该序号下是哪几个原料」；
   中途用过 2px 深灰横线 + 左侧 2px 竖线，老板评价「很丑陋」，已推翻。
   第一版只加深线条，问题是这张表是**密集核对表**（几十行），高对比粗线把表格切碎，
   读起来像一堆互不相干的横条，秩序感全无。

   现在改成**靠块面分层，而不是靠画线**：
     ① 组内组分之间：保持最淡的 1px ink-100 细线（几乎看不见，只做防串行）；
     ② 序号组第一行（.is-grp-top）：一条 1px ink-300 中性线 + 上方多留 6px 呼吸位 ——
        靠「留白」而不是「加粗」表达换组，这是印刷排版的常规做法，不喧宾夺主；
     ③ rowspan 合并的五列（序号/投料量/使用目的/报送码/生产商）整体用 ink-100 底色，
        组分行用 ink-25。两级都极淡，靠**色阶**而非线条勾出「这几行属于同一个序号」的竖向色块，
        眼睛顺着这块底色滑下来就知道这组有几个人。
   颜色语义（warn/bad 汇总色）优先级最高，写在后面，不被上述三层覆盖。
   CSS 没法跨行判断「组首行」，由 review.js 在渲染时直接打标。 */
.rv-tbl > tbody > tr > td { border-top: 1px solid var(--ink-100, #EFF2F0); }
.rv-tbl > tbody > tr.is-grp-top > td { border-top: 1px solid var(--ink-400, #8E9A95); }
.rv-tbl > tbody > tr.is-grp-top > td { padding-top: calc(var(--sp-3, 8px) + 5px); }
.rv-tbl .row-idx { vertical-align: middle; }

/* 2026-10-07 老板定：限量 / 阈值与数据缺口前置到本表 —— 有问题的原料整行标色，
   一眼看到「哪一条要处理」，不必再翻到第 2 段找缺口清单。
   红底＝超限 / 不符合；黄底＝须人工核对；红边＝有数据缺口（鼠标悬停看原因）。 */
.rv-tbl-group.is-bad > td { background: var(--danger-100); }
.rv-tbl-group.is-gap:not(.is-bad) > td { background: #FFF8F8; }
.rv-tbl-group.is-bad > td:first-child { box-shadow: inset 3px 0 0 var(--danger-500); }
.rv-tbl-group.is-gap > td:first-child { box-shadow: inset 3px 0 0 var(--danger-600); }
/* 限量 / 安全阈值单元格：上排＝数值，下排＝依据（表 3/4/5 与序号） */
.rv-lim { display: inline-flex; flex-direction: column; line-height: 1.35; }
.rv-lim i { font-style: normal; font-size: var(--fs-2xs); color: var(--ink-500); }
.rv-lim.is-bad { color: var(--danger-700); font-weight: var(--fw-semibold); }
.rv-lim.is-gap { color: var(--danger-700); font-weight: var(--fw-medium); border-bottom: 1px dotted var(--danger-600); cursor: help; }
.rv-lim.is-na { color: var(--ink-400); }
/* 复合限量条件（同类物质合计 / 分档 / 以某元素计）：**只给这一格黄底**，不染整行。
   老板 2026-10-08 定：「只需要限量/安全阈值处进行标黄处理即可，无需整行标黄」。
   黄底用 warn-100 而不是行级 warn —— 行级黄底铺满 10 列会把「这一格要合并计算」
   说成「这一条成分不可信」，是过度着色。 */
.rv-lim.is-warn {
  color: var(--warn-700); font-weight: var(--fw-medium); cursor: help;
  background: var(--warn-100); border-radius: var(--r-sm, 4px);
  padding: 2px 6px; margin-left: -6px;
}
.rv-lim.is-warn i { color: var(--warn-700); opacity: .85; }
/* 机构浓度（CIR / 境外限量）：非我国法定限量，视觉上与法定限值分开 */
.rv-lim.is-org { color: var(--ink-700); cursor: help; }
.rv-lim.is-org i { color: var(--ink-400); }
/* 2026-10-08 老板定：多家机构参照值并存时，给下拉框让用户自己选采用哪一家。
   选的值超过本配方添加量 → 黄底提示（不判不合规、不阻断导出）。 */
.rv-limsel {
  max-width: 100%; width: 100%;
  font: inherit; font-size: var(--fs-xs); line-height: 1.35;
  padding: 3px 6px; border: 1px solid var(--ink-300); border-radius: var(--r-sm, 4px);
  background: var(--surface, #fff); color: var(--ink-800); cursor: pointer;
}
.rv-limsel:hover { border-color: var(--brand-500, #2563eb); }
.rv-limsel:focus-visible { outline: 2px solid var(--brand-500, #2563eb); outline-offset: 1px; }
.rv-limsel.is-warn {
  border-color: var(--warn-500, #d97706); color: var(--warn-700, #92400e);
  background: var(--warn-100, #FCF1DC); font-weight: var(--fw-medium);
}
/* 已确认超法定限量（红）：下拉框本身也要红，否则「超限」这一行的唯一提示色没了 */
.rv-limsel.is-bad {
  border-color: var(--danger-600, #B32C2C); color: var(--danger-700, #8E2626);
  background: var(--danger-100, #FBEAEA); font-weight: var(--fw-medium);
}
/* ---------- 弹窗：为什么标黄 / 标红（2026-10-08 老板定，导入后自动弹一次） ----------
   老板反馈「以这个复配原料为例，你能告诉我标黄的原因是什么吗」——
   表格上一片黄底，评估人看不出是哪几行、为什么、该补什么资料。
   弹窗按**原因分类**分段，每段说清「是什么 / 为什么 / 怎么补」；
   同一复配原料下的多个组分合并成一行，避免 7 个组分刷 7 行。 */
.why-lead {
  padding: 9px 12px; margin-bottom: var(--sp-4);
  background: var(--ink-50); border: 1px solid var(--ink-200); border-radius: var(--r-sm);
  font-size: var(--fs-sm); color: var(--ink-700); line-height: 1.7;
}
.why-sec {
  padding: 10px 12px; margin-bottom: var(--sp-3);
  border-radius: var(--r-sm); border: 1px solid var(--ink-200);
  border-left-width: 3px;
}
.why-sec--bad { background: var(--danger-100, #FEF2F2); border-left-color: var(--danger-500); }
.why-sec--warn { background: var(--warn-100, #FFFBEB); border-left-color: var(--warn-500); }
.why-sec--noref { background: var(--ink-50); border-left-color: var(--ink-400); }
.why-sec__hd {
  display: flex; align-items: baseline; gap: var(--sp-2);
  font-size: var(--fs-sm); color: var(--ink-900); margin-bottom: var(--sp-2);
}
.why-sec__hd span { font-size: var(--fs-2xs); color: var(--ink-500); }
.why-list { margin: 0 0 6px; padding-left: 18px; }
.why-list li { font-size: var(--fs-xs); color: var(--ink-700); line-height: 1.8; }
.why-list b { color: var(--ink-900); }
.why-sec__fix {
  font-size: var(--fs-2xs); color: var(--ink-600); line-height: 1.7;
  padding-top: 6px; border-top: 1px dashed var(--ink-300);
}
.why-foot {
  margin-top: var(--sp-3); font-size: var(--fs-2xs); color: var(--ink-500); line-height: 1.7;
}

/* 复配组分行（2026-10-08：取消复配原料首行，改 rowspan 合并）。
   组分行整体压成浅灰以区别于单组分行；但「要处理」的行仍按 warn / bad 着底色，
   否则组分出了缺口、整组却还是白底，看着像正常项。
   rowspan 单元格一律纵向居中 —— 序号/投料量/报送码/生产商是整组属性，不该吊在第一行顶上。 */
.rv-tbl-comp > td { background: var(--white, #fff); color: var(--ink-600); font-size: var(--fs-2xs); }
/* 逐组分行着色（2026-10-08 老板反馈「整组 7 行全黄，只有 1 行有问题」）：
   每一行只按**自己这个组分**的状态上色 —— 一行有问题只染那一行，
   旁边正常的组分保持原底色。原先整组取最重色共用，一行的问题会把整组都染黄，
   真正要处理的那行反而被淹掉。 */
/* 逐组分行着色（2026-10-08 老板最终定调）：
   **黄色一律不上行** —— 只有「限量 / 安全阈值」那一格带黄底。
   黄色＝待办（缺资料 / 要合并计算 / 超参照），铺满 10 列会把「这一格要补」
   说成「这条成分有问题」，也会把真正出问题的那一行淹掉。
   **红色仍保留行级**：禁用 / 超法定限量＝已确认不合规，是阻断项，必须一眼看见。 */
.rv-tbl-comp.is-bad > td { background: var(--danger-100, #FBEAEA); }
.rv-tbl-comp.is-bad > td:first-child { box-shadow: inset 3px 0 0 var(--danger-500); }
/* rowspan 合并格（序号 / 投料量 / 使用目的 / 报送码 / 生产商）：**一律 neutral**。
   2026-10-08 老板否掉了「组内最重色汇总」——序号 15 那整列 5 行全黄，
   实际只有 1 个组分缺依据，这一大片黄是误导。合并五列现在只承载结构信息。 */
.rv-tbl-comp > td[rowspan] {
  vertical-align: middle; background: var(--ink-50, #F7F9F8);
  font-size: var(--fs-xs); color: var(--ink-700);
}
/* 组分名左对齐留白（不用 nth-child —— 合并后各行的列位置并不一致） */
.rv-tbl-comp > td.rv-comp-name { padding-left: var(--sp-5); text-align: left; }

/* ---------- 暴露参数：按产品属性带出参考值（2026-10-07） ---------- */
.rv-expose {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: 10px 12px; margin-bottom: var(--sp-4);
  background: var(--ink-50); border: 1px solid var(--ink-200); border-radius: var(--r-sm);
}
.rv-expose__tx { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.rv-expose__tx > b { display: inline-flex; align-items: center; gap: 5px; font-size: var(--fs-sm); color: var(--ink-900); }
.rv-expose__tx > span { font-size: var(--fs-xs); color: var(--ink-600); line-height: var(--lh-normal); }
.rv-expose__tx b b, .rv-expose__tx span b { font-weight: var(--fw-semibold); color: var(--ink-800); }
.rv-expose > .btn { flex: 0 0 auto; }

/* 评估人字段下沿的「去评估人管理维护名单」入口（与左侧常驻导航的评估人管理同一处） */
.rv-assessor-go { margin-top: 6px; }

/* 缺口列表末尾「另有 N 项原料级缺口见第 1 段配方表」的提示条 */
.rv-gapgrp__else {
  margin-top: var(--sp-3); padding: 7px 10px;
  background: var(--ink-50); border-left: 2px solid var(--ink-200);
  border-radius: var(--r-sm); font-size: var(--fs-2xs); color: var(--ink-600); line-height: var(--lh-normal);
}
.rv-gapgrp__else b { color: var(--ink-800); }

/* ---------- 生成前检查 / 缺口 ---------- */
.rv-check {
  padding: var(--sp-4) var(--sp-5);
  background: #fff;
  border: var(--border-soft);
  border-radius: var(--r-lg);
}
.rv-check__hd { display: flex; align-items: center; gap: 6px; font-size: var(--fs-xs); font-weight: var(--fw-semibold); color: var(--ink-800); margin-bottom: var(--sp-3); }
.rv-check__badge { margin-left: auto; padding: 1px 8px; border-radius: 99px; font-size: var(--fs-2xs); font-weight: var(--fw-medium); }
.rv-check__badge--ok { background: var(--ok-100, #e8f5ec); color: var(--ok-700); }
.rv-check__badge--warn { background: var(--warn-100, #fdf1dd); color: var(--warn-700); }
.rv-check__sub { margin: var(--sp-4) 0 var(--sp-2); padding-top: var(--sp-3); border-top: 1px dashed var(--ink-150); font-size: var(--fs-2xs); font-weight: var(--fw-semibold); color: var(--ink-500); letter-spacing: 0.3px; }
.rv-check__gaps { display: flex; flex-direction: column; gap: 6px; max-height: 46vh; overflow: auto; }
.rv-check__gap { display: flex; flex-direction: column; gap: 2px; padding: 6px 8px; border-left: 3px solid var(--ink-200); background: var(--ink-25, #fbfbfb); border-radius: 0 var(--r-sm) var(--r-sm) 0; }
.rv-check__gap b { font-size: var(--fs-xs); color: var(--ink-800); }
.rv-check__gap span { font-size: var(--fs-2xs); line-height: var(--lh-normal); color: var(--ink-500); }
.rv-gap--block { border-left-color: var(--danger-500); }
.rv-gap--warn { border-left-color: var(--warn-500); }
.rv-gap--gap { border-left-color: var(--info-500, var(--brand-400)); }
.rv-gap--ok { color: var(--ok-700); }
.rv-check__foot { display: flex; gap: var(--sp-2); margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: var(--border-soft); }

/* 表单必填 / 未填标记
   2026-10-08：必填由「必填」二字改为红色星号（表单通例，不挤占标签宽度）。
   星号用 aria-hidden —— 它是视觉提示，标签文本里另有「未填」承担语义提示。 */
.rv-req { margin-left: 3px; font-size: var(--fs-sm); line-height: 1; font-style: normal; color: var(--danger-600); }
.rv-miss { margin-left: 5px; font-size: var(--fs-2xs); font-style: normal; color: var(--warn-700); }

/* 使用方法行：下拉 + 「按产品名称判定」按钮并排 */
.rv-methodrow { display: flex; gap: var(--sp-2); align-items: center; }
.rv-methodrow .select { flex: 1 1 auto; min-width: 0; }

/* ---------- 原料生产商（2026-10-07 老板定：挪进核对表，第 10 列表内直填） ---------- */
.rv-tbl .rv-maker-in { width: 100%; min-width: 150px; height: 28px; font-size: var(--fs-xs); }

/* ---------- 附件勾选 ---------- */
.rv-docgrid { display: flex; flex-direction: column; gap: 4px; margin-top: var(--sp-3); }
.rv-doc { display: grid; grid-template-columns: 18px 1fr; gap: 2px 6px; padding: 5px 6px; border-radius: var(--r-sm); cursor: pointer; }
.rv-doc:hover { background: var(--ink-50); }
.rv-doc input { margin: 2px 0 0; grid-row: span 2; }
.rv-doc__nm { font-size: var(--fs-xs); color: var(--ink-800); }
.rv-doc__note { font-size: var(--fs-2xs); color: var(--ink-400); }

/* ---------- 报告信息摘要 ---------- */
.rv-sum { width: 100%; border-collapse: collapse; font-size: var(--fs-xs); }
.rv-sum td { padding: 5px 0; border-bottom: 1px dashed var(--ink-150); vertical-align: top; }
.rv-sum__k { width: 108px; color: var(--ink-500); white-space: nowrap; }
.rv-form__acts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--sp-3); }

/* 导入步：配方表占满整宽（列多且名称长），校验结果在其下 */
.rv-split--flat { grid-template-columns: minmax(0, 1fr); }
.rv-block { min-width: 0; }
/* ---------- 常驻操作条（三段共一条，钉在主区底边） ----------
   2026-10-07 老板定：「上一步 / 下一步应该常驻，不用翻动页面就能上一步下一步」。
   原来三段各自在正文末尾放一条 .rv-next（原样式已删），长页面里要滚到底才看得见。

   ⚠ 这里**不能用 position:sticky** —— sticky 只在元素跨过阈值时才吸附，
   元素还在视口下方时它老老实实待在文档流里，等于没常驻（第一版就是这么写的，
   截图里底边什么都没有）。真正常驻的做法：主区自成一屏（.rv-main 定高 + overflow:hidden），
   内容区 .rv-main__in 自己滚，本条在滚动区**之外** —— 于是它永远钉在主区底边。
   副作用：左栏章节高亮原先监听 #viewport 的 scroll，现改监听 [data-scroll-root]（见 main.js）。 */
/* ⚠ 类名是 .rv-actbar 不是 .rv-bar —— 本文件里 .rv-bar 早已被
   「降序排列」弹窗的含量占比条占用（height:6px 的细条，见下方「含量占比条」）。
   第一版重名，结果常驻条被那条规则压成 6px 细线（padding 撑到 25px），
   截图一眼看出不对。此类名一处一义，别再复用。 */
.rv-actbar {
  flex: none;
  display: flex; align-items: center; gap: var(--sp-4);
  padding: 12px var(--rv-pad-x);
  background: var(--white);
  border-top: var(--line);
  box-shadow: 0 -1px 3px rgba(16, 32, 27, .04);
}
.rv-actbar__note { display: flex; align-items: center; gap: 7px; min-width: 0; font-size: var(--fs-xs); color: var(--ink-600); }
.rv-actbar__note svg { flex: none; }
.rv-actbar__note > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rv-actbar__note--ok { color: var(--ok-700); }
.rv-actbar__note--danger { color: var(--danger-600); }
.rv-actbar__acts { margin-left: auto; display: flex; align-items: center; gap: var(--sp-2); flex: none; }
.rv-actbar__side { display: flex; align-items: center; gap: var(--sp-2); }
/* 2026-10-08 老板定：「上一步」必须一直在右半区，跨段落不许跳位。
   原来第 3 段套了 --split（space-between）把它甩到最左，第 1、2 段却在右边，
   同类按钮位置飘忽。现三段统一右对齐、顺序固定，上一步紧挨着排在操作区最左，
   整块贴右边 —— 从左到右恒为：上一步 → 清空 → 存草稿 → 主行动。 */

/* 2026-10-08 老板定：底条按钮**高度一致 + 按功能分色**。
   原来这里 btn / btn--sm / btn--primary 混排，高度和色相都不齐，看不出谁轻谁重。
   现统一走 .rv-actbar__acts 作用域：高度 32px 一档，字体字号一致，
   色相只承担一件事 —— 让用户一眼分出「导航 / 存档 / 危险 / 主行动」四类。 */
.rv-actbar__acts .btn { height: 32px; font-size: var(--fs-sm); }
/* 存档（保存草稿）：绿 —— 与「导出」区分开，导出是主行动，存档是备用 */
.rv-actbar__acts .btn--save { color: var(--ok-700); border-color: var(--ok-200, var(--ink-200)); background: var(--white); }
.rv-actbar__acts .btn--save:hover { background: var(--ok-100, var(--ink-50)); border-color: var(--ok-500, var(--ink-300)); }
/* 导航（上一步 / 下一步）：中性灰 —— 不是行动，只是换个页面 */
.rv-actbar__acts .btn--nav { color: var(--ink-600); background: var(--white); }
.rv-actbar__acts .btn--nav:hover { background: var(--ink-50); }
/* 危险（清空）：红描边 + 淡红底 —— 破坏性动作，一眼可辨，但不抢主行动的实心位 */
.rv-actbar__acts .btn--danger { color: var(--danger-600); border-color: var(--danger-200, var(--ink-200)); background: var(--white); }
.rv-actbar__acts .btn--danger:hover { background: var(--danger-100); border-color: var(--danger-500); }
/* 免费档的引导位（2026-10-08 会员机制）：暖金铜描边，与主行动的实心态明确区分，
   免得用户以为点它就能导出。用 --warn-* 是为了跟禁用语/设计稿那套告警色一致。 */
.rv-actbar__acts .btn--up { color: var(--warn-700, #8a5a1b); border-color: var(--warn-300, #e3c9a0); background: var(--warn-50, #fdf7ee); }
.rv-actbar__acts .btn--up:hover { background: var(--warn-100, #f9ecd9); border-color: var(--warn-500, #c99553); }
.rv-actbar__acts .btn--danger[aria-expanded="true"] { background: var(--danger-100); border-color: var(--danger-500); }

/* 清空菜单（单个按钮 + 点击弹出，2026-10-08 老板第二次定）
   第一版是「分裂按钮」：主按钮旁边另挂一个小箭头框，拼成两个视觉块。
   老板反馈"很割裂"——两个框反而不如一个框完整。改成一个按钮，点它弹菜单选范围。 */
.rv-menu { position: relative; display: inline-flex; }
.rv-menu > .btn { gap: 6px; }
.rv-menu > .btn svg:last-child { opacity: .65; margin-left: -2px; }
.rv-menu__pop {
  position: absolute; right: 0; bottom: calc(100% + 6px);
  min-width: 268px; padding: 4px;
  background: var(--white); border: var(--border); border-radius: var(--r-md);
  box-shadow: 0 6px 20px rgba(16, 32, 27, .12);
  display: flex; flex-direction: column; gap: 2px; z-index: 20;
}
.rv-menu__pop[hidden] { display: none; }
.rv-menu__item {
  display: flex; align-items: flex-start; gap: 8px; width: 100%;
  padding: 7px 8px; border: 0; border-radius: var(--r-sm);
  background: transparent; text-align: left; cursor: pointer; color: var(--ink-700);
  font-size: var(--fs-xs); line-height: 1.45;
}
.rv-menu__item:hover { background: var(--ink-50); }
.rv-menu__item svg { flex: none; margin-top: 1px; color: var(--ink-500); }
.rv-menu__item span b { display: block; font-weight: 400; color: var(--ink-500); font-size: var(--fs-2xs); }

/* 标签文案：含量显示 */
.sort-conc { margin-left: auto; font-size: var(--fs-2xs); color: var(--ink-400); }

/* ---------- 报告内新增部件 ---------- */
.rpt-comp { margin: 0 0 6pt; text-align: justify; }
.rpt-tag { margin-left: 6pt; padding: 0 4pt; font-size: var(--fs-2xs); border: 0.5pt solid #999; border-radius: 2pt; }
.rpt-tag--has { color: #1c6b3a; border-color: #9ccfaf; }
.rpt-tag--need { color: #9a5b10; border-color: #e0c08a; }

/* 窄屏兜底 */
@media (max-width: 1280px) {
  .rv-split--flat { grid-template-columns: minmax(0, 1fr); }
  .rv-cols { grid-template-columns: 1fr; }
}

/* 减少动效偏好：本页无动画，仅保证 zoom 预览不受影响 */
@media (prefers-reduced-motion: reduce) {
  .rv-form, .rv-doc-wrap { transition: none; }
}


/* ============================================================
   三段式骨架（2026-10-05 重排，老板定「保留三段式 + 减少重复」）
   ------------------------------------------------------------
   三段 tab 形态不动，改的是**内容归属**：每条内容只归一段管。
     ① 导入配方与核对 → 只管「配方本身对不对」
     ② 补齐安评信息 → 只管「申报资料齐不齐」
     ③ 生成安评报告 → 只管「报告成品」
   总判据（能否导出）由常驻操作条 .rv-bar 表达，**三段共用、只出现一次**。
   ============================================================ */

/* ---------- 顶部横排步骤条：2026-10-07 撤掉 ----------
   页面改两段式后，导航移到左栏（.rv-railseg）。原 .rv-steps / .rv-steps__*
   的 tab 样式随之停用；此处保留记录，避免日后被当成"定义了没人用"而误删后
   又需要回退。回退做法：恢复本段样式 + reviewPage 里的 <div class="rv-steps">。 */

/* ---------- 页头结论卡：2026-10-09 整体撤除 ----------
   老板定「这个功能区块去掉」—— 它横在正文最上方占一条，且「能否导出」的判据
   在左栏、配方表标红行、操作条按钮状态里都已能读到。相关类 .rv-hero / __top /
   __title / __acts / __line 一并不再用，样式删除，避免日后被当成"定义了没人用"误判。 */

/* ---------- 分段正文：单栏通栏（表格宽，不做双栏挤窄） ---------- */
.rv-docbody { padding-bottom: var(--sp-8); }

/* ---------- 归属徽章：标出「这条内容归哪段管」 ---------- */
.rv-own {
  display: inline-flex; align-items: center; flex: none;
  font-size: var(--fs-2xs); font-weight: var(--fw-medium);
  padding: 1px 7px; border-radius: var(--r-sm); white-space: nowrap;
}
.rv-own--1 { background: var(--info-100); color: var(--info-700); }
.rv-own--2 { background: var(--warn-100); color: var(--warn-700); }
.rv-own--3 { background: var(--brand-50); color: var(--brand-700); }

/* ---------- 段末交接条 .rv-handover：2026-10-07 撤掉 ----------
   老板定「这个区块完全没有必要」：它写的「这段到此为止 / 下一段管什么」
   与左栏阶段名、页面各节标题重复，且横在正文末尾挡视线。
   「下一步做什么」现在由常驻操作条（.rv-actbar）承担，翻不翻页都看得见。
   样式与 DOM 一并删除，不留无引用定义。 */

/* ---------- 待补资料：按主题归并的折叠组（替代逐条平铺） ---------- */
.rv-gapgrps { border: var(--border-soft); border-radius: var(--r-lg); background: var(--white); overflow: hidden; }
.rv-gapgrp { border-bottom: var(--line-soft); }
.rv-gapgrp:last-child { border-bottom: none; }
.rv-gapgrp > summary {
  display: flex; align-items: center; gap: var(--sp-3); cursor: pointer; list-style: none;
  padding: 10px var(--sp-4); font-size: var(--fs-sm); color: var(--ink-800);
}
.rv-gapgrp > summary::-webkit-details-marker { display: none; }
.rv-gapgrp > summary:hover { background: var(--ink-50); }
.rv-gapgrp__sev { flex: none; }
.rv-gapgrp__n { font-weight: var(--fw-medium); }
.rv-gapgrp__c {
  margin-left: auto; display: flex; align-items: center; gap: var(--sp-3); flex: none;
  font-size: var(--fs-2xs); color: var(--ink-400);
}
.rv-gapgrp__c i { font-style: normal; color: var(--brand-700); }
.rv-gapgrp[open] > summary { border-bottom: var(--line-soft); background: var(--ink-50); }
.rv-gapgrp__body { padding: var(--sp-3) var(--sp-4) var(--sp-4); background: var(--white); }

/* ---------- 报告章节就绪表：2026-10-07 撤掉（老板定：撤页头「章节状态」入口，
   也就没有第二处口径）。.rv-chgoto 随之一并删除，不留无引用定义。 ---------- */

/* ---------- 报告正文（第 3 段）：这一页本身就是报告内页 ----------
   2026-10-07 起主区不再并排第二处目录 —— 目录在左栏（.rv-rail .rv-railch，
   可点滚动 + 滚动高亮），正文独占主区，形制与原料百科详情页一致。
   原 .rv-docwrap / .rv-doctoc 的并排目录随之停用（与左栏重复）。 */
.rv-docpaper { min-width: 0; background: var(--white); border: var(--border-soft); border-radius: var(--r-lg); padding: var(--sp-6) clamp(24px, 3.5vw, 56px) var(--sp-7); }

/* ---------- 配方表防竖排兜底（2026-10-05） ----------
   复配原料名可能是较长商品名，若不限宽会被 INCI 列挤成 1 字宽 → 中文逐字竖排。
   处置：名称列限宽 + 允许在分隔符处断行，但绝不逐字断。 */
.rv-tbl td:first-child + td,
.rv-tbl td.strong {
  max-width: 260px;
  word-break: normal;
  overflow-wrap: break-word;
  line-break: auto;
}

/* ==================== tab1 弹窗 + 功能框（2026-10-07） ====================
   老板定：判定明细不再平铺在 tab1 页面上，一律收进弹窗 —— 页面只留配方本身。
   弹窗状态存在 state.rvModal 里，重画后仍在（选名称、复制文案不会把窗口关掉）。 */

/* ---------- 名称待确认：状态条 ---------- */
.rv-pend {
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 var(--sp-4); padding: 10px 14px;
  border: 1px solid var(--warn-300); border-radius: var(--r-md);
  background: var(--warn-100);
}
.rv-pend--ok { border-color: #BEE3CD; background: var(--ok-100); }
.rv-pend__ic { flex: none; display: grid; place-items: center; color: var(--warn-700); }
.rv-pend--ok .rv-pend__ic { color: var(--ok-600); }
.rv-pend__tx { flex: 1; min-width: 0; font-size: var(--fs-xs); color: var(--ink-700); line-height: 1.7; }
.rv-pend__tx b { margin-right: 6px; color: var(--ink-900); }

/* ---------- 功能框 ---------- */
/* 2026-10-07：四个工具框从页面末尾提到**配方表上方**（老板定「常用的放上面，
   放底部不易察觉」），因此需要与下面的「导入核对」小节拉开距离。 */
.rv-tools { display: grid; grid-template-columns: repeat(auto-fit, minmax(238px, 1fr)); gap: var(--sp-4); margin: 0 0 var(--sp-6); }
.rv-tool {
  display: flex; align-items: center; gap: 10px; text-align: left;
  padding: 13px 14px; border: var(--line); border-radius: var(--r-md);
  background: var(--white); cursor: pointer; font-family: inherit;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.rv-tool:hover { border-color: var(--brand-400); background: var(--brand-50); }
.rv-tool__ic {
  width: 32px; height: 32px; border-radius: var(--r-md); flex: none;
  display: grid; place-items: center;
  background: var(--brand-50); border: 1px solid var(--brand-100); color: var(--brand-600);
}
.rv-tool__tx { flex: 1; min-width: 0; }
.rv-tool__n { display: block; font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--ink-900); }
.rv-tool__s { display: block; margin-top: 2px; font-size: var(--fs-2xs); color: var(--ink-500); }
.rv-tool__c { flex: none; font-size: var(--fs-2xs); color: var(--ink-400); font-variant-numeric: tabular-nums; }
/* 就地开关态（降序排列开启时）：与页面主色一致的高亮，一眼看出当前排序状态 */
.rv-tool.is-on { border-color: var(--brand-500, #0e5748); box-shadow: 0 0 0 1px var(--brand-500, #0e5748) inset; background: var(--brand-50); }
.rv-tool.is-on .rv-tool__s { color: var(--brand-600, #0e5748); }

/* ---------- 弹窗外壳 ---------- */
.rv-modal {
  position: fixed; inset: 0; z-index: 120;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 52px 24px 40px; overflow-y: auto;
  background: rgba(17, 26, 23, .38);
}
.rv-modal__box {
  display: flex; flex-direction: column; width: 100%; max-width: 780px;
  max-height: calc(100vh - 92px);
  background: var(--white); border: 1px solid var(--ink-200); border-radius: var(--r-lg);
  box-shadow: 0 18px 48px rgba(16, 32, 27, .22);
}
.rv-modal__box--wide { max-width: 1160px; }
.rv-modal__hd { flex: none; display: flex; align-items: flex-start; gap: var(--sp-4); padding: 14px 18px; border-bottom: var(--line); }
.rv-modal__tt { flex: 1; min-width: 0; }
.rv-modal__t { margin: 0; font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--ink-900); }
.rv-modal__s { display: block; margin-top: 3px; font-size: var(--fs-2xs); color: var(--ink-500); line-height: 1.6; }
.rv-modal__x {
  flex: none; width: 28px; height: 28px; border: none; border-radius: var(--r-md);
  display: grid; place-items: center; background: none; color: var(--ink-500); cursor: pointer;
}
.rv-modal__x:hover { background: var(--ink-100); color: var(--ink-900); }
.rv-modal__bd { padding: 16px 18px; overflow-y: auto; }
.rv-modal__ft {
  flex: none; display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
  padding: 11px 18px; border-top: var(--line); background: var(--ink-50);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
  font-size: var(--fs-2xs); color: var(--ink-500); line-height: 1.7;
}
.rv-modfoot-hint { font-size: var(--fs-2xs); color: var(--ink-500); }
.rv-modal .metrics { margin-bottom: var(--sp-5); }

/* ---------- 弹窗内文字整体调大（2026-10-07 老板反馈「文本字号有些小，看不清楚」）----------
   弹窗是阅读判定明细的主场所，统一抬一档：正文 14、表 13、辅助说明 12，脚注随之调大。 */
.rv-modal__bd { font-size: var(--fs-base); }
.rv-modal__bd .tbl { font-size: var(--fs-sm); }
.rv-modal__bd .tbl td { height: auto; padding-top: 7px; padding-bottom: 7px; }
.rv-modal__bd .text-11 { font-size: var(--fs-xs); }
.rv-modal__bd .text-12 { font-size: var(--fs-sm); }
.rv-modal__bd .mono-sm { font-size: var(--fs-sm); }
.rv-modal__s { font-size: var(--fs-xs); }
.rv-modal__ft { font-size: var(--fs-xs); }
.rv-modfoot-hint { font-size: var(--fs-xs); }
.rv-labeltext__hd { font-size: var(--fs-base); }
.rv-labeltext__l { font-size: var(--fs-base); }
.rv-labeltext__l--en { font-size: var(--fs-sm); }
.rv-labeltext__note { font-size: var(--fs-xs); }

/* ---------- 弹窗内的小节 / 脚注 ---------- */
.rv-modsub {
  margin: var(--sp-5) 0 var(--sp-3); padding-bottom: 5px;
  border-bottom: var(--line);
  font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--ink-700);
}
.rv-modsub:first-child { margin-top: 0; }
.rv-modnote { margin-top: var(--sp-3); font-size: var(--fs-xs); color: var(--ink-500); line-height: 1.8; }
.rv-modnote b { color: var(--ink-700); }

/* ---------- 弹窗·法规要求行着色（2026-10-07 老板定） ----------
   这块是重要提醒：强制项（禁用 / 超限）红底，标签警示等提醒项黄底，正常项不铺色。 */
.rv-modal .check-row { padding: 9px 12px; border-radius: 6px; }
.rv-modal .check-row--fail { background: var(--danger-100); }
.rv-modal .check-row--warn { background: var(--warn-100); }

/* ---------- 弹窗内的名称选择 ---------- */
.rv-pick--modal { margin: 0; padding: 0; border: none; background: none; }
.rv-pick--modal .rv-pick__row:first-child { border-top: none; }
.rv-pick__conc { margin-left: 8px; font-size: var(--fs-2xs); color: var(--ink-500); }

/* ---------- 标签成分弹窗的文案块 ---------- */
.rv-labeltext { padding: 16px 18px; border: var(--line); border-radius: var(--r-md); background: var(--white); }
.rv-labeltext__hd { font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--ink-900); }
.rv-labeltext__hd--mt { margin-top: var(--sp-6); }
.rv-labeltext__l { margin-top: 6px; font-size: var(--fs-sm); color: var(--ink-800); line-height: 1.95; word-break: break-word; }
.rv-labeltext__l--en { color: var(--ink-500); font-family: var(--font-mono); font-size: var(--fs-xs); }
.rv-labeltext__note { margin-top: var(--sp-5); font-size: var(--fs-2xs); color: var(--danger-600); line-height: 1.7; }

/* ---------- 含量占比条 ---------- */
.rv-bar { height: 6px; background: var(--ink-100); border-radius: var(--r-full); overflow: hidden; }
.rv-bar__f { height: 100%; background: var(--brand-400); border-radius: var(--r-full); }

/* 窄屏：弹窗占满 */
@media (max-width: 720px) {
  .rv-modal { padding: 20px 12px; }
  .rv-modal__box, .rv-modal__box--wide { max-width: none; }
  .rv-tools { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================
   两段式骨架（2026-10-07 落地）
   ------------------------------------------------------------
   老板定「与原料百科 / 法规百科 / 标准库内页同形制」：
   左栏 250px + 主区，骨架直接复用三库详情页的 .kb-art2 / .kb-rail /
   .kb-rail__in / .kb-rail__hd / .kb-railitem（零分叉），
   这里只补本页特有的几块：品牌头、进度条、阶段条、章节目录、主区留白。
   ============================================================ */
.rv-page { padding: 0; }
.rv-rail { border-right: var(--line-soft); }

.rv-railbrand { padding: 0 2px 10px; margin-bottom: 12px; border-bottom: var(--line-soft); }
.rv-railbrand b { display: block; font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--ink-900); }
.rv-railbrand span { display: block; margin-top: 2px; font-size: var(--fs-2xs); color: var(--ink-400); }

.rv-prog { margin: 0 2px 14px; }
.rv-prog__bar { height: 5px; background: var(--ink-150); border-radius: var(--r-full); overflow: hidden; }
.rv-prog__fill { height: 100%; background: var(--brand-600); border-radius: var(--r-full); transition: width 260ms var(--t-base); }
.rv-prog__tx { display: flex; justify-content: space-between; gap: 8px; margin-top: 6px; font-size: var(--fs-2xs); color: var(--ink-500); }
.rv-prog__tx b { color: var(--ink-800); font-weight: var(--fw-medium); }

/* 阶段条 / 章节目录：沿用 .kb-railitem 的形制，只补按钮自身的重置与排布 */
.rv-railseg, .rv-railch {
  width: 100%; text-align: left; font: inherit;
  border: none; border-left: 2px solid transparent; background: none;
}
.rv-railseg { align-items: center; padding: 7px 5px; }
.rv-railseg__tx { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rv-railseg--lock { opacity: .45; cursor: not-allowed; }
.rv-railseg--lock:hover { background: none; color: var(--ink-600); }

.rv-railch { padding: 4px 5px; }
.rv-railch__n { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 主区：卡片工作台放在页面底色上，卡片边界才看得出来
   （三库主区是白底读文档，那是阅读形态，与工作台不同）。

   2026-10-07：主区改成**自成一屏**（定高 + overflow:hidden），内容区 .rv-main__in
   自己滚 —— 为了底部的常驻操作条（.rv-actbar）真正常驻（理由见 .rv-actbar 注释）。
   不等宽限制照旧：2026-10-05 老板定「页面一律自适应铺满，宽屏下右侧不留白」。 */
.rv-main {
  --rv-pad-x: 30px;
  --rv-pad-b: 44px;
  background: var(--ink-50);
  display: flex; flex-direction: column;
  height: calc(100vh - var(--topbar-h));
  overflow: hidden;
}
.rv-main__in {
  flex: 1; min-height: 0; overflow-y: auto;
  padding: 22px var(--rv-pad-x) var(--rv-pad-b);
}

/* 中屏以下：左栏塌到顶部（与三库详情页同一套回退） */
@media (max-width: 1000px) {
  .rv-page .kb-art2 { grid-template-columns: minmax(0, 1fr); }
  .rv-rail { border-right: none; border-bottom: var(--line-soft); }
  .rv-rail .kb-rail__in { position: static; max-height: none; }
  /* 窄屏：左栏塌到主区上方，主区不再固定一屏（否则左栏一屏 + 主区一屏会双滚动），
     退回全局滚动；底条用 sticky 兜底，不再是钉底常驻。 */
  .rv-main { --rv-pad-x: 18px; --rv-pad-b: 28px; height: auto; overflow: visible; }
  .rv-main__in { flex: none; overflow: visible; padding: 16px var(--rv-pad-x) var(--rv-pad-b); }
  .rv-actbar { position: sticky; bottom: 0; z-index: 12; }
}

/* 复合限量但条文有数值（如「总量1%（以锌计)」）：数值照常显示，只是角标提示不自动判。
   与 is-warn 的区别是左侧加一道竖线，提示「这个数字不是本原料用量」。 */
.rv-lim.is-warn.is-basis { box-shadow: inset 2px 0 0 var(--warn-600); padding-left: 7px; }

/* 查不到任何限量/使用浓度依据（老板 2026-10-08 定：标黄，不标红）。
   黄＝「缺依据、要补资料」，与「须核对」同级；
   红＝已确认的问题（禁用原料 / 超限量），两者语义不同，不可混用。
   绝不把「没查到」渲染成「不安全」——配方里常有几成原料查不到阈值。
   与 .rv-lim.is-warn 同样只染**这一格**，不牵整行。 */
.rv-lim.is-noref {
  color: var(--warn-700); font-weight: var(--fw-medium); cursor: help;
  background: var(--warn-100); border-radius: var(--r-sm, 4px);
  padding: 2px 6px; margin-left: -6px;
}
.rv-lim.is-noref i { color: var(--warn-700); opacity: .85; font-style: normal; }
