/* ==========================================================================
   AIxls — 全站样式
   所有工具页共用一套骨架，仅通过 --accent 变量切换分类主色。
   品牌主色：蓝 #2563EB（theme-brand / :root 默认）；六分类色见底部 theme-*。
   ========================================================================== */

/* hidden 属性守卫（2026-09-12）：HTML hidden 靠浏览器默认 [hidden]{display:none} 生效，
 * 会被任何作者级 display（如 .btn 的 inline-flex）覆盖——JS 里 el.hidden=true 全部落空，
 * 「添加关联步骤 / 添加第一个关联步骤」两个互斥按钮同屏就是这里漏的。
 * 此守卫放最前，保证 .hidden 切换对全站所有元素生效。 */
[hidden] { display: none !important; }

:root {
  --accent: #2563eb;
  --accent-soft: #eff6ff;
  --accent-deep: #1d4ed8;

  --ink: #0f172a;
  --ink-2: #475569;
  --ink-3: #64748b;
  --ink-4: #94a3b8;

  --line: #e2e8f0;
  --line-strong: #cbd5e1;
  --surface: #ffffff;
  --surface-2: #f8fafc;
  --surface-3: #f1f5f9;

  --radius: 12px;
  --radius-lg: 16px;
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, .06);
  --shadow: 0 4px 16px rgba(15, 23, 42, .08);
  --shadow-lg: 0 12px 32px rgba(15, 23, 42, .12);

  --font: "PingFang SC", "Microsoft YaHei", "Sarasa Gothic SC", "Noto Sans SC",
    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Courier New", monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
}

html { scroll-padding-top: 80px; }

body {
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
button { font-family: inherit; }

.wrap {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 24px;
}

/* ------------------------------- 导航 ------------------------------- */

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 14px 40px;
  background: rgba(255, 255, 255, .88);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
}

.nav__brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -.01em;
}

/* 导航栏品牌区的一句话定位，让访客一眼知道网站做什么 */
.nav__tagline {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-2);
  letter-spacing: 0;
  padding-left: 12px;
  margin-left: 2px;
  border-left: 1px solid var(--line);
  white-space: nowrap;
}

/* 导航在窄屏会换行，tagline 在小屏隐藏避免拥挤（每页 hero 副标题已说明） */
@media (max-width: 907px) {
  .nav__tagline { display: none; }
}

.nav__mark {
  width: 28px;
  height: 28px;
  flex: none;
}

.nav__links {
  display: flex;
  align-items: center;
  gap: 26px;
}

.nav__links a {
  font-size: 15px;
  color: var(--ink-2);
  padding: 4px 0;
  border-bottom: 2px solid transparent;
  transition: color .15s, border-color .15s;
}

.nav__links a:hover { color: var(--ink); }

.nav__links a.is-active {
  color: var(--ink);
  font-weight: 600;
  border-bottom-color: var(--accent);
}

/* --------------------- 工具分类下拉（2026-09-16） --------------------- */

/* 触发器：桌面 hover 展开、触屏与键盘点击展开。
   hover 只做「加速」，真正的开关是 .is-open —— 纯 hover 菜单在触屏上等于没这个功能，
   而 AIxls 的导航窄屏只是换行、没有汉堡菜单，一旦依赖 hover 就是手机上直接失效。 */

.nav__drop { position: relative; }

.nav__drop-trigger {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  cursor: pointer;
}

/* 展开指示：两条边拼出的三角，展开时翻过来 */
.nav__drop-trigger::after {
  content: "";
  width: 6px;
  height: 6px;
  margin-top: -3px;
  border-right: 1.6px solid currentColor;
  border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg);
  transition: transform .18s;
}
.nav__drop.is-open .nav__drop-trigger::after {
  margin-top: 2px;
  transform: rotate(225deg);
}

.nav__panel {
  position: absolute;
  top: calc(100% + 14px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 60;
  display: none;
  /* 先给固定宽度兜底：老浏览器不认 min() 时会整条丢弃，没有兜底的话
     面板宽度会塌成 auto（跟着触发器那么窄），一眼就看出是坏的。 */
  width: 480px;
  width: min(480px, calc(100vw - 32px));
  padding: 18px 20px 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}

.nav__drop.is-open .nav__panel { display: block; }

/* 只给「真有指针」的设备绑 hover 展开：触屏浏览器在 tap 时会补发 mouseenter，
   不加这道闸，手机上会出现「展开又被自己收回去」，看着像点了没反应。
   is-suppressed 是「用户刚主动关掉」的标记 —— 没有它的话，点收起或按 Esc 时
   鼠标还停在触发器上，:hover 会立刻把面板顶回来，用户以为点不动。 */
@media (hover: hover) and (pointer: fine) {
  .nav__drop:hover:not(.is-suppressed) .nav__panel { display: block; }
}

.nav__panel-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 22px;
}

.nav__panel-col { display: flex; flex-direction: column; }

.nav__panel-cat {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-3);
  letter-spacing: .02em;
  padding: 2px 8px 6px;
  margin-bottom: 5px;
  border-bottom: 1px solid var(--line);
}
.nav__panel-cat:hover { color: var(--accent); }

.nav__panel-item {
  font-size: 14px;
  color: var(--ink);
  padding: 5px 8px;
  border-radius: 7px;
  transition: background .12s, color .12s;
}
.nav__panel-item:hover {
  background: var(--accent-soft);
  color: var(--accent-deep);
}

.nav__panel-foot {
  display: block;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: 13px;
  font-weight: 500;
  color: var(--accent);
}
.nav__panel-foot b { font-weight: 600; }

/* 窄屏：导航会换行，触发器在视口里的位置算不准 → 面板改用 fixed 贴视口两侧，
   top 由 JS 在展开时按实测位置写入（见 common.js#positionPanel）。
   这里必须留一个可用兜底值，避免 JS 未执行时面板飘在屏幕外。 */
@media (max-width: 860px) {
  .nav__panel {
    position: fixed;
    left: 16px;
    right: 16px;
    top: 72px;
    width: auto;
    transform: none;
    max-height: calc(100vh - 96px);
    overflow-y: auto;
  }
}

@media (max-width: 560px) {
  .nav__panel { padding: 14px 16px 12px; }
}

/* 真的窄到放不下两列了才退单列 —— 480px 视口下两列各约 197px，
   最长的「文本与结构批处理」也才 112px，没必要让用户滚那么久。 */
@media (max-width: 400px) {
  .nav__panel-cols { grid-template-columns: 1fr; gap: 10px; }
}

/* ------------------- 工具页「同组工具」快捷条 ------------------- */

/* 工具页之间原本跳不过去（想换工具得回首页滚网格），这条是那趟绕路的替代品。 */

.tool-quickbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px dashed var(--line);
}

.tool-quickbar__label {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-3);
  letter-spacing: .02em;
  margin-right: 6px;
}

.tool-quickbar__item {
  font-size: 13px;
  color: var(--ink-2);
  padding: 5px 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  transition: border-color .13s, color .13s, background .13s;
}
.tool-quickbar__item:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent-deep);
}

.tool-quickbar__all {
  font-size: 13px;
  font-weight: 500;
  color: var(--accent);
  margin-left: 6px;
  white-space: nowrap;
}

@media (max-width: 620px) {
  .tool-quickbar__all { margin-left: 0; }
}

/* ------------------------------- 按钮 ------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  /* UI 统一（2026-09-11）：按钮只留 3 档高度 —— sm 32 / 默认 40 / lg 50。
     原来靠 padding 凑，实测出来 28 / 32 / 33 / 37 / 43 / 51 / 56 共 7 种，
     尤其 40 与 43 只差 3px，看着像「做歪了」而不是「有意区分」。
     40 = 与表单控件同高，所以输入框旁边的按钮能严丝合缝对齐。 */
  height: 40px;
  padding: 0 20px;
  border: 1px solid transparent;
  border-radius: 10px;
  font-size: 15px;
  font-weight: 600;
  /* 必须写死行高：继承 body 的 1.6 会让 nav / hero 里的按钮比工具区同款高出 4~5px
     （实测 btn--sm 33px vs 37px、btn--lg 51px vs 56px）。UI 统一第一条。 */
  line-height: 1.25;
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, transform .1s, opacity .15s;
}

.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: not-allowed; }

.btn--primary {
  background: var(--accent);
  color: #fff;
}
.btn--primary:hover:not(:disabled) { background: var(--accent-deep); }

