/* Tailwind CSS CDN（按规范以 URL 方式引入；本页样式已自带，不依赖其加载成功） */
@import url('https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css');

/* ============================================================
   金蝶云星空 · 数据源连接自检
   设计方向：技术控制台 / 工业实用风
   —— 信息密度优先，状态反馈极度明确，克制装饰
   ============================================================ */

:root {
  --blue-700: #1E3A8A;
  --blue-600: #1D4ED8;
  --blue-500: #2563EB;

  --ink-900: #0F172A;
  --ink-600: #475569;
  --ink-400: #94A3B8;
  --ink-200: #E2E8F0;
  --ink-100: #F1F5F9;

  --surface: #FFFFFF;
  --canvas: #F8FAFC;
  /*
   * 页面底色的浅绿（用户 2026-10-14 定的）。
   * 原来 body 上铺的是 28px 的**网纹格**（两条 linear-gradient），业务员反馈"很凌乱" ——
   * 现在换成一块干净的浅绿底，内容以平铺的白色卡片压在上面，分区分块反而更清楚。
   * 只给 body 用：内部面板仍走 --canvas（近白），免得整屏泛绿、数字看不清。
   */
  --canvas-green: #EDF6EE;
  --console: #0F172A;

  --ok: #16A34A;
  --err: #DC2626;
  --warn: #D97706;
  --info: #0284C7;

  --radius-sm: 6px;
  --radius: 10px;
  --radius-lg: 14px;

  /*
   * 卡片阴影改成"平铺"——用户 2026-10-14：内容平铺，不要浮起来的厚重感。
   * 原来带一层 24px 大扩散的投影，叠在底色上显得一坨一坨；
   * 现在只留一条 1px 的贴地投影，靠描边把块分清楚，整屏干净很多。
   */
  --shadow-card: 0 1px 2px rgba(15, 23, 42, 0.035);
  --shadow-lift: 0 2px 4px rgba(15, 23, 42, 0.06), 0 18px 40px -24px rgba(29, 78, 216, 0.45);

  --mono: "JetBrains Mono", "Cascadia Mono", "Cascadia Code", Consolas, "Courier New", monospace;
  --sans: "PingFang SC", "HarmonyOS Sans SC", "Microsoft YaHei", "Hiragino Sans GB", system-ui, -apple-system, "Segoe UI", sans-serif;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-quart: cubic-bezier(0.25, 1, 0.5, 1);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
}

body {
  /*
   * 浅绿底、**不带网纹**（用户 2026-10-14：网纹格看着凌乱）。
   * 不要加回网格背景图 —— 那正是这次被去掉的东西。
   */
  background-color: var(--canvas-green);
  color: var(--ink-900);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -0.01em; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
b, strong { font-weight: 600; }

/* ------------------------------- 顶栏 ------------------------------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--ink-200);
}

.topbar-inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 12px 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.brand { display: flex; align-items: center; gap: 12px; min-width: 0; }

.brand-mark {
  width: 38px;
  height: 38px;
  flex: 0 0 38px;
  display: grid;
  place-items: center;
  border-radius: 9px;
  background: linear-gradient(150deg, var(--blue-500), var(--blue-700));
  color: #fff;
  font-size: 19px;
  font-weight: 600;
  box-shadow: 0 6px 16px -8px rgba(29, 78, 216, 0.9);
}

.brand-text h1 { font-size: 17px; line-height: 1.3; }
.brand-text p { font-size: 12px; color: var(--ink-600); letter-spacing: 0.01em; }

.topbar-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }

.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 26px;
  padding: 0 10px;
  border-radius: 999px;
  border: 1px solid var(--ink-200);
  background: var(--surface);
  color: var(--ink-600);
  font-size: 12px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.pill--admin {
  border-color: rgba(29, 78, 216, 0.28);
  background: rgba(29, 78, 216, 0.07);
  color: var(--blue-700);
  font-weight: 600;
}

/* ---------------------- 顶栏「我是谁」 ----------------------
 * 和旁边几个 pill 长得像亲戚，但它是可操作的，所以要有边框与 hover。
 * 没选人时整块压暗并描一圈警示色 —— 提交类操作会因此没有操作人，
 * 必须一眼看得出来，而不是等交完了才发现那一列是空的。
 */
.whoami {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 4px 0 10px;
  height: 26px;
  border-radius: 999px;
  border: 1px solid var(--ink-200);
  background: var(--surface);
  white-space: nowrap;
}

.whoami.is-set {
  border-color: rgba(16, 122, 87, 0.3);
  background: rgba(16, 122, 87, 0.06);
}

.whoami-label {
  font-size: 12px;
  color: var(--ink-600);
  font-variant-numeric: tabular-nums;
}

.whoami.is-set .whoami-label { color: var(--ok); font-weight: 600; }

/* 用 select 而不是自己写下拉：原生控件在触摸屏上更好点，也不用管键盘 */
.whoami-select {
  border: none;
  background: transparent;
  font: inherit;
  font-size: 12px;
  color: var(--ink-700);
  padding: 0 4px 0 0;
  max-width: 168px;
  cursor: pointer;
  outline: none;
}

.whoami-select option { color: var(--ink-700); background: #fff; }

/* 没选人却点了提交：晃一下顶栏这一块，让眼睛能立刻找到它该在哪 */
@keyframes whoami-nudge {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-3px); }
  40% { transform: translateX(3px); }
  60% { transform: translateX(-2px); }
  80% { transform: translateX(2px); }
}

.whoami.is-nudge {
  animation: whoami-nudge 0.4s ease-in-out 2;
  border-color: var(--err);
  background: rgba(190, 40, 40, 0.08);
}

.pill--dot i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ink-400);
  box-shadow: 0 0 0 3px rgba(148, 163, 184, 0.18);
}

.pill--dot.is-ok i { background: var(--ok); box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.16); animation: breathe 2.6s var(--ease-quart) infinite; }
.pill--dot.is-err i { background: var(--err); box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.16); }

@keyframes breathe {
  0%, 100% { box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.16); }
  50% { box-shadow: 0 0 0 6px rgba(22, 163, 74, 0.06); }
}

/* ------------------------------- 容器 ------------------------------- */

.container {
  max-width: 1280px;
  margin: 0 auto;
  padding: 24px 28px 56px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* ------------------------------- 提示条 ------------------------------- */

.notice {
  display: flex;
  gap: 14px;
  padding: 16px 18px;
  border-radius: var(--radius);
  border: 1px solid rgba(2, 132, 199, 0.22);
  background: linear-gradient(180deg, rgba(2, 132, 199, 0.07), rgba(2, 132, 199, 0.03));
  animation: fade-up 0.5s var(--ease-out) both;
}

.notice-icon {
  flex: 0 0 24px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--info);
  color: #fff;
  font-weight: 700;
  font-size: 13px;
  font-family: var(--mono);
  margin-top: 1px;
}

.notice-body strong { font-size: 14px; color: var(--ink-900); }
.notice-body p { margin-top: 4px; font-size: 13px; color: var(--ink-600); }

/* ------------------------------- 卡片 ------------------------------- */

.card {
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  animation: fade-up 0.5s var(--ease-out) both;
  overflow: hidden;
}

.card:nth-of-type(2) { animation-delay: 0.05s; }
.card:nth-of-type(3) { animation-delay: 0.1s; }

@keyframes fade-up {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  padding: 18px 22px;
  border-bottom: 1px solid var(--ink-100);
}

.card-head-main { display: flex; gap: 14px; align-items: flex-start; }

.card-index {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  color: var(--blue-600);
  background: rgba(29, 78, 216, 0.08);
  border: 1px solid rgba(29, 78, 216, 0.18);
  border-radius: var(--radius-sm);
  padding: 3px 7px;
  line-height: 1.3;
  margin-top: 1px;
  letter-spacing: 0.06em;
}

.card-title { font-size: 18px; }
.card-desc { margin-top: 3px; font-size: 13px; color: var(--ink-600); max-width: 76ch; }

.saved-tag,
.elapsed-tag {
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--ink-600);
  background: var(--ink-100);
  border: 1px solid var(--ink-200);
  border-radius: 999px;
  padding: 4px 11px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.elapsed-tag.is-ok { color: var(--ok); background: rgba(22, 163, 74, 0.08); border-color: rgba(22, 163, 74, 0.24); }
.elapsed-tag.is-err { color: var(--err); background: rgba(220, 38, 38, 0.07); border-color: rgba(220, 38, 38, 0.24); }

.card-body { padding: 20px 22px; }

.card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding: 14px 22px;
  border-top: 1px solid var(--ink-100);
  background: linear-gradient(180deg, rgba(248, 250, 252, 0.6), rgba(248, 250, 252, 0.95));
}

.foot-left, .foot-right { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* ------------------------------- 表单 ------------------------------- */

.form-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px 18px;
}

.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field--wide { grid-column: span 2; }
.field--narrow { grid-column: span 1; }

.field label {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-900);
  display: flex;
  align-items: center;
  gap: 4px;
}

.field label b { color: var(--err); font-family: var(--mono); font-size: 12px; }

.input {
  width: 100%;
  height: 38px;
  padding: 0 12px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink-900);
  font-family: var(--mono);
  font-size: 13px;
  transition: border-color 0.18s var(--ease-quart), box-shadow 0.18s var(--ease-quart), background 0.18s;
}

.input::placeholder { color: var(--ink-400); font-family: var(--sans); }

.input:hover { border-color: #CBD5E1; }

.input:focus {
  outline: none;
  border-color: var(--blue-500);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.14);
  background: #fff;
}

.input--sm { height: 34px; font-size: 12.5px; }

.hint { font-size: 12px; color: var(--ink-400); line-height: 1.5; }

.input-wrap { position: relative; display: flex; align-items: center; }

.input-wrap .input { padding-right: 62px; }

.reveal {
  position: absolute;
  right: 6px;
  height: 26px;
  padding: 0 9px;
  border: 1px solid var(--ink-200);
  border-radius: 5px;
  background: var(--ink-100);
  color: var(--ink-600);
  font-size: 11.5px;
  font-family: var(--sans);
  cursor: pointer;
  transition: all 0.15s var(--ease-quart);
}

.reveal:hover { background: #fff; color: var(--blue-600); border-color: rgba(37, 99, 235, 0.35); }
.reveal--plain { font-family: var(--mono); }

/* 开关 */
.switches {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px dashed var(--ink-200);
}

.switch { display: flex; align-items: center; gap: 10px; cursor: pointer; user-select: none; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }

.switch-track {
  position: relative;
  width: 40px;
  height: 22px;
  flex: 0 0 40px;
  border-radius: 999px;
  background: #CBD5E1;
  transition: background 0.22s var(--ease-quart);
}

.switch-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.3);
  transition: transform 0.22s var(--ease-out);
}

.switch input:checked + .switch-track { background: var(--blue-600); }
.switch input:checked + .switch-track .switch-knob { transform: translateX(18px); }
.switch input:focus-visible + .switch-track { box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2); }

.switch-text { display: flex; flex-direction: column; line-height: 1.4; }
.switch-text b { font-size: 13px; }
.switch-text em { font-style: normal; font-size: 11.5px; color: var(--ink-400); }

/* ------------------------------- 按钮 ------------------------------- */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 38px;
  padding: 0 16px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: transform 0.12s var(--ease-quart), box-shadow 0.2s var(--ease-quart), background 0.18s, border-color 0.18s, color 0.18s;
}

.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none; }
.btn:focus-visible { outline: 2px solid var(--blue-500); outline-offset: 2px; }

.btn--primary {
  background: linear-gradient(180deg, var(--blue-500), var(--blue-600));
  color: #fff;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.12), 0 12px 24px -14px rgba(29, 78, 216, 0.85);
}

.btn--primary:hover:not(:disabled) { box-shadow: var(--shadow-lift); filter: brightness(1.03); }

.btn--ghost {
  background: #fff;
  border-color: var(--ink-200);
  color: var(--ink-900);
}

.btn--ghost:hover:not(:disabled) { border-color: rgba(37, 99, 235, 0.4); color: var(--blue-600); }

.btn--quiet { background: transparent; color: var(--ink-600); border-color: transparent; }
.btn--quiet:hover:not(:disabled) { background: var(--ink-100); color: var(--err); }

.btn--sm { height: 32px; padding: 0 12px; font-size: 12.5px; }

.btn-spinner {
  display: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: #fff;
  animation: spin 0.7s linear infinite;
}

.btn.is-busy .btn-spinner { display: block; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ------------------------------- 执行区 ------------------------------- */

.exec-grid {
  display: grid;
  grid-template-columns: minmax(300px, 420px) minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}

.steps { display: flex; flex-direction: column; gap: 0; }

.step {
  position: relative;
  display: flex;
  gap: 14px;
  padding: 0 0 20px 0;
  opacity: 0.55;
  transition: opacity 0.3s var(--ease-quart);
}

.step:last-child { padding-bottom: 0; }

.step::after {
  content: "";
  position: absolute;
  left: 11px;
  top: 26px;
  bottom: 4px;
  width: 2px;
  background: var(--ink-200);
  transition: background 0.3s;
}

.step:last-child::after { display: none; }

.step.is-active { opacity: 1; }
.step.is-done { opacity: 1; }
.step.is-done::after { background: rgba(22, 163, 74, 0.45); }
.step.is-failed { opacity: 1; animation: shake 0.42s var(--ease-quart); }
.step.is-failed::after { background: rgba(220, 38, 38, 0.4); }

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-4px); }
  50% { transform: translateX(3px); }
  80% { transform: translateX(-2px); }
}

.step-dot {
  position: relative;
  z-index: 1;
  flex: 0 0 24px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: #fff;
  border: 2px solid var(--ink-200);
  transition: border-color 0.25s, background 0.25s, box-shadow 0.25s;
}

.step.is-active .step-dot {
  border-color: var(--blue-500);
  box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.12);
}

.step.is-active .step-dot::after {
  content: "";
  position: absolute;
  inset: -2px;
  border-radius: 50%;
  border: 2px solid rgba(37, 99, 235, 0.45);
  animation: pulse 1.5s var(--ease-quart) infinite;
}

@keyframes pulse {
  0% { transform: scale(1); opacity: 0.85; }
  100% { transform: scale(1.55); opacity: 0; }
}

.step.is-active .step-glyph {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--blue-500);
}

.step.is-done .step-dot { border-color: var(--ok); background: var(--ok); }
.step.is-done .step-glyph {
  width: 10px;
  height: 6px;
  border-left: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: rotate(-45deg) translate(1px, -1px);
}

