:root {
  /* ---------- 基础 ---------- */
  --bg: #f4f6fa;
  --surface: #ffffff;
  --border: #e6e9f1;
  --text: #0f172a;
  --muted: #5b6472;
  --primary: #0ea5e9;
  --primary-2: #2563eb;
  --primary-dark: #0284c7;

  --red: #ef4444;
  --shadow: 0 1px 2px rgba(15,23,42,0.04), 0 8px 24px rgba(15,23,42,0.06);
  /* 顶栏是 sticky 的，所有吸顶元素都要让开它的高度；改由 JS 量出来真实值 */
  --topbar-h: 64px;

  /* ---------- 字号尺度（8 档，不要再加） ----------
     micro=极小徽标/脚注  label=表单标签  small=辅助文字  body=正文
     lead=强调  h3=小节标题  h2=区块标题  h1=报告主标题 */
  --fs-micro: 11px;   /* 徽标/脚注：屏幕可见下限 */
  --fs-label: 12px;   /* 表单标签、辅助说明 */
  --fs-small: 13px;   /* 提示、次要信息 */
  --fs-body: 14px;    /* 正文、输入框、按钮 */
  --fs-lead: 15px;    /* 强调正文 */
  --fs-h3: 17px;
  --fs-h2: 20px;
  --fs-h1: 26px;
  --lh-h: 1.25;
  --lh-label: 1.35;
  --lh-body: 1.5;
  --lh-print: 1.45;

  /* ---------- 圆角尺度（3 档 + 全圆） ---------- */
  --r-card: 16px;
  --r-control: 10px;
  --r-chip: 6px;
  --r-pill: 999px;

  /* ---------- 间距尺度（4 的倍数） ---------- */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;

  /* ---------- 语义色：文字 vs 填充分开 ----------
     文字色一律达成 4.5:1（见 tools/contrast-check.js），用于小字；
     填充色用于色块/徽标底，配白字也要达 4.5:1。 */
  --link: #1d4ed8;
  --link-hover: #1e40af;
  --danger-text: #b91c1c;
  --warn-text: #92400e;
  --warn-bg: #fffbeb;
  --warn-border: #fcd34d;
  --ok-text: #065f46;
  --ok-bg: #ecfdf5;
  --ok-border: #a7f3d0;
  --danger-bg: #fef2f2;
  --danger-border: #fecaca;
  --info-bg: #eef6ff;
  --info-border: #dbeafe;
  /* 品牌渐变：必须整条都能承载白字（最差点 ≥5:1，见 tools/gradient-check.js） */
  --grad-from: #0e7490;
  --grad-to: #1d4ed8;

  /* 严重度：minor/moderate/major/critical */
  --sev-minor-text: #5b6472;
  --sev-minor-fill: #5b6472;
  --sev-minor-bg: #f1f5f9;
  --sev-moderate-text: #a34a06;
  --sev-moderate-fill: #b45309;
  --sev-moderate-bg: #fef3c7;
  --sev-major-text: #b03a0a;
  --sev-major-fill: #c2410c;
  --sev-major-bg: #ffedd5;
  --sev-critical-text: #b91c1c;
  --sev-critical-fill: #b91c1c;
  --sev-critical-bg: #fee2e2;

  /* 管况：good/fair/poor/critical */
  --cond-good-text: #047857;
  --cond-good-fill: #047857;
  --cond-fair-text: #b45309;
  --cond-fair-fill: #b45309;

  --cond-poor-fill: #c2410c;
  --cond-critical-text: #b91c1c;
  --cond-critical-fill: #b91c1c;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", Inter, sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: var(--lh-body);
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: 14px 28px;
  background: linear-gradient(120deg, #0b1220 0%, #16233f 60%, #1e293b 100%);
  border-bottom: 1px solid rgba(255,255,255,0.06);
  position: sticky;
  top: 0;
  z-index: 10;
}
/* 报告面板宽屏时给左栏目录留出空间（表格/证据图不会被挤窄） */
body.report-wide main { max-width: 1220px; }
.brand { display: flex; align-items: center; gap: 14px; }
.logo { display: inline-flex; }
.topbar h1 { margin: 0; font-size: var(--fs-h3); font-weight: 700; color: #fff; letter-spacing: -0.01em; }
.sub { margin: 0; color: #94a3b8; font-size: var(--fs-small); }
.badge {
  font-size: var(--fs-label);
  font-weight: 600;
  padding: 5px 12px;
  border-radius: var(--r-pill);
  background: rgba(14,165,233,0.14);
  color: #7dd3fc;
  border: 1px solid rgba(14,165,233,0.3);
  white-space: nowrap;
}
.badge.warn { background: rgba(245,158,11,0.14); color: var(--warn-border); border-color: rgba(245,158,11,0.3); }
/* 状态徽标可点：后端不可用时它就是"重试"入口 */
.badge-btn { font-family: inherit; cursor: pointer; }
.badge-btn:hover { background: rgba(14,165,233,0.24); }
.topbar-right { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; justify-content: flex-end; }
#draftBadge { background: rgba(16,185,129,0.16); color: #6ee7b7; border-color: rgba(16,185,129,0.32); }

main { max-width: 1080px; margin: 28px auto; padding: 0 16px; }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  padding: var(--sp-5) 28px;
  margin-bottom: var(--sp-5);
  box-shadow: var(--shadow);
}

/* 屏幕阅读器专用文本 / 程序化焦点不需要可见焦点环 */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
[tabindex="-1"]:focus { outline: none; }
/* 焦点样式只有一套规则：蓝色 2px 外描边 + 2px 偏移。
   深色背景（顶栏、吸底条、画布）上换成浅蓝，否则蓝环在深底上几乎看不见。 */
:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }
.topbar :focus-visible, .anno-stage :focus-visible, .lightbox-stage :focus-visible {
  outline-color: #7dd3fc;
}

h2 { font-size: var(--fs-h3); line-height: var(--lh-h); font-weight: 700; margin: 26px 0 10px; letter-spacing: -0.01em; }
.card > h2:first-child { margin-top: 0; }
.hint { font-weight: 500; color: var(--muted); font-size: var(--fs-label); }

.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--sp-3); }
label { display: block; font-size: var(--fs-small); line-height: var(--lh-label); font-weight: 600; color: var(--muted); }
input[type="text"], input[type="email"], input[type="password"], input[type="date"], textarea {
  display: block;   /* 千万别用 inline-block：会被父级的行内居中影响，各框按自身宽度各自居中 */
  width: 100%;
  margin-top: 5px;
  padding: var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--r-control);
  font-size: var(--fs-body);
  font-family: inherit;
  background: #fff;
  color: var(--text);
  transition: border-color .15s, box-shadow .15s;
}
input[type="text"]:focus, input[type="email"]:focus, input[type="password"]:focus, input[type="date"]:focus, textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(14,165,233,0.15);
}
textarea { resize: vertical; }

.checks { display: flex; flex-wrap: wrap; gap: var(--sp-2) 14px; }
.checks label {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--text);
  font-size: var(--fs-body);
  font-weight: 500;
  cursor: pointer;
  /* 现场戴手套勾选：命中区至少 32px，不能只靠 13px 的方块 */
  min-height: 32px;
  padding: 3px 2px;
}
.checks input {
  cursor: pointer;
  accent-color: var(--primary);
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
}

.evidence-ctrls { display: flex; gap: 10px; flex-wrap: wrap; }
.gallery { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-3); min-height: 20px; }
.gallery .item { position: relative; }
.gallery img { width: 120px; height: 84px; object-fit: cover; border-radius: var(--r-control); border: 1px solid var(--border); display: block; }
.gallery .cap { font-size: var(--fs-micro); color: var(--muted); text-align: center; margin-top: 3px; }
.gallery .del {
  position: absolute; top: -7px; right: -7px;
  width: 21px; height: 21px; border-radius: 50%;
  border: 2px solid #fff; background: var(--red); color: #fff;
  font-size: var(--fs-small); line-height: var(--lh-body); cursor: pointer;
}

.actions { display: flex; align-items: center; gap: 14px; margin-top: 22px; flex-wrap: wrap; }