.btn--ghost {
  background: #fff;
  border-color: var(--line-strong);
  color: var(--ink);
}
.btn--ghost:hover:not(:disabled) { border-color: var(--ink-4); background: var(--surface-2); }

.btn--sm { height: 32px; padding: 0 14px; font-size: 13px; border-radius: 8px; }
.btn--lg { height: 50px; padding: 0 30px; font-size: 16px; }

/* ------------------------------- Hero ------------------------------- */

.hero {
  padding: 28px 0 24px;
  text-align: center;
  background: linear-gradient(180deg, var(--accent-soft) 0%, #fff 100%);
}

/* 首屏满屏布局（2026-09-04）：用户反馈顶部拥挤、工具标题行距首屏底部空隙过大。
 * 仅首页（.hero--home）：按断点设 min-height（100vh 减去 nav+统计卡+工具标题段的
 * 实测高度，留 20px 余量），让「点击任意工具即可开始…」落在第一屏底部；
 * 内容垂直居中，上下留白均衡。
 * min-height 小于自然高度时自动不生效（矮窗口安全）。常量基于 2026-09-04 实测：
 *   ≥1000px 统计卡 1 行（delta 262 / nav 66）；908-999 统计卡 2 行（delta 384）；
 *   721-907 统计卡 2 行 + 窄 nav（delta 405 / nav 62）；≤720 内容本就超首屏，不参与。 */
@media (min-width: 721px) {
  .hero--home { display: flex; flex-direction: column; justify-content: center; }
}
@media (min-width: 721px) and (max-width: 907px) {
  .hero--home { min-height: calc(100vh - 487px); }
}
@media (min-width: 908px) and (max-width: 999px) {
  .hero--home { min-height: calc(100vh - 470px); }
}
@media (min-width: 1000px) {
  /* 760px 上限防止超高分屏上 hero 与统计卡之间出现大片空洞 */
  .hero--home { min-height: min(calc(100vh - 348px), 760px); }
}

.hero h1 {
  margin: 0 0 10px;
  font-size: 36px;
  line-height: 1.22;
  letter-spacing: -.02em;
}

.hero__sub {
  margin: 0 auto;
  max-width: 640px;
  font-size: 16px;
  color: var(--ink-2);
}

.hero__badges {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 18px;
}

/* 窄屏 hero（2026-09-02 加）：h1 36px 在 320px 宽下会折成 3 行，
 * hero 实测高达 524px——小屏手机整屏才 568px，工具列表被整块挤到折叠线以下。
 * 按 520px 断点降字号与留白，把首屏还给内容。 */
@media (max-width: 520px) {
  .hero { padding: 20px 0 18px; }
  .hero h1 { font-size: 26px; margin-bottom: 8px; }
  .hero__sub { font-size: 15px; }
  /* 徽标缩一号，4 枚在 320px 下由 3 行降到 2 行（省约 40px） */
  .hero__badges { gap: 8px; margin-top: 14px; }
  .hero__badges .badge { padding: 5px 11px; font-size: 12.5px; }
  /* 窄屏 hero 两个大按钮竖排，收紧到 44（仍属「大 CTA」档，不与 32/40 混淆） */
  .hero .btn--lg { height: 44px; padding: 0 22px; font-size: 15px; }
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-size: 13px;
}

/* ------------------------------ 区块 ------------------------------ */

.section { padding: 44px 0; }
.section--soft { background: var(--surface-2); }
.section__title { margin: 0 0 6px; font-size: 24px; letter-spacing: -.01em; }
.section__desc { margin: 0 0 24px; color: var(--ink-3); }

.panel {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 28px;
  box-shadow: var(--shadow-sm);
}

/* ------------------------- 联系卡片（关于页） ------------------------- */
/* 一张「技术支持 / 邮箱 / 微信」的对齐表：窄屏自动把操作按钮换到下一行，
   避免按钮把值挤成省略号（联系方式被截断 = 用户复制不到，等于没有）。 */
.contact-card {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-2);
  overflow: hidden;
}

.contact-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 14px;
  padding: 14px 18px;
}

.contact-row + .contact-row { border-top: 1px solid var(--line); }

.contact-row__label {
  flex: 0 0 76px;
  color: var(--ink-3);
  font-size: 13px;
}

.contact-row__value {
  flex: 1 1 200px;
  min-width: 0;
  color: var(--ink);
  font-size: 15px;
  word-break: break-all;
}

.contact-row__value code {
  padding: 2px 8px;
  border-radius: 6px;
  background: #fff;
  border: 1px solid var(--line);
  font-size: 14px;
}

.contact-row__act {
  display: inline-flex;
  gap: 8px;
  margin-left: auto;
}

@media (max-width: 560px) {
  .contact-row__label { flex-basis: 100%; }
  .contact-row__act { margin-left: 0; }
}

/* ---------------------------- 上传区 ---------------------------- */

.dropzone {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 168px;
  padding: 32px;
  border: 2px dashed var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface-2);
  text-align: center;
  cursor: pointer;
  transition: border-color .15s, background .15s;
}

.dropzone:hover { border-color: var(--accent); background: var(--accent-soft); }
.dropzone.is-dragover { border-color: var(--accent); background: var(--accent-soft); }
.dropzone.is-filled { border-style: solid; border-color: var(--accent); background: var(--accent-soft); }
.dropzone input[type=file] { display: none; }

.dropzone__icon { width: 44px; height: 44px; color: var(--ink-3); margin-bottom: 4px; }
.dropzone__title { font-size: 15px; font-weight: 600; color: var(--ink-2); }
.dropzone__sub { font-size: 13px; color: var(--ink-4); word-break: break-all; max-width: 90%; }

/* recon 专用：主表/子表双上传区并排 + 压低高度（原 168px 太占地方） */
.recon-upload-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.recon-upload-row .dropzone--compact {
  min-height: 104px;
  padding: 16px;
  gap: 3px;
}
.recon-upload-row .dropzone__icon--sm { width: 28px; height: 28px; margin-bottom: 0; }
.recon-upload-row .dropzone__title { font-size: 14px; }
.recon-upload-row .dropzone__sub { font-size: 12px; }
@media (max-width: 620px) {
  .recon-upload-row { grid-template-columns: 1fr; }
}

.grid-2 {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 20px;
  align-items: center;
}

.vs {
  font-size: 15px;
  font-weight: 700;
  color: var(--ink-4);
  letter-spacing: .08em;
}

@media (max-width: 720px) {
  .grid-2 { grid-template-columns: 1fr; }
  .vs { text-align: center; }
}

/* ---------------------------- 表单控件 ---------------------------- */

.field { margin-bottom: 18px; }
.field:last-child { margin-bottom: 0; }

.field__labelrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 7px;
}
.field__labelrow .field__label { margin-bottom: 0; }

.field__label {
  display: block;
  margin-bottom: 7px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
}

.field__hint { font-size: 13px; color: var(--ink-4); margin-top: 6px; }

/* 合并方式下的自动检测说明：只在检测到表头不一致时出现，常态不显示。
 * 避免「纵向/横向一致时也加一行说明」的纯占位噪音。 */
.mode-hint {
  margin: 8px 0 0;
  font-size: 13px;
  line-height: 1.6;
  color: #92400e;
  background: #fffbeb;
  border: 1px solid rgba(180, 83, 9, .22);
  border-radius: 8px;
  padding: 8px 12px;
}
.mode-hint[hidden] { display: none; }

.select,
.input {
  width: 100%;
  height: 40px;          /* 与按钮、步骤卡控件同一基线（见「全站控件基线」注释） */
  padding: 0 12px;
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  font-family: inherit;
  font-size: 14px;
  color: var(--ink);
  background: #fff;
}

.select:focus,
.input:focus { outline: 2px solid var(--accent-soft); border-color: var(--accent); }

.input--sm { width: 110px; }

/* 多行文本（批量替换对照表等）；等宽字体便于对齐「旧值 = 新值」 */
.textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.7;
  color: var(--ink);
  background: #fff;
  resize: vertical;
}
.textarea:focus { outline: 2px solid var(--accent-soft); border-color: var(--accent); }

/* 规则勾选项下面的参数区 */
.rule-pane {
  margin: 10px 0 0 26px;
  padding: 14px 16px;
  border-left: 2px solid var(--line);
  background: var(--surface-2);
  border-radius: 0 8px 8px 0;
}
.rule-pane:empty { display: none; }

.checkline {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 6px 0;
  cursor: pointer;
  font-size: 14px;
  color: var(--ink-2);
}