.step.is-failed .step-dot { border-color: var(--err); background: var(--err); }
.step.is-failed .step-glyph {
  position: relative;
  width: 10px;
  height: 10px;
}
.step.is-failed .step-glyph::before,
.step.is-failed .step-glyph::after {
  content: "";
  position: absolute;
  top: 4px;
  left: 0;
  width: 10px;
  height: 2px;
  background: #fff;
}
.step.is-failed .step-glyph::before { transform: rotate(45deg); }
.step.is-failed .step-glyph::after { transform: rotate(-45deg); }

.step-body h3 { font-size: 14px; }
.step-body p { font-size: 12.5px; color: var(--ink-600); margin-top: 2px; }

.step-note {
  display: block;
  margin-top: 5px;
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--blue-600);
  word-break: break-word;
}
.step.is-done .step-note { color: var(--ok); }
.step.is-failed .step-note { color: var(--err); }

/* 控制台 */
.console {
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid #1E293B;
  background: var(--console);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), 0 18px 40px -30px rgba(15, 23, 42, 0.9);
}

.console-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 9px 14px;
  border-bottom: 1px solid rgba(148, 163, 184, 0.16);
  background: rgba(148, 163, 184, 0.06);
}

.console-title {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #94A3B8;
}

.console-clear {
  background: transparent;
  border: 1px solid rgba(148, 163, 184, 0.25);
  color: #94A3B8;
  font-size: 11.5px;
  border-radius: 5px;
  padding: 2px 9px;
  cursor: pointer;
  transition: all 0.15s;
}
.console-clear:hover { color: #fff; border-color: rgba(255, 255, 255, 0.4); }

.console-body {
  height: 340px;
  overflow-y: auto;
  padding: 12px 14px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.75;
  color: #E2E8F0;
  scrollbar-width: thin;
}

.console-body::-webkit-scrollbar { width: 8px; }
.console-body::-webkit-scrollbar-thumb { background: #334155; border-radius: 4px; }

.log-line {
  display: flex;
  gap: 10px;
  animation: log-in 0.25s var(--ease-out) both;
  word-break: break-word;
}

@keyframes log-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

.log-time { flex: 0 0 auto; color: #64748B; }
.log-text { flex: 1 1 auto; color: #CBD5E1; }

.log-line--info .log-text { color: #7DD3FC; }
.log-line--ok .log-text { color: #4ADE80; }
.log-line--err .log-text { color: #FCA5A5; }
.log-line--warn .log-text { color: #FCD34D; }
.log-line--idle .log-text { color: #64748B; }

.log-detail {
  color: #94A3B8;
  padding-left: 0;
  display: block;
  white-space: pre-wrap;
}

/* ------------------------------- 结论卡 ------------------------------- */

.card--verdict { border-color: rgba(29, 78, 216, 0.22); }

.verdict {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 20px 22px;
  border-bottom: 1px solid var(--ink-100);
}

.verdict.is-ok { background: linear-gradient(180deg, rgba(22, 163, 74, 0.09), rgba(22, 163, 74, 0.02)); }
.verdict.is-err { background: linear-gradient(180deg, rgba(220, 38, 38, 0.08), rgba(220, 38, 38, 0.02)); }
.verdict.is-warn { background: linear-gradient(180deg, rgba(217, 119, 6, 0.09), rgba(217, 119, 6, 0.02)); }

.verdict-main { min-width: 0; }

.verdict-badge {
  display: inline-block;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #fff;
  background: var(--ink-900);
  padding: 3px 9px;
  border-radius: 5px;
  margin-bottom: 8px;
}

.verdict.is-ok .verdict-badge { background: var(--ok); }
.verdict.is-err .verdict-badge { background: var(--err); }
.verdict.is-warn .verdict-badge { background: var(--warn); }

.verdict-title { font-size: 24px; line-height: 1.28; }
.verdict-sub { margin-top: 5px; font-size: 13px; color: var(--ink-600); }

.verdict-actions { display: flex; gap: 10px; flex: 0 0 auto; }

.kv { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 10px; }

.kv-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-sm);
  background: var(--canvas);
}

.kv-key { font-size: 12.5px; color: var(--ink-600); flex: 0 0 auto; }

.kv-val {
  font-family: var(--mono);
  font-size: 12.5px;
  font-weight: 600;
  text-align: right;
  word-break: break-all;
}

.kv-val.is-ok { color: var(--ok); }
.kv-val.is-err { color: var(--err); }
.kv-val.is-warn { color: var(--warn); }
.kv-val.is-info { color: var(--blue-600); }

.advice {
  margin-top: 16px;
  padding: 16px 18px;
  border-radius: var(--radius);
  border: 1px solid rgba(220, 38, 38, 0.22);
  background: rgba(220, 38, 38, 0.04);
}

.advice.is-warn { border-color: rgba(217, 119, 6, 0.28); background: rgba(217, 119, 6, 0.05); }
.advice h4 { font-size: 14px; margin-bottom: 8px; }
.advice ul { display: flex; flex-direction: column; gap: 7px; }

.advice li {
  position: relative;
  padding-left: 18px;
  font-size: 13px;
  color: var(--ink-600);
}

.advice li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 8px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--err);
}

.advice.is-warn li::before { background: var(--warn); }

.raw { margin-top: 12px; }
.raw summary { cursor: pointer; font-size: 12.5px; color: var(--blue-600); }
.raw pre {
  margin: 8px 0 0;
  padding: 12px;
  border-radius: var(--radius-sm);
  background: var(--console);
  color: #FCA5A5;
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 220px;
  overflow: auto;
}

.tag {
  border: 1px solid var(--ink-200);
  background: var(--canvas);
  border-radius: 4px;
  padding: 1px 6px;
  font-family: var(--mono);
  font-size: 11px;
}

.tag--view { color: var(--info); border-color: rgba(2, 132, 199, 0.3); background: rgba(2, 132, 199, 0.06); }
.tag--table { color: var(--blue-700); border-color: rgba(29, 78, 216, 0.25); background: rgba(29, 78, 216, 0.05); }
.tag--score { color: var(--warn); border-color: rgba(217, 119, 6, 0.3); background: rgba(217, 119, 6, 0.07); font-weight: 600; }

/* ------------------------------- 数据表 ------------------------------- */

.sub-title {
  font-size: 13px;
  color: var(--ink-600);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin: 0 0 10px;
}

.sub-title + .table-wrap { margin-bottom: 22px; }

.table-wrap {
  border: 1px solid var(--ink-200);
  border-radius: var(--radius);
  overflow: auto;
  max-height: 420px;
  background: #fff;
}

/*
 * 应收款汇总表：筛选条 + 口径行 + 分页条**一起吸顶**（用户 2026-10-14
 * 「当向下活动时，这个内容固定在表头」）。
 *
 * ⚠️ top 必须写成**顶栏高度**（实测 51px），不能写 0：
 *    顶栏是 z-index:40 的 sticky，筛选条自己 top:0 时会钻到它下面 ——
 *    看上去就是"滚动之后筛选条不见了"（原来正是这个毛病）。
 *    z-index 取 25：低于顶栏(40)、高于表格里的 sticky 表头(1)。
 *
 * 背景必须给：吸顶时下面的表格会从它背后穿过去。
 */
#dqStickyHead {
  position: sticky;
  top: 51px;
  z-index: 25;
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* 上下各留一点，吸顶时不会把上下两行挤在一起 */
  padding: 8px 0 6px;
  background: var(--canvas-green);
}

/* 容器已经在吸顶了，里面的筛选条不能再自己吸（否则会钻到顶栏下面去） */
#dqStickyHead .filterbar { position: static; }

/*
 * 应收款汇总表的列表**不要内层滚动条**（用户 2026-10-14）。
 *
 * 它自带分页与「每页 N 条」，再套一层 420px 高的内滚动框，右边就同时出现两条竖滚动条
 * （页面一条、表格一条），既乱又得对准了拖。放开高度让它自然撑开，
 * 整页只留一条滚动条；横向该滚还是滚（列多，那是必要的）。
 */
#dqResultWrap { max-height: none; }

table.data { width: 100%; border-collapse: collapse; font-size: 12.5px; }

/*
 * ===================== 表头吸顶：必须**两处都写** =====================
 *
 * 实测（2026-10-14，本项目在用的 Edge/Chromium）：
 *   把 `position: sticky` 只写在 `thead th` 上 → **完全不吸顶**，表头照样跟着滚走。
 *   原因是表格单元格的包含块是那一行，行只有表头那么高 —— 单元格压根没有可以
 *   吸附的余量。把 sticky 写在 `thead`（table-header-group）上才真的钉住：
 *   实测容器滚动 6000px 后，`thead` 仍停在容器顶边（391 / 390）。
 *
 * 所以两条都留着：
 *   · `thead` 上这条 —— 在 Chromium 里真正起作用的
 *   · `th` 上这条 —— 老 Safari 等只认单元格 sticky 的引擎
 * 两者同值时不会互相打架（实测同时写上依然吸住）。
 *
 * 另：单元格背景必须不透明（见下面的 background），否则钉住之后下面的行会透上来。
 */
table.data thead {
  position: sticky;
  top: 0;
  z-index: 1;
}

table.data thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--ink-100);
  text-align: left;
  font-weight: 600;
  font-size: 11.5px;
  letter-spacing: 0.04em;
  color: var(--ink-600);
  padding: 9px 12px;
  border-bottom: 1px solid var(--ink-200);
  white-space: nowrap;
}

table.data td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--ink-100);
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-900);
  white-space: nowrap;
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
}

table.data tbody tr:hover td { background: rgba(29, 78, 216, 0.035); }
table.data tbody tr:last-child td { border-bottom: none; }
table.data td.num, table.data th.num { text-align: right; color: var(--ink-400); width: 46px; }

.empty {
  padding: 16px;
  border: 1px dashed var(--ink-200);
  border-radius: var(--radius);
  color: var(--ink-400);
  font-size: 12.5px;
  text-align: center;
}

/* ------------------------------- 页脚 & Toast ------------------------------- */

.foot {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 28px 40px;
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--ink-400);
}

.toast {
  position: fixed;
  left: 50%;
  bottom: 32px;
  transform: translateX(-50%) translateY(12px);
  padding: 11px 18px;
  border-radius: var(--radius);
  background: var(--ink-900);
  color: #fff;
  font-size: 13px;
  box-shadow: 0 18px 40px -18px rgba(15, 23, 42, 0.8);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.24s var(--ease-quart), transform 0.24s var(--ease-out);
  z-index: 90;
  max-width: min(90vw, 520px);
}

.toast.is-show { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast.is-err { background: var(--err); }
.toast.is-ok { background: #14532D; }

/* ------------------------------- 响应式 ------------------------------- */

@media (max-width: 1180px) {
  .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .exec-grid { grid-template-columns: minmax(0, 1fr); }
  .console-body { height: 260px; }
}

@media (max-width: 720px) {
  .topbar-inner, .container, .foot { padding-left: 16px; padding-right: 16px; }
  .form-grid { grid-template-columns: minmax(0, 1fr); }
  .field--wide { grid-column: span 1; }
  .verdict { flex-direction: column; align-items: stretch; }
  .verdict-title { font-size: 20px; }
  .card-head, .card-body, .card-foot { padding-left: 16px; padding-right: 16px; }
  .manual-inputs .input { max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

/* ============================================================
   WebAPI 面板容器
   ============================================================ */

/* .panel 是「数据连接与设置」各卡片（A1~B2）的纵向容器，靠它撑开卡片间距 */
.panel { display: flex; flex-direction: column; gap: 18px; }
.panel[hidden] { display: none; }

/* WebAPI 面板微调 */
.notice--api {
  border-color: rgba(29, 78, 216, 0.24);
  background: linear-gradient(180deg, rgba(29, 78, 216, 0.075), rgba(29, 78, 216, 0.028));
}

.notice--api .notice-icon { background: var(--blue-600); }

code {
  font-family: var(--mono);
  font-size: 12px;
  background: rgba(15, 23, 42, 0.06);
  border: 1px solid rgba(15, 23, 42, 0.08);
  border-radius: 4px;
  padding: 0 4px;
}

.form-grid--api { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.presets {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding-bottom: 16px;
  margin-bottom: 4px;
  border-bottom: 1px dashed var(--ink-200);
}

/* 单据试查模块的通俗说明 */
.help {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}

.help-item {
  padding: 12px 14px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius);
  background: var(--canvas);
}

.help-tag {
  display: inline-block;
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--blue-700);
  background: rgba(29, 78, 216, 0.09);
  border: 1px solid rgba(29, 78, 216, 0.2);
  border-radius: 4px;
  padding: 1px 6px;
  margin-bottom: 6px;
}

.help-item b { display: block; font-size: 13px; margin-bottom: 3px; }
.help-item p { font-size: 12.5px; color: var(--ink-600); line-height: 1.6; }

.help-note {
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--ink-600);
  padding: 11px 14px;
  margin-bottom: 16px;
  border-radius: var(--radius-sm);
  border-left: 3px solid var(--warn);
  background: rgba(217, 119, 6, 0.06);
}

.help-note b { color: var(--ink-900); }

.hint-list {
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 10px;
  list-style: none;
}

.hint-list li {
  position: relative;
  padding-left: 16px;
  font-size: 12.5px;
  color: var(--ink-600);
  line-height: 1.6;
}

.hint-list li::before {
  content: "→";
  position: absolute;
  left: 0;
  color: var(--blue-600);
  font-family: var(--mono);
}

.empty-title { display: block; color: var(--err); font-size: 13.5px; }
.empty-reason { margin-top: 4px; font-size: 12.5px; color: var(--ink-600); word-break: break-word; }

.presets-label { font-size: 12.5px; color: var(--ink-600); }

.preset {
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--ink-600);
  background: var(--canvas);
  border: 1px solid var(--ink-200);
  border-radius: 999px;
  padding: 4px 11px;
  cursor: pointer;
  transition: all 0.16s var(--ease-quart);
}

.preset:hover {
  color: var(--blue-600);
  border-color: rgba(37, 99, 235, 0.45);
  background: rgba(29, 78, 216, 0.05);
  transform: translateY(-1px);
}

.query-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 18px 0 22px;
}

.steps--api .step:last-child::after { display: none; }

.probe-list { display: flex; flex-direction: column; gap: 6px; }

.probe-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 12px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-sm);
  background: var(--canvas);
  font-size: 12.5px;
}

.probe-item .pi-status {
  flex: 0 0 auto;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  border-radius: 4px;
  padding: 1px 6px;
}