/* 字段级校验：错误就显示在出错的输入框下面，不要攒到表单底部 */
.field-msg { display: none; margin-top: 5px; font-size: var(--fs-label); font-weight: 600; color: var(--red); }
.field-msg.show { display: block; }
input.field-invalid, textarea.field-invalid {
  border-color: var(--red) !important;
  box-shadow: 0 0 0 3px rgba(239,68,68,0.14) !important;
}
.req-link, .req-jump {
  background: none; border: none; padding: 0; font: inherit; cursor: pointer;
  color: var(--red); font-weight: 700; text-decoration: underline;
}
.kbd-hint kbd {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--fs-micro); padding: 1px 5px; border: 1px solid var(--border);
  border-bottom-width: 2px; border-radius: var(--r-chip); background: #f8fafc; color: var(--text);
}
.req-list { margin: 6px 0 0; padding-left: 18px; }
.req-list li { margin-bottom: 2px; }

/* Required fields, inline helpers, collapsible groups */
.req { color: var(--red); font-weight: 700; }
.inline-row { display: flex; gap: var(--sp-2); align-items: center; }
.inline-row input { flex: 1; }
.btn-mini {
  margin-top: 5px; padding: var(--sp-3); border-radius: var(--r-control); border: 1px solid var(--border);
  background: #fff; color: var(--text); font-size: var(--fs-body); cursor: pointer; font-family: inherit;
}
.btn-mini:hover { background: #f1f5f9; }
label.block { display: block; margin-top: 14px; }
label.block textarea { font-weight: 400; }
.req-msg { color: var(--red); }
.fold { margin-top: 14px; border: 1px dashed var(--border); border-radius: var(--r-control); padding: var(--sp-3) var(--sp-4); background: #fbfdff; }
.fold > summary { cursor: pointer; font-size: var(--fs-small); font-weight: 600; color: var(--muted); }
.fold .grid { margin-top: var(--sp-3); }
.notes-tools { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 8px 0 6px; }
.notes-tools .btn-secondary { padding: 7px 12px; font-size: var(--fs-small); }
#dictateState.live { color: var(--red); font-weight: 600; }

/* Video frame picker */
.frame-picker { border: 1px solid var(--border); border-radius: var(--r-control); padding: var(--sp-3) var(--sp-4); margin-top: var(--sp-3); background: #fbfdff; }
.frame-picker-head { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; justify-content: space-between; }
.frame-picker-head .btn-secondary { padding: 7px 12px; font-size: var(--fs-small); }
.frame-grid { display: flex; flex-wrap: wrap; gap: 10px; margin-top: var(--sp-3); }
.frame-card { border: 2px solid var(--border); border-radius: var(--r-control); padding: 4px; background: #fff; cursor: pointer; text-align: center; }
.frame-card img { width: 132px; height: 92px; object-fit: cover; border-radius: var(--r-chip); display: block; }
.frame-card .t { font-size: var(--fs-micro); color: var(--muted); margin-top: 3px; }
.frame-card.sel { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(14,165,233,0.15); }
.frame-picker-bar { margin-top: 10px; }
.frame-picker-bar .hint { font-weight: 600; }
.frame-picker-head .btn-primary { padding: 7px 12px; font-size: var(--fs-small); }

/* Editable evidence caption */
.gallery .cap-edit {
  width: 120px; margin-top: 4px; padding: 4px 6px; font-size: var(--fs-micro); font-family: inherit;
  border: 1px solid var(--border); border-radius: var(--r-chip); color: var(--text); background: #fff;
}
.gallery .cap-edit:focus { outline: none; border-color: var(--primary); }
.evidence-block .cap-edit-print { display: block; font-size: var(--fs-micro); color: var(--muted); margin-top: 2px; }

/* 顶部通知条：上传/下载/缓存异常要显眼，不能只写在一行小字里 */
.notice {
  position: relative;
  max-width: 960px; margin: 12px auto -12px; padding: 10px 44px 10px 16px; border-radius: var(--r-control);
  font-size: var(--fs-small); font-weight: 600; border: 1px solid;
}
.notice.error { background: var(--danger-bg); color: var(--danger-text); border-color: var(--danger-border); }
.notice.warn { background: var(--warn-bg); color: #92400e; border-color: var(--warn-border); }
.notice.ok { background: var(--ok-bg); color: var(--ok-text); border-color: var(--ok-border); }
.notice-close {
  position: absolute; top: 50%; right: 8px; transform: translateY(-50%);
  width: 24px; height: 24px; padding: 0; border-radius: 50%; cursor: pointer;
  border: 1px solid currentColor; background: transparent; color: inherit;
  font-size: var(--fs-lead); line-height: var(--lh-h); font-family: inherit; opacity: .7;
}
.notice-close:hover { opacity: 1; }
.notice-text { display: block; padding-right: 4px; }

/* QA banner (post-generation deterministic checks) */
.qa-banner {
  border: 1px solid var(--warn-border); background: var(--warn-bg); color: #92400e;
  border-radius: var(--r-control); padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-4); font-size: var(--fs-small);
}
.qa-banner strong { display: block; margin-bottom: 4px; }
.qa-banner ul { margin: 6px 0 0; padding-left: 20px; }
.qa-banner .qa-ok { color: var(--ok-text); }

/* Issue check（出具前预检） */
.issue-panel { border: 1px solid var(--border); border-radius: var(--r-control); padding: var(--sp-4); margin-bottom: var(--sp-4); font-size: var(--fs-small); background: #fbfdff; }
.issue-head { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-2); }
.issue-verdict { font-weight: 700; padding: var(--sp-1) var(--sp-3); border-radius: var(--r-pill); font-size: var(--fs-small); }
.issue-verdict.ok { background: var(--ok-bg); color: #047857; border: 1px solid var(--ok-border); }
.issue-verdict.bad { background: var(--danger-bg); color: var(--danger-text); border: 1px solid var(--danger-border); }
.issue-list { list-style: none; margin: 0; padding: 0; }
.issue-list li { padding: 6px 0; border-top: 1px dashed var(--border); display: flex; gap: var(--sp-2); align-items: flex-start; }
.issue-list li:first-child { border-top: none; }
.issue-lv { flex-shrink: 0; font-weight: 700; font-size: var(--fs-micro); border-radius: var(--r-chip); padding: 1px 7px; }
.issue-lv.error { background: var(--sev-critical-bg); color: var(--danger-text); }
.issue-lv.warning { background: var(--sev-moderate-bg); color: #92400e; }
.issue-lv.info { background: var(--info-bg); color: #075985; }
.issue-stats { color: var(--muted); font-size: var(--fs-label); }

/* 证据标注器 */
.modal { position: fixed; inset: 0; background: rgba(15,23,42,0.72); z-index: 60; display: flex; align-items: center; justify-content: center; padding: 18px; }
.modal-box { background: #fff; border-radius: var(--r-card); padding: var(--sp-4) var(--sp-5); max-width: 980px; width: 100%; max-height: 94vh; overflow: auto; }
.modal-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.modal-head strong { font-size: var(--fs-h3); }
.anno-tools { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 12px 0; }
.anno-tools select { padding: 6px 8px; font-size: var(--fs-small); margin-top: 0; }
.anno-tools .btn-secondary { padding: 7px 12px; font-size: var(--fs-small); }
.swatch { width: 26px; height: 26px; border-radius: 50%; border: 2px solid #fff; box-shadow: 0 0 0 1px var(--border); cursor: pointer; }
.swatch.active { box-shadow: 0 0 0 3px rgba(37,99,235,0.35); }
.swatch-red { background: var(--sev-critical-fill); }
.swatch-yellow { background: #facc15; }
.swatch-cyan { background: #22d3ee; }
.swatch-black { background: #111827; }
.anno-stage { background: #0b1220; border-radius: var(--r-control); padding: 8px; text-align: center; }
#annoCanvas { max-width: 100%; height: auto; touch-action: none; cursor: crosshair; border-radius: var(--r-chip); }
.modal-foot { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; margin-top: 14px; }
.evidence-thumb { position: relative; }
.evidence-thumb .badge-stored { position: absolute; left: 6px; bottom: 6px; font-size: var(--fs-micro); font-weight: 700; background: rgba(6,95,70,0.9); color: #fff; border-radius: var(--r-chip); padding: 1px 6px; }
.evidence-thumb .badge-local { position: absolute; left: 6px; bottom: 6px; font-size: var(--fs-micro); font-weight: 700; background: rgba(180,83,9,0.92); color: #fff; border-radius: var(--r-chip); padding: 1px 6px; }
.item .mini-actions { display: flex; gap: 4px; justify-content: center; margin-top: 4px; }
.item .mini-actions button { font-size: var(--fs-micro); padding: 3px 8px; border-radius: var(--r-chip); border: 1px solid var(--border); background: #fff; cursor: pointer; font-family: inherit; }
.item .mini-actions button:hover { background: #f1f5f9; }
/* 点击缩略图放大：现场照片要能看清显示器底部的距离/深度 */
.gallery img { cursor: zoom-in; }
.evidence-block img { cursor: zoom-in; }
.item .err-line { display: none; font-size: var(--fs-micro); color: var(--danger-text); font-weight: 600; text-align: center; margin-top: 3px; }
.item.upload-failed .err-line { display: block; }
.item.upload-failed img { border-color: var(--red); }
.item.upload-failed .badge-local { background: rgba(185,28,28,0.92); }

/* Lightbox：证据图原尺寸查看 */
.lightbox-box { display: flex; flex-direction: column; max-width: 1100px; }
.lightbox-stage {
  background: #0b1220; border-radius: var(--r-control); padding: 8px; margin-top: var(--sp-3);
  display: flex; align-items: center; justify-content: center; min-height: 200px;
}
.lightbox-stage img { max-width: 100%; max-height: 70vh; border-radius: var(--r-chip); display: block; }
.lightbox-prev, .lightbox-next { padding: 7px 12px; font-size: var(--fs-small); }

.btn-primary, .btn-secondary {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 11px 20px;
  border-radius: var(--r-control);
  font-size: var(--fs-body);
  font-weight: 600;
  cursor: pointer;
  border: 1px solid transparent;
  font-family: inherit;
  transition: transform .06s ease, box-shadow .15s, background .15s, border-color .15s;
}
.btn-primary {
  background: linear-gradient(135deg, var(--grad-from) 0%, var(--grad-to) 100%);
  color: #fff;
  box-shadow: 0 4px 14px rgba(29,78,216,0.28);
}
.btn-primary:hover { box-shadow: 0 6px 18px rgba(29,78,216,0.34); }
.btn-primary:active { transform: translateY(1px); }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; box-shadow: none; }
.btn-secondary { background: #fff; color: var(--text); border-color: var(--border); }
.btn-secondary:hover { background: #f1f5f9; border-color: #cbd5e1; }
.btn-secondary:disabled, .btn-secondary.btn-disabled { opacity: 0.5; cursor: not-allowed; }
.warn-text { color: var(--warn-text); font-weight: 600; }

/* 试用版水印：绝对定位在报告文档里，每 ~700px 一条（约等于每打印一页一条）。
   不用 background-image（浏览器默认不打印背景图），也不用 position:fixed（只有 Chrome 逐页重复）。 */
.report-doc { position: relative; }
.trial-watermark { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 5; }
.trial-watermark span {
  position: absolute; left: 50%; white-space: nowrap;
  transform: translateX(-50%) rotate(-28deg);
  font-size: 30px; font-weight: 800; letter-spacing: 2px;
  color: rgba(15, 23, 42, 0.10);
}
.watermark-hint { margin: -6px 0 12px; }
.watermark-hint .link-btn { margin-left: 6px; }

@media print {
  /* 打印时颜色要更实一点，否则浅灰在纸上几乎看不见（也强制把颜色送进打印） */
  .trial-watermark span { color: rgba(15, 23, 42, 0.16); -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

.hidden { display: none !important; }

/* 试用到期：填表之前就要看见（以前只有点了 Generate 才报错，用户以为程序坏了） */
.trial-banner {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap;
  padding: var(--sp-3); margin-bottom: var(--sp-3);
  border: 1px solid var(--warn-text); border-radius: var(--r-control);
  background: var(--warn-bg, #fffbeb); color: var(--warn-text);
}
.trial-banner strong { display: block; }
.trial-banner span { font-size: var(--fs-small); }

/* Report */
.report-toolbar { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-2); flex-wrap: wrap; }
/* 子栏：视图选项（模板下拉）单独一行。控件行用 center 对齐、说明文字另起一行，
   这样窄屏换行时不会出现"上一行的元素压到下一行"（flex-end + 换行就会那样）。 */
.report-subbar {
  display: flex; align-items: center; gap: var(--sp-3);
  flex-wrap: wrap; margin-bottom: var(--sp-2);
}
.report-subbar .format-label { flex: 0 0 auto; flex-direction: row; align-items: center; }
.report-subbar select { margin-top: 0; max-width: 100%; flex: 0 1 auto; padding: 11px 12px; }
.report-subbar .subbar-meta { flex: 1 1 220px; min-width: 0; }
.report-subnote {
  margin: 0 0 var(--sp-4); padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--border); font-weight: 500;
}
.report-doc { font-size: var(--fs-body); color: var(--text); }
.report-doc .doc-head { border-bottom: 2px solid var(--text); padding-bottom: 10px; margin-bottom: var(--sp-4); }
.report-doc .doc-head h2 { margin: 0 0 4px; font-size: var(--fs-h2); }
.report-doc .doc-head .meta-line { color: var(--muted); font-size: var(--fs-small); }
.report-doc .cond-badge {
  display: inline-block; padding: var(--sp-1) var(--sp-3); border-radius: var(--r-pill);
  font-weight: 700; font-size: var(--fs-small); color: #fff; margin: 10px 0;
}
.cond-good { background: var(--cond-good-fill); }
.cond-fair { background: var(--cond-fair-fill); }
.cond-poor { background: var(--cond-poor-fill); }
.cond-critical { background: var(--cond-critical-fill); }

.report-doc h3 { font-size: var(--fs-h3); line-height: var(--lh-h); margin: 18px 0 8px; border-left: 4px solid var(--primary); padding-left: 8px; }

.report-doc table { width: 100%; border-collapse: collapse; font-size: var(--fs-small); }
.report-doc th, .report-doc td { border: 1px solid var(--border); padding: var(--sp-2) 10px; text-align: left; vertical-align: top; }
.report-doc th { background: #f1f5f9; }

.sev { font-weight: 700; }
.sev-minor { color: var(--sev-minor-text); }
.sev-moderate { color: var(--sev-moderate-text); }
.sev-major { color: var(--sev-major-text); }
.sev-critical { color: var(--sev-critical-text); }

.report-doc ul { margin: 6px 0; padding-left: 20px; }
.disclaimer-box {
  background: #fff7ed; border: 1px solid #fed7aa; border-radius: var(--r-control);
  padding: var(--sp-3) var(--sp-4); font-size: var(--fs-label); color: #9a3412; margin-top: var(--sp-4);
}
.evidence-block { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: 10px; }
.evidence-block figure { margin: 0; }
.evidence-block img { width: 180px; border: 1px solid var(--border); border-radius: var(--r-control); }
.evidence-block figcaption { font-size: var(--fs-micro); color: var(--muted); margin-top: 4px; }
.signature-line { margin-top: 28px; display: flex; gap: 40px; }
.signature-line div { flex: 1; border-top: 1px solid var(--text); padding-top: 6px; font-size: var(--fs-small); color: var(--muted); }

/* Report: grades, codes, scope */
.doc-head .meta-line.title-line { color: var(--text); font-weight: 700; font-size: var(--fs-body); margin-top: 6px; }
.doc-head .report-no { float: right; font-size: var(--fs-small); color: var(--muted); font-weight: 600; }
.grade-row { display: flex; gap: var(--sp-4); flex-wrap: wrap; margin: 10px 0 4px; align-items: center; }
.grade-card {
  display: inline-flex; flex-direction: column; padding: 6px 14px; border-radius: var(--r-control);
  background: #f1f5f9; border: 1px solid var(--border); font-size: var(--fs-label); color: var(--muted);
}
.grade-card b { font-size: var(--fs-h3); color: var(--text); }
.stats-line { font-size: var(--fs-small); color: var(--muted); }
.code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  /* 小号等宽字压线过不了 AA：用更深的蓝（--link），别用品牌亮蓝 */
  font-size: var(--fs-label); font-weight: 700; background: #eef2ff; color: var(--link);
  border-radius: var(--r-chip); padding: 1px 6px; white-space: nowrap;
}
.tag { display: inline-block; font-size: var(--fs-micro); font-weight: 700; border-radius: var(--r-pill); padding: 1px 8px; white-space: nowrap; }
.tag-om { background: var(--ok-bg); color: var(--cond-good-text); }
.tag-st { background: var(--danger-bg); color: var(--danger-text); }
.adjust-note { display: block; font-size: var(--fs-micro); color: #92400e; margin-top: 3px; }
.adjust-note.manual { color: var(--link); }
/* 报告手工编辑区：AI 只给初稿，检查员改一切 */
.edit-panel { border: 2px solid var(--primary); border-radius: var(--r-control); padding: var(--sp-4) var(--sp-5) 24px; background: #f8fafc; }
.edit-panel h3 { margin: 0 0 14px; font-size: var(--fs-h3); }
.edit-panel h4 { margin: 20px 0 8px; font-size: var(--fs-body); border-left: 4px solid var(--primary); padding-left: 8px; scroll-margin-top: calc(var(--topbar-h) + 12px); }
.edit-panel .block { display: block; margin: 12px 0; }
.edit-panel textarea { width: 100%; }
.edit-recs { margin: 0; padding-left: 20px; }
.edit-recs li { margin-bottom: 6px; }
.edit-finding { background: #fff; border: 1px solid var(--border); border-radius: var(--r-control); padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-3); }
.edit-finding-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-weight: 700; font-size: var(--fs-small); color: var(--primary-2); margin-bottom: var(--sp-2); }
.edit-actions { display: flex; align-items: center; gap: var(--sp-3); margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }

/* 编辑器：保存操作常驻可见（长报告不必滚到底才能存） */
.edit-head {
  display: flex; flex-wrap: wrap; gap: 10px 16px;
  align-items: center; justify-content: space-between;
  position: sticky; top: var(--topbar-h); z-index: 6;
  margin: -18px -20px 14px; padding: var(--sp-3) var(--sp-5);
  background: rgba(248,250,252,0.97); border-bottom: 1px solid var(--border);
  backdrop-filter: blur(4px);
}
.edit-head h3 { margin: 0; }
.edit-head-right { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.dirty-pill {
  font-size: var(--fs-label); font-weight: 700; border-radius: var(--r-pill); padding: 3px 10px;
  background: var(--warn-bg); color: #92400e; border: 1px solid var(--warn-border); white-space: nowrap;
}
.edit-toc { display: flex; gap: var(--sp-3); flex-wrap: wrap; font-size: var(--fs-small); margin: 0 0 10px; }
.edit-toc a { color: var(--primary-2); text-decoration: none; border-bottom: 1px dashed rgba(37,99,235,0.4); }
.edit-toc a:hover { border-bottom-style: solid; }
.edit-status:not(:empty) {
  display: block; margin: 0 0 12px; padding: var(--sp-2) var(--sp-3); border-radius: var(--r-control);
  background: #fff; border: 1px solid var(--border);
}
.edit-status.req-msg { color: var(--red); font-weight: 600; }

/* 实时派生预览：改完立刻看到管级/统计会变成什么 */
.edit-preview {
  display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: center;
  margin: 4px 0 10px; padding: 9px 12px; border-radius: var(--r-control);
  background: #eef6ff; border: 1px solid #dbeafe; font-size: var(--fs-small); color: #1e3a8a;
}
.edit-preview .prev-item b { color: #0f172a; }
.edit-preview .pill-pinned {
  font-size: var(--fs-micro); font-weight: 700; color: #92400e; background: var(--sev-moderate-bg);
  border: 1px solid var(--warn-border); border-radius: var(--r-pill); padding: 1px 7px;
}
.edit-preview .prev-note { color: var(--muted); font-size: var(--fs-micro); }

/* 字段标题旁的"恢复初稿" */
.edit-field .ef-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.link-btn {
  background: none; border: none; padding: 0; font: inherit; cursor: pointer;
  color: var(--primary-2); text-decoration: underline; font-size: var(--fs-label);
}
.link-btn:hover { color: var(--primary-dark); }
.restore-btn { font-weight: 600; }
.edit-finding .ef-derived { display: inline-flex; gap: 6px; align-items: center; margin-left: auto; }
.chip { display: inline-block; font-size: var(--fs-micro); font-weight: 700; border-radius: var(--r-chip); padding: 1px 6px; }
.chip.code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; background: #eef2ff; color: var(--primary-2); }
.quick-fill { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 0 0 10px; }
.quick-btn { font-size: var(--fs-micro); padding: 3px 8px; }
.undo-banner {
  display: block; margin-top: var(--sp-3); padding: var(--sp-2) var(--sp-3); border-radius: var(--r-control);
  background: var(--warn-bg); border: 1px solid var(--warn-border); color: #92400e; font-size: var(--fs-small); font-weight: 600;
}
.edit-field-msg { margin-top: 4px; }
/* 编辑表单栅格：align-items:end 让控件底部对齐，标签文字换行也不会把输入框挤错位 */
.edit-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--sp-3); align-items: end; }
/* 发现项三列：Defect type / Severity / Location 固定一行，窄屏才竖排 */
.edit-grid-3 { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1.4fr) minmax(0, .8fr); gap: var(--sp-3); align-items: end; }
@media (max-width: 700px) { .edit-grid-3 { grid-template-columns: 1fr; } }
.scope-table td:first-child { width: 34%; font-weight: 600; color: var(--muted); }
.scope-table td { font-size: var(--fs-small); }

/* Print-page footer: identity block, repeats the traceable identifiers */
.print-footer {
  /* 屏幕上也要显示（原来是 display:none，只有打印才出现）——页脚是每页的追溯标识，
     预览里看不到它，检查员就没法确认"我保存的 PDF 最后长什么样"。 */
  display: block; margin-top: 22px; padding-top: 8px; border-top: 1px solid #94a3b8;
  font-size: var(--fs-micro); color: var(--muted); line-height: var(--lh-body);
}

/* Format selector */
/* 表单里是标签在上、控件在下；报告子栏里两者同行，用 center 对齐即可 */
.format-label { display: inline-flex; flex-direction: column; font-size: var(--fs-small); font-weight: 600; color: var(--muted); }
/* purpose 与所选模板不匹配时的温和提示（不禁用，只推荐） */
select {
  margin-top: 5px;
  padding: var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--r-control);
  font-size: var(--fs-body);
  font-family: inherit;
  background: #fff;
  color: var(--text);
  cursor: pointer;
}
select:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(14,165,233,0.15); }

/* Report format variants */
.brief-list { padding-left: 20px; margin: 6px 0; }
.brief-list li { margin-bottom: 6px; }
.finding-block { margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px dashed var(--border); }
.finding-block:last-child { border-bottom: none; }
.finding-block h4 { margin: 0 0 4px; font-size: var(--fs-body); }
.finding-block p { margin: 4px 0; }
.check-list { list-style: none; padding: 0; margin: 6px 0; }
.check-item { padding: 8px 0; border-bottom: 1px solid var(--border); }
.check-item:last-child { border-bottom: none; }
.check-item .box { font-size: var(--fs-h3); color: var(--primary); margin-right: 4px; }
.check-note { margin: 3px 0 0 20px; font-size: var(--fs-small); color: var(--muted); }

/* Auth panel */
.auth-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; margin-top: var(--sp-2); }
.auth-row input { flex: 1 1 160px; margin-top: 0; }
/* 注册第二步：确认密码 + 可选资料。独立成块，避免和登录输入混在一起。
   控件行必须 align-items: end —— 标签文字长度不同会换成不同行数，
   start/默认对齐会让输入框各按自己的标签高度排下去，四个框就不在同一水平线上（实测差 17px）。 */
.signup-box {
  margin-top: var(--sp-4); padding: var(--sp-4);
  border: 1px solid var(--border); border-radius: var(--r-control);
  background: #f8fafc;
}
.signup-box .signup-head { display: flex; flex-direction: column; gap: 2px; margin-bottom: var(--sp-3); }
.signup-box .signup-grid { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); align-items: end; }
/* 标签强制单行：标签文字长短不一会换成不同行数，只对齐输入框会让标签参差；而允许换行时
   若行高不够又可能把文字挤出格子。这里用"单行 + 超出省略"，无论列多窄都不会溢出或错位。 */
.signup-box .signup-grid > label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 控件必须是块级：inline-block 的输入框会留在标签的行内格式化上下文里，
   一旦该上下文居中，每个框就按自身宽度各自居中（实测手机上左边界 170/116/108/146 参差），
   显示上像"栏位错位/重叠"。块级化后一律左对齐。 */
/* logo 是"按钮 + 预览"，比纯文本字段高，给它整行以免和别的字段错位 */
.signup-box .signup-logo-field { grid-column: 1 / -1; }
.signup-logo-label { display: block; font-size: var(--fs-small); line-height: var(--lh-label); font-weight: 600; color: var(--muted); }
.signup-logo-msg:empty { display: none; }
.signup-logo-msg { margin: 6px 0 0; }
.signup-logo-row { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.signup-logo-row .btn-secondary { margin: 0; }
.signup-logo-row .btn-secondary.danger { padding: 6px 10px; font-size: var(--fs-label); }
/* 文件选择框：视觉上藏起来，但**不是 display:none** ——
   iOS Safari / 部分浏览器会拒绝给 display:none 的 file input 开选择框，
   而且 display:none 的控件键盘也聚焦不到。所以用"sr-only"套路：看不见、仍可聚焦、仍可激活。
   隐藏手段叠了三层，因为 file input 的按钮是浏览器原生绘制的，个别浏览器（国产内核 / 老 WebKit）
   会无视 clip/clip-path 把它照画出来 —— 用户看到的就是多出来一个原生的"选择文件"按钮：
   opacity: 0 是所有引擎都认的兜底，pointer-events: none 保证它不抢点击（点击交给外面的 label）。 */
.sr-only-file {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  opacity: 0; pointer-events: none; white-space: nowrap; border: 0; appearance: none;
}
/* label 当按钮用时（原生 label → file input）：聚焦时把焦点环画在可见的 label 上 */
.btn-secondary:focus-within, .btn-secondary:has(:focus-visible) { outline: 2px solid var(--primary); outline-offset: 2px; }
label.btn-secondary { user-select: none; }
.signup-box input, #profilePanel input { display: block; }
.signup-box .signup-actions {
  display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
  margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: 1px solid var(--border);
}
/* 账号默认资料：和报告表单同一套视觉，但它是"设置"而不是"本次输入" */
#profilePanel .branding-row { margin-top: var(--sp-3); }
#profilePanel input:disabled { background: #f1f5f9; color: var(--muted); cursor: not-allowed; }
.profile-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap; }
.profile-head h2 { margin: 0; }
.profile-toggle { margin-top: 0; display: none; }
#profilePanel .profile-body.collapsed { display: none; }
/* 手机上表单已经很长，资料卡默认折叠，把垂直空间让给输入与吸底操作条 */
@media (max-width: 640px) {
  .profile-toggle { display: inline-flex; }
  .profile-body { margin-top: var(--sp-3); }
}
.auth-status { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.auth-who { font-weight: 600; }
.plan-badge { display: inline-block; font-size: var(--fs-label); font-weight: 600; padding: 4px 10px; border-radius: var(--r-pill); background: var(--info-bg); color: var(--link); border: 1px solid var(--info-border); }
.plan-badge.warn { background: var(--sev-moderate-bg); color: #92400e; border-color: var(--warn-border); }
.activate-area { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-top: var(--sp-3); }
.activate-area input { flex: 1 1 180px; margin-top: 0; }
.activate-area .btn-secondary { text-decoration: none; }

/* Branding */
.branding-row { display: flex; gap: 14px; align-items: flex-end; flex-wrap: wrap; }
.branding-row > label:first-child { flex: 1 1 200px; }
.logo-preview { width: 48px; height: 48px; object-fit: contain; border: 1px solid var(--border); border-radius: var(--r-control); background: #fff; }

/* Report branding header */
.brand-row { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-2); }
.brand-logo { height: 44px; width: auto; object-fit: contain; }
.brand-name { font-size: var(--fs-h3); font-weight: 700; }

/* History */
.history-list { display: flex; flex-direction: column; gap: 10px; }
.history-item { display: flex; justify-content: space-between; gap: 14px; padding: 12px; border: 1px solid var(--border); border-radius: var(--r-control); }
.history-main { flex: 1; min-width: 0; }
.history-main .hint { display: block; margin-top: 2px; }
.history-main .small { font-size: var(--fs-micro); }
.history-actions { display: flex; gap: var(--sp-2); align-items: flex-start; flex-shrink: 0; }
.btn-secondary.danger { color: var(--danger-text); border-color: var(--danger-border); }
.btn-secondary.danger:hover { background: var(--danger-bg); }

/* Table scroll on small screens */
.table-wrap { overflow-x: auto; }

/* Report 双栏：目录形态完全由宽度断点决定（JS 只负责表达"用户要不要看"→ .toc-open）
   默认（手机/窄屏）：目录收成横向胶囊条，只有用户点开（.toc-open）才显示 */
.report-layout { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; align-items: start; }
.toc-toggle { display: inline-flex; margin-bottom: var(--sp-3); }
.toc-toggle.no-sections { display: none; }
.to-top { display: block; margin: 18px 0 0 auto; }
.report-toc {
  display: none; align-items: center; gap: 6px 10px; flex-wrap: wrap;
  border: 1px solid var(--border); background: #fbfdff; border-radius: var(--r-control);
  padding: var(--sp-3) var(--sp-4); margin: 0 0 16px; font-size: var(--fs-small);
}
.report-layout.toc-open .report-toc { display: block; max-height: 42vh; overflow-y: auto; }
.report-toc .toc-label { display: block; font-weight: 700; color: var(--muted); margin-bottom: 6px; }
.report-toc a { display: block; padding: 4px 6px; color: var(--primary-2); text-decoration: none; }
.report-toc a:hover { background: #eff6ff; }
.report-toc a.active {
  color: var(--text); font-weight: 700;
  border-left: 3px solid var(--primary); background: #eef6ff;
  border-radius: 0 var(--r-chip) var(--r-chip) 0; padding-left: 5px;
}
.report-doc h3 { scroll-margin-top: calc(var(--topbar-h) + 16px); }

/* 编辑报告时：报告的目录/回到顶部让位给编辑器（正文此刻是隐藏的） */
#reportPanel.editing .report-toc,
#reportPanel.editing .toc-toggle { display: none !important; }

/* History: search / filter / sort 与条件色点 */
.history-toolbar { display: flex; gap: 14px; flex-wrap: wrap; align-items: flex-end; margin: 4px 0 12px; }
.history-toolbar .search-label { flex: 1 1 240px; }
.history-toolbar input[type="search"] {
  width: 100%; margin-top: 5px; padding: var(--sp-3); border: 1px solid var(--border);
  border-radius: var(--r-control); font-size: var(--fs-body); font-family: inherit; background: #fff; color: var(--text);
}
.history-toolbar input[type="search"]:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(14,165,233,0.15); }
.history-item .name-line { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.cond-dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; flex-shrink: 0; }
.cond-dot.cond-good { background: var(--cond-good-fill); }
.cond-dot.cond-fair { background: var(--cond-fair-fill); }
.cond-dot.cond-poor { background: var(--cond-poor-fill); }
.cond-dot.cond-critical { background: var(--cond-critical-fill); }
.history-empty { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
/* 按日期分组：标题吸顶，滚动时始终知道在看哪一段 */
.history-group { margin-bottom: 6px; }
.history-group-head {
  position: sticky; top: var(--topbar-h); z-index: 3;
  display: flex; align-items: center; gap: var(--sp-2);
  padding: 7px 2px; margin: 0 0 8px;
  background: var(--surface); border-bottom: 1px solid var(--border);
  font-size: var(--fs-small); font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .02em;
}
.history-group-head .pill { font-weight: 700; color: var(--primary-2); background: #eef2ff; border-radius: var(--r-pill); padding: 1px 8px; text-transform: none; }

footer { max-width: 960px; margin: 0 auto 40px; padding: 0 16px; color: var(--muted); font-size: var(--fs-label); text-align: center; }
footer a { color: var(--link); text-decoration: underline; }

@media (max-width: 640px) {
  .topbar { padding: var(--sp-3) var(--sp-4); }
  .topbar h1 { font-size: var(--fs-lead); }
  .sub { display: none; }
  main { margin: 16px auto; }
  .card { padding: 16px; border-radius: var(--r-control); }
  .grid { grid-template-columns: 1fr; }
  .actions { flex-direction: column; align-items: stretch; }
  .actions .btn-primary, .actions .btn-secondary { justify-content: center; }
  /* 主操作吸底：七段表单不用一路划到底才够得到 Generate */
  #actionsBar {
    position: sticky; bottom: 0; z-index: 5;
    margin: 18px -16px -16px; padding: var(--sp-3) var(--sp-4);
    background: rgba(255,255,255,0.97); border-top: 1px solid var(--border);
    box-shadow: 0 -6px 16px rgba(15,23,42,0.08);
    backdrop-filter: blur(4px);
  }
  #actionsBar .format-label { flex-direction: row; align-items: center; gap: 10px; }
  #actionsBar select { margin-top: 0; flex: 1; }
  .signature-line { flex-direction: column; gap: var(--sp-4); }
  .report-doc .doc-head h2 { font-size: var(--fs-h3); }
  .doc-head .report-no { float: none; display: block; }
  .evidence-block img { width: 100%; }
  .history-item { flex-direction: column; }
  .history-actions { width: 100%; }
  .history-actions button { flex: 1; justify-content: center; }
  .frame-card img { width: 96px; height: 68px; }
  .frame-picker-head { flex-direction: column; align-items: flex-start; }
  .modal-box { padding: 14px; }
  .lightbox-stage img { max-height: 52vh; }
  /* 手机端目录一律折叠成可点开的块，正文优先占屏幕（形态由 CSS 决定，见文件末尾的宽屏规则） */
  .report-layout.toc-open .report-toc { max-height: 40vh; }
  .to-top { margin-left: 0; width: 100%; justify-content: center; }
}

/* 打印/存 PDF：分页控制 + 每份报告的追溯标识 */
@page { margin: 12mm 12mm 14mm; }

@media print {
  /* 关键：浏览器默认不打印背景色，会让 Overall 徽标/评级卡/严重度标签的底色整块消失，
     看起来和页面、以及服务端 PDF 完全不同。让这些元素强制保留配色。 */
  .cond-badge, .grade-card, .tag, .code, .disclaimer-box, .report-doc th, .qa-banner,
  .check-item .box, .severity, .sev, .brand-logo {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .topbar, #authPanel, #formPanel, #historyPanel, .report-toolbar, footer, .no-print { display: none !important; }
  /* 只允许报告进纸：main 里除 #reportPanel 之外的区块一律不打印。
     原来靠上面那行白名单，漏掉了 #profilePanel —— 用户报告 "My defaults"（姓名/执照号/公司名/logo、
     Save defaults 按钮）被一起印进 PDF 了。改成结构规则：以后再加面板也不会漏。 */
  main > section:not(#reportPanel) { display: none !important; }
  /* 报告面板没打开时（在填表页按 Ctrl+P）不要强行印一份空/旧报告 */
  #reportPanel.hidden { display: none !important; }
  /* 打印永远单栏：目录、回到顶部都不进纸 */
  .report-layout, .report-layout.toc-open { display: block !important; }
  /* 页面本身是浅灰底，打印时去掉；卡片的白底保留（也告诉浏览器这是有意为之） */
  body { background: #fff; }
  main { max-width: none; margin: 0; padding: 0; }
  #reportPanel {
    display: block !important; border: none; box-shadow: none; padding: 0; margin: 0;
    background: #fff; -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  /* 让纸张内容和屏幕上的排版一致：A4 宽度下的左右留白，
     加上这条是为了让"打印出来的样子"和页面里看到的一致（页脚/页眉由浏览器自己加） */
  .report-doc { max-width: none; }
  /* 追溯行改成**每页重复**的固定页脚（Chrome/Edge 会把 position:fixed 的元素逐页重复），
     而不是原来那样"只在最后一页末尾多印一行" —— 那既和页头重复，又完全没起到
     "任何一页单独流出去也能认出来"的作用（第 2 页起原本什么都没有）。
     给报告容器留出等高内边距，避免固定页脚压住最后一两行正文。 */
  .print-footer {
    display: block;
    position: fixed; left: 0; right: 0; bottom: 0;
    margin: 0; padding-top: 3px; border-top: 1px solid #94a3b8;
    font-size: 7pt; line-height: 1.35; color: #334155; background: #fff;
  }
  #reportContent, #reportPanel { padding-bottom: 9mm; }
  #reportContent { break-inside: auto; }
  tr, .finding-block, .evidence-block figure, .signature-line, .grade-row, .disclaimer-box, .scope-table { break-inside: avoid; page-break-inside: avoid; }
  thead { display: table-header-group; }
  .report-doc h3, .report-doc h4 { break-after: avoid; page-break-after: avoid; }
  .report-doc .doc-head { break-after: avoid; }
  .evidence-block img { width: 150px; }
  /* 免责声明整段不进纸（服务端 PDF 由 pdfreport.js 的 SHOW_DISCLAIMER 同步关闭，
     两边的产物必须一致）：纸面只保留每页页脚的追溯标识（报告号/客户/日期/检查员+执照号）。 */
  .disclaimer-box { display: none !important; }
}

/* ---------- 忘记密码 / 重置 / 邮箱验证 ---------- */
/* 文字按钮：视觉上仍是一行链接，但命中区撑到 24px 以上（原来只有 19px 高） */
.link-btn {
  background: none; border: none; padding: 3px 0; margin: -3px 0; font: inherit; cursor: pointer;
  color: var(--link); text-decoration: underline; text-align: left;
  min-height: 24px;
}
.link-btn:hover { color: var(--link-hover); }
.link-btn:disabled { color: var(--muted); cursor: default; }
.forgot-box {
  border: 1px solid var(--border); border-radius: var(--r-control); padding: var(--sp-3); margin-top: var(--sp-2);
  background: #f8fafc; display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: flex-end;
}
.forgot-box label { display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-label); color: var(--muted); }
.forgot-box input { min-width: 240px; margin-top: 0; }
.forgot-box .hint { flex-basis: 100%; margin: 0; word-break: break-all; }
#authReset .auth-row, #authVerify { margin-top: 6px; }

/* ============================================================
   报告模板：分类选择器 + 六套版式
   规则：模板只改排版与取舍，编码/严重度/评级始终来自服务端确定性层。
   ============================================================ */

/* ---------- 表单里的模板选择器 ---------- */
.template-picker { border: 1px solid var(--border); border-radius: var(--r-control); padding: var(--sp-3) var(--sp-4); margin: 14px 0 4px; background: #fbfdff; }
.template-head { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: baseline; margin-bottom: 9px; }
.template-title { font-weight: 700; font-size: var(--fs-body); }
.template-cats { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: 10px; }
.tpl-cat {
  border: 1px solid var(--border); background: #fff; border-radius: var(--r-pill); padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-small); cursor: pointer; display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
}
.tpl-cat.active { border-color: var(--link); background: var(--info-bg); color: var(--link-hover); font-weight: 600; }
.tpl-cat-hint { font-size: var(--fs-micro); color: var(--muted); font-weight: 400; }
.tpl-cat.active .tpl-cat-hint { color: var(--link); }
.template-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(235px, 1fr)); gap: var(--sp-3); }
.tpl-card {
  border: 1px solid var(--border); border-radius: var(--r-control); padding: var(--sp-3); background: #fff;
  cursor: pointer; display: flex; flex-direction: column; gap: 3px;
}
/* 单选钮在 flex 列容器里会被拉伸成一条（实测 236×13），必须锁死尺寸 */
.tpl-card input[type="radio"] {
  width: 16px; height: 16px; flex: 0 0 auto; align-self: flex-start;
  margin: 2px 6px 0 0; accent-color: var(--link);
}
.tpl-card.selected { border-color: var(--link); box-shadow: 0 0 0 2px rgba(29, 78, 216, .18); }
.tpl-card input { margin-right: 6px; }
.tpl-name { font-weight: 600; font-size: var(--fs-body); }
.tpl-audience { font-size: var(--fs-micro); color: var(--link); }
.tpl-desc { font-size: var(--fs-label); color: var(--muted); line-height: var(--lh-print); }
/* purpose 与所选模板不匹配时的温和提示（不禁用，只推荐） */
.tpl-warn { color: var(--warn-text); background: var(--warn-bg); border: 1px solid var(--warn-border); border-radius: var(--r-chip); padding: 1px 6px; }
/* 模板选择器跟着报告工具栏走；打印时必须隐藏（别把控件印到纸上） */
#templateSwitchLabel { display: inline-flex; }
@media (max-width: 640px) { .template-cards { grid-template-columns: 1fr; } }

/* ---------- 通用零件：评级条 / 图带 / 声明 ---------- */
.grade-bar { display: flex; gap: 4px; margin: 8px 0 4px; }
.grade-bar .gb { width: 34px; height: 8px; border-radius: var(--r-chip); background: #e2e8f0; display: inline-block; }
.grade-bar .gb.on.g1 { background: var(--cond-good-fill); }
.grade-bar .gb.on.g2 { background: var(--cond-good-fill); }
.grade-bar .gb.on.g3 { background: var(--cond-fair-fill); }
.grade-bar .gb.on.g4 { background: var(--cond-poor-fill); }
.grade-bar .gb.on.g5 { background: var(--cond-critical-fill); }

/* ---------- ① 技术标准版（原有版式，只是加一个类钩子） ---------- */
.tpl-technical-standard { font-size: var(--fs-small); }

/* ---------- ② 技术详写版：与技术标准版同观感，正文是逐条叙述块 ---------- */
.tpl-technical-detailed { font-size: var(--fs-small); }
.tpl-technical-detailed .finding-block { border-left: 3px solid #e2e8f0; padding-left: 12px; margin: 14px 0; }
.tpl-technical-detailed .finding-block h4 { margin-bottom: 4px; }

/* ---------- ③ 现场勾选清单 ---------- */
.tpl-field-checklist { font-size: var(--fs-body); }
.tpl-field-checklist .check-list { list-style: none; padding-left: 0; }
.tpl-field-checklist .check-item {
  border: 1px solid var(--border); border-left: 4px solid var(--border);
  border-radius: var(--r-control); padding: var(--sp-3); margin: 8px 0; background: #fff;
}
.tpl-field-checklist .check-item .box { font-size: var(--fs-h3); margin-right: 6px; }
.tpl-field-checklist .check-note { font-size: var(--fs-small); color: var(--text); margin-top: 4px; }
.tpl-field-checklist .checklist-head { border-bottom: 2px solid var(--border); padding-bottom: 8px; }

/* ---------- ② 一页买家版 ---------- */
.tpl-buyer-summary { font-size: var(--fs-small); }
.buyer-hero { border-radius: var(--r-card); padding: var(--sp-4) var(--sp-5); margin-bottom: 14px; border: 1px solid var(--border); background: #f8fafc; }
.buyer-hero.fail { background: var(--danger-bg); border-color: var(--danger-border); }
.buyer-hero.conditional { background: var(--warn-bg); border-color: var(--warn-border); }
.buyer-hero.pass { background: var(--ok-bg); border-color: var(--ok-border); }
.buyer-hero h2 { margin: 6px 0 2px; font-size: var(--fs-h2); }
.bh-top { display: flex; justify-content: space-between; font-size: var(--fs-micro); color: var(--muted); }
.bh-addr { color: var(--muted); font-size: var(--fs-small); }
.bh-verdict {
  display: inline-block; margin: 10px 0 6px; font-weight: 800; letter-spacing: .04em;
  padding: 5px 12px; border-radius: var(--r-pill); font-size: var(--fs-small); background: #0f172a; color: #fff;
}
.buyer-hero.fail .bh-verdict { background: var(--cond-critical-fill); }
.buyer-hero.conditional .bh-verdict { background: var(--cond-fair-fill); }
.buyer-hero.pass .bh-verdict { background: var(--cond-good-fill); }
.bh-headline { font-size: var(--fs-lead); margin: 2px 0 6px; }
.bh-sub { font-size: var(--fs-small); color: var(--muted); }
.buyer-finding {
  border: 1px solid var(--border); border-left: 6px solid var(--border); border-radius: var(--r-control);
  padding: var(--sp-3); margin: 8px 0; background: #fff;
}
.buyer-finding.sev-minor { border-left-color: var(--sev-minor-fill); }
.buyer-finding.sev-moderate { border-left-color: var(--sev-moderate-fill); }
.buyer-finding.sev-major { border-left-color: var(--sev-major-fill); }
.buyer-finding.sev-critical { border-left-color: var(--sev-critical-fill); }
.bf-head { display: flex; align-items: baseline; gap: var(--sp-2); }
.bf-rank {
  width: 20px; height: 20px; border-radius: 50%; background: #0f172a; color: #fff; font-size: var(--fs-micro);
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.bf-title { font-weight: 700; }
.bf-loc { color: var(--muted); font-size: var(--fs-label); margin-left: auto; }
.bf-body { margin: 6px 0 4px; }
.bf-plain { margin: 0; font-size: var(--fs-small); color: var(--text); font-style: italic; }
.buyer-next { background: var(--info-bg); border: 1px solid var(--info-border); border-radius: var(--r-control); padding: var(--sp-3) var(--sp-4); margin: 12px 0; }
.buyer-limits { background: var(--sev-major-bg); border: 1px solid var(--warn-border); border-radius: var(--r-control); padding: var(--sp-3) var(--sp-4); margin: 12px 0; }
.buyer-note { font-size: var(--fs-label); color: var(--muted); }
.tpl-buyer-summary .evidence-block img { width: 110px; }

/* ---------- ③ 客户友好版 ---------- */
.tpl-client-modern { font-size: var(--fs-body); }
.modern-hero {
  border-radius: var(--r-card); padding: 20px 22px; margin-bottom: var(--sp-4); border: 1px solid var(--border);
  background: linear-gradient(135deg, var(--info-bg), #f8fafc);
}
.modern-hero.fail { background: linear-gradient(135deg, var(--sev-critical-bg), #fff7f7); }
.modern-hero.conditional { background: linear-gradient(135deg, var(--sev-moderate-bg), #fffdf5); }
.modern-hero.pass { background: linear-gradient(135deg, #d1fae5, #f7fffb); }
.modern-hero h2 { font-size: var(--fs-h2); line-height: var(--lh-h); margin: 6px 0; }
.mh-addr { font-size: var(--fs-small); color: var(--text); margin: 0 0 6px; }
.mh-verdict { font-size: var(--fs-h2); font-weight: 800; margin: 8px 0 4px; }
.modern-hero.fail .mh-verdict { color: var(--danger-text); }
.modern-hero.conditional .mh-verdict { color: var(--cond-fair-text); }
.modern-hero.pass .mh-verdict { color: var(--cond-good-text); }
.mh-headline { font-size: var(--fs-body); color: var(--text); margin: 0; }
.modern-card {
  border: 1px solid var(--border); border-radius: var(--r-card); padding: var(--sp-4); margin: 12px 0;
  background: #fff; box-shadow: 0 1px 2px rgba(15, 23, 42, .05);
}
.mc-bar { display: flex; gap: var(--sp-2); align-items: center; font-size: var(--fs-micro); margin-bottom: 6px; }
.mc-sev { font-weight: 700; padding: 2px 8px; border-radius: var(--r-pill); background: #e2e8f0; }
.modern-card.sev-critical .mc-sev { background: var(--sev-critical-bg); color: var(--sev-critical-text); }
.modern-card.sev-major .mc-sev { background: var(--sev-major-bg); color: var(--sev-major-text); }
.modern-card.sev-moderate .mc-sev { background: var(--sev-moderate-bg); color: var(--sev-moderate-text); }
.modern-card.sev-minor .mc-sev { background: var(--sev-minor-bg); color: var(--sev-minor-text); }
.mc-loc { color: var(--muted); }
.mc-plain { font-size: var(--fs-lead); font-weight: 600; margin: 4px 0; }
.mc-desc { color: var(--text); margin: 4px 0; }
.mc-action { margin: 4px 0 0; }
.modern-scope summary { cursor: pointer; font-weight: 600; margin: 10px 0; }

/* ---------- ④ 家检交付包（封面页） ---------- */
.tpl-classic-cover .cover-page {
  border: 1px solid var(--border); border-radius: var(--r-card); padding: 26px 28px; margin-bottom: 18px;
  background: #fff; text-align: center;
}
.cover-top { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.cover-logo { max-height: 70px; }
.cover-company { font-weight: 700; letter-spacing: .04em; }
.tpl-classic-cover h1 { font-size: var(--fs-h1); margin: 14px 0 18px; }
.cover-table { margin: 0 auto 18px; max-width: 560px; text-align: left; }
.cover-grade {
  display: flex; flex-direction: column; gap: 4px; align-items: center;
  padding: 12px; border-radius: var(--r-control); background: #f1f5f9; margin-bottom: var(--sp-4);
}
.cover-grade.cond-good { background: var(--ok-bg); }
.cover-grade.cond-fair { background: var(--warn-bg); }
.cover-grade.cond-poor { background: var(--sev-major-bg); }
.cover-grade.cond-critical { background: var(--danger-bg); }
.cg-grade { font-size: var(--fs-lead); font-weight: 700; }
.cover-summary { text-align: left; font-size: var(--fs-small); }
.cover-foot { margin-top: 18px; font-size: var(--fs-micro); color: var(--muted); }
.attention-list { list-style: none; padding-left: 0; }
.attention-list li { border: 1px solid var(--border); border-left: 5px solid var(--border); padding: var(--sp-2) 10px; margin: 8px 0; background: #fff; border-radius: var(--r-chip); }
.attention-list li.sev-minor { border-left-color: var(--sev-minor-fill); }
.attention-list li.sev-moderate { border-left-color: var(--sev-moderate-fill); }
.attention-list li.sev-major { border-left-color: var(--sev-major-fill); }
.attention-list li.sev-critical { border-left-color: var(--sev-critical-fill); }
.al-action { font-size: var(--fs-small); color: var(--text); margin-top: 3px; }

/* ---------- ⑤ 市政 / PACP 段报告 ---------- */
.tpl-pacp-technical { font-size: var(--fs-small); }
.pacp-head { border-bottom: 3px solid #0f172a; padding-bottom: 8px; margin-bottom: var(--sp-3); }
.pacp-head h2 { margin: 4px 0; }
.pacp-table { font-size: var(--fs-micro); width: 100%; table-layout: fixed; }
.pacp-table th, .pacp-table td { padding: 5px 6px; vertical-align: top; overflow-wrap: anywhere; }
.pacp-table td.pacp-sev { text-align: center; font-weight: 700; }
.pacp-table .pc-n { width: 22px; }
.pacp-table .pc-dist { width: 72px; }
.pacp-table .pc-clock { width: 42px; }
.pacp-table .pc-code { width: 46px; }
.pacp-table .pc-defect { width: 104px; }
.pacp-table .pc-sev { width: 38px; }
.pacp-class { display: block; font-size: var(--fs-micro); font-weight: 400; color: var(--muted); letter-spacing: .02em; }
.pacp-action { margin-top: 3px; font-size: var(--fs-micro); color: var(--link); }
.pacp-ratings { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin: 8px 0 14px; }
.pr-box { border: 1px solid var(--border); border-radius: var(--r-control); padding: var(--sp-3); background: #f8fafc; display: flex; flex-direction: column; gap: 3px; }
.pr-box span { font-size: var(--fs-micro); color: var(--muted); }
.pr-box b { font-size: var(--fs-h3); }

/* ---------- ⑥ 市政合规表 ---------- */
.tpl-compliance-form .verdict-stamp {
  border: 3px solid #0f172a; border-radius: var(--r-control); padding: var(--sp-4); margin: 16px 0;
  font-size: var(--fs-h3); font-weight: 800; letter-spacing: .04em; text-align: center;
}
.verdict-stamp .vs-note { display: block; font-size: var(--fs-small); font-weight: 400; letter-spacing: 0; margin-top: 6px; color: var(--text); }
.stamp-pass { border-color: var(--cond-good-fill); color: var(--cond-good-text); background: var(--ok-bg); }
.stamp-cond { border-color: var(--cond-fair-fill); color: var(--cond-fair-text); background: var(--warn-bg); }
.stamp-fail { border-color: var(--cond-critical-fill); color: var(--cond-critical-text); background: var(--danger-bg); }
.cert-block { margin-top: 14px; }
.cert-line { font-size: var(--fs-small); }
.compliance-list .check-item { border-left: 4px solid var(--border); }

/* ---------- ⑦ 保险 / 理赔叙述版 ---------- */
.claim-head { border-bottom: 2px solid var(--border); padding-bottom: 8px; margin-bottom: var(--sp-3); }
.claim-verdict { border-left: 5px solid var(--border); padding: var(--sp-2) var(--sp-3); background: #f8fafc; border-radius: var(--r-chip); margin: 8px 0 14px; }
.claim-verdict.fail { border-left-color: var(--cond-critical-fill); }
.claim-verdict.conditional { border-left-color: var(--cond-fair-fill); }
.claim-verdict.pass { border-left-color: var(--cond-good-fill); }
.timeline { list-style: none; padding-left: 0; margin: 0; }
.tl-item { display: flex; gap: var(--sp-3); padding: 10px 0; border-bottom: 1px dashed var(--border); }
.tl-item.sev-critical .tl-dist { color: var(--sev-critical-text); }
.tl-item.sev-major .tl-dist { color: var(--sev-major-text); }
.tl-dist { flex: 0 0 132px; font-weight: 700; font-size: var(--fs-small); }
.tl-body p { margin: 4px 0; }
.tl-plain { font-style: italic; color: var(--text); }
.tl-action { color: var(--link); }
.scope-list { margin: 6px 0 12px 18px; }
.scope-list.repair li::marker { color: var(--cond-critical-fill); }
.scope-list.maintenance li::marker { color: var(--link); }

/* ---------- 模板的打印规则 ---------- */
@media print {
  .template-picker, #templateSwitchLabel { display: none !important; }
  .tpl-classic-cover .cover-page { break-after: page; page-break-after: always; border: none; padding: 0 0 12mm; }
  .buyer-hero, .buyer-finding, .buyer-next, .buyer-limits, .modern-hero, .modern-card, .cover-grade,
  .verdict-stamp, .pr-box, .tl-item, .attention-list li, .cert-block, .claim-verdict,
  .tpl-field-checklist .check-item, .tpl-technical-detailed .finding-block {
    break-inside: avoid; page-break-inside: avoid;
  }
  .buyer-hero, .modern-hero, .cover-grade, .verdict-stamp, .bh-verdict, .pr-box, .mc-sev, .grade-bar .gb,
  .attention-list li, .claim-verdict, .buyer-finding {
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  .tpl-buyer-summary { font-size: var(--fs-micro); }
  .tpl-buyer-summary .buyer-hero h2 { font-size: var(--fs-h2); }
  .tpl-pacp-technical .pacp-table { font-size: var(--fs-micro); }
  /* 纸面上不能靠横向滚动：固定表格布局 + 允许长词断行，避免最后一列被裁掉 */
  .table-wrap { overflow: visible !important; }
  .report-doc table { width: 100%; table-layout: fixed; }
  .report-doc th, .report-doc td { overflow-wrap: anywhere; padding: 5px 6px; }
}

/* 宽屏（≥1000px）：目录变成左侧常驻栏，与正文并排。
   放在文件最后、且不用 .toc-open 提升优先级 —— 断点即事实，JS 不需要参与判断。 */
@media (min-width: 1000px) {
  .report-layout { grid-template-columns: 216px minmax(0, 1fr); gap: 26px; }
  .report-layout .report-toc {
    display: block; margin: 0; padding: 12px 10px;
    position: sticky; top: calc(var(--topbar-h) + 12px);
    max-height: calc(100vh - var(--topbar-h) - 32px); overflow-y: auto;
  }
  .report-layout .report-toc a { padding: 5px 6px; }
  /* 宽屏左栏已经常驻，折叠按钮没有意义 */
  .toc-toggle { display: none; }
}