.checkline input { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
.checkline:hover { color: var(--ink); }

.radioline {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 6px 0;
  cursor: pointer;
  font-size: 14px;
  color: var(--ink-2);
}
.radioline input { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }

.colpick-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  max-height: 220px;
  overflow-y: auto;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--surface-2);
}

.colpick {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #fff;
  font-size: 13px;
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.colpick:hover { border-color: var(--accent); }
.colpick input { accent-color: var(--accent); width: 14px; height: 14px; }
.colpick:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-weight: 600;
}

.sheet-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
  margin-top: 12px;
}
.sheet-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--border, #e2e8f0);
  border-radius: 12px;
  background: var(--surface, #fff);
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.sheet-card:hover { border-color: var(--accent); background: var(--accent-soft); }
.sheet-card__chk { width: 18px; height: 18px; accent-color: var(--accent); flex-shrink: 0; }
.sheet-card:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.sheet-card__body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.sheet-card__name {
  font-weight: 600;
  color: var(--ink, #0f172a);
  word-break: break-all;
  font-size: 14.5px;
}
.sheet-card__meta { font-size: 12.5px; color: var(--ink-3, #64748b); }

.inline { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* ---------------------------- 结果统计 ---------------------------- */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: 14px;
  margin-bottom: 22px;
}

.stat {
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
}

.stat__value { font-size: 26px; font-weight: 700; letter-spacing: -.02em; }
.stat__label { font-size: 13px; color: var(--ink-3); margin-top: 2px; }

.stat--same .stat__value { color: #16a34a; }
.stat--modified .stat__value { color: #d97706; }
.stat--onlya .stat__value { color: #2563eb; }
.stat--onlyb .stat__value { color: #7c3aed; }
.stat--accent .stat__value { color: var(--accent); }
.stat--muted .stat__value { color: var(--ink-3); }
.stat--warn .stat__value { color: #dc2626; }

/* 卡片下方小字：比率 / 对照 / 守恒结论。颜色跟随卡片语义色，不另设一套。 */
.stat__hint { font-size: 12px; color: var(--ink-4); margin-top: 4px; }
.stat--same .stat__hint { color: #16a34a; }
.stat--modified .stat__hint { color: #d97706; }
.stat--accent .stat__hint { color: var(--ink-4); }
.stat--warn .stat__hint { color: #dc2626; }

/* ---------------------------- 预览表 ---------------------------- */

.preview__empty {
  margin: 0;
  padding: 36px;
  text-align: center;
  color: var(--ink-4);
  background: var(--surface-2);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
}

.preview__scroll {
  max-height: 440px;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
}

.preview__table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 13px;
}

.preview__table th,
.preview__table td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
  max-width: 260px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.preview__table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface-3);
  font-weight: 600;
  color: var(--ink);
  text-align: left;
}

.preview__table tbody tr:hover td { background: var(--surface-2); }

.preview__rownum {
  width: 48px;
  text-align: right;
  color: var(--ink-4);
  background: var(--surface-2);
  position: sticky;
  left: 0;
  z-index: 1;
}
.preview__table thead .preview__rownum { z-index: 3; }

.preview__table tr.is-modified td.is-diff { background: #fffbeb; color: #92400e; }
.preview__table tr.is-onlya td { background: #eff6ff; }
.preview__table tr.is-onlyb td { background: #f5f3ff; }
/* 去重「被移除行」整行高亮：红色语义 = 将被删除，供复核后决定是否下载留档 */
.preview__table tbody tr.is-dupe td { background: #fef2f2; }
.preview__table tbody tr.is-dupe:hover td { background: #fee2e2; }

.preview__more {
  margin: 10px 0 0;
  font-size: 13px;
  color: var(--ink-4);
  text-align: center;
}

.chip {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
.chip--same { background: #f0fdf4; color: #15803d; }
.chip--modified { background: #fffbeb; color: #b45309; }
.chip--onlya { background: #eff6ff; color: #1d4ed8; }
.chip--onlyb { background: #f5f3ff; color: #6d28d9; }
.chip--neutral { background: var(--surface-3); color: var(--ink-3); }

/* ---------------------------- 首页卡片 ---------------------------- */

/* ----------------------- 首页工具分组（2026-09-16） ----------------------- */

/* 18 个工具平铺时只能一路滚着找，分组让「想干什么」到「看到工具名」少一次搜索。
   分组依据与顺序来自 assets/js/common.js#TOOL_GROUPS，由 scripts/reorder-tool-cards.cjs 生成。 */

.tool-groups {
  display: flex;
  flex-direction: column;
  gap: 34px;
}

/* 导航是 sticky 的，锚点跳过来时标题会被压在导航底下——这一行是必需的，
   不是美化。 */
.tool-group { scroll-margin-top: 90px; }

.tool-group__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  margin-bottom: 16px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

.tool-group__title {
  margin: 0;
  font-size: 17px;
  letter-spacing: -.01em;
}

.tool-group__desc {
  margin: 0;
  font-size: 13px;
  color: var(--ink-3);
}

/* 方案体系入口跨工具、不属于任何单一分类，单独收在最后，
   用一条虚线跟上面的分类拉开，免得看着像第五个分类。 */
.tool-feature {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 20px;
  padding-top: 26px;
  border-top: 1px dashed var(--line);
  scroll-margin-top: 90px;
}

.tool-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 20px;
}

.tool-card {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto 1fr auto;
  align-items: center;
  gap: 14px;
  padding: 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: #fff;
  box-shadow: var(--shadow-sm);
  transition: transform .15s, box-shadow .15s, border-color .15s;
}

.tool-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow);
  border-color: var(--line-strong);
}

.tool-card__icon {
  grid-column: 1;
  grid-row: 1;
  width: 48px;
  height: 48px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.tool-card__icon svg { width: 26px; height: 26px; }
.tool-card h3 { grid-column: 2; grid-row: 1; margin: 0; font-size: 18px; }
.tool-card p { grid-column: 1 / -1; grid-row: 2; margin: 0; font-size: 14px; color: var(--ink-3); flex: none; }

.tool-card__go {
  grid-column: 1;
  grid-row: 3;
  font-size: 14px;
  font-weight: 600;
  color: var(--accent-deep);
}

.feature-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 20px;
}

.feature {
  padding: 26px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: #fff;
}
.feature h3 { margin: 14px 0 6px; font-size: 17px; }
.feature p { margin: 0; font-size: 14px; color: var(--ink-3); }

.feature__icon { width: 40px; height: 40px; }

/* 特性卡里的补充说明（如「某功能规划中，尚未启用」）。
   .feature p 统一 margin:0，出现多段落时由这里补间距。
   注意选择器必须写成 .feature .feature__note —— 单写 .feature__note 的特异性
   (0,1,0) 低于 .feature p 的 (0,1,1)，字号与颜色会被静默覆盖。 */
.feature p + p { margin-top: 8px; }
.feature .feature__note {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--line);
  font-size: 13px;
  color: var(--ink-4);
}

.metric-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.metric { padding: 24px; background: #fff; text-align: center; }
.metric__value { font-size: 30px; font-weight: 700; letter-spacing: -.02em; }
.metric__label { font-size: 13px; color: var(--ink-3); margin-top: 4px; }

/* --------------------------- 底部转化区 --------------------------- */

.cta-band {
  padding: 40px 0;
  background: linear-gradient(180deg, var(--surface) 0%, var(--accent-soft) 100%);
  border-top: 1px solid var(--line);
}

.cta-band__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  flex-wrap: wrap;
}

.cta-band h2 { margin: 0 0 8px; font-size: 24px; letter-spacing: -.01em; }
.cta-band p { margin: 0; font-size: 14px; color: var(--ink-3); max-width: 560px; line-height: 1.7; }
.cta-band__actions { display: flex; gap: 12px; flex-wrap: wrap; }

/* ------------------------------ 页脚 ------------------------------ */

.footer {
  margin-top: 0;
  padding: 48px 0;
  background: #0f172a;
  color: #e2e8f0;
}

.footer__brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 20px;
  font-weight: 700;
  color: #fff;
}

.footer__tagline { margin: 14px 0 0; font-size: 14px; color: #94a3b8; max-width: 340px; line-height: 1.7; }

.footer__trust { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
.footer__trust-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border: 1px solid #1e293b;
  border-radius: 999px;
  background: rgba(148, 163, 184, .07);
  font-size: 12px;
  color: #94a3b8;
}
.footer__trust-item svg { flex: none; color: #4ade80; }

/* 顶部区：左侧品牌+信任徽标，右侧固定四栏链接。
   注意用固定 4 列而非 auto-fit：auto-fit 会把 3 组短链接拉伸到整行宽度，
   在大屏上留下大片横向空白。 */
.footer__top {
  display: grid;
  grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: 48px;
  align-items: start;
}

.footer__cols {
  display: grid;
  /* 2026-09-16：改 4 列网格，第一列「全部工具」跨 2 列。
     原来 3 等分时第一列只有 245px，再拆 2×2 每组仅 111px ——
     「自然语言查表」这种 6 字名会挤成两行，比平铺还难读（真机量过）。
     跨 2 列后每组约 178px，四组 2×2 排得开。 */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 24px;
}

.footer__cols > div:first-child { grid-column: span 2; }

/* 2026-09-16：「全部工具」改为按 4 个分类分组（数据源 common.js#TOOL_GROUPS），
   2×2 排布、每组带小标题。分组与链接由 scripts/sync-footer-tool-groups.cjs 生成，
   这里只管版式。
   （上一版是 2026-09-10 的「14 项单列太长 → 纯 CSS 拆双栏」，靠折行压高度，
     但用户看页脚时仍然看不出工具是按用途分的 —— 与顶部导航对不上。） */
.footer-cat {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 24px;
  row-gap: 14px;      /* 分组已经把 18 项重新组织过，行距不必再留那么大 */
  align-content: start;
}

.footer-cat__group { min-width: 0; }

.footer-cat__group h5 {
  margin: 0 0 4px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .02em;
  color: #cbd5e1;   /* 比链接亮、比 h4 暗，形成「组名 → 组员」的层次 */
}

/* 组内链接比普通页脚链接紧一点：18 项比原来多出 4 行组名，
   页脚每高 1px 都是全局代价（21 个页面都带着它）。
   ⚠️ 必须带 .footer__cols 前缀：`.footer__cols a` 是同特异性、且定义在本条**之后**，
   光写 .footer-cat a 会被它覆盖（宽度够、高度白省）。 */
.footer__cols .footer-cat a { padding: 2px 0; font-size: 13.5px; }

.footer__cols h4 { margin: 0 0 10px; font-size: 14px; color: #fff; }
.footer__cols a { display: block; padding: 3px 0; font-size: 14px; color: #94a3b8; }
.footer__cols a:hover { color: #fff; }

.footer__bottom {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 36px;
  padding-top: 20px;
  border-top: 1px solid #1e293b;
  font-size: 13px;
  color: #64748b;
}

.footer__beian {
  color: #94a3b8;
  text-decoration: none;
}
.footer__beian:hover {
  color: #cbd5e1;
  text-decoration: underline;
}
/* 公安备案号：图标 + 文字并排（图标由 beian.mps.gov.cn 官方下载，本地 assets/beian.png）
   ⚠️ 官方图标是 **36×40 非正方形**，所以只锁高度、宽度 auto 按比例 —— 写 width:20px 会拉伸 11%。 */
.footer__beian--mps {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.footer__beian--mps img {
  display: block;
  height: 20px;
  width: auto;
}

/* --------------------------- Toast / Busy --------------------------- */

.toast-host {
  position: fixed;
  top: 76px;
  right: 20px;
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.toast {
  padding: 11px 16px;
  border-radius: 10px;
  background: #0f172a;
  color: #fff;
  font-size: 14px;
  box-shadow: var(--shadow-lg);
  opacity: 1;
  transform: translateX(0);
  transition: opacity .2s, transform .2s;
  max-width: 340px;
  display: flex;
  align-items: center;
  gap: 10px;
}

/* 错误/警告 toast 的「复制」按钮（跨工具共用，反馈报错一键复制全文） */
.toast__copy {
  flex: 0 0 auto;
  padding: 2px 10px;
  border: 1px solid rgba(255, 255, 255, .45);
  border-radius: 6px;
  background: transparent;
  color: #fff;
  font-size: 12px;
  line-height: 1.6;
  cursor: pointer;
}
.toast__copy:hover { background: rgba(255, 255, 255, .15); }

.toast.is-out { opacity: 0; transform: translateX(12px); }
.toast--success { background: #15803d; }
.toast--error { background: #b91c1c; }
.toast--warn { background: #b45309; }

.busy {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: none;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 14px;
  /* 不糊化背景：blur 会让后面的文件卡片进度条发虚（Jay 23:59 截图）。
     提高一点不透明度，让弹窗更聚焦，同时保留 faint 背景可见性。 */
  background: rgba(255, 255, 255, .88);
}
.busy.is-visible { display: flex; }

.busy__spinner {
  width: 34px;
  height: 34px;
  border: 3px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .8s linear infinite;
}

.busy__text { font-size: 18px; font-weight: 600; color: var(--ink); text-align: center; max-width: 82vw; }

/* 进度百分比（醒目大字）+ 进度条：让慢操作一眼看到「到哪了」 */
.busy__progress {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: min(420px, 78vw);
}
.busy__ptrow { display: flex; align-items: baseline; gap: 4px; }
.busy__pct {
  font-size: 46px;
  font-weight: 800;
  line-height: 1;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  letter-spacing: -1px;
}
.busy__pct-sign { font-size: 20px; font-weight: 700; color: var(--accent); }
.busy__bar {
  width: 100%;
  height: 10px;
  border-radius: 999px;
  background: var(--line);
  overflow: hidden;
}
.busy__bar-fill {
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: var(--accent);
  transition: width .18s ease-out;
}
/* 不确定进度（无法估算百分比）：显示流动条纹，明确「在动」 */
.busy__bar.is-indeterminate .busy__bar-fill {
  width: 34%;
  transition: none;
  animation: busySlide 1.1s ease-in-out infinite;
}
@keyframes busySlide {
  0%   { margin-left: -34%; }
  100% { margin-left: 100%; }
}

/* --------------------------- 确认弹窗（XL.confirm） --------------------------- */
/* 全站唯一的「是/否」确认通道：比原生 confirm 好看、可换按钮文案、返回 Promise。
   层级 400 > busy(300) > toast(200)，保证任何状态下都能弹出来。 */
.xl-confirm {
  position: fixed;
  inset: 0;
  z-index: 400;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(15, 23, 42, .38);
  padding: 20px;
}
.xl-confirm[hidden] { display: none; }
.xl-confirm__card {
  width: 100%;
  max-width: 420px;
  padding: 20px 22px;
  border-radius: var(--radius-lg, 14px);
  background: #fff;
  box-shadow: var(--shadow-lg);
}
.xl-confirm__msg {
  font-size: 14.5px;
  line-height: 1.65;
  color: var(--ink, #0f172a);
  word-break: break-word;
  white-space: pre-line;   /* 文案里可以用 \n 分段 */
}
.xl-confirm__actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 18px;
  flex-wrap: wrap;
}

/* 进度副行：当前文件名 / 第 i/N 个 / 已用时 X.Xs —— 让慢操作有可感知的进度与时间 */
.busy__sub { font-size: 14px; color: var(--ink-3); max-width: 82vw; text-align: center; word-break: break-all; line-height: 1.5; }

@keyframes spin { to { transform: rotate(360deg); } }

/* ------------------------------ 杂项 ------------------------------ */

.hint { margin: 0; font-size: 13px; color: var(--ink-4); }
.divider { height: 1px; background: var(--line); margin: 28px 0; }

/* ------------------------- FAQ / 最佳实践 ------------------------- */

.faq { margin: 0; }
.faq__item { padding: 18px 0; border-bottom: 1px solid var(--line); }
.faq__item:first-child { padding-top: 0; }
.faq__item:last-child { padding-bottom: 0; border-bottom: 0; }
.faq__q { margin: 0 0 8px; font-size: 15px; font-weight: 600; color: var(--ink); }
.faq__a { margin: 0; font-size: 14px; color: var(--ink-2); line-height: 1.7; }

.best-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 20px;
}
.best {
  padding: 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: #fff;
}
.best h3 { margin: 0 0 8px; font-size: 16px; }
.best p { margin: 0; font-size: 14px; color: var(--ink-3); line-height: 1.6; }

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

/* ===================== 智能对账（recon）UI 重设计 P0-a.2/3 =====================
 * 设计原则（详见 docs/recon-ui-redesign.md）：
 *   1. 三层视觉分组：页面（顶部流程条）/ 卡片（步骤卡 + 文件卡）/ 段落（fieldset）
 *   2. 零术语：所有控件给业务翻译（主表 = 出发表 / 维表 = 关联表 / left = 保留主表全部行）
 *   3. 默认安全：不勾 = 不裁剪原列；勾选 = 显式控制输出
 *   4. 进度可视化：摘要行 + 流程条 + 进度条
 */

/* 告警面板（2026-09-15 补样式）
 * ⚠️ `.callout-warning` 从 P0-a 起就在用（#fileGuard / #runGuard / #resultWarnings），
 *    但**样式一直没写** —— 于是这些守卫提示在页面上是「裸文本」，既不像告警、也和正文混在一起，
 *    用户很容易整段跳过。这里补成「左侧色条 + 浅底 + 圆角」的告警块。
 *    默认琥珀色（warning 语义：数据可疑 / 还没配好）；硬失败加 --error 变红。 */
.callout-warning {
  border: 1px solid rgba(180, 83, 9, .28);
  border-left: 4px solid #d97706;
  background: #fffbeb;
  border-radius: var(--radius);
  padding: 12px 14px;
  margin: 12px 0;
  font-size: 14px;
  line-height: 1.65;
  color: #78350f;
}
.callout-warning strong { color: #92400e; }
.callout-warning ol {
  margin: 8px 0 0;
  padding-left: 22px;
}
.callout-warning li { margin: 4px 0; }
.callout-warning details { margin-top: 10px; }
.callout-warning summary {
  cursor: pointer;
  font-size: 13px;
  color: #92400e;
  opacity: .9;
}
.callout-warning pre {
  margin: 8px 0 0;
  padding: 10px;
  max-height: 180px;
  overflow: auto;
  background: rgba(120, 53, 15, .07);
  border-radius: 8px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
}
/* 硬失败（执行出错）用红色，与「数据可疑」区分 */
.callout-warning--error {
  border-color: rgba(185, 28, 28, .28);
  border-left-color: #b91c1c;
  background: #fef2f2;
  color: #7f1d1d;
}
.callout-warning--error strong { color: #991b1b; }
.callout-warning--error summary { color: #991b1b; }
.callout-warning--error pre { background: rgba(127, 29, 29, .06); }

/* 文件区卡片网格（P0-a.3） */
.recon-file-grid {
  display: grid;
  /* 一行 2 张（原 auto-fill 会在宽屏排 4 张，卡片内容挤得看不清） */
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  margin-bottom: 16px;
}
@media (max-width: 620px) {
  .recon-file-grid { grid-template-columns: 1fr; }
}
.recon-file-card {
  position: relative;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: #fff;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: border-color .15s;
}
.recon-file-card:hover { border-color: var(--ink-4); }
.recon-file-card[data-role="main"] { border-color: rgba(29, 158, 117, .35); background: rgba(29, 158, 117, .03); }
.recon-file-card[data-role="table"] { border-color: rgba(37, 99, 235, .25); }
.recon-file-card__name {
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  word-break: break-all;
  padding-right: 40px;   /* 让位给右上角 32px 的 × 按钮（原 24px 会被放大后的图标压住） */
}
.recon-file-card__meta {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--ink-3);
}
.recon-file-card__badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
}
.recon-file-card__badge--main { background: rgba(29, 158, 117, .12); color: #0f6e56; }
.recon-file-card__badge--table { background: rgba(37, 99, 235, .10); color: #185fa5; }
.recon-file-card__badge--pending { background: rgba(180, 120, 20, .12); color: #8a5a10; }
/* 解析中的占位卡片：虚线边框 + 弱化底，和已就绪的卡片一眼区分 */
.recon-file-card--pending {
  border-style: dashed;
  border-color: var(--line-strong);
  background: rgba(0, 0, 0, .015);
}
.recon-file-progress {
  height: 10px;
  border-radius: 999px;
  background: var(--line);
  overflow: hidden;
  /* 加一层微弱发光，让它在半透 busy 遮罩后仍能被一眼看到 */
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.04);
}
.recon-file-progress__bar {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 999px;
  /* 用深色 accent，穿透 busy 遮罩后仍保留足够对比度 */
  background: var(--accent-deep);
  transition: width .2s ease;
}
.recon-file-progress__text {
  font-size: 13px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  text-align: right;
}
.recon-file-card__menu {
  position: absolute;
  top: 10px;
  right: 10px;
}
.recon-file-card__row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.recon-file-card__row select { flex: 1; min-width: 0; }
/* 对账页：统一的区块间距（替掉原来散在 HTML 里的 inline style，
   同一种间距写死 4 遍必然会长歪） */
.section__title--gap { margin-top: 32px; }
.recon-block { margin-bottom: 18px; }
.recon-row--gap { margin-top: 16px; }

/* 套用/保存方案板块：输入框/下拉框与按钮同一行（不再让 .input 独占整行）。
   输入/选择用 flex:1 自适应剩余宽度，按钮保持自然宽度；窄屏时整体优雅换行。 */
.recipebar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.recipebar #recipeSel { flex: 1 1 240px; width: auto; min-width: 180px; }
.recipebar #recipeName { flex: 1 1 240px; width: auto; min-width: 180px; max-width: 420px; }
.recipebar .btn { flex: 0 0 auto; }
.recon-upload-note { text-align: center; margin: 8px 0 0; }

/* 全站控件基线（2026-09-11 UI 统一）：高度统一 40px、字号 14px。
   之前同一屏里 select 37 / input 35 / .input 39 / 分隔符 27 —— 五种高度，
   并排时肉眼可见地参差不齐（Jay 反馈「选择框高度太小、不像一套的」）。
   定死 height 而不是靠 padding 凑：select 的 UA 默认行高和 input 不一样，
   只用 padding 永远差 2px。 */
.recon-file-card select,
.recon-step-row select,
.recon-step-row input[type="text"],
.recon-step-actions__inline input[type="text"] {
  height: 40px;
  padding: 0 10px;
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  font-family: inherit;
  font-size: 14px;
  color: var(--ink);
  background: #fff;
}
.recon-file-card select:focus,
.recon-step-row select:focus,
.recon-step-row input[type="text"]:focus,
.recon-step-actions__inline input[type="text"]:focus {
  outline: 2px solid var(--accent-soft);
  border-color: var(--accent);
}
/* concat 分隔符：窄输入框，但高度/字号跟同排控件一致（原来 inline style width:60px 只有 27px 高） */
.recon-step-actions__inline input[type="text"] { width: 72px; }

/* 步骤卡片 4 段落（P0-a.2） */
.recon-step-card {
  padding: 20px 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: #fff;
  margin-bottom: 16px;
}
.recon-step-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 4px;
}
.recon-step-card__head h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
}
.recon-step-card__summary {
  font-size: 12px;
  color: var(--ink-3);
  line-height: 1.55;
  padding: 8px 12px;
  margin-bottom: 14px;
  background: var(--surface-2);
  border-radius: var(--radius-md);
  border-left: 3px solid var(--accent);
}
.recon-step-card__menu {
  display: flex;
  gap: 6px;
}
.recon-step-section {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 14px 16px 12px;
  margin-bottom: 12px;
}
.recon-step-section legend {
  font-size: 13px;
  font-weight: 500;
  padding: 0 6px;
  color: var(--ink);
}
.recon-step-section .hint { font-size: 12px; color: var(--ink-3); margin-top: 8px; line-height: 1.55; }
.recon-step-row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: center;
}
.recon-step-row label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  min-width: 140px;
  font-size: 12px;
  color: var(--ink-3);
}
.recon-step-row label select { font-size: 14px; }
.recon-step-actions {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-top: 8px;
  flex-wrap: wrap;
}
.recon-step-actions__spacer { flex: 1; }
.recon-step-actions__inline {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--ink-3);
}
/* 分隔符输入框已并入「全站控件基线」（40px / 14px），这里只保留容器排布 */
.recon-step-actions__inline { display: inline-flex; align-items: center; gap: 6px; }
.recon-step-actions__inline span { font-size: 13px; color: var(--ink-3); }

/* kebab 操作菜单按钮 */
.btn--icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 28→32：和 btn--sm(33) 同一档，点击目标也够大；圆角 6→8、字号 16→15 与按钮体系一致 */
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  font-size: 15px;
  color: var(--ink-3);
  cursor: pointer;
  line-height: 1;
  transition: color .15s, border-color .15s;
}

/* ===================== 智能对账 P0-a.1 顶部流程条 =====================
 * 4 阶段：导入 → 构建 → 执行 → 下载
 *   is-done（绿色）：已完成
 *   is-active（蓝框+淡蓝底）：当前阶段
 *   两者皆无（灰）：未开始
 * 子条：实时显示「主表 + 2 张维表 ✓ │ s1 ✓ │ s2 ▣ 执行中… │ ☐ 下载」
 */
.recon-progress {
  background: #fff;
  border-bottom: 1px solid var(--line);
  padding: 16px 0 12px;
}
.recon-progress__bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
.recon-progress__step {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8px 16px;
  border-radius: var(--radius-md);
  border: 1.5px solid transparent;
  transition: border-color .2s, background .2s;
  min-width: 96px;
}
.recon-progress__num {
  font-size: 18px;
  font-weight: 600;
  color: var(--ink-3);
  line-height: 1;
  transition: color .2s;
}
.recon-progress__label {
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 4px;
  transition: color .2s;
}
.recon-progress__arrow {
  color: var(--ink-4);
  font-size: 14px;
  opacity: .5;
}
.recon-progress__step.is-done .recon-progress__num,
.recon-progress__step.is-done .recon-progress__label {
  color: #0f6e56;
}
.recon-progress__step.is-done {
  border-color: rgba(29, 158, 117, .25);
  background: rgba(29, 158, 117, .04);
}
.recon-progress__step.is-active .recon-progress__num {
  color: var(--accent);
}
.recon-progress__step.is-active .recon-progress__label {
  color: var(--ink);
  font-weight: 500;
}
.recon-progress__step.is-active {
  border-color: var(--accent);
  background: rgba(37, 99, 235, .05);
}
.recon-progress__sub {
  text-align: center;
  font-size: 12px;
  color: var(--ink-3);
  min-height: 22px;
  padding: 4px 16px 0;
  line-height: 1.6;
}
.recon-progress__sub .ok { color: #0f6e56; font-weight: 500; }
.recon-progress__sub .pending { color: var(--accent); }
.recon-progress__sub .sep {
  display: inline-block;
  margin: 0 8px;
  color: var(--ink-4);
}
.recon-progress__hint {
  color: var(--ink-4);
  font-style: italic;
}
.recon-progress__sub .run-progress {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.recon-progress__sub .run-progress__bar {
  display: inline-block;
  width: 60px;
  height: 6px;
  background: var(--line);
  border-radius: 3px;
  overflow: hidden;
  vertical-align: middle;
}
.recon-progress__sub .run-progress__bar > span {
  display: block;
  height: 100%;
  background: var(--accent);
  transition: width .2s;
}

/* ===================== 智能对账 P0-a.4 执行进度条 + 取消按钮 =====================
 * 进度条 DOM 动态插入到 #busyOverlay 内（不动公共层）。
 * 进度文本 + 进度条 + 取消按钮垂直堆叠在 spinner 下方。
 */
.recon-run-progress {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  margin-top: 16px;
  width: min(420px, 86vw);
  /* 进度比例/进度条 sits on #busyOverlay 的半透毛玻璃上，字会发虚。
     加一层实底白卡片，让文字和进度条彻底脱离毛玻璃背景，对比度拉回来。 */
  padding: 18px 22px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 10px 34px rgba(15, 23, 42, .10);
}
.recon-run-progress__text {
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  text-align: center;
  min-height: 20px;
  word-break: break-all;
}
.recon-run-progress__bar {
  width: 100%;
  height: 10px;
  background: var(--line);
  border-radius: 999px;
  overflow: hidden;
}
.recon-run-progress__bar > span {
  display: block;
  height: 100%;
  width: 0;
  background: var(--accent);
  border-radius: 999px;
  transition: width .15s ease-out;
}
/* 2026-09-13：进度百分比 + 大号计时（与 .recon-dl-progress 同款，对齐下载卡）。
   百分比放左边、计时放右边，gap 16px 让两件信息都呼吸开来。 */
.recon-run-progress__meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  width: 100%;
  gap: 16px;
}
.recon-run-progress__percent {
  font-size: 16px;
  font-weight: 600;
  color: var(--accent);
  font-variant-numeric: tabular-nums;   /* 数字等宽，百分比跳动不抖版 */
}
.recon-run-progress__timer {
  font-size: 28px;
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}
.recon-run-progress__cancel {
  background: #fff;
  border: 1px solid var(--line-strong);
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 500;
  height: 32px;
  padding: 0 16px;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: border-color .15s, color .15s;
}
.recon-run-progress__cancel:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}
.recon-run-progress__cancel:disabled {
  opacity: .5;
  cursor: not-allowed;
}

/* ===================== 智能对账 XLSX 下载进度卡（Jay 2026-09-12 深夜）=====================
 * 大表 XLSX 生成要等十几秒到一分钟：角落 12px 的「已用时」看不清、也没有进度感。
 * 卡片 = 阶段文案（真实行进度/百分比）+ 进度条 + 28px 大号计时字。
 * DOM 由 recon.js 动态注入 #busyOverlay（同 .recon-run-progress 模式，不动公共层）。
 */
.recon-dl-progress {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  margin-top: 16px;
  width: min(420px, 86vw);
  padding: 18px 22px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 10px 34px rgba(15, 23, 42, .10);
}
.recon-dl-progress__phase {
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  text-align: center;
  min-height: 20px;
  word-break: break-all;
}
.recon-dl-progress__bar {
  width: 100%;
  height: 10px;
  background: var(--line);
  border-radius: 999px;
  overflow: hidden;
}
.recon-dl-progress__bar > span {
  display: block;
  height: 100%;
  width: 0;
  background: var(--accent);
  border-radius: 999px;
  transition: width .15s ease-out;
}
.recon-dl-progress__timer {
  font-size: 28px;
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums;   /* 数字等宽，秒数跳动不抖版 */
  line-height: 1.2;
}

/* 每步中间结果：分步骤展示 + 下载 */
.recon-step-outputs { margin-top: 24px; }
.recon-step-outputs__title {
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
  margin: 0 0 14px;
}
.recon-step-output {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin-bottom: 14px;
}
.recon-step-output__header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 18px;
  margin-bottom: 12px;
}
.recon-step-output__title {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
}
.recon-step-output__stats {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  font-size: 13px;
  color: var(--ink-2);
  flex: 1 1 auto;
}
.recon-step-output__stats > span {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 3px 9px;
}

/* ===================== 智能对账 P0-b 键类型诊断 =====================
 * 显示在步骤卡「关联键」段落下方：
 *   --ok  绿色（类型一致）
 *   --warn 黄色（含不可见字符 / 首尾空白 / 类型不一致）
 *   --info 灰色（待诊断）
 * 红线：诊断只是告诉用户「做了什么」，绝不修改原数据。
 */
.recon-diag {
  font-size: 12px;
  line-height: 1.55;
  padding: 6px 10px;
  margin-top: 8px;
  border-radius: var(--radius-md);
  border-left: 3px solid;
}
.recon-diag--ok {
  background: rgba(29, 158, 117, .06);
  color: #0f6e56;
  border-left-color: rgba(29, 158, 117, .5);
}
.recon-diag--warn {
  background: rgba(217, 119, 6, .07);
  color: #92590b;
  border-left-color: rgba(217, 119, 6, .5);
}
.recon-diag--info {
  background: var(--surface-2);
  color: var(--ink-3);
  border-left-color: var(--ink-4);
}
.btn--icon:hover { color: var(--ink); border-color: var(--ink-4); }

/* 旧 .recon-file-row / .recon-step-row / .recon-step-fs 已废弃：v0 布局（截图 1-4 那种挤在一起的样式）
   新卡片用 .recon-file-card / .recon-step-card / .recon-step-section。
   旧类名仍存在但无样式，保留以兼容可能的旧 CSS（browser-smoke 探针）。 */

.result { display: none; }
.result.is-active { display: block; }

.notice {
  padding: 12px 16px;
  border-radius: 10px;
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-size: 13px;
  border: 1px solid rgba(29, 78, 216, .18);
}

.notice--warn {
  background: #fffbeb;
  color: #92400e;
  border-color: rgba(180, 83, 9, .22);
}

/* 智能对账：事前重复键提示条（Jay 2026-09-14 拍板「事前提示，不阻断」） */
.recon-dupwarn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 12px;
}
.recon-dupwarn__text { flex: 1 1 260px; line-height: 1.7; }

.notice--info {
  background: var(--surface-2, #f8fafc);
  color: var(--ink-2, #475569);
  border-color: var(--line, #e2e8f0);
  line-height: 1.75;
  margin-bottom: 20px;
}

/* 生成文件清单（合并工具多选下载） */
.filelist {
  border: 1px solid var(--line, #e2e8f0);
  border-radius: var(--radius-lg, 14px);
  overflow: hidden;
}

.filelist__head {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 16px;
  background: var(--surface-2, #f8fafc);
  border-bottom: 1px solid var(--line, #e2e8f0);
}

.filelist__head .checkline { margin: 0; }

.filelist__count {
  font-size: 12.5px;
  color: var(--ink-3, #64748b);
}

.filelist__spacer { flex: 1 1 auto; }

.filelist__items {
  list-style: none;
  margin: 0;
  padding: 0;
}

.fl-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line, #e2e8f0);
}

.fl-item:last-child { border-bottom: 0; }

.fl-item__chk { margin: 0; flex: 0 0 auto; }

.fl-item__main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.fl-item__name {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-1, #0f172a);
  word-break: break-all;
}

.fl-item__meta {
  font-size: 12.5px;
  color: var(--ink-3, #64748b);
}

.fl-item__dl { flex: 0 0 auto; }

/* ---------------------------- AI 面板 ---------------------------- */

.ai-panel {
  margin-top: 24px;
  padding: 24px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: #fff;
  box-shadow: var(--shadow-sm);
}

.ai-panel__head {
  display: flex;
  align-items: center;
  gap: 10px;
}

.ai-panel__icon { width: 22px; height: 22px; color: var(--accent); flex: none; }
.ai-panel__title { margin: 0; font-size: 17px; }

/* 品牌主色（首页与全局默认）；分类主色（各工具页在 <body> 上加 class） */
.theme-brand  { --accent: #2563eb; --accent-soft: #eff6ff; --accent-deep: #1d4ed8; }
.theme-compare { --accent: #16a34a; --accent-soft: #f0fdf4; --accent-deep: #15803d; }
.theme-merge   { --accent: #7c3aed; --accent-soft: #f5f3ff; --accent-deep: #6d28d9; }
.theme-split   { --accent: #d97706; --accent-soft: #fffbeb; --accent-deep: #b45309; }
.theme-dedupe  { --accent: #0d9488; --accent-soft: #f0fdfa; --accent-deep: #0f766e; }
.theme-convert { --accent: #4f46e5; --accent-soft: #eef2ff; --accent-deep: #4338ca; }
.theme-clean   { --accent: #e11d48; --accent-soft: #fff1f2; --accent-deep: #be123c; }
/* 批次 1 新增工具（2026-09-02） */
.theme-lookup    { --accent: #0891b2; --accent-soft: #ecfeff; --accent-deep: #0e7490; }
.theme-transform { --accent: #c026d3; --accent-soft: #fdf4ff; --accent-deep: #a21caf; }
.theme-rmb       { --accent: #ca8a04; --accent-soft: #fefce8; --accent-deep: #a16207; }
/* 批次 2 新增工具（2026-09-02）：排序/筛选/分列/透视 */
.theme-sort     { --accent: #0ea5e9; --accent-soft: #f0f9ff; --accent-deep: #0369a1; }
.theme-filter   { --accent: #db2777; --accent-soft: #fdf2f8; --accent-deep: #be185d; }
.theme-splitcol { --accent: #65a30d; --accent-soft: #f7fee7; --accent-deep: #4d7c0f; }
.theme-pivot    { --accent: #a855f7; --accent-soft: #faf5ff; --accent-deep: #9333ea; }
/* 智能对账（v4 P0 上线 2026-09-11）：绿松石/翡翠，账本/对账隐喻（避开 .theme-compare 的 #16a34a 翠绿） */
.theme-recon    { --accent: #059669; --accent-soft: #ecfdf5; --accent-deep: #047857; }

/* 861~1100px 是页脚的尴尬区间：品牌列固定吃掉 320px，剩下的宽度按 4 列分
   会把每个分类组压到 103~134px（真机量到 900px 时仅 103px，比平铺还难读）。
   让「全部工具」占满整行、另两列在第二行并排。 */
@media (max-width: 1100px) and (min-width: 861px) {
  .footer__cols { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .footer__cols > div:first-child { grid-column: 1 / -1; }
}

@media (max-width: 860px) {
  .nav { padding: 12px 20px; flex-wrap: wrap; }
  .nav__links { gap: 16px; font-size: 14px; }
  .hero h1 { font-size: 32px; }
  .wrap { padding: 0 20px; }
  .panel { padding: 20px; }

  .footer__top { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .footer__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; }
  .footer__tagline { max-width: none; }
  .cta-band h2 { font-size: 21px; }
}

@media (max-width: 520px) {
  .footer__cols { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  /* 只剩 1 列时 span 2 会超出显式网格，明确收回；四组仍保持 2×2（组宽约 155px 够用） */
  .footer__cols > div:first-child { grid-column: auto; }
  .cta-band__actions .btn { width: 100%; justify-content: center; }
}

/* ============================================================
 * 4 步向导（XLWizard）
 * 顶部进度条 + 内容区 + 上一步/下一步按钮。 所有工具复用。
 * ============================================================ */
.wizard { margin-top: 8px; }

.wizard__steps {
  display: flex;
  align-items: stretch;
  gap: 0;
  list-style: none;
  margin: 0 0 20px;
  padding: 0;
  border: 1px solid var(--border, #e2e8f0);
  border-radius: 12px;
  background: var(--surface, #fff);
  overflow: hidden;
}
.wizard__step {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  cursor: default;
  border-right: 1px solid var(--border, #e2e8f0);
  color: var(--ink-3, #64748b);
  background: var(--surface, #fff);
  transition: background .15s, color .15s;
}
.wizard__step:last-child { border-right: 0; }
.wizard__step.is-active {
  background: var(--accent-soft, #eff6ff);
  color: var(--accent, #2563eb);
  font-weight: 600;
}
.wizard__step.is-done {
  color: var(--ink, #0f172a);
  cursor: pointer;
  background: var(--surface, #fff);
}
.wizard__step.is-done:hover { background: var(--surface-2, #f8fafc); }
.wizard__step.is-locked { color: var(--ink-4, #94a3b8); }
.wizard__num {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-2, #f8fafc);
  color: var(--ink-3, #64748b);
  font-size: 13px;
  font-weight: 600;
}
.wizard__step.is-active .wizard__num { background: var(--accent, #2563eb); color: #fff; }
.wizard__step.is-done .wizard__num { background: var(--accent-deep, #1d4ed8); color: #fff; }
.wizard__label { font-size: 14px; }

.wizard__panes { min-height: 200px; }

.wizard__nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--border, #e2e8f0);
}
.wizard__nav::before {
  content: '';
  display: none;
}

/* 步骤内容里的常用小件：避免每个工具页重复写 */
.wizard__pane-actions {
  display: flex;
  gap: 10px;
  margin-top: 16px;
  flex-wrap: wrap;
}
.wizard__pane-hint {
  font-size: 13px;
  color: var(--ink-3, #64748b);
  margin: 4px 0 0;
}
.wizard__pane-error {
  font-size: 13px;
  color: #b91c1c;
  margin: 4px 0 0;
}

/* ==========================================================================
   公式助手（tools/formula，2026-09-12）
   解释列表 / 生成结果 / tab 按钮。复用 .panel / .btn / .field__labelrow。
   ========================================================================== */
.tab-btn.is-active {
  background: var(--brand, #2563EB);
  color: #fff;
  border-color: var(--brand, #2563EB);
}
.tab-btn {
  background: var(--bg, #fff);
  color: var(--ink-1, #0f172a);
  border: 1px solid var(--line, #e2e8f0);
}
.explain-output, .explain-empty {
  font-size: 14px;
  color: var(--ink-1, #0f172a);
  line-height: 1.7;
}
.explain-empty {
  padding: 16px;
  background: #f8fafc;
  border-radius: 8px;
  color: var(--ink-2, #475569);
}
.explain-empty-title {
  font-weight: 500;
  margin-bottom: 4px;
}
.explain-empty-sub { margin: 4px 0; }
.explain-empty code {
  background: #fff;
  border: 1px solid var(--line, #e2e8f0);
  padding: 1px 6px;
  border-radius: 4px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
}
.explain-list, .explain-sub, .explain-args {
  list-style: none;
  margin: 0;
  padding-left: 18px;
  border-left: 2px dashed var(--line, #e2e8f0);
}
.explain-item {
  margin: 6px 0;
  padding-left: 8px;
}
.explain-head {
  font-weight: 500;
  margin-bottom: 4px;
}
.explain-name { color: var(--brand, #2563EB); font-weight: 500; }
.explain-src {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  background: #f1f5f9;
  padding: 1px 6px;
  border-radius: 4px;
  margin-right: 6px;
  color: #0f172a;
}
.lit-string { background: #fef3c7; }
.lit-num    { background: #e0f2fe; }
.lit-range  { background: #ede9fe; }
.lit-bool   { background: #fce7f3; }
.explain-paren { color: #94a3b8; font-family: ui-monospace, monospace; }
.explain-desc { color: var(--ink-2, #475569); font-size: 13px; }
.explain-arg {
  margin: 4px 0;
}
.explain-arg-label {
  font-size: 12px;
  color: var(--ink-2, #475569);
  margin-bottom: 2px;
}
.explain-error {
  padding: 12px;
  background: #fef2f2;
  color: #991b1b;
  border-radius: 8px;
  font-size: 13px;
}
.generate-result {
  border: 1px solid var(--line, #e2e8f0);
  border-radius: 10px;
  padding: 14px 16px;
  background: #f8fafc;
}
.generate-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 6px;
}
.generate-score {
  font-size: 12px;
  color: var(--ink-2, #475569);
}
.generate-desc {
  font-size: 13px;
  color: var(--ink-2, #475569);
  margin-bottom: 10px;
}
.generate-template {
  background: #fff;
  border: 1px solid var(--line, #e2e8f0);
  border-radius: 8px;
  padding: 10px 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px;
  color: #0f172a;
  margin-bottom: 10px;
  word-break: break-all;
}
.generate-args-title {
  font-size: 13px;
  font-weight: 500;
  margin-bottom: 4px;
}
.generate-args {
  list-style: none;
  margin: 0 0 10px 0;
  padding: 0;
}
.generate-args li {
  display: flex;
  gap: 10px;
  padding: 4px 0;
  border-bottom: 1px dashed var(--line, #e2e8f0);
  font-size: 13px;
}
.generate-args li:last-child { border-bottom: 0; }
.arg-label {
  flex: 0 0 120px;
  font-weight: 500;
  color: #0f172a;
}
.arg-desc { color: var(--ink-2, #475569); flex: 1; }
.generate-tip {
  font-size: 12px;
  color: var(--ink-2, #475569);
  margin-bottom: 8px;
}

/* ---------- 工资条拆分（payroll） ---------- */
.payroll-col-checks {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 8px 12px;
  padding: 12px 14px;
  border: 1px solid var(--line, #e2e8f0);
  border-radius: 8px;
  background: #fafbfc;
}
.payroll-col-check {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  cursor: pointer;
  user-select: none;
}
.payroll-col-check input { cursor: pointer; }

.payroll-preview {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 16px;
  margin-top: 16px;
  min-height: 240px;
}
@media (max-width: 720px) {
  .payroll-preview { grid-template-columns: 1fr; }
}
.payroll-preview__list {
  max-height: 360px;
  overflow-y: auto;
  border: 1px solid var(--line, #e2e8f0);
  border-radius: 8px;
  background: #fafbfc;
}
.payroll-preview__items { list-style: none; margin: 0; padding: 0; }
.payroll-preview__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 12px;
  cursor: pointer;
  border-bottom: 1px solid var(--line, #e2e8f0);
  font-size: 13px;
}
.payroll-preview__item:last-child { border-bottom: none; }
.payroll-preview__item:hover { background: #f1f5f9; }
.payroll-preview__item.is-active {
  background: #e0f2fe;
  border-left: 3px solid #0284c7;
}
.payroll-preview__name {
  font-weight: 500;
  color: #0f172a;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.payroll-preview__meta {
  color: var(--ink-2, #475569);
  font-size: 12px;
  flex-shrink: 0;
}
.payroll-preview__more {
  padding: 8px 12px;
  font-size: 12px;
  color: var(--ink-2, #475569);
  text-align: center;
}
.payroll-preview__detail {
  border: 1px solid var(--line, #e2e8f0);
  border-radius: 8px;
  padding: 14px;
  background: #fff;
  overflow-x: auto;
}
.payroll-preview__head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 8px;
  flex-wrap: wrap;
}
.payroll-preview__head .payroll-preview__name { font-size: 15px; }
.payroll-preview__head .payroll-preview__meta { font-size: 12px; }
.payroll-preview__table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}
.payroll-preview__table th,
.payroll-preview__table td {
  border: 1px solid var(--line, #e2e8f0);
  padding: 4px 8px;
  text-align: left;
  white-space: nowrap;
}
.payroll-preview__table th {
  background: #f8fafc;
  font-weight: 600;
  color: #0f172a;
}
.payroll-preview__table td.payroll-preview__more {
  text-align: center;
  color: var(--ink-2, #475569);
  font-style: italic;
}

.payroll-skipped {
  margin-top: 16px;
  padding: 12px 16px;
  background: #fffbeb;
  border: 1px solid #fcd34d;
  border-radius: 8px;
  font-size: 13px;
}
.payroll-skipped__title {
  font-weight: 600;
  color: #92400e;
  margin-bottom: 6px;
}
.payroll-skipped__list {
  margin: 0;
  padding-left: 20px;
  color: #78350f;
  line-height: 1.7;
}
.result-summary {
  font-weight: normal;
  font-size: 14px;
  color: var(--ink-2, #475569);
}

/* ---------- 跨表汇总（cross） ---------- */
.cross-blocks-summary { margin: 12px 0 0; }
.cross-blocks-summary__ok,
.cross-blocks-summary__warn {
  padding: 10px 14px;
  border-radius: 8px;
  font-size: 14px;
  line-height: 1.5;
}
.cross-blocks-summary__ok {
  background: #ecfdf5;
  color: #047857;
  border: 1px solid #a7f3d0;
}
.cross-blocks-summary__warn {
  background: #fffbeb;
  color: #92400e;
  border: 1px solid #fde68a;
}

.cross-group-checks {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 8px 12px;
  padding: 12px 14px;
  border: 1px solid var(--line, #e2e8f0);
  border-radius: 8px;
  background: #fafbfc;
}

.cross-agg-list { display: flex; flex-direction: column; gap: 8px; }
.cross-agg-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border: 1px solid var(--line, #e2e8f0);
  border-radius: 8px;
  background: #fafbfc;
}
.cross-agg-row__col {
  flex: 1;
  font-size: 14px;
  font-weight: 500;
  color: var(--ink, #0f172a);
}
.cross-agg-row__chk { display: flex; align-items: center; gap: 6px; font-size: 14px; cursor: pointer; user-select: none; }
.cross-agg-row__chk input { cursor: pointer; }
.cross-agg-row__sel { width: 110px; }

.cross-structure__ok,
.cross-structure__warn {
  padding: 12px 16px;
  border-radius: 8px;
  font-size: 14px;
  margin-bottom: 12px;
}
.cross-structure__ok { background: #ecfdf5; color: #047857; border: 1px solid #a7f3d0; }
.cross-structure__warn { background: #fffbeb; color: #92400e; border: 1px solid #fde68a; }

.cross-structure-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  margin-bottom: 12px;
}
.cross-structure-table th,
.cross-structure-table td {
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid var(--line, #e2e8f0);
}
.cross-structure-table th { background: #f1f5f9; font-weight: 600; }

.cross-structure__diff {
  font-size: 14px;
  padding: 8px 12px;
  border-left: 3px solid #d97706;
  background: #fffbeb;
  color: #78350f;
  margin-top: 6px;
  border-radius: 0 6px 6px 0;
  line-height: 1.6;
}

.cross-warnings {
  margin: 12px 0;
  padding: 12px 16px;
  border-radius: 8px;
  background: #fef3c7;
  border: 1px solid #fde68a;
  font-size: 14px;
}
.cross-warnings__title { font-weight: 600; color: #92400e; margin-bottom: 6px; }
.cross-warnings ul { margin: 0; padding-left: 20px; color: #78350f; line-height: 1.6; }

/* 事前重复键提示（Jay 2026-09-14 拍板「事前提示，不阻断」） */
.recon-dupwarn {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 8px 0 0;
  padding: 10px 12px;
  border-radius: 8px;
  background: #fff7ed;
  border: 1px solid #fed7aa;
  color: #9a3412;
  font-size: 13px;
  line-height: 1.6;
}
.recon-dupwarn__icon { flex: none; font-size: 14px; line-height: 1.4; }
.recon-dupwarn__body { flex: 1 1 auto; }
.recon-dupwarn__fix {
  margin-top: 6px;
  padding: 3px 10px;
  font-size: 12px;
  border: 1px solid #fdba74;
  background: #fff;
  color: #c2410c;
  border-radius: 6px;
  cursor: pointer;
}
.recon-dupwarn__fix:hover { background: #ffedd5; }