.probe-item.is-ok .pi-status { color: #fff; background: var(--ok); }
.probe-item.is-bad .pi-status { color: #fff; background: var(--ink-400); }

.probe-item .pi-name { font-family: var(--mono); font-weight: 600; }
.probe-item .pi-msg { color: var(--ink-600); }

.field-list { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }

.field-chip {
  font-family: var(--mono);
  font-size: 11.5px;
  border-radius: 4px;
  padding: 2px 8px;
  border: 1px solid rgba(22, 163, 74, 0.3);
  background: rgba(22, 163, 74, 0.08);
  color: #15803D;
}

.field-chip.is-bad {
  border-color: rgba(220, 38, 38, 0.26);
  background: rgba(220, 38, 38, 0.06);
  color: var(--err);
  text-decoration: line-through;
}

@media (max-width: 1180px) {
  .form-grid--api { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 720px) {
  .form-grid--api { grid-template-columns: minmax(0, 1fr); }
  .help { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================
   报表直读（WebAPI 面板内部的子工作区）
   ============================================================ */

.submodes {
  display: flex;
  gap: 6px;
  padding: 6px;
  background: rgba(255, 255, 255, 0.72);
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  animation: fade-up 0.45s var(--ease-out) both;
}

.submode {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 14px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: transparent;
  color: var(--ink-600);
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s var(--ease-quart), color 0.2s, border-color 0.2s, box-shadow 0.22s;
}

.submode:hover { background: rgba(29, 78, 216, 0.05); color: var(--blue-700); }

.submode.is-active {
  background: #fff;
  color: var(--blue-700);
  border-color: rgba(29, 78, 216, 0.3);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05), 0 12px 26px -20px rgba(29, 78, 216, 0.9);
}

.submode-tag {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 2px 5px;
  border-radius: 4px;
  background: var(--ink-100);
  color: var(--ink-400);
}

.submode.is-active .submode-tag { background: rgba(29, 78, 216, 0.1); color: var(--blue-600); }

.submode-badge {
  font-family: var(--mono);
  font-size: 10.5px;
  padding: 1px 7px;
  border-radius: 999px;
  border: 1px solid rgba(217, 119, 6, 0.32);
  background: rgba(217, 119, 6, 0.08);
  color: var(--warn);
}

.subpanel { display: flex; flex-direction: column; gap: 18px; animation: fade-up 0.4s var(--ease-out) both; }
.subpanel[hidden] { display: none; }

/* 只读提示条 */
.readonly-bar {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 14px;
  margin-bottom: 14px;
  border-radius: var(--radius);
  border: 1px solid rgba(2, 132, 199, 0.24);
  background: linear-gradient(180deg, rgba(2, 132, 199, 0.07), rgba(2, 132, 199, 0.025));
}

.readonly-badge {
  flex: 0 0 auto;
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #fff;
  background: var(--info);
  border-radius: 4px;
  padding: 2px 8px;
  margin-top: 1px;
}

.readonly-bar p { font-size: 12.5px; color: var(--ink-600); line-height: 1.65; }
.readonly-bar b { color: var(--ink-900); }

/* 兜底说明 */
.fallback {
  margin-bottom: 16px;
  border: 1px solid rgba(217, 119, 6, 0.26);
  border-left: 3px solid var(--warn);
  border-radius: var(--radius-sm);
  background: rgba(217, 119, 6, 0.05);
  padding: 11px 14px;
}

.fallback summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-900);
}

.fallback p { margin-top: 9px; font-size: 12.5px; color: var(--ink-600); line-height: 1.7; }

.fallback ul { margin-top: 8px; display: flex; flex-direction: column; gap: 7px; }

.fallback li {
  position: relative;
  padding-left: 16px;
  font-size: 12.5px;
  color: var(--ink-600);
  line-height: 1.7;
}

.fallback li::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 8px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--warn);
}

.fallback b { color: var(--ink-900); }

/* 报表已知事实 */
.report-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 10px;
  margin-bottom: 20px;
}

.fact {
  padding: 10px 13px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-sm);
  background: var(--canvas);
  min-width: 0;
}

.fact--wide { grid-column: 1 / -1; }
.fact b { display: block; font-size: 11.5px; color: var(--ink-400); font-weight: 600; margin-bottom: 4px; }
.fact code { font-size: 12.5px; }

.hint--block { display: block; margin-bottom: 12px; line-height: 1.7; }

/* 分段控件 */
.segment {
  display: flex;
  gap: 0;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-sm);
  overflow: hidden;
  height: 38px;
}

.segment-item { flex: 1 1 0; min-width: 0; position: relative; cursor: pointer; }
.segment-item input { position: absolute; opacity: 0; width: 0; height: 0; }

.segment-item span {
  display: grid;
  place-items: center;
  height: 100%;
  font-size: 12.5px;
  color: var(--ink-600);
  background: #fff;
  border-right: 1px solid var(--ink-200);
  transition: background 0.18s var(--ease-quart), color 0.18s;
  white-space: nowrap;
}

.segment-item:last-child span { border-right: none; }
.segment-item:hover span { background: rgba(29, 78, 216, 0.05); }
.segment-item input:checked + span { background: var(--blue-600); color: #fff; font-weight: 600; }
.segment-item input:focus-visible + span { box-shadow: inset 0 0 0 2px rgba(29, 78, 216, 0.4); }

/* 参数大文本框 */
.textarea {
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink-900);
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.7;
  resize: vertical;
  transition: border-color 0.18s var(--ease-quart), box-shadow 0.18s;
}

.textarea:focus {
  outline: none;
  border-color: var(--blue-500);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.14);
}

.textarea.is-invalid { border-color: var(--err); box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.12); }

.hint.is-ok { color: var(--ok); }
.hint.is-bad { color: var(--err); }

/* 请求摘要 */
.req-summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 13px;
  margin-bottom: 20px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-sm);
  background: var(--canvas);
  animation: fade-up 0.3s var(--ease-out) both;
}

.rs-label {
  flex: 0 0 auto;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-400);
}

.req-summary code {
  flex: 1 1 auto;
  min-width: 0;
  background: transparent;
  border: none;
  padding: 0;
  font-size: 12px;
  color: var(--ink-900);
  word-break: break-all;
}

.mini-copy {
  flex: 0 0 auto;
  font-family: var(--mono);
  font-size: 11px;
  padding: 3px 9px;
  border: 1px solid var(--ink-200);
  border-radius: 5px;
  background: #fff;
  color: var(--ink-600);
  cursor: pointer;
  transition: all 0.16s var(--ease-quart);
}

.mini-copy:hover { color: var(--blue-600); border-color: rgba(37, 99, 235, 0.4); }

/* 试调记录 */
.call-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 22px; }

.call-item {
  border: 1px solid var(--ink-200);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
  animation: fade-up 0.3s var(--ease-out) both;
  transition: border-color 0.2s var(--ease-quart), box-shadow 0.2s;
}

.call-item:hover { box-shadow: var(--shadow-card); }
.call-item.is-new { animation: call-flash 0.8s var(--ease-quart); }

@keyframes call-flash {
  0% { box-shadow: 0 0 0 3px rgba(29, 78, 216, 0.22); }
  100% { box-shadow: 0 0 0 0 rgba(29, 78, 216, 0); }
}

.call-head {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 13px;
  background: transparent;
  border: none;
  cursor: pointer;
  text-align: left;
  font-family: var(--sans);
}

.call-dot {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ink-400);
}

.call-verdict {
  flex: 0 0 auto;
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 4px;
  background: var(--ink-100);
  color: var(--ink-600);
}

.call-target {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--mono);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-900);
  word-break: break-all;
}

.call-meta {
  flex: 0 0 auto;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-400);
  font-variant-numeric: tabular-nums;
}

.call-item.is-readable { border-color: rgba(22, 163, 74, 0.34); }
.call-item.is-readable .call-dot { background: var(--ok); }
.call-item.is-readable .call-verdict { background: rgba(22, 163, 74, 0.12); color: #15803D; }

.call-item.is-rejected { border-color: rgba(220, 38, 38, 0.3); }
.call-item.is-rejected .call-dot { background: var(--err); }
.call-item.is-rejected .call-verdict { background: rgba(220, 38, 38, 0.1); color: var(--err); }

.call-item.is-notfound .call-dot { background: #94A3B8; }
.call-item.is-notfound .call-verdict { background: var(--ink-100); color: var(--ink-600); }

.call-item.is-unknown .call-dot { background: var(--warn); }
.call-item.is-unknown .call-verdict { background: rgba(217, 119, 6, 0.12); color: #B45309; }

.call-detail {
  padding: 0 13px 13px;
  border-top: 1px dashed var(--ink-200);
  margin-top: 2px;
  padding-top: 11px;
}

.call-detail[hidden] { display: none; }

.call-detail-row {
  display: flex;
  gap: 8px;
  align-items: baseline;
  font-size: 12px;
  margin-bottom: 7px;
}

.call-detail-row b { flex: 0 0 74px; color: var(--ink-400); font-weight: 600; font-size: 11.5px; }
.call-detail-row span { flex: 1 1 auto; min-width: 0; color: var(--ink-600); word-break: break-all; font-family: var(--mono); }

.call-raw {
  margin: 9px 0 0;
  padding: 11px 12px;
  border-radius: var(--radius-sm);
  background: var(--console);
  color: #CBD5E1;
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.65;
  max-height: 260px;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

/* 已保存模板 */
.profile-list { display: flex; flex-direction: column; gap: 8px; }

.profile-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 13px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius);
  background: var(--surface);
}

.profile-item .pi-body { flex: 1 1 auto; min-width: 0; }
.profile-item .pi-name { font-size: 13px; font-weight: 600; }
.profile-item .pi-sub {
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--ink-400);
  margin-top: 2px;
  word-break: break-all;
}

@media (max-width: 720px) {
  .submodes { flex-direction: column; }
  .submode-badge { margin-left: auto; }
  .call-meta { display: none; }
}

/* ============================================================
   结果表分页条（欠款查询 · 完整表格展示）
   ============================================================ */

.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 10px;
  padding: 9px 12px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-sm);
  background: var(--canvas);
}

.pager[hidden] { display: none; }

/*
 * 分页条在**表格上方**时用这个修饰类（应收款汇总表，用户 2026-10-14 要求）。
 * 默认 .pager 是给表格下方的：margin-top:10 把上下外边距反过来，
 * 免得它与上面的口径摘要挤成一块、又和表格粘住。
 */
/*
 * 空态里夹着失败原因时（发票清单取数失败）标红：
 * 「没读到」和「真的没有」是两回事，颜色上也要让人一眼分开。
 */
.empty.is-err { color: var(--err); }

/* ---------------- 销售数据分析（#viewSales） ---------------- */

/* 算不出来的一律显示「—」（没有目标 / 去年没数），绝不显示 0% 骗人 */
.sl-na { color: var(--ink-400); }

.sl-pct { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--ink-600); }
.sl-pct.is-good { color: var(--ok); }
.sl-pct.is-bad { color: var(--err); }

/*
 * 同比：**涨=绿、跌=中性灰**。
 * 注意与欠款口径的区别 —— 那边「涨」是坏事（欠款变多），用的是红；
 * 销售页反过来：销售额涨了是好事。两个页面用同一套颜色会把人误导，所以这里显式写死。
 */
.sl-yoy { font-variant-numeric: tabular-nums; white-space: nowrap; }
.sl-yoy.is-up { color: var(--ok); }
.sl-yoy.is-down { color: var(--ink-600); }

.sl-hint { font-size: 12px; color: var(--ink-400); }
.sl-tick { width: 34px; text-align: center; }
#slTargetTable .input, #slCatTable .input { width: 100%; min-width: 120px; }
#slCatTable .mono { font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace); font-size: 12px; }
#slStats .stat-value.is-info { color: var(--blue-700); }

/*
 * 「我的对账单」列表上方的整理进度条。
 * 放在列表卡外面（一行，贴左），不抢卡片本身的视觉重心。
 */
.st-prep-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 2px;
}

.st-prep-text { font-size: 12.5px; color: var(--ink-600); }
.st-prep-text.is-ready { color: var(--ok); font-weight: 600; }

.pager--top {
  margin-top: 0;
  margin-bottom: 10px;
}

/*
 * ⚠️ 这两条不能省：`.input` 是 `width:100%`（表单里的规矩），
 * 放进这条 flex 行里，那个「每页 N 条」的下拉会**拉满剩下整行**，
 * 把分页条撑成两行。顶部这条要的是紧凑一行。
 */
.pager--top .pager-actions { flex-wrap: nowrap; }
.pager--top .pager-actions select { width: auto; min-width: 118px; }

.pager-info {
  font-size: 12.5px;
  color: var(--ink-600);
  font-variant-numeric: tabular-nums;
}

.pager-info b { color: var(--ink-900); }

.pager-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

.pager-actions select { height: 30px; font-size: 12.5px; }

/* 只读输入框：保持可读但明显不可编辑 */
input[readonly] {
  background: var(--canvas);
  color: var(--ink-600);
  cursor: default;
}

/* ============================================================
   顶端筛选条（应收款汇总表查询）
   ============================================================ */

.filterbar {
  position: sticky;
  top: 0;
  z-index: 30;
  padding: 12px 16px 10px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(8px);
  box-shadow: var(--shadow-card);
  animation: fade-up 0.45s var(--ease-out) both;
}

.filterbar-main {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
}

.fb-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.fb-field label {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-400);
}

.fb-field .input { min-width: 150px; }
.fb-field select.input { min-width: 220px; }

.fb-hint {
  margin-top: 8px;
  font-size: 12px;
  color: var(--ink-400);
}

.fb-hint.is-bad { color: var(--err); }

/* 行内勾选框（显示三零行） */
.chk-inline {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  color: var(--ink-600);
  cursor: pointer;
  user-select: none;
}

.chk-inline input {
  width: 15px;
  height: 15px;
  accent-color: var(--blue-600);
  cursor: pointer;
}

/* 分段按钮组（本月 / 上个月） */
.seg {
  display: inline-flex;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: #fff;
}

.seg-btn {
  font-family: var(--sans);
  font-size: 13px;
  color: var(--ink-600);
  background: transparent;
  border: none;
  border-right: 1px solid var(--ink-200);
  padding: 0 18px;
  height: 34px;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.18s var(--ease-quart), color 0.18s;
}

.seg-btn:last-child { border-right: none; }
.seg-btn:hover { background: rgba(29, 78, 216, 0.05); color: var(--blue-700); }
.seg-btn.is-active { background: var(--blue-600); color: #fff; font-weight: 600; }

/* ============================================================
   侧栏一级 / 二级分组（基础设置）
   ============================================================ */

.sidebar-group {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* 白底侧栏：分组标题用深灰蓝，展开后加深到近黑。
   注意：这一组颜色与 .sidebar-item 是一对的 —— 侧栏换底色时两处必须同时改，
   否则会出现「白字白底」整条菜单看不见。 */
.sidebar-group-head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 9px 12px;
  border: none;
  border-radius: var(--radius);
  background: transparent;
  color: #475569;
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background 0.18s var(--ease-quart), color 0.18s;
}

.sidebar-group-head:hover { background: var(--ink-100); color: var(--blue-700); }

.sg-arrow {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  display: grid;
  place-items: center;
  color: #94A3B8;
  transition: transform 0.22s var(--ease-quart), color 0.18s;
}

.sg-arrow svg { width: 11px; height: 11px; }

.sidebar-group.is-open .sg-arrow { transform: rotate(90deg); color: var(--blue-600); }
.sidebar-group.is-open .sidebar-group-head { color: var(--ink-900); }

.sg-icon {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  display: grid;
  place-items: center;
  color: #64748B;
}

.sg-icon svg { width: 17px; height: 17px; }
.sg-text { flex: 1 1 auto; min-width: 0; }

/* 贴底分隔线：margin-top:auto 把「基础设置」整组推到侧栏底部 */
.sidebar-sep {
  height: 1px;
  margin: auto 4px 8px;
  background: var(--ink-200);
}

/* 组内容：左侧一条竖线做层级引导 */
.sidebar-group-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-left: 12px;
  margin-left: 18px;
  border-left: 2px solid var(--ink-200);
  overflow: hidden;
  max-height: 260px;
  opacity: 1;
  transition: max-height 0.22s var(--ease-quart), opacity 0.18s var(--ease-quart);
}

.sidebar-group:not(.is-open) .sidebar-group-body {
  max-height: 0;
  opacity: 0;
  pointer-events: none;
}

/* 二级项：不显示图标，字号略小 */
.sidebar-item--sub { padding: 8px 10px; }
.sidebar-item--sub .si-text b { font-size: 13.5px; }

/* ============================================================
   账户管理与映射
   ============================================================ */

.ac-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 14px;
}

.ac-tools .input { min-width: 150px; }
.ac-tools-spacer { flex: 1 1 auto; }

/*
 * 三个筛选控件（搜索 / 全部部门 / 全部区域）排到**一行**（用户 2026-10-14）。
 *
 * ⚠️ 它们原本是三行，原因不在 .ac-tools（它本来就是 flex + wrap 的行布局），
 *    而是 .input 的基础规则写着 `width: 100%` —— flex 项的 flex-basis 跟着走 100%，
 *    于是每一件都占满一整行，被 wrap 成三行。所以这里先把宽度顶回 auto，再逐个给宽。
 *
 * 宽度分工：搜索给固定的一档（够放关键字就行），两个下拉窄一些；
 * **唯一能长大的是 .ac-tools-spacer**，这样「新增账户 / 粘贴导入」仍然稳稳靠右。
 */
.ac-tools .input { width: auto; }
.ac-tools #acKeyword { flex: 0 1 300px; }
.ac-tools select.input { flex: 0 0 160px; }

.ac-panel {
  margin-bottom: 16px;
  padding: 14px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius);
  background: var(--canvas);
  animation: fade-up 0.25s var(--ease-out) both;
}

.ac-panel[hidden] { display: none; }

.ac-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
  font-size: 13.5px;
}

.ac-panel .form-grid { margin-bottom: 14px; }
.ac-panel .query-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 0; }

/* 部门 / 区域标签 */
.tag-chip {
  display: inline-block;
  font-size: 11.5px;
  padding: 1px 8px;
  border-radius: 999px;
  border: 1px solid var(--ink-200);
  background: #fff;
  color: var(--ink-600);
}

.tag-chip--dept {
  border-color: rgba(29, 78, 216, 0.24);
  background: rgba(29, 78, 216, 0.07);
  color: var(--blue-700);
}

.tag-chip--region {
  border-color: rgba(217, 119, 6, 0.26);
  background: rgba(217, 119, 6, 0.07);
  color: #B45309;
}

/* 停用行降低对比度 */
.data tr.is-off td { color: var(--ink-400); }
.data tr.is-off .tag-chip { opacity: 0.6; }

/* 待核对的到款：客户填了但在金蝶档案里查不到，这笔不计入「到款未入账」。
   给整行一层很淡的琥珀底 —— 既要能一眼扫出来，又不能盖过「待关联」那种明显的提示色。 */
.data tr.is-dubious td { background: rgba(217, 119, 6, 0.05); }

.row-actions { display: inline-flex; gap: 6px; }

.mini-btn {
  font-family: var(--sans);
  font-size: 11.5px;
  padding: 2px 9px;
  border: 1px solid var(--ink-200);
  border-radius: 5px;
  background: #fff;
  color: var(--ink-600);
  cursor: pointer;
  transition: all 0.16s var(--ease-quart);
}

.mini-btn:hover { color: var(--blue-600); border-color: rgba(37, 99, 235, 0.45); }
.mini-btn--danger:hover { color: var(--err); border-color: rgba(220, 38, 38, 0.4); }

/* 导入预览 */
.import-preview { margin-top: 12px; }
.import-preview .ip-sum { font-size: 12.5px; color: var(--ink-600); margin-bottom: 8px; }
.import-preview .ip-sum b { color: var(--ink-900); }

/* 筛选条第二行：报表切换 + 字段设置 / 导出 等次要操作 */
.filterbar-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--ink-200);
}

.fb-field--row {
  flex-direction: row;
  align-items: center;
  gap: 6px;
}

.fb-field--row label { font-size: 12.5px; color: var(--ink-600); }
.fb-field--row .input { min-width: 170px; }

/* 客户输入框要更宽一些：客户名动辄十几个字（「常熟市中日叉车销售有限公司」），
   按 .input 默认的 150px 连一行都放不下，选起来很难受。 */
.fb-field--grow { flex: 1 1 260px; min-width: 220px; }
.fb-field--grow .input { min-width: 0; width: 100%; }

/* ---------------- 客户对账单：标题行 ---------------- */

/*
 * 对账单的标题行标签特别长（区间 · 行数 · 欠款 · 已隐藏几张 · 是否缓存），
 * 而 .card-head-main 是 flex、h3 会被压缩 —— 结果「<客户名> · 对账单」被挤成两行。
 *
 * 办法是分工：**标题不缩、自己一行；标签负责换行**。
 * 反过来（让标题自由换行）会让每张对账单的卡片头高度飘忽，
 * 客户名长一点的客户（「常熟市中日叉车销售有限公司」）就多占一行。
 */
#stResultCard .card-head-main .card-title {
  flex: 0 0 auto;
  white-space: nowrap;
}

#stResultCard .card-head-main .saved-tag {
  min-width: 0;
  white-space: normal;
  text-align: right;
}

/* ---------------- 客户对账单：预览区 ---------------- */

/*
 * 预览里嵌的是**打印页本身**（/api/report/statement/view，A4 横向）。
 * 所以这里给一块浅灰底、带圆角的「纸面」容器 —— 让预览一眼看出是「一张单子」
 * 而不是又一段页面内容。
 *
 * 固定高度 + 内部滚动是刻意的：对账单可能好几页，让外层页面跟着长的话，
 * 想往下看别的东西要滚很久；滚动条反而更清楚「这是一张长单子」。
 */
.stmt-frame-wrap {
  border: 1px solid var(--ink-200);
  border-radius: 10px;
  background: #f1f5f9;
  padding: 12px;
}

.stmt-frame {
  display: block;
  width: 100%;
  height: 620px;
  border: none;
  border-radius: 6px;
  background: #fff;
  box-shadow: 0 1px 4px rgba(15, 23, 42, 0.08);
}

@media (max-width: 900px) {
  .stmt-frame { height: 460px; }
}

/* 列表上方的口径摘要（替换原卡片头） */
.result-meta {
  font-size: 12.5px;
  color: var(--ink-600);
  padding: 2px 2px 0;
  font-variant-numeric: tabular-nums;
}

/* ============================================================
   系统外壳：左侧栏 + 内容区（数据分析系统）
   ============================================================ */

:root {
  --chevron-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 4.5L6 8.5L10 4.5' fill='none' stroke='%2394A3B8' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
}

.app-shell {
  display: flex;
  align-items: stretch;
  min-height: 100vh;
}

/* --------------------------- 左侧栏 --------------------------- */

.sidebar {
  flex: 0 0 232px;
  width: 232px;
  background: #FFFFFF;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  border-right: 1px solid var(--ink-200);
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 16px 16px 14px;
  border-bottom: 1px solid var(--ink-200);
}

.sidebar-logo {
  flex: 0 0 34px;
  width: 34px;
  height: 34px;
  border-radius: 9px;
  display: grid;
  place-items: center;
  background: linear-gradient(150deg, var(--blue-500), var(--blue-700));
  color: #fff;
  font-size: 17px;
  font-weight: 600;
  box-shadow: 0 6px 14px -9px rgba(29, 78, 216, 0.9);
}

.sidebar-brand-text { display: flex; flex-direction: column; min-width: 0; }
.sidebar-brand-text b { font-size: 15px; color: var(--ink-900); letter-spacing: -0.01em; }

/* 品牌区副标题现在显示运行版本（如 v1.0.0+a1b2c3d）。
   不再用大写字母变换 —— 版本号要大写就显得很怪；数字用等宽对齐。 */
.sidebar-brand-text em {
  font-style: normal;
  font-size: 10.5px;
  color: #94A3B8;
  letter-spacing: 0.03em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar-menu {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 10px;
  flex: 1 1 auto;
}

/* 一级菜单项：只有一行主标题。白底 → 深灰蓝文字，靠浅灰底表示悬浮 */
.sidebar-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 12px;
  border: none;
  border-radius: var(--radius);
  background: transparent;
  color: #334155;
  text-align: left;
  cursor: pointer;
  font-family: var(--sans);
  transition: background 0.2s var(--ease-quart), color 0.2s;
}

.sidebar-item:hover { background: var(--ink-100); color: var(--ink-900); }
.sidebar-item:focus-visible { outline: 2px solid var(--blue-500); outline-offset: 2px; }

.sidebar-item.is-active {
  background: rgba(37, 99, 235, 0.08);
  color: var(--blue-700);
}

.sidebar-item.is-active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  bottom: 8px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--blue-500);
}

.si-icon { flex: 0 0 20px; width: 20px; height: 20px; opacity: 0.95; }
.si-icon svg { width: 20px; height: 20px; display: block; }

.si-text { display: flex; align-items: center; min-width: 0; }
.si-text b { font-size: 14px; font-weight: 600; letter-spacing: 0.005em; }

.sidebar-foot {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 14px;
  border-top: 1px solid var(--ink-200);
}

.sidebar-foot .pill {
  height: 23px;
  padding: 0 8px;
  font-size: 11px;
  background: var(--ink-100);
  border-color: var(--ink-200);
  color: #475569;
}

/* --------------------------- 主区 --------------------------- */

.main-area {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.crumb { display: flex; align-items: center; gap: 8px; font-size: 13px; min-width: 0; }
.crumb-root { color: var(--ink-400); }
.crumb-sep { color: var(--ink-200, #E2E8F0); font-family: var(--mono); }
.crumb-current { color: var(--ink-900); font-weight: 600; }

.pill--safe {
  border-color: rgba(22, 163, 74, 0.28);
  background: rgba(22, 163, 74, 0.07);
  color: #15803D;
}

/*
 * 主工作区：**全页平铺**（用户 2026-10-14 定：所有页面都铺满整屏）。
 *
 * 演进过程：先是全站 1240px 居中 → 单独给「到款登记表」开 .is-flat → 现在全部放开。
 * 所以**没有** .is-flat 这个类了，也不用在 shell.js 里按视图切换 ——
 * 窄的容器在这套表里只会把列挤成省略号（账龄表 16 列、到款明细 12 列）。
 */
.workspace {
  flex: 1 1 auto;
  width: 100%;
  max-width: none;
  padding: 18px 22px 48px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.view { display: flex; flex-direction: column; gap: 18px; animation: fade-up 0.4s var(--ease-out) both; }
.view[hidden] { display: none; }

.view-head { padding-bottom: 12px; border-bottom: 1px solid var(--ink-200); }
.view-title { font-size: 18px; }
.view-desc { margin-top: 5px; font-size: 13px; color: var(--ink-600); line-height: 1.75; max-width: 90ch; }

/* --------------------------- 引导卡 --------------------------- */

.guide-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: 22px 24px;
  border: 1px dashed rgba(37, 99, 235, 0.38);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, rgba(29, 78, 216, 0.06), rgba(29, 78, 216, 0.015));
  animation: fade-up 0.4s var(--ease-out) both;
}

.guide-icon {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--blue-600);
  color: #fff;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 14px;
}

.guide-title { font-size: 16px; }
.guide-text { font-size: 13px; color: var(--ink-600); line-height: 1.8; max-width: 84ch; }
.guide-text b { color: var(--ink-900); }
.guide-actions { margin-top: 2px; }

/* --------------------------- 汇总条 --------------------------- */

.stat-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 4px 0;
  padding: 14px 18px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  animation: fade-up 0.4s var(--ease-out) both;
}

/*
 * 账龄查询表：区间的月份切换（本月 / 上个月），紧跟在「账龄结果」统计条之后。
 * 按钮原是「部门汇总」面板的头的（面板已下架），用户 2026-10-14 要求搬到这儿。
 */
.ag-slots-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
}

.ag-slots-label { font-size: 12.5px; color: var(--ink-600); }

.stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-right: 14px;
  border-right: 1px solid var(--ink-100);
  min-width: 0;
}

.stat:last-child { border-right: none; padding-right: 0; }
.stat-label { font-size: 11.5px; color: var(--ink-400); }
.stat-value { font-family: var(--mono); font-size: 20px; font-weight: 600; font-variant-numeric: tabular-nums; line-height: 1.3; }
.stat-value--money { color: var(--blue-700); }
.stat-value--small { font-size: 12.5px; font-weight: 400; color: var(--ink-600); }

/* --------------------------- 筛选行 --------------------------- */

.filter-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding-bottom: 14px;
  margin-bottom: 14px;
  border-bottom: 1px dashed var(--ink-200);
}

.filter-row .input { flex: 0 1 168px; }
.filter-row select.input { flex: 0 1 148px; }

/* --------------------------- 下拉框 --------------------------- */

select.input {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 30px;
  font-family: var(--sans);
  cursor: pointer;
  background-image: var(--chevron-down);
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 12px 12px;
}

select.input:focus { background-color: #fff; background-image: var(--chevron-down); background-repeat: no-repeat; background-position: right 10px center; background-size: 12px 12px; }

/* --------------------------- 表格增强 --------------------------- */

table.data th.money, table.data td.money { text-align: right; font-variant-numeric: tabular-nums; }
table.data td.actions { text-align: right; white-space: nowrap; }

.row-btn {
  font-family: var(--sans);
  font-size: 11.5px;
  padding: 3px 9px;
  margin-left: 5px;
  border-radius: 5px;
  border: 1px solid var(--ink-200);
  background: #fff;
  color: var(--ink-600);
  cursor: pointer;
  transition: all 0.15s var(--ease-quart);
}

.row-btn:hover { color: var(--blue-600); border-color: rgba(37, 99, 235, 0.4); }
.row-btn--danger:hover { color: var(--err); border-color: rgba(220, 38, 38, 0.4); }

table.data tr.is-editing td { background: rgba(37, 99, 235, 0.06); }

/* --------------------------- 响应式降级 --------------------------- */

@media (max-width: 1080px) {
  .app-shell { flex-direction: column; }

  .sidebar {
    position: static;
    width: 100%;
    flex: 0 0 auto;
    height: auto;
    overflow: visible;
    border-right: none;
    border-bottom: 1px solid rgba(148, 163, 184, 0.14);
  }

  .sidebar-brand { padding: 12px 14px 10px; }
  /* 窄屏也保留版本号 —— 部署后要能在任何屏幕上确认跑的版本 */

  .sidebar-menu {
    flex-direction: row;
    overflow-x: auto;
    gap: 8px;
    padding: 0 14px 10px;
    scrollbar-width: none;
  }

  .sidebar-menu::-webkit-scrollbar { display: none; }

  .sidebar-item {
    flex: 0 0 auto;
    align-items: center;
    padding: 7px 15px;
    border-radius: 999px;
    background: rgba(148, 163, 184, 0.1);
  }

  .sidebar-item.is-active::before { display: none; }
  .sidebar-item.is-active { background: var(--blue-600); }
  .si-icon { display: none; }
  .si-text em { display: none; }

  .sidebar-foot { border-top: none; padding: 0 14px 12px; }
}

@media (max-width: 720px) {
  .workspace { padding: 16px 16px 40px; }
  .foot { padding-left: 16px; padding-right: 16px; }
  .filter-row .input,
  .filter-row select.input { flex: 1 1 100%; }
  .stat { border-right: none; padding-right: 0; }
  .stat-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 0; }
}

/* ============================================================
   金蝶报表取数：数据源自检 / 字段设置 / 账龄结果
   ============================================================ */

.selfcheck {
  padding: 12px 16px;
  border: 1px solid rgba(2, 132, 199, 0.24);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, rgba(2, 132, 199, 0.06), rgba(2, 132, 199, 0.02));
  animation: fade-up 0.45s var(--ease-out) both;
}

.selfcheck > summary {
  cursor: pointer;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink-900);
}

.selfcheck-body { margin-top: 12px; }
.selfcheck-body .filter-row { margin-bottom: 10px; padding-bottom: 12px; }

/* 字段勾选面板 */
.field-picker {
  margin: 4px 0 18px;
  padding: 14px 16px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius);
  background: var(--canvas);
  animation: fade-up 0.3s var(--ease-out) both;
}

.field-picker[hidden] { display: none; }

.field-group { margin-bottom: 12px; }
.field-group:last-of-type { margin-bottom: 4px; }

.field-group-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-400);
  letter-spacing: 0.04em;
  margin-bottom: 6px;
}

.field-checks { display: flex; flex-wrap: wrap; gap: 6px 16px; }

.field-check {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--ink-600);
  cursor: pointer;
  user-select: none;
}

.field-check input { accent-color: var(--blue-600); }
.field-check.is-locked { opacity: 0.65; cursor: default; }

/* 提示条 */
.warnbar {
  margin-top: 14px;
  padding: 12px 15px;
  border: 1px solid rgba(217, 119, 6, 0.28);
  border-left: 3px solid var(--warn);
  border-radius: var(--radius-sm);
  background: rgba(217, 119, 6, 0.06);
}

.warnbar[hidden] { display: none; }
.warnbar b { display: block; font-size: 13px; margin-bottom: 6px; }
.warnbar ul { display: flex; flex-direction: column; gap: 6px; }

.warnbar li {
  position: relative;
  padding-left: 16px;
  font-size: 12.5px;
  color: var(--ink-600);
  line-height: 1.7;
}

.warnbar li::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 8px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--warn);
}

/* 账龄表：各段由绿到深的红（风险色阶） */
table.data td.age {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

table.data td.age-1 { background: rgba(22, 163, 74, 0.09); }
table.data td.age-2 { background: rgba(22, 163, 74, 0.05); }
table.data td.age-3 { background: rgba(217, 119, 6, 0.06); }
table.data td.age-4 { background: rgba(217, 119, 6, 0.1); }
table.data td.age-5 { background: rgba(217, 119, 6, 0.15); }
table.data td.age-6 { background: rgba(220, 38, 38, 0.07); }
table.data td.age-7 { background: rgba(220, 38, 38, 0.11); }
table.data td.age-8 { background: rgba(220, 38, 38, 0.16); }

table.data tr.is-total td {
  background: var(--ink-100) !important;
  font-weight: 600;
  border-top: 2px solid var(--ink-200);
}

table.data td.zero { color: var(--ink-400); }

/* 出错时的「金蝶原始返回」区块（放在 .empty 里，需要左对齐） */
.raw-block {
  margin-top: 14px;
  text-align: left;
}

.raw-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 4px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-600);
}

.raw-sub {
  margin: 9px 0 4px;
  font-size: 11.5px;
  color: var(--ink-400);
  letter-spacing: 0.04em;
}

.raw-block .call-raw { margin-top: 0; }

/* ============================================================
   应收款汇总表查询 · 筛选第二行 + 统计条
   ============================================================ */

/* 筛选第二行：与上一行用虚线分开，避免看起来像一个很高的筛选区 */
/* 欠款查询：把所有筛选压成一条控制带。
   只作用于本页（#dqFilterbar），不动其它页面共用的 .filterbar-main / .fb-field 尺寸。 */
#dqFilterbar .filterbar-main { gap: 8px; }
#dqFilterbar .fb-field { gap: 3px; }
#dqFilterbar .fb-field label { font-size: 11px; letter-spacing: 0; }
#dqFilterbar .fb-field .input { min-width: 112px; }
#dqFilterbar .fb-field select.input { min-width: 132px; }
#dqFilterbar #dqOrg { min-width: 148px; }
#dqFilterbar #dqUnit { min-width: 148px; }

/* ------------------------------------------------------------
   欠款汇总表（部门 / 销售区域 / 销售员）
   欠款查询页与仪表盘共用，渲染逻辑在 public/dimTable.js。
   同样**不动公共 table.data** —— 那张表被账户管理、到款登记共用。
   ------------------------------------------------------------ */
.dim-panel {
  padding: 16px 18px 14px;
  border: 1px solid var(--ink-200);
  border-radius: 12px;
  background: #fff;
  margin-bottom: 16px;
  animation: fade-up 0.3s var(--ease-out) both;
}

.dim-panel[hidden] { display: none; }

.dim-panel-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 12px;
}

.dim-panel-head h3 {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-900);
}

/* 月份切换 / 维度页签紧挨着标题，右侧的统计摘要靠 auto 顶到最右 */
.dim-panel-meta {
  margin-left: auto;
  font-size: 12px;
  color: var(--ink-400);
  font-variant-numeric: tabular-nums;
}

/* 面板标题里的小号分段按钮（如「部门汇总」旁边的 本月 / 上个月）。
   默认 .seg-btn 高 34px，放在标题行里太高。 */
.seg--xs .seg-btn {
  height: 26px;
  padding: 0 12px;
  font-size: 12px;
}

.seg--xs .seg-btn:disabled {
  color: var(--ink-400);
  background: var(--ink-100);
  cursor: not-allowed;
}

.seg--xs .seg-btn:disabled:hover { background: var(--ink-100); color: var(--ink-400); }

/* 维度页签（只有仪表盘用；欠款查询页是单张部门表，不显示页签） */
.dim-tabs {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  border-radius: 7px;
  background: var(--ink-100);
}

.dim-tab {
  border: none;
  background: transparent;
  padding: 4px 12px;
  border-radius: 5px;
  font-family: var(--sans);
  font-size: 12.5px;
  color: var(--ink-600);
  cursor: pointer;
  transition: background 0.16s var(--ease-quart), color 0.16s;
}

.dim-tab:hover { color: var(--ink-900); }
.dim-tab.is-active { background: #fff; color: var(--blue-700); font-weight: 600; box-shadow: 0 1px 3px rgba(15, 23, 42, 0.1); }

/* 行数多（业务员 40 行、区域 28 行）→ 表内滚动，别把页面拉长 */
.dim-scroll {
  max-height: 340px;
  overflow: auto;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius);
}

.dim-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}

/* 同 table.data：吸顶真正生效的是 thead 上这条（见文件上方说明） */
.dim-table thead {
  position: sticky;
  top: 0;
  z-index: 1;
}

.dim-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--ink-100);
  padding: 8px 10px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--ink-600);
  text-align: left;
  white-space: nowrap;
  border-bottom: 1px solid var(--ink-200);
}

.dim-table td {
  padding: 7px 10px;
  border-bottom: 1px solid var(--ink-100);
  white-space: nowrap;
  color: var(--ink-900);
  font-variant-numeric: tabular-nums;
}

.dim-table tbody tr:last-child td { border-bottom: none; }
.dim-table tbody tr:hover td { background: rgba(29, 78, 216, 0.035); }

.dim-table .dim-name {
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  font-family: var(--sans);
}

.dim-table th.money,
.dim-table td.money { text-align: right; }

/* 期末余额是这张表真正要看的数 */
.dim-table th.strong,
.dim-table td.strong { font-weight: 600; color: var(--blue-700); }

/*
 * 超期类的列（超90天合计 / 超360天合计）—— 与账龄页、仪表盘卡片同一套语义：
 * 这几个数是**用来盯的**，有就标红。为 0 时保持普通颜色，
 * 否则整列通红反而看不出哪一行真有问题。
 *
 * ⚠️ 这两个类名在别处也出现过，但那是 .verdict / .kv-val / .advice / .cb-note 上的修饰类，
 *    跟表格单元格没有关系 —— 之前账龄页用了 is-warn 却没有对应的表格样式，是不生效的。
 */
.dim-table td.is-warn { color: var(--err); font-weight: 600; }
.dim-table th.is-warn-head { color: var(--err); }

/*
 * 可排序的表头（用户 2026-10-13 要求，三角箭头示意）。
 *
 * 箭头无论有没有选中都**占着同样的宽度** —— 否则点一下表头会横向抖一下，
 * 而这张表的列本来就多，一抖整个表都在动。
 */
.dim-table thead th.sortable {
  cursor: pointer;
  user-select: none;
}

.dim-table thead th.sortable:hover { background: var(--ink-200); color: var(--ink-900); }
.dim-table thead th.sortable.is-on { color: var(--blue-700); }

.dim-table .sort-arrow {
  /* 固定宽度：空着也占位，点了不抖 */
  display: inline-block;
  width: 11px;
  margin-left: 2px;
  font-size: 9px;
  line-height: 1;
  color: var(--blue-600);
}

/* 合计行：组织合计，压在最后一行 */
.dim-table tr.is-total td {
  border-top: 2px solid var(--ink-200);
  background: rgba(37, 99, 235, 0.05);
  font-weight: 600;
}

.dim-table tr.is-total td.dim-name { font-family: var(--sans); color: var(--ink-900); }

.dim-note {
  margin: 10px 0 0;
  font-size: 11.5px;
  color: var(--ink-400);
  line-height: 1.7;
}

/* ------------------------------------------------------------
   紧凑数据表
   只作用于 #dqTable —— table.data 被账户管理、到款登记等页面共用，
   绝不能改公共选择器（见 styles.css 第 ~875 行的 table.data 定义）。
   table-layout:fixed + colgroup 百分比列宽 = 永远填满容器、不出横向滚动条。
   ------------------------------------------------------------ */
#dqTable {
  table-layout: fixed;
  width: 100%;
}

#dqTable thead th {
  padding: 7px 8px;
  font-size: 11px;
  letter-spacing: 0.02em;
}

#dqTable td {
  padding: 6px 8px;
  font-size: 11.5px;
  /* 宽度由 colgroup 决定，单元格不要再各自设上限，否则列宽会被压变形 */
  max-width: none;
}

#dqTable td.money,
#dqTable thead th.money {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 720px) {
  /* 窄屏放不下一行，让筛选控件两两成行，比硬挤成一行更好读 */
  #dqFilterbar .fb-field { flex: 1 1 45%; }
  #dqFilterbar .fb-field .input,
  #dqFilterbar .fb-field select.input { min-width: 0; width: 100%; }
  .dim-scroll { max-height: 260px; }
  .dim-panel-meta { margin-left: 0; }
}

/* ============================================================
   仪表盘（首屏）
   ============================================================ */

/*
 * 指标卡：**一行铺满**（用户 2026-10-13 要求）。
 *
 * 原来写的是 grid 固定 4 列 —— 加上账龄那三张之后一共 7 张，
 * 就会折成 4+3：第二行只有三张、右边空出一大块，看着像少了一张。
 *
 * 改成 flex + nowrap：有几张就并排几张，每张均分宽度，**永远不折行**。
 * min-width:0 不能省 —— flex 子项默认不收缩，7 张卡会把容器撑破。
 */
.dash-cards {
  display: flex;
  flex-wrap: nowrap;
  gap: 12px;
  margin-bottom: 18px;
}

.dash-card {
  flex: 1 1 0;
  min-width: 0;
  position: relative;
  padding: 13px 14px 12px;
  border: 1px solid var(--ink-200);
  border-radius: 12px;
  background: #fff;
  overflow: hidden;
  animation: fade-up 0.3s var(--ease-out) both;
}

/* 左侧一道竖色条区分语义：欠款=红 / 应收=蓝 / 收款=绿 / 客户数=灰 */
.dash-card::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--accent, #64748B);
}

.dash-card--danger { --accent: #DC2626; }
.dash-card--info { --accent: #2563EB; }
.dash-card--ok { --accent: #16A34A; }
.dash-card--neutral { --accent: #64748B; }

.dash-card-label {
  font-size: 12.5px;
  color: var(--ink-600);
  letter-spacing: 0.01em;
}

/*
 * 字号按「一行 7 张」定：一行铺满时每张只有 140px 左右，
 * 26px 的「2,691.9 万」根本放不下，会挤成两行把卡片撑高。
 */
.dash-card-value {
  margin-top: 6px;
  font-size: 20px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--ink-900);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.dash-card-unit {
  margin-left: 4px;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-400);
}

.dash-card-sub {
  margin-top: 6px;
  font-size: 11px;
  color: var(--ink-400);
  line-height: 1.45;
  font-variant-numeric: tabular-nums;
  /* 允许折行：说明文字长短不一，硬压一行会把卡片挤变形 */
  word-break: break-word;
}

/* 账龄卡片 */
.dash-panel {
  padding: 18px 18px 16px;
  border: 1px solid var(--ink-200);
  border-radius: 12px;
  background: #fff;
  margin-bottom: 16px;
  animation: fade-up 0.3s var(--ease-out) both;
}

.dash-panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 16px;
}

.dash-panel-head h3 {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-900);
}

.dash-panel-meta {
  font-size: 12px;
  color: var(--ink-400);
  font-variant-numeric: tabular-nums;
}

/* 8 段横向条形 */
.dash-bars { display: flex; flex-direction: column; gap: 9px; }

.dash-bar-row {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr) 120px 56px;
  align-items: center;
  gap: 12px;
}

.dash-bar-label { font-size: 12.5px; color: var(--ink-600); }

.dash-bar-track {
  height: 18px;
  border-radius: 5px;
  background: var(--ink-100);
  overflow: hidden;
}

/* 宽度用 CSS 变量传入；入场时从 0 长到 --w，避免直接跳到位 */
.dash-bar-fill {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 5px;
  background: var(--c, #2563EB);
  transition: width 0.6s var(--ease-out);
}

.dash-bar-fill.is-in { width: var(--w); }

.dash-bar-amount {
  text-align: right;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-900);
  font-variant-numeric: tabular-nums;
}

.dash-bar-ratio {
  text-align: right;
  font-size: 12px;
  color: var(--ink-400);
  font-variant-numeric: tabular-nums;
}

.dash-aging-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin-top: 16px;
  padding-top: 13px;
  border-top: 1px dashed var(--ink-200);
  font-size: 12.5px;
  color: var(--ink-600);
}

.dash-aging-total b {
  color: var(--ink-900);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

.dash-aging-check { color: var(--ok); }
.dash-aging-check.is-bad { color: var(--err); }

/* 引导卡：未精算、无快照、无组织时都用它 */
.dash-guide h3 {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-900);
  margin-bottom: 8px;
}

.dash-guide p {
  font-size: 13px;
  color: var(--ink-600);
  line-height: 1.75;
  max-width: 78ch;
}

.dash-guide p b { color: var(--ink-900); }
.dash-guide-note { margin-top: 8px; font-size: 12.5px; color: var(--ink-400); }

.dash-guide-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 15px;
}

.dash-guide-org { margin-top: 10px; font-size: 12px; color: var(--ink-400); }

/* 只有独立出现（不在账龄卡片里）的引导才加虚线框 */
#dbEmpty > .dash-guide {
  padding: 22px;
  border: 1px dashed var(--ink-200);
  border-radius: 12px;
  background: #fff;
  animation: fade-up 0.3s var(--ease-out) both;
}

/* 窄屏才允许折行 —— 一行铺满是为了正常宽度下好看，
   屏幕不够时硬挤成一排会让数字互相压住，反而读不了。 */
@media (max-width: 1080px) {
  .dash-cards { flex-wrap: wrap; }
  .dash-card { flex: 1 1 calc(50% - 6px); }
}

@media (max-width: 720px) {
  .dash-card { flex: 1 1 100%; }
  .dash-bar-row { grid-template-columns: 62px minmax(0, 1fr) 92px 48px; gap: 8px; }
  .dash-card-value { font-size: 22px; }
}

/* ============================================================
   到款登记：客户「输入即出候选」组合框
   ============================================================ */

/*
 * 注意：这里的前缀刻意用 .cb- 而不是 .ac- ——
 * .ac-panel / .ac-tools 已经被「账户管理与映射」页占用，两者长得完全不一样，
 * 复用只会让后来人分不清哪个样式属于谁。
 */

.cb-host { position: relative; }

/*
 * 定位必须是 fixed，位置由 JS 按输入框的实时坐标摆放。
 * 原因：录入器现在嵌在表格行里，而 .table-wrap 有 overflow:auto ——
 * 绝对定位的面板会被容器裁掉，候选人只露出半截。
 */
.cb-panel {
  position: fixed;
  /*
   * 必须高过遮罩层（.modal-mask 是 90）—— 拆分弹窗里也要能弹客户候选，
   * 低于遮罩的话候选面板会被压在遮罩下面，看得见点不着。
   */
  z-index: 120;
  min-width: 380px;
  max-width: min(620px, 88vw);
  max-height: 268px;
  overflow-y: auto;
  padding: 5px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-sm);
  background: #fff;
  box-shadow: 0 20px 44px -20px rgba(15, 23, 42, 0.38), 0 2px 8px -4px rgba(15, 23, 42, 0.12);
  animation: cb-in 0.15s var(--ease-out) both;
}

.cb-panel[hidden] { display: none; }

@keyframes cb-in {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: translateY(0); }
}

/* 一行四列：编码 · 名称 · 组织 · 业务员。编码与业务员窄且等宽，名称吃掉剩余空间 */
.cb-item {
  display: grid;
  grid-template-columns: 112px minmax(0, 1fr) 78px 64px;
  gap: 10px;
  align-items: center;
  padding: 7px 9px;
  border-radius: 6px;
  cursor: pointer;
}

.cb-item:hover,
.cb-item.is-active {
  background: rgba(37, 99, 235, 0.08);
}

/* 键盘高亮用左侧竖条，比整行反色更克制，也不会盖掉文字的层次 */
.cb-item.is-active { box-shadow: inset 2px 0 0 var(--blue-500); }

.cb-code {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-600);
  white-space: nowrap;
}

.cb-name {
  font-size: 13px;
  color: var(--ink-900);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cb-org {
  font-size: 11.5px;
  color: var(--blue-700);
  background: rgba(37, 99, 235, 0.07);
  border: 1px solid rgba(37, 99, 235, 0.18);
  border-radius: 999px;
  padding: 1px 7px;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cb-org:empty { border: none; background: none; }

.cb-seller {
  font-size: 11.5px;
  color: var(--ink-400);
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cb-empty {
  padding: 12px 10px;
  font-size: 12.5px;
  color: var(--ink-400);
  line-height: 1.6;
}

/* 输入框的两种即时反馈：选中回填（绿）/ 与金蝶不一致（红） */
.input.is-flash-ok {
  border-color: rgba(22, 163, 74, 0.55);
  box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.15);
}

.input.is-bad {
  border-color: rgba(220, 38, 38, 0.55);
  box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.12);
}

/* 客户名录状态条：严格校验全靠它，所以放在录入区正下方 */
.cb-note {
  margin-top: 16px;
  padding: 9px 13px;
  border: 1px dashed var(--ink-200);
  border-radius: var(--radius-sm);
  background: var(--canvas);
  font-size: 12px;
  color: var(--ink-600);
  line-height: 1.75;
  font-variant-numeric: tabular-nums;
}

.cb-note b { color: var(--ink-900); }
.cb-note.is-warn { border-color: rgba(217, 119, 6, 0.32); background: rgba(217, 119, 6, 0.05); }

/* ------------------------- 到款记录表：单元格样式 ------------------------- */

.cell-mono {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-600);
  white-space: nowrap;
}

.cell-clip {
  display: block;
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 状态标签：已入账（蓝，计入到款未入账）/ 待关联客户（琥珀，不计入） */
.tag--ok {
  color: var(--blue-700);
  border-color: rgba(29, 78, 216, 0.25);
  background: rgba(29, 78, 216, 0.05);
}

.tag--pending {
  color: var(--warn);
  border-color: rgba(217, 119, 6, 0.3);
  background: rgba(217, 119, 6, 0.07);
}

/* 一键采用候选的小按钮（校验失败提示里用） */
.cb-apply {
  font-family: var(--mono);
  font-size: 11.5px;
  padding: 2px 8px;
  border: 1px solid rgba(29, 78, 216, 0.28);
  border-radius: 5px;
  background: rgba(29, 78, 216, 0.05);
  color: var(--blue-700);
  cursor: pointer;
}

.cb-apply:hover { background: rgba(29, 78, 216, 0.12); }

@media (max-width: 1080px) {
  .cb-panel { min-width: 320px; }
}

/* 窄屏时候选面板收窄，避免在右侧溢出视口 */
@media (max-width: 720px) {
  .cb-panel {
    min-width: 0;
    width: min(92vw, 420px);
  }
  .cb-item { grid-template-columns: 96px minmax(0, 1fr) 62px; }
  .cb-org { display: none; }
}

/* ============================================================
   到款登记：紧凑化 + 行内录入 + 批量操作 + 渠道设置
   ============================================================ */

/* ---------------------------- 紧凑化 ---------------------------- */

.view-head--tight { margin-bottom: -6px; }

.stat-strip--tight { gap: 10px; padding: 10px 14px; }
.stat-strip--tight .stat-label { font-size: 11.5px; }
.stat-strip--tight .stat-value { font-size: 18px; margin-top: 2px; }
.stat-strip--tight .stat-value--money { font-size: 16px; }

.card--tight .card-head { padding: 12px 16px; }
.card--tight .card-body { padding: 0 16px 14px; }

.filter-row--tight { padding-bottom: 10px; margin-bottom: 10px; }
.filter-row--tight .input { flex: 0 1 130px; }
.filter-row--tight select.input { flex: 0 1 118px; }

/* ------------------ 行内编辑：整行变输入框 ------------------ */

/* 编辑中的行：与普通行区分开，左侧再来一条色条，扫一眼就知道「这行正在改」 */
#trTable tr.is-editing > td {
  padding: 5px 6px;
  background: #F8FAFF;
  vertical-align: middle;
}

#trTable tr.is-editing > td:first-child { box-shadow: inset 3px 0 0 var(--blue-500); }

/* 新增行用绿色色条，和「编辑已有行」区分 */
#trTable tr.is-new > td { background: #F6FBF7; }
#trTable tr.is-new > td:first-child { box-shadow: inset 3px 0 0 var(--ok); }

/* 行内控件：尺寸必须贴合单元格，撑破表格就会出现横向滚动条 */
.cell-input,
.cell-select {
  width: 100%;
  min-width: 0;
  height: 28px;
  padding: 0 4px;
  font-family: var(--sans);
  font-size: 12px;
  color: var(--ink-900);
  background: #fff;
  border: 1px solid var(--ink-200);
  border-radius: 5px;
}

.cell-input:focus,
.cell-select:focus {
  outline: none;
  border-color: var(--blue-500);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.13);
}

.cell-input--num { text-align: right; font-variant-numeric: tabular-nums; }

/* 日期与编码用等宽 + 10.5px：'2026-10-12' 十个字符，12px 等宽要 72px，
   而这一列在浏览态只被 '2026-10-08' 撑到 89px，扣掉单元格与输入框的内边距就放不下
   （实测差 2px，日期会被吃掉最后一位）。10.5px 每字符约 6.3px，留出余量。 */
.cell-input--mono { font-family: var(--mono); font-size: 10.5px; }

/* 必填但还空着：给一层极淡的琥珀底，不刺眼但漏不掉 */
.cell-input.is-empty { background: #FFFDF6; border-color: rgba(217, 119, 6, 0.3); }

/* 校验没通过：红框 + 红圈，和外面那行错误提示呼应 */
.cell-input.is-bad {
  border-color: rgba(220, 38, 38, 0.6);
  box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.12);
}

.cell-input.is-flash-ok {
  border-color: rgba(22, 163, 74, 0.55);
  box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.15);
}

/* 编辑行里的操作按钮再紧一点：这一列本来就挤 */
#trTable tr.is-editing .row-btn,
#rcTableDetail tr.is-editing .row-btn { margin-left: 3px; padding: 3px 7px; }

.row-btn--primary {
  color: #fff;
  background: var(--blue-600);
  border-color: var(--blue-600);
}

.row-btn--primary:hover { color: #fff; background: var(--blue-700); border-color: var(--blue-700); }

/* -------------------------- 批量操作条 -------------------------- */

.batch-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  margin-bottom: 10px;
  border: 1px solid rgba(37, 99, 235, 0.28);
  border-radius: var(--radius-sm);
  background: rgba(37, 99, 235, 0.05);
  animation: fade-up 0.2s var(--ease-out) both;
}

.batch-bar[hidden] { display: none; }

.batch-info {
  font-size: 12.5px;
  color: var(--blue-700);
  font-variant-numeric: tabular-nums;
}

.batch-info b { font-size: 13.5px; }
.batch-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-left: auto; }

/* ---------------------------- 勾选列 ---------------------------- */

.data th.col-check,
.data td.col-check { width: 30px; text-align: center; }
.data td.col-check input { cursor: pointer; accent-color: var(--blue-600); }
.data tr.is-checked td { background: rgba(37, 99, 235, 0.05); }

/* 到款明细与对账明细都是 11 列，内边距与字号压一压，尽量少出现横向滚动 */
#trTable th,
#trTable td,
#rcTableDetail th,
#rcTableDetail td { padding: 7px 8px; font-size: 12.5px; }
#trTable .cell-mono,
#rcTableDetail .cell-mono { font-size: 12px; }
#trTable .cell-clip,
#rcTableDetail .cell-clip { max-width: 120px; }

/* 操作列是一排按钮，必须 nowrap —— 换行会让行高翻倍，整张表就不紧凑了 */
#trTable td.actions,
#rcTableDetail td.actions { white-space: nowrap; padding-right: 8px; }
#trTable th.actions,
#rcTableDetail th.actions { white-space: nowrap; }

/* 状态列是只读标签，不需要让它撑宽 */
#trTable td .tag { white-space: nowrap; }

/* 操作列最多放 5 个按钮（编辑/拆分/下推/退款/删除），每多 10px 就多一份横向滚动的风险，
   所以内边距与字号都压到最小可用值 */
#trTable .row-btn,
#rcTableDetail .row-btn {
  padding: 3px 6px;
  margin-left: 3px;
  font-size: 11px;
}

/* ============================================================
   渠道对账：金额、差额、人工覆盖标记
   ============================================================ */

/* 金额一律等宽右对齐，纵向扫一列时小数点才能对齐 */
.rc-money {
  font-family: var(--mono);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* 差额：0 是绿的（对上了），非 0 是红的（要查）。整张表就是为了把红的挑出来 */
.rc-diff-ok { color: var(--ok); }
.rc-diff-bad { color: var(--err); font-weight: 600; }

.rc-none { color: var(--ink-400); }

/* 「✎」= 这一列是人填的，不是自动统计值。
   不标出来，后来人会对着它算不平，还以为程序算错了 */
.rc-ovr {
  margin-left: 4px;
  font-size: 9.5px;
  font-style: normal;
  line-height: 1;
  color: var(--warn);
  vertical-align: 2px;
  cursor: help;
}

/* 最后一次对账之后新收到的到款：不提示就会静默漏掉，账面永远差这一笔 */
.rc-pending {
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--warn);
  white-space: nowrap;
  cursor: help;
}

.rc-off {
  font-size: 10.5px;
  color: var(--ink-400);
  border: 1px solid var(--ink-200);
  border-radius: 999px;
  padding: 0 6px;
  margin-left: 4px;
}

/* 期初余额自动承接时输入框是禁用的 —— 要让它明显「不可改」，而不是看起来能填 */
.cell-input:disabled {
  color: var(--ink-400);
  background: var(--ink-100);
  cursor: not-allowed;
}

/* 统计条里出现「差额不为 0」「有渠道对不上」时，数字变红才看得见 */
.stat-value.is-bad { color: var(--err); }

/* 「客户对不上」的红标：原来是一整个文字标签，光它就要 60 多像素，
   把整张表顶出了横向滚动条。改成 15px 的圆点，说明放进 title。 */
.warn-mark {
  display: inline-grid;
  place-items: center;
  width: 15px;
  height: 15px;
  margin-right: 4px;
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  color: #fff;
  background: var(--err);
  border-radius: 50%;
  vertical-align: -2px;
  cursor: help;
}

/* ------------------------- 状态标签（6 态） ------------------------- */

/* 每条状态一种颜色，扫一眼就知道这一行走到哪一步了。
   待入账/已提交是「还在本系统里」的（蓝系），已入账是「已经落到金蝶」的（绿）。 */
.tag.st-pending { color: #B45309; border-color: rgba(217, 119, 6, 0.32); background: rgba(217, 119, 6, 0.07); }
.tag.st-matched { color: var(--blue-700); border-color: rgba(29, 78, 216, 0.28); background: rgba(29, 78, 216, 0.06); }
.tag.st-submitted { color: #6D28D9; border-color: rgba(109, 40, 217, 0.28); background: rgba(109, 40, 217, 0.07); }
.tag.st-posted { color: #15803D; border-color: rgba(22, 163, 74, 0.30); background: rgba(22, 163, 74, 0.07); }
.tag.st-to_refund { color: #C2410C; border-color: rgba(194, 65, 12, 0.30); background: rgba(194, 65, 12, 0.07); }
.tag.st-refunded { color: var(--ink-400); border-color: var(--ink-200); background: var(--ink-100); }

/* 行内小标记：客户在金蝶档案里查不到 */
.tag.tag--unmatched {
  color: var(--err);
  border-color: rgba(220, 38, 38, 0.28);
  background: rgba(220, 38, 38, 0.06);
}

/* ------------------ 名录提示 / 编辑状态（都只占一行，不撑高页面） ------------------ */

/* 名录条：严格校验全靠它，所以常驻可见，但要压到只有一行高 */
.cb-note--slim {
  margin: 0 0 10px;
  padding: 6px 10px;
  font-size: 11.5px;
  line-height: 1.6;
}

/* 行内编辑时的反馈条：校验失败原因、正在保存等 */
.edit-state {
  margin: 0 0 10px;
  padding: 7px 11px;
  font-size: 12px;
  line-height: 1.65;
  border: 1px solid rgba(220, 38, 38, 0.28);
  border-radius: var(--radius-sm);
  background: rgba(220, 38, 38, 0.05);
  color: var(--err);
}

.edit-state[hidden] { display: none; }

.edit-state.is-ok {
  border-color: rgba(22, 163, 74, 0.3);
  background: rgba(22, 163, 74, 0.05);
  color: var(--ok);
}

.edit-state .cb-apply { margin-left: 6px; }

/* --------------------------- 渠道设置 --------------------------- */

.ch-panel {
  margin-bottom: 14px;
  padding: 12px 14px;
  border: 1px dashed var(--ink-200);
  border-radius: var(--radius-sm);
  background: var(--canvas);
  animation: fade-up 0.22s var(--ease-out) both;
}

.ch-panel[hidden] { display: none; }

.ch-panel-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 10px;
}

.ch-panel-head b { font-size: 13.5px; }
.ch-table th, .ch-table td { font-size: 12.5px; padding: 6px 10px; }
.ch-table tr.is-off td { color: var(--ink-400); }

.ch-add {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
}

.ch-add .input { flex: 0 1 170px; }

/* 同一笔收款（拆分出来的多行）在视觉上归拢一下 */
.data tr.batch-first td { border-top: 2px solid rgba(37, 99, 235, 0.22); }
.data td .batch-tag {
  display: inline-block;
  margin-left: 6px;
  font-family: var(--mono);
  font-size: 10px;
  color: var(--blue-700);
  background: rgba(37, 99, 235, 0.08);
  border-radius: 3px;
  padding: 0 4px;
}

/* ------------------- 小弹窗（拆分 / 退款） ------------------- */

.modal-mask {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(15, 23, 42, 0.42);
  animation: tr-fade-in 0.16s var(--ease-out) both;
}

@keyframes tr-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/*
 * ⚠️ 这一条必须有：`hidden` 属性靠的是浏览器默认样式 `[hidden] { display:none }`，
 * 而**作者样式一律优先于浏览器默认样式** —— 上面刚写了 `display: grid`，
 * 于是「带 hidden 的遮罩」照样铺在页面上。
 *
 * 实测事故（用户 2026-10-14 报「客户对账单都是灰色状态」）：
 * 对账单页的申诉遮罩 #stAppealMask 常驻显示，整个列表被罩上一层 42% 的深色，
 * 而且鼠标点不动列表（点击被遮罩吃掉）。
 *
 * 本表其它组件（.cb-panel / .warnbar / .view / .panel …）都有各自的 [hidden] 兜底，
 * 当初唯独漏了遮罩。
 */
.modal-mask[hidden] { display: none; }

.modal-box {
  width: min(760px, 100%);
  max-height: 86vh;
  display: flex;
  flex-direction: column;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 30px 70px -30px rgba(15, 23, 42, 0.55);
  animation: fade-up 0.2s var(--ease-out) both;
}

.modal-head { padding: 14px 18px; border-bottom: 1px solid var(--ink-200); }
.modal-head b { font-size: 15px; color: var(--ink-900); }
.modal-body { padding: 16px 18px; overflow-y: auto; }
.modal-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 12px 18px;
  border-top: 1px solid var(--ink-200);
}

.modal-note { font-size: 12.5px; color: var(--ink-600); line-height: 1.75; margin-bottom: 14px; }
.modal-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }

/* 拆分：一行 = 一个客户 + 它的金额 */
.split-rows { display: flex; flex-direction: column; gap: 8px; }
.split-row { display: grid; grid-template-columns: 130px minmax(0, 1fr) minmax(0, 1fr) 46px; gap: 8px; align-items: center; }
.split-foot { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
.split-sum { font-size: 12.5px; color: var(--ink-600); font-variant-numeric: tabular-nums; }
.split-sum.is-ok { color: var(--ok); font-weight: 600; }
.split-sum.is-bad { color: var(--err); font-weight: 600; }

@media (max-width: 720px) {
  .split-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .split-row [data-f="customerName"] { grid-column: span 2; }
  .modal-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================
   仪表盘 · 嵌进「欠款结构」面板的筛选条
   ============================================================ */

/*
 * 这条控制带从「独立卡片」改成了「面板内的一条控制带」：
 * 它原本与 .dim-panel 平级，现在住在 .dim-panel 里面，是卡片里的**第一行**
 * （面板内顺序：筛选条 → 标题行 → 维度表）。
 *
 * ⚠️ 只用一个新类去覆盖，** .filterbar 原规则一行不动**：
 * 那条规则被 #dbFilterbar（本页）与 #dqFilterbar（应收款汇总表查询）共用，
 * 改它会连带改掉另一页。
 */
.filterbar--embedded {
  /* 吸顶必须去掉：住在卡片里还吸顶，滚动时会被整条拽出卡片，把面板切成两半 */
  position: static;
  z-index: auto;

  /* 卡片外观全部还原：外层 .dim-panel 已经是白底卡片，
     里面再套一张白卡片就是「卡片套卡片」，边界反而更糊 */
  padding: 0;
  border: none;
  border-radius: 0;
  background: transparent;
  backdrop-filter: none;
  box-shadow: none;

  /* 它不再是「控件区与数据表」的分界 —— 那条虚线交给了紧挨表格的标题行，
     见下面的 #dbDimPanel .dim-panel-head */
  margin-bottom: 10px;

  /* .dim-panel 自己有 fade-up，内层再播一次就是两个动画打架 */
  animation: none;
}

/*
 * 虚线挂在标题行底下。
 *
 * 为什么是标题行而不是筛选条：这条线分隔的是「控件区」与「数据表」，
 * 与两行谁先谁后无关 —— 谁挨着表格，线就归谁。调换顺序时只改这一处即可。
 *
 * ⚠️ .dim-panel-head 是**共用类**：「应收款汇总表查询」页的部门汇总面板也在用它，
 * 所以必须用 #dbDimPanel 限定作用域，否则那张卡会平白多出一条线。
 */
#dbDimPanel .dim-panel-head {
  padding-bottom: 10px;
  border-bottom: 1px dashed var(--ink-200);
}

/* 两个字段现在都是「标签 + 控件」的单行，竖向对齐基准从 end 改成 center */
.filterbar--embedded .filterbar-main {
  align-items: center;
  gap: 16px;
}

/* .fb-field select.input 原规则给的是 220px；这里收窄一点，
   让「结算组织 · 区间 · 刷新 · 已加载」稳稳占住一行 */
.filterbar--embedded .fb-field select.input { min-width: 168px; }

/* ⚠️ 标签必须禁止换行。
   中文在 flex 容器里**可以在任意两个字之间断行**，于是 label 的 min-content 宽度
   只有一个字 —— flex 收缩时「结算组织」会被压成「结算组 / 织」两行（实测只剩 38px，
   而它需要约 50px）。加了 nowrap，min-content 就是整词的宽度，收缩会让给下拉框。 */
.filterbar--embedded .fb-field--row label { white-space: nowrap; }

/* ---------------- 面板标题行右侧：快照新鲜度 + 维度统计 ---------------- */

/*
 * 为什么要包一层 .dim-panel-side：
 * .dim-panel-meta 靠 margin-left:auto 把自己顶到最右；两个都带 auto 的元素并排时，
 * 两个 auto 会把它们分别推到行的两端、中间空出一大片。包成一组就只剩一个 auto。
 */
.dim-panel-side {
  margin-left: auto;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}

/* 「数据来自本地快照 · … 拉取于 …」是数据出处的备注，不是结论，
   所以语气比右边的统计数字更弱一档 */
.dim-panel-side-note {
  font-size: 11.5px;
  color: var(--ink-400);
  font-variant-numeric: tabular-nums;
}

/* 右半边那组统计：抵消内层的 auto，并在两段小字之间加一条发丝线 ——
   不加的话它们会连成一长串，读不出是两件事 */
.dim-panel-side .dim-panel-meta {
  margin-left: 0;
  padding-left: 12px;
  border-left: 1px solid var(--ink-200);
}

/* 窄屏时标题行本来就会换行，辅助信息不再往右顶 */
@media (max-width: 1080px) {
  .dim-panel-side { margin-left: 0; }
}

/* ============================================================
   账龄查询（面向市场人员）
   ============================================================ */

/* 「没有这个数据」与「数据是 0」必须长得不一样：
   信用额度为空 = 这个客户压根没有信用档案，填 0 会让人以为「授信为 0」 */
.cell-none { color: var(--ink-400); }

/* 超期90天欠款：业务员最先看的就是这一列，给它一点分量，
   但不改变「红=有问题」的既有约定，所以不动颜色只加粗 */
#agTable .age-over90 { font-weight: 600; }

/* 账龄段配色（沿用原来的由浅到深），合计行也一样适用 */
#agTable .age { font-variant-numeric: tabular-nums; }
#agTable .age.zero { color: var(--ink-400); }

/* ---------------- 汇总条：本月 vs 上月 ---------------- */

/*
 * 每张卡片下面那行「上月 X · ↑ 变化」。小一号、中性灰，不跟主数字抢注意力。
 * nowrap 是**必须**的：「上月 2,286.9 万 · ↑ 405.0 万」一折行，
 * 五张卡片就会高低不齐（grid 只拉伸高度、不重排内部）。
 */
.stat-delta {
  display: block;
  margin-top: 3px;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--ink-600);
  white-space: nowrap;
}

.stat-delta b { font-weight: 600; }

/* 欠款类指标涨了是要盯的 → 红；跌了是好事 → 绿。
   客户数不挂 upIsBad，涨跌只是事实，走上面的中性灰。 */
.stat-delta.is-bad b { color: var(--err); }
.stat-delta.is-good b { color: var(--ok); }

/* ---------------- 表头列宽可拖动 ---------------- */

/*
 * ⚠️ 这里**故意不写** `#agTable { table-layout: fixed }`。
 *
 * 固定布局必须由 JS 在「量完自然列宽之后」再加（见 aging.js 的 applyColWidths）。
 * 写在 CSS 里的话，表格从第一次渲染就是固定布局 —— 没有 colgroup 时固定布局
 * 会把所有列**平均分**，于是量出来的初始列宽就是 16 个 59px（等宽格子），
 * 和改之前的样子完全不一样。这个坑踩过一次，别再把这一行加回来。
 */
#agTable.is-fixed-layout { table-layout: fixed; }

/*
 * 抓手要绝对定位到 th 的右边缘，所以 th 必须是定位上下文 ——
 * 但**必须写成 sticky，不能写成 relative**。
 *
 * ⚠️ 这里原本是 `position: relative`，后果是**表头不再吸顶**：
 *    它和上面 `table.data thead th { position: sticky; top: 0 }` 同权重、
 *    又在文件更后面，直接把全局那条覆盖掉了（实测 computed position = relative）。
 *    表头于是跟着 420px 高的表格容器一起滚走、只剩半截 ——
 *    用户 2026-10-14：「这个表头栏要固定，不能随着滑动过被折叠」。
 *
 * sticky 元素**本身就是定位上下文**，抓手照样能绝对定位到它的右边缘，
 * 所以这一条同时满足「吸顶」与「抓手定位」，不需要 relative。
 */
#agTable thead th {
  position: sticky;
  top: 0;
  z-index: 1;
}

/* ⚠️ 真正把账龄表头钉住的是**这一条**：Chromium 里单元格上的 sticky 不生效，
   必须是 thead（table-header-group）。详见文件上方 table.data thead 的说明。 */
#agTable thead {
  position: sticky;
  top: 0;
  z-index: 1;
}

/*
 * ===================== 这两条 white-space 都不能加布局限定 =====================
 *
 * 它们不只是显示规则，还是**「量自然列宽」那一步的输入**：
 * 列宽是先把表格松开、让浏览器按内容排一次量出来的。这时候如果数据格子允许折行，
 * 量到的就是「被容器压扁」的宽度，锁死之后每个金额都变成「332…」——
 * 实测踩过，整张表的数据全成了省略号。
 *
 * 所以：数据永远不折行（金额、编码、客户名都不是能断开的串），
 * 表头永远可折行（16 列平均每列才 59px，列名一行放不下；
 * 折成「销售 / 部门」看得懂，截成「销…」等于把表头删了）。
 */
#agTable td { white-space: nowrap; }

#agTable thead th {
  white-space: normal;
  word-break: break-word;
  line-height: 1.25;
}

/* 内容截断只在固定布局下开。auto 布局时让内容自然撑开表格 ——
   那才是「内容真正需要多宽」，也是初始列宽的来源。 */
#agTable.is-fixed-layout td { overflow: hidden; text-overflow: ellipsis; }
#agTable.is-fixed-layout thead th { overflow: hidden; }

/*
 * 「量列宽」那一瞬间的临时状态（由 aging.js 加、量完立刻摘，页面上看不到）。
 *
 * 允许折行时量到的宽度才和改之前一致：销售部门 / 销售区域 / 销售员 / 往来单位名称
 * 这四列会被压到 36~52px（内容一直靠 title 悬停看全，本页向来如此），
 * 从而把宽度让给 8 个账龄段。
 *
 * 不折行的话这四列会吃 84~320px，合计 1,828px，把账龄段全挤出屏幕 ——
 * 而账龄段才是这张表的主角。
 */
#agTable.is-measuring td,
#agTable.is-measuring thead th { white-space: normal; }

/*
 * ---------------- 到款明细（#trTable）同款：表头列宽可拖动 ----------------
 *
 * 与上面 #agTable 那批**同义**，只是换了张表。实现见 public/colResize.js。
 *
 * 唯一区别：本表 **不写 `is-measuring` 的折行规则**里的额外成分 ——
 * 到款明细默认就是 auto 布局（绝不主动锁宽），只有用户真拖过一次才转固定布局，
 * 所以量列宽那一刻不会有「初始状态被动过」的观感问题。
 */
#trTable.is-fixed-layout { table-layout: fixed; }
/* 同 #agTable：写成 sticky（既是定位上下文、又保住吸顶），别写成 relative */
#trTable thead th {
  position: sticky;
  top: 0;
  z-index: 1;
}
/* 同 #agTable：钉住表头靠这条 */
#trTable thead {
  position: sticky;
  top: 0;
  z-index: 1;
}

/*
 * 左右内边距各让 2px（原 8px），12 列一共省出约 48px。
 *
 * 加上「付款人信息」之后这张表有 10 个数据列，实测自然宽度 1036px
 * （最胖的是「操作」209px 和「客户名称」162px）。
 * 让出这 48px 后，**宽屏（≥1440）默认就放得下**；窄窗口仍可能要横拖一下 ——
 * 那正是上面这套列宽拖拽存在的意义，不用为了迁就窄屏去砍客户名称。
 * 只动本表：别的表列没这么密，内边距该留就留。
 */
#trTable th,
#trTable td { padding-left: 6px; padding-right: 6px; }

/*
 * 固定布局下让「截断型」单元格跟着列宽走。
 *
 * 默认 .cell-clip 写死 max-width:120px（auto 布局时防止备注/付款人把表撑宽）。
 * 但用户既然手动把这一列拖宽了，就是想看清内容 —— 还卡在 120px 上等于白拖。
 * 这里放开上限，交给 td 的 ellipsis 按真实列宽收尾。
 */
#trTable.is-fixed-layout .cell-clip { max-width: 100%; }
#trTable.is-fixed-layout td { overflow: hidden; text-overflow: ellipsis; }
#trTable.is-fixed-layout thead th { overflow: hidden; }
#trTable.is-measuring td,
#trTable.is-measuring thead th { white-space: normal; }

/*
 * 拖动手柄。平时完全透明（不干扰读表），鼠标移到列缝上才显出一条竖线。
 * right:-4px 让热区跨在两列之间 —— 贴着那条线更容易点中。
 * touch-action:none 是给触屏的：不写 pointermove 会被当成滚动吞掉。
 */
.col-resizer {
  position: absolute;
  top: 0;
  right: -4px;
  width: 9px;
  height: 100%;
  z-index: 3;
  cursor: col-resize;
  touch-action: none;
}

.col-resizer::after {
  content: '';
  position: absolute;
  top: 22%;
  bottom: 22%;
  left: 4px;
  width: 2px;
  border-radius: 1px;
  background: transparent;
}

.col-resizer:hover::after { background: var(--blue-500); }

/* 拖拽过程中：全页统一光标 + 禁止选中 —— 否则会一边拖一边把表格文字刷蓝 */
body.is-col-resizing,
body.is-col-resizing * {
  cursor: col-resize !important;
  user-select: none !important;
}

/* ------------------ 账龄历史数据：导入区 ------------------ */

/* 覆盖状态：缺哪个月直接决定账龄准不准，所以必须展开就能看见。
   但它有 12 行，摆在上头会把粘贴框和按钮挤出屏幕 —— 所以放在导入控件**下面**，
   只用一条上边线跟上面的操作区分开。 */
.ag-sales-status {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--ink-200);
}
.ag-sales-status:empty { display: none; border-top: 0; padding-top: 0; margin-top: 0; }

/* 这张状态表是辅助信息，字号再收一档，别把导入按钮挤下去 */
.ag-sales-status .data th,
.ag-sales-status .data td { padding: 4px 8px; font-size: 12px; }

/* 原生文件选择框在按钮排里又长又高，压到和按钮同一水平线 */
.file-input {
  width: auto;
  max-width: 250px;
  height: 26px;
  padding: 2px 6px;
  font-size: 11.5px;
  line-height: 1.1;
  color: var(--ink-600);
}

.file-input::file-selector-button {
  margin-right: 8px;
  padding: 2px 8px;
  font-family: inherit;
  font-size: 11.5px;
  color: var(--ink-700);
  background: #fff;
  border: 1px solid var(--ink-200);
  border-radius: 5px;
  cursor: pointer;
}

.file-input::file-selector-button:hover { border-color: var(--blue-500); color: var(--blue-700); }

/* 导入结果里的「已写入」「窗口齐了」这类正向提示 */
.import-preview .ip-sum .is-ok,
.ag-sales-status .ip-sum .is-ok { color: var(--ok); }

/* ================= 列表优先页（我的对账单 / 我的发票 共用） ================= */

/* 视图头右侧的动作区（临时查 / 整理 PDF 按钮） */
.view-head-actions { margin-left: auto; display: flex; gap: 8px; align-items: center; }

.lst { padding: 0; overflow: hidden; }

.lst-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-700);
  border-bottom: 1px solid var(--ink-100);
  background: var(--surface-2, #fafbfc);
}

.lst-count {
  font-size: 12px;
  font-weight: 400;
  color: var(--ink-500);
  font-variant-numeric: tabular-nums;
}

/* 行：按钮样式重置 + 左右两栏 */
.lst-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 16px;
  border: none;
  border-bottom: 1px solid var(--ink-100);
  background: transparent;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s ease;
}

.lst-row:last-child { border-bottom: none; }
.lst-row:hover { background: #EFF6FF; }

/* 当前展开的那一行 */
.lst-row.is-active {
  background: #EFF6FF;
  box-shadow: inset 3px 0 0 var(--blue-600);
}

/* 已下载（我的发票）：左侧绿色竖条，一眼区分 */
.iv-row.is-done { box-shadow: inset 3px 0 0 var(--ok); }
.iv-row.is-done.is-active { box-shadow: inset 3px 0 0 var(--blue-600); }

.lst-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }

.lst-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-800);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lst-meta {
  font-size: 12px;
  color: var(--ink-500);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/*
 * ============ 发票清单：元信息（日期 · 号码 · 操作留痕）摆到公司名称**后面同一行** ============
 * 用户 2026-10-14：「这个内容放到公司名称后面」。
 * 改完一行就是一条，行高从两行降到一行，一屏能多看几条。
 *
 * ⚠️ 必须限定 #ivList：.lst-main / .lst-name / .lst-meta 都是**共用类**，
 *    「客户对账单」的列表也在用（那边名称与元信息是上下两行，是它的正常排法），
 *    不限定就会顺手把另一页也改了。
 */
#ivList .lst-main {
  flex-direction: row;
  align-items: baseline; /* 14px 的名称与 12px 的元信息按文字基线对齐，不按盒底 */
  gap: 10px;
}

/* 名称优先：先保证公司名看得全，让后面那串（号码/留痕）先截断 */
#ivList .lst-name { flex: 0 0 auto; max-width: 52%; }
#ivList .lst-meta { flex: 1 1 auto; min-width: 0; }

.lst-right {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
}

.lst-amt {
  font-size: 15px;
  font-weight: 700;
  color: var(--blue-700);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* 状态小标签 */
.lst-tag {
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11.5px;
  color: var(--ink-500);
  background: var(--ink-100);
  white-space: nowrap;
}

.lst-tag.is-ok { color: var(--ok); background: rgba(16, 122, 87, 0.1); }
.lst-tag.is-err { color: var(--err); background: rgba(190, 40, 40, 0.1); }
.lst-tag.is-stale { color: #B45309; background: rgba(217, 119, 6, 0.12); }

/* 行内图标按钮（下载 / 复制） */
.iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--ink-200);
  border-radius: 8px;
  background: var(--surface);
  color: var(--ink-600);
  cursor: pointer;
  transition: all 0.15s ease;
}

.iconbtn:hover:not(:disabled) {
  color: var(--blue-700);
  border-color: var(--blue-600);
  background: #EFF6FF;
}

.iconbtn:disabled { opacity: 0.35; cursor: not-allowed; }

/* 手风琴展开区（发票 PDF 预览） */
.lst-row-wrap { border-bottom: 1px solid var(--ink-100); }
.lst-row-wrap:last-child { border-bottom: none; }
.lst-row-wrap .lst-row { border-bottom: none; }

.lst-expand {
  padding: 0 16px 14px 16px;
  background: #f8fafc;
  animation: fade-up 0.2s var(--ease-out) both;
}

.lst-expand[hidden] { display: none; }

.iv-frame {
  display: block;
  width: 100%;
  height: 70vh;
  border: 1px solid var(--ink-200);
  border-radius: 10px;
  background: #fff;
}

/* 分段筛选 tabs（全部 / 未下载 / 已下载） */
.seg-tabs {
  display: inline-flex;
  gap: 4px;
  padding: 3px;
  margin-bottom: 10px;
  border: 1px solid var(--ink-200);
  border-radius: 10px;
  background: var(--surface);
}

.seg-tab {
  padding: 5px 14px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  font: inherit;
  font-size: 12.5px;
  color: var(--ink-600);
  cursor: pointer;
  transition: all 0.15s ease;
}

.seg-tab:hover { color: var(--blue-700); }

.seg-tab.is-on {
  color: var(--blue-700);
  font-weight: 600;
  border-color: rgba(37, 99, 235, 0.35);
  background: #EFF6FF;
}

.seg-n {
  margin-left: 2px;
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-400);
}

.seg-tab.is-on .seg-n { color: var(--blue-700); }

/* 卡片头部一行内嵌工具（发票清单：筛选 tabs + 整理按钮 + 计数） */
.lst-head--tools { gap: 10px; flex-wrap: wrap; }

.lst-tools {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

/* 嵌在卡片头里的 tabs 要比独立排放时小一号，才不顶高整行 */
.seg-tabs--sm { margin-bottom: 0; padding: 2px; }
.seg-tabs--sm .seg-tab { padding: 3px 10px; font-size: 12px; }

/* ---------------- 我的对账单：行内展开 + 行内动作 ---------------- */

/* 展开中的那一行（高亮类挂在 wrap 上，与发票区一致） */
.lst-row-wrap.is-active .lst-row {
  background: #EFF6FF;
  box-shadow: inset 3px 0 0 var(--blue-600);
}

/*
 * ⚠️ 关掉滚动锚定：展开区一撑开，Chrome 会把滚动位置"钉"在原来的锚点上，
 * 把 JS 刚设好的滚动位置顶掉几百像素（实测行顶跑到 0，被 sticky 顶栏盖住）。
 * 列表这一块自己控制滚动，不需要浏览器帮忙锚定。
 */
#stList { overflow-anchor: none; }

/* 行内动作按钮多了，右侧允许换行，免得窄屏把金额挤没 */
.lst-right { flex-wrap: wrap; justify-content: flex-end; }

/* 「本月已对账」标记：绿色对勾 + 小字，一眼看出对过没有 */
.lst-conf {
  font-size: 11.5px;
  color: var(--ok);
  background: rgba(16, 122, 87, 0.1);
  border-radius: 999px;
  padding: 2px 8px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/*
 * 展开区里的预览卡：**去掉第二层卡片皮**（边框/阴影/圆角/外边距），
 * 内边距收紧 —— 否则读起来像"卡片里又塞了一张卡片"，很厚重。
 */
.lst-expand #stResultWrap > .card,
.lst-expand #stResultWrap > .warnbar { margin: 0 0 10px 0; }

.lst-expand #stResultWrap > .card {
  border: none;
  box-shadow: none;
  background: transparent;
}

.lst-expand #stResultWrap > .card > .card-head { padding-left: 0; padding-right: 0; }
.lst-expand #stResultWrap > .card > .card-body { padding: 0; }

/* 展开区里的 A4 预览略矮一点：它现在是"行的一部分"，不该占满一屏 */
.lst-expand .stmt-frame { height: 560px; }

/* 临时查的结果也挂在筛选条下面，同样去掉二级卡片皮 */
#stQuickResult { margin-top: 14px; }

/* ---------------- B5 对账单申诉（管理员接收） ---------------- */

.ap-item {
  padding: 12px 14px;
  margin-bottom: 10px;
  border: 1px solid var(--ink-200);
  border-radius: 10px;
  background: #fff;
  animation: fade-up 0.2s var(--ease-out) both;
}

/* 已处理的压暗一档：一眼看出还剩几条待办 */
.ap-item.is-done { opacity: 0.72; background: #fafbfc; }

.ap-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

.ap-head b { font-size: 14px; color: var(--ink-800); }

.ap-meta {
  font-size: 12px;
  color: var(--ink-500);
  font-variant-numeric: tabular-nums;
}

.ap-text {
  font-size: 13px;
  color: var(--ink-800);
  line-height: 1.7;
  margin: 4px 0 6px;
  white-space: pre-wrap;
  word-break: break-word;
}

.ap-snap {
  font-size: 12px;
  color: var(--ink-500);
  font-variant-numeric: tabular-nums;
  background: #f1f5f9;
  border-radius: 6px;
  padding: 5px 9px;
}

.ap-reply {
  font-size: 12.5px;
  color: var(--ok);
  margin-top: 6px;
}

.ap-act {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-top: 8px;
}

.ap-act .input { flex: 1 1 260px; min-width: 0; }

@media (max-width: 900px) {
  .lst-amt { font-size: 13.5px; }
  .lst-meta { white-space: normal; }
  .iv-frame { height: 55vh; }
}
