:root {
  --bg: #f4f6fb;
  --panel: #ffffff;
  --panel-2: #f8fafc;
  --ink: #16213b;
  --ink-2: #5a6785;
  --ink-3: #8b97b1;
  --line: #e3e8f2;
  --brand: #2f6bff;
  --brand-soft: #eaf0ff;
  --ok: #16a34a;
  --warn: #d97706;
  --danger: #dc2626;
  --purple: #7c3aed;
  --radius: 14px;
  --shadow: 0 6px 24px rgba(22, 33, 59, .07);
  --mono: Consolas, "Liberation Mono", Menlo, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0; height: 100%;
  background: var(--bg); color: var(--ink);
  font-family: "Microsoft YaHei UI", "PingFang SC", system-ui, sans-serif;
  font-size: 14px;
}

#app { display: flex; height: 100vh; overflow: hidden; }

.sidebar {
  width: 232px; flex: 0 0 232px; background: #101a35; color: #cdd6ea;
  display: flex; flex-direction: column; padding: 18px 12px; gap: 4px;
}
.brand { display: flex; align-items: center; gap: 10px; padding: 6px 8px 18px; }
.brand-logo {
  width: 34px; height: 34px; border-radius: 10px; flex: none;
  background: linear-gradient(135deg, #2f6bff, #7c3aed);
  display: grid; place-items: center; color: #fff; font-weight: 700; font-size: 15px;
}
.brand-text strong { display: block; color: #fff; font-size: 14px; }
.brand-text span { font-size: 11px; color: #7f8db0; }
.nav-item {
  padding: 9px 12px; border-radius: 10px; cursor: pointer; display: flex;
  align-items: center; gap: 9px; font-size: 13px; color: #c6d0e6; user-select: none;
}
.nav-item:hover { background: rgba(255,255,255,.06); color: #fff; }
.nav-item.active { background: var(--brand); color: #fff; font-weight: 600; }
.nav-item .dot { width: 6px; height: 6px; border-radius: 50%; background: #4a5878; }
.nav-item.active .dot { background: #fff; }
.sidebar-foot { margin-top: auto; font-size: 11px; color: #6d7a9c; padding: 10px 8px; line-height: 1.7; }

.main { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
.topbar {
  height: 58px; flex: none; background: var(--panel); border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 14px; padding: 0 20px;
  position: relative;              /* 通知浮层 #bell-pop 相对它定位 */
}

/* ---- 站内通知（2026-10-23）：小喇叭 + 未读角标 + 下拉列表 ---- */
.bell {
  position: relative; flex: none; width: 32px; height: 32px; border-radius: 9px;
  border: 1px solid var(--line); background: #fff; color: var(--ink-2);
  display: grid; place-items: center; cursor: pointer; padding: 0;
}
.bell:hover { background: var(--panel-2); color: var(--brand); border-color: #d5e1ff; }
.bell.has-unread { color: var(--brand); border-color: #d5e1ff; background: var(--brand-soft); }
.bell-badge {
  position: absolute; top: -6px; right: -6px; min-width: 17px; height: 17px;
  padding: 0 4px; border-radius: 999px; background: #dc2626; color: #fff;
  font-size: 10px; line-height: 17px; text-align: center; font-weight: 500;
  box-shadow: 0 0 0 2px #fff;
}
.bell-pop {
  position: absolute; right: 20px; top: 52px; width: 360px; max-height: 400px;
  overflow: auto; background: #fff; border: 1px solid var(--line);
  border-radius: 12px; box-shadow: 0 10px 28px rgba(22, 33, 59, .14);
  z-index: 40; padding: 6px;
}
.bell-head {
  display: flex; align-items: center; gap: 8px; padding: 8px 10px 6px;
  font-size: 12px; color: var(--ink-3);
}
.bell-head .spacer { flex: 1; }
.bell-item { padding: 9px 10px; border-radius: 8px; cursor: pointer; }
.bell-item:hover { background: var(--panel-2); }
.bell-item.unread { background: #f3f7ff; }
.bell-item .t { font-size: 13px; color: var(--ink); line-height: 1.5; }
.bell-item .m { font-size: 11px; color: var(--ink-3); margin-top: 3px; }
.bell-item .b { font-size: 12px; color: var(--ink-2); margin-top: 4px; line-height: 1.6; }
.bell-empty { padding: 22px 10px; text-align: center; font-size: 13px; color: var(--ink-3); }
.kind-tag {
  display: inline-block; padding: 0 6px; border-radius: 6px; font-size: 10px;
  line-height: 16px; margin-right: 6px; background: var(--brand-soft); color: var(--brand);
}
.kind-tag.biz { background: #fef3c7; color: #92400e; }

/* ---- 权限分配（2026-10-23）---- */
/* ⚠️ white-space:nowrap 必须有：片区名只有两三个字，单元格一窄就被拆成「龙/岗」两行 */
.usr-zone {
  display: inline-flex; align-items: center; gap: 3px; margin-right: 6px;
  font-size: 12px; color: var(--ink-2); white-space: nowrap; vertical-align: middle;
}
/* ⚠️ width/padding 必须显式复位（2026-10-23 截图实测 bug）：
 *    全局规则 `input, textarea, select { width:100%; padding:8px 11px }` 也命中了复选框，
 *    checkbox 撑满整个 label → 后面的片区名被挤没，界面上只剩「龙」「光」「大」一个字。
 *    修完是「龙岗」「光明」「大鹏」完整显示。 */
.usr-zone input {
  width: auto; height: auto; padding: 0; margin: 0; flex: none;
  accent-color: var(--brand); cursor: pointer;
}
/* 创建行控件统一高度：input/select 是 8px 上下 padding，.btn 是 7px，本来就差 2px，
 * 在一行里肉眼可见地「按钮矮一截」。这里统一按 border-box 定高。 */
#usr-name, #usr-role, #usr-account, #usr-password, #usr-add {
  height: 36px; box-sizing: border-box;
}
#usr-add { padding: 0 16px; flex: none; }
#usr-tip:empty { display: none; }
#usr-table td { padding: 6px 8px; vertical-align: middle; }
#usr-table select, #usr-table input[type="text"] { font-size: 12px; padding: 4px 6px; }
.role-tag { padding: 1px 7px; border-radius: 999px; font-size: 11px; background: var(--panel-2); color: var(--ink-2); border: 1px solid var(--line); }
.role-tag.hq { background: #ede9fe; color: #5b21b6; border-color: #ddd6fe; }
.role-tag.zone { background: #e0f2fe; color: #075985; border-color: #bae6fd; }
.topbar h1 { font-size: 16px; margin: 0; font-weight: 600; }
.topbar .sub { font-size: 12px; color: var(--ink-3); }
.pill {
  padding: 3px 10px; border-radius: 999px; font-size: 11px; background: var(--brand-soft);
  color: var(--brand); border: 1px solid #d5e1ff; white-space: nowrap;
}
.pill.ok { background: #e8f7ef; color: var(--ok); border-color: #c7ecd7; }
.pill.warn { background: #fef6e7; color: var(--warn); border-color: #f7e2bd; }
.pill.danger { background: #fdecec; color: var(--danger); border-color: #f7cccc; }
.spacer { flex: 1; }
.content { flex: 1; overflow-y: auto; padding: 20px 24px 40px; }
.view { display: none; }
.view.active { display: block; }

.card {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 16px 18px; margin-bottom: 16px;
}
.card h3 { margin: 0 0 12px; font-size: 14px; font-weight: 600; }
.card h3 .hint { font-weight: 400; font-size: 12px; color: var(--ink-3); margin-left: 8px; }
.grid { display: grid; gap: 16px; }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* 网格里的整行字段（备注等需加大加宽的输入）：跨满全部列 */
.grid > .field-wide { grid-column: 1 / -1; }

.kpi .label { font-size: 12px; color: var(--ink-3); }
.kpi .value { font-size: 24px; font-weight: 700; margin-top: 6px; }
.kpi .delta { font-size: 12px; margin-top: 4px; color: var(--ink-3); }

table { width: 100%; border-collapse: collapse; font-size: 13px; }
th, td { padding: 8px 10px; text-align: left; border-bottom: 1px solid var(--line); vertical-align: top; }
th { color: var(--ink-2); font-weight: 600; background: var(--panel-2); font-size: 12px; }
/* 滚动容器内表头固定：不随内容上下滑动（合同概况等） */
.scroll thead th { position: sticky; top: 0; z-index: 1; }
tbody tr:hover { background: #fafbff; }
.scroll { max-height: 420px; overflow: auto; }
/* 空表提示（2026-10-22）：没有数据时不再画整排表头，只显示这一格 —— 居中、留白、不贴边 */
tbody tr td.muted:only-child {
  padding: 26px 12px; text-align: center; color: var(--ink-3); font-size: 13px;
  border-bottom: 0; background: transparent;
}
tbody tr:hover td.muted:only-child { background: transparent; }

.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.btn {
  border: 1px solid var(--line); background: #fff; color: var(--ink); border-radius: 9px;
  padding: 7px 14px; font-size: 13px; cursor: pointer;
}
.btn:hover { border-color: var(--brand); color: var(--brand); }
.btn.primary { background: var(--brand); color: #fff; border-color: var(--brand); }
.btn.danger { color: var(--danger); border-color: #f3cfcf; }
/* 草稿库「删除」的待确认态：红底白字，比 .btn.danger 更醒目（须排在 .btn.danger 之后） */
.btn.danger-on { background: var(--danger); border-color: var(--danger); color: #fff; }
/* 表格「操作」栏里并排的多个按钮 */
.row-acts { display: inline-flex; gap: 6px; }
.btn.small { padding: 4px 10px; font-size: 12px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
input, textarea, select {
  border: 1px solid var(--line); border-radius: 9px; padding: 8px 11px; font-size: 13px;
  font-family: inherit; color: var(--ink); background: #fff; outline: none; width: 100%;
}
input:focus, textarea:focus, select:focus { border-color: var(--brand); }
label.f { display: block; font-size: 12px; color: var(--ink-2); margin: 0 0 5px; }
.field { margin-bottom: 12px; }
/* 我方公司：输入框 + 右侧 ▾ 按钮合成一个控件
   —— 在框里打字 = 手动输入（自动切「其他（手动输入）」+ 通用套）；
      点右侧按钮 = 从菜单里选档位（专属套）。两者同样通过「应用」写回服务端。 */
.combo { position: relative; display: flex; align-items: center; }
.combo > input { flex: 1 1 auto; min-width: 0; padding-right: 40px; }
.combo-btn {
  position: absolute; right: 1px; top: 1px; bottom: 1px; width: 34px;
  display: grid; place-items: center;
  border: 0; border-left: 1px solid var(--line); background: transparent;
  color: var(--ink-2); cursor: pointer; border-radius: 0 9px 9px 0;
}
.combo-btn:hover { background: var(--brand-soft); color: var(--brand); }
.combo-btn .caret { font-size: 11px; opacity: .85; transition: transform .15s; }
.combo-btn.active .caret { transform: rotate(180deg); }
/* 菜单向下弹出；菜单项复用既有的 .menu-item / .mi-sub / .selected
   宽度不锁死在输入框上：min-width 跟随输入框，内容更长时（公司全称）可以撑宽 */
.combo-menu {
  position: absolute; top: calc(100% + 4px); left: 0; z-index: 20;
  min-width: 100%; width: max-content; max-width: 440px;
  padding: 6px; max-height: 240px; overflow-y: auto;
  background: #fff; border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 12px 32px rgba(22,33,59,.16);
}
/* author 的 display 会盖过 UA 的 [hidden]{display:none}，必须显式补一条 */
.combo-menu[hidden] { display: none; }
/* 贴内容宽度的控件（13px 字号 + padding22 + border2 = 每多 1 个中文字多 13px）
   合同 338px = 上一版 273px 再加 5 个字；文书模板 206px = 上一版 180px 再加 2 个字 */
.w-contract { width: 338px; }
.w-tpl      { width: 206px; }
.w-cn20  { width: 284px; }
.w-cn7   { width: 120px; }
.w-num16 { width: 150px; }

/* 台账修改：每栏一个 combo。栅格列不给 overflow:hidden（否则菜单被裁到框里看不见），
   菜单往上浮在整块卡片之上（z-index 20 已够，比邻居卡片高即可）。 */
#ed-fields { overflow: visible; }
#ed-fields .field { position: relative; }
.ed-combo > input { cursor: text; }
.ed-combo .combo-menu { max-height: 260px; }
/* 键盘上下键选中的项：与鼠标 hover 同一观感 */
.ed-combo .menu-item.hover { background: var(--brand-soft); }
/* 改动标记：标签后的红点 */
.ed-dot { color: var(--brand); font-size: 12px; margin-left: 4px; }
.ed-dot[hidden] { display: none; }

/* 卡片全量渲染（2026-10-17 用户口径）：两卡都按导入表**全量表头**露栏。
   · 可编辑栏 = 能写回台账的标准列，沿用 .ed-combo（候选搜索 + ▾ 二级菜单）；
   · 只读栏  = 台账里没有对应列（项目类型 / 全部合同金额 / 回款率 / 所属片区 …），
               值取自导入表的唯一出处「催收队列快照」，只展示、不参与保存。 */
.readonly-badge {
  display: inline-block; margin-left: 6px; padding: 0 6px; border-radius: 6px;
  font-size: 11px; line-height: 16px; color: var(--ink-3);
  background: var(--panel-2); border: 1px solid var(--line);
}
.ro-box {
  display: flex; align-items: center; min-height: 36px;
  padding: 8px 11px; border: 1px dashed var(--line); border-radius: 9px;
  background: var(--panel-2); color: var(--ink-2); font-size: 13px;
  overflow-wrap: anywhere;
}
.ro-box.empty { color: var(--ink-3); }
/* 只读栏在栅格里独占一行（值通常较长，挤两列会溢行） */
.ro-wide { grid-column: 1 / -1; }
#ct-fields, #ed-fields { overflow: visible; }

/* 文书起草头部：合同/文书模板/生成草稿/(选择公司+联系人+电话+应用) 全在一行，
   靠 .row 自带的 flex-wrap 自动换行 —— 窗口够宽就是一行，
   不够宽时按整体宽度往下掉，绝不会出现横向滚动条或把控件压窄。 */
.app-row { align-items: flex-end; }
/* 不可切分的换行单元：里面的东西一起上、一起下，不会被拦腰拆到两行。
   目前只有一处 ——「选择公司 + 联系人 + 联系电话 + 应用」，它们整组随窗口宽度换行。 */
.wrap-unit { display: flex; gap: 10px; align-items: flex-end; }
textarea { min-height: 92px; resize: vertical; line-height: 1.6; }
.tag { display: inline-block; padding: 2px 8px; border-radius: 6px; font-size: 11px; margin: 0 6px 4px 0; }
.tag.L0 { background: #eef4ff; color: #3563d6; }
/* 告警等级标签：severity 3=红 / 2=黄 / 1=蓝（原 L1/L2 与口径错位，已修正） */
.tag.L3 { background: #feecec; color: #c02626; }
.tag.L2 { background: #fef9c3; color: #a16207; }
.tag.L1 { background: #eef4ff; color: #3563d6; }
/* .tag 自带 display:inline-block，会盖过 UA 的 [hidden]{display:none}，须显式补一条 */
.tag[hidden] { display: none; }
/* label 里挂的小标签（如「晨越专属」）：收紧内边距、去掉下外边距。
   否则它会把 label 从 15px 撑到 22px，同一行里下面的输入框/下拉就被顶得比隔壁低 3.5px。 */
label.f .tag { margin: 0 0 0 6px; padding: 1px 8px; vertical-align: 1px; }

/* 今日 Alert 条目：按等级淡色填充，条目之间留间距 */
.alert-item { border-radius: 10px; padding: 10px 12px; margin-bottom: 10px;
  border: 1px solid transparent; line-height: 1.6; font-size: 13px; }
.alert-item.sev3 { background: #fef2f2; border-color: #fecaca; }   /* 淡红填充 */
.alert-item.sev2 { background: #fefce8; border-color: #fde68a; }   /* 淡黄填充 */
.alert-item.sev1 { background: #eff6ff; border-color: #bfdbfe; }   /* 淡蓝填充 */
.alert-item .muted { margin-top: 4px; }
.mono { font-family: var(--mono); font-size: 12px; }
.muted { color: var(--ink-3); font-size: 12px; }

.chat-wrap { display: flex; gap: 16px; height: calc(100vh - 150px); }
.chat-main {
  flex: 1; display: flex; flex-direction: column; background: #fff; border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden;
}
.chat-log { flex: 1; overflow-y: auto; padding: 18px 20px; }
.chat-side { width: 320px; flex: 0 0 320px; overflow-y: auto; }
.msg { display: flex; gap: 10px; margin-bottom: 16px; align-items: flex-start; }
.msg .avatar {
  width: 30px; height: 30px; border-radius: 8px; flex: none; display: grid; place-items: center;
  font-size: 12px; color: #fff; background: var(--brand);
}
.msg.user .avatar { background: #64748b; }
.msg .bubble { max-width: 82%; }
/* 用户消息靠右显示（头像在右、气泡在左） */
.msg.user { flex-direction: row-reverse; }
.msg.user .bubble { display: flex; flex-direction: column; align-items: flex-end; }
.msg .who { display: none; }
.msg .body {
  background: var(--panel-2); border: 1px solid var(--line); padding: 11px 14px;
  border-radius: 4px 12px 12px 12px; line-height: 1.75; white-space: pre-wrap; word-break: break-word;
}
.msg.user .body { background: var(--brand-soft); border-color: #dbe6ff; border-radius: 12px 4px 12px 12px; }
/* 长回复折叠（2026-10-22）：助手回复过长时默认只露前 4 行，点「展开全文」看全部。
   遮罩用与气泡同色的渐变，避免文字被硬切、看起来像渲染坏了。 */
.msg .body.is-clamped { max-height: 120px; overflow: hidden; position: relative; }
.msg .body.is-clamped::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 42px;
  background: linear-gradient(rgba(248, 250, 252, 0), var(--panel-2));
  pointer-events: none;
}
.expand-btn {
  margin-top: 6px; padding: 3px 10px; font-size: 12px; line-height: 1.6;
  border: 1px solid var(--line); border-radius: 6px; background: #fff;
  color: var(--brand); cursor: pointer;
}
.expand-btn:hover { background: var(--brand-soft); }
/* 气泡下面的一行小字（现只用于「已降级：…备用通道」这类一次性说明；
   原「已脱敏 / 含敏感数据」徽标的 ok / danger 两态已随脱敏功能删除，2026-10-16） */
.msg-badge {
  margin-top: 6px; display: inline-block; font-size: 11px; line-height: 1.5;
  padding: 2px 8px; border-radius: 999px; border: 1px solid var(--line); color: var(--ink-2);
}
.msg-badge.muted  { color: var(--ink-3); }
.steps { margin-top: 10px; border-top: 1px dashed var(--line); padding-top: 8px; }
.step-row { font-size: 12px; color: var(--ink-2); padding: 3px 0; display: flex; gap: 8px; }
.step-row .ok { color: var(--ok); }
.step-row .err { color: var(--danger); }
.cite { font-size: 12px; color: var(--purple); margin-top: 8px; }
.pending {
  margin-top: 10px; border: 1px solid #f0cfcf; background: #fdf5f5; border-radius: 10px;
  padding: 10px 12px; font-size: 12px; color: #8a2a2a;
}
.thinking { display: inline-flex; align-items: center; gap: 6px; color: var(--ink-3); font-size: 12px; }
.thinking i { width: 5px; height: 5px; border-radius: 50%; background: var(--ink-3); animation: b 1s infinite; }
.thinking i:nth-child(2) { animation-delay: .2s; }
.thinking i:nth-child(3) { animation-delay: .4s; }
@keyframes b { 0%,60%,100% { opacity: .25 } 30% { opacity: 1 } }
.composer { border-top: 1px solid var(--line); padding: 12px 14px; background: #fcfdff; }
.composer textarea { min-height: 62px; }
.examples { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.examples .btn { font-size: 12px; padding: 4px 9px; border-radius: 999px; }

/* 输入框容器：输入区 + 底部工具栏（选项按钮 + 发送按钮） */
.composer-box {
  position: relative;
  border: 1px solid var(--line); border-radius: 12px; background: #fff;
  padding: 10px 12px 8px; transition: border-color .15s;
}
.composer-box:focus-within { border-color: var(--brand); }
.composer-box textarea {
  width: 100%; border: none; outline: none; resize: vertical; min-height: 124px;
  padding: 0; line-height: 1.7; font-size: 13px; background: transparent; box-shadow: none;
}
.composer-box textarea:focus { border-color: transparent; }
/* 底部工具栏：左选项按钮组，右发送按钮 */
.composer-bar { display: flex; align-items: flex-end; justify-content: space-between; gap: 10px; margin-top: 8px; }
.composer-tools { display: flex; align-items: flex-end; gap: 8px; flex-wrap: wrap; flex: 1; min-width: 0; }
/* 每个选项按钮 + 向上弹出的二级菜单 */
.tool { position: relative; }
.tool-btn {
  border: 1px solid var(--line); background: var(--panel-2); color: var(--ink-2);
  border-radius: 999px; padding: 5px 12px; font-size: 12px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
}
.tool-btn:hover { border-color: var(--brand); color: var(--brand); }
.tool-btn.active { background: var(--brand-soft); border-color: var(--brand); color: var(--brand); }
.tool-btn .caret { font-size: 9px; opacity: .7; transition: transform .15s; }
.tool-btn.active .caret { transform: rotate(180deg); }
/* 二级菜单：向上弹出，含完整名称与选中态 */
.tool-menu {
  position: absolute; bottom: calc(100% + 8px); left: 0; min-width: 260px; max-height: 320px;
  overflow-y: auto; background: #fff; border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 12px 32px rgba(22,33,59,.16); padding: 6px; z-index: 40; display: none;
}
.tool-menu.open { display: block; animation: menuIn .15s ease; }
@keyframes menuIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.tool-menu .menu-title { font-size: 11px; color: var(--ink-3); padding: 6px 10px 4px; font-weight: 600; }
.menu-item {
  display: block; width: 100%; text-align: left; padding: 8px 10px; border: none; background: none;
  border-radius: 8px; font-size: 13px; color: var(--ink); cursor: pointer; line-height: 1.45;
}
.menu-item:hover { background: var(--brand-soft); }
.menu-item.selected { background: var(--brand-soft); color: var(--brand); font-weight: 600; }
.menu-item .mi-sub { display: block; font-size: 11px; color: var(--ink-3); font-weight: 400; }
.tool-note { margin-left: 2px; }
#chat-send { flex: none; align-self: flex-end; padding: 8px 22px; border-radius: 9px; }

/* 输入区右侧：使用须知 + 发送（原「输入框脱敏开关」的 .sw-btn 样式已随脱敏功能删除，2026-10-16） */
.composer-right { display: flex; align-items: center; gap: 8px; flex: none; }

/* 「使用须知」按钮 + 二级弹出（相对输入框右下角向上展开） */
.comp-help { position: relative; }
/* 边框加深加粗：与发送按钮并排时更醒目 */
#comp-help-btn {
  background: #fff; color: var(--ink); white-space: nowrap;
  border: 2px solid var(--ink); padding: 6px 13px; font-weight: 600;
}
#comp-help-btn:hover { background: var(--brand-soft); border-color: var(--brand); color: var(--brand); }
#comp-help-btn.active { background: var(--brand-soft); border-color: var(--brand); color: var(--brand); }
.comp-help-pop {
  position: absolute; bottom: calc(100% + 10px); right: 0; width: 420px; max-width: 86vw;
  max-height: 340px; overflow-y: auto; background: #fff; border: 1px solid var(--line);
  border-radius: 12px; box-shadow: 0 12px 32px rgba(22, 33, 59, .18); padding: 12px 14px;
  z-index: 45; display: none; text-align: left;
}
.comp-help-pop.open { display: block; animation: menuIn .15s ease; }
.chp-title { font-size: 12px; font-weight: 700; color: var(--ink); margin-bottom: 6px; }
.chp-list { margin: 0; padding-left: 18px; }
.chp-list li { font-size: 12px; line-height: 1.7; color: var(--ink-2); margin-bottom: 6px; }
.chp-list li b { color: var(--ink); }
.chp-list code {
  font-family: var(--mono); font-size: 11px; background: var(--panel-2);
  border: 1px solid var(--line); border-radius: 4px; padding: 0 4px; color: var(--ink);
}
.chp-em { color: var(--brand); font-weight: 600; }

/* 使用须知按钮（运行态势卡片右下角） */
#help-btn { background: #fff; color: var(--ink-2); white-space: nowrap; }
#patrol-tip { flex: 0 1 auto; min-width: 0; }

/* 使用须知弹窗：固定宽度，内容超出时上下滚动 */
.help-mask {
  position: fixed; inset: 0; background: rgba(16, 26, 53, .42); z-index: 200;
  display: none; align-items: center; justify-content: center; padding: 24px;
}
.help-mask.open { display: flex; animation: fadeIn .18s ease; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.help-modal {
  width: 420px; max-width: 100%; background: #fff; border-radius: 16px;
  box-shadow: 0 24px 64px rgba(16, 26, 53, .28); display: flex; flex-direction: column;
  overflow: hidden; animation: popIn .18s ease;
}
@keyframes popIn { from { opacity: 0; transform: translateY(10px) scale(.98); } to { opacity: 1; transform: none; } }
.help-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px; border-bottom: 1px solid var(--line); flex: none;
}
.help-head h3 { margin: 0; font-size: 15px; font-weight: 600; }
.help-close {
  border: none; background: none; font-size: 22px; line-height: 1; color: var(--ink-3);
  cursor: pointer; padding: 0 4px;
}
.help-close:hover { color: var(--ink); }
.help-body {
  padding: 18px 22px 22px; overflow-y: auto; max-height: 60vh; line-height: 1.9;
  font-size: 13px; color: var(--ink);
}
.help-body ol { margin: 0; padding-left: 20px; }
.help-body li { margin-bottom: 10px; }
.drop {
  border: 1px dashed #c9d4ec; border-radius: 10px; padding: 18px; text-align: center;
  color: var(--ink-3); cursor: pointer; background: #fbfcff;
}
.drop.over { border-color: var(--brand); background: var(--brand-soft); color: var(--brand); }
.drop .dz-title { font-size: 13px; font-weight: 600; color: var(--ink-2); }
.drop .dz-sub { margin-top: 6px; font-size: 12px; line-height: 1.6; }
.drop.over .dz-title { color: var(--brand); }
#toast { position: fixed; right: 22px; bottom: 22px; display: flex; flex-direction: column; gap: 8px; z-index: 99; }
.toast {
  background: #16213b; color: #fff; padding: 10px 16px; border-radius: 10px; font-size: 13px;
  box-shadow: 0 8px 24px rgba(0,0,0,.18); opacity: 0; transform: translateY(8px);
  animation: tin .25s forwards;
}
.toast.ok { background: #16a34a; }
.toast.err { background: #dc2626; }
@keyframes tin { to { opacity: 1; transform: none; } }
.bar { height: 8px; border-radius: 6px; background: #eef1f8; overflow: hidden; }
.bar > i { display: block; height: 100%; background: linear-gradient(90deg, #2f6bff, #7c3aed); }

.chart { width:100%; height:300px; }
/* 时效图要放下 15 条（2026-10-16）：给它更高的画布；同一排的漏斗图跟着一样高，看起来才齐 */
#ch-statute, #ch-funnel { height: 420px; }
/* 驾驶舱顶部（2026-10-16 用户要求）：左边 4 个 KPI 排成 2×2，右边空出同样大小的位置放「数据筛选」。
   右侧可视区正好是 2 列 × 2 行筛选框，超出的往上滚（高度按 KPI 区实测对齐，两个板块看起来齐平）。 */
.dash-top { display:grid; grid-template-columns:1fr 1fr; gap:14px; align-items:start; }
.dash-filters {
  display:grid; grid-template-columns:1fr 1fr; gap:8px 10px;
  max-height:126px; overflow-y:auto; padding-right:2px;
}
.dash-filters .df-item label { display:block; font-size:12px; color:var(--ink-3); margin-bottom:3px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* 筛选框：一个按钮，点开是复选+搜索面板（Excel 自动筛选同款交互） */
.dash-filters .df-btn {
  width:100%; text-align:left; padding:5px 8px; font-size:12px; line-height:1.5;
  border:1px solid var(--line); background:#fff; border-radius:8px; color:var(--ink-2); cursor:pointer;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.dash-filters .df-btn:hover { border-color:var(--brand); color:var(--brand); }
.dash-filters .df-btn.on { border-color:var(--brand); background:var(--brand-soft);
  color:var(--brand); font-weight:600; }
.dash-filters select { width:100%; }
@media (max-width: 1100px) { .dash-top { grid-template-columns:1fr; } .dash-filters { max-height:none; } }
/* 驾驶舱每张图下面那句「为什么长这样」的说明（2026-10-16 补：漏斗右半边为 0、账龄天数不详等原因） */
.dash-note { margin-top: 6px; font-size: 12px; line-height: 1.75; }
.dash-note b { color: var(--ink-2); }
.msg .body h1,.msg .body h2,.msg .body h3 { font-size:14px; margin:8px 0 4px; }
/* ---- 草稿框：按钮固定在本容器右上角（悬浮，不另起一行）---- */
.draft-wrap {
  position: relative; border: 1px solid var(--line); border-radius: 10px;
  background: #fbfcff;
}
.draft-wrap.editing { border-color: var(--brand); box-shadow: 0 0 0 2px #e8efff inset; }

/* 工具条：绝对定位钉在框内右上角，不是文档流里的一行；
   正文与编辑区顶部留出同样高度的避让空间，滚动时也不会压住字。 */
.draft-tools {
  position: absolute; top: 8px; right: 10px; z-index: 3;
  display: flex; align-items: center; gap: 6px;
  padding: 3px 4px; border-radius: 9px;
  background: rgba(251,252,255,.92);
}
.draft-save-tip { max-width: 320px; text-align: right; font-size: 12px; color: var(--ink-3); }

/* 滚动容器：整封函件（含附件行与署名块）尽量一屏看完，超出才滚动 */
.draft-scroll { max-height: 640px; overflow: auto; }

/* ---- 说明面板：从按钮下方展开，不再占据正文上方一整块 ---- */
.note-pop {
  position: absolute; top: 44px; right: 10px; z-index: 4;
  width: min(440px, calc(100% - 20px));
  padding: 10px 13px;
  border: 1px solid #dbe4f5; border-radius: 10px; background: #fff;
  box-shadow: 0 14px 34px rgba(16,24,40,.16);
}
.note-pop[hidden] { display: none; }
.note-h { font-size: 12px; font-weight: 600; color: var(--brand); margin-bottom: 6px; }
.note-list { margin: 0; padding: 0; list-style: none; }
.note-list li { font-size: 12px; line-height: 1.7; color: var(--ink-2); }
.note-list li + li { margin-top: 3px; }
.note-list b { color: var(--ink); font-weight: 600; }

/* ---- 草稿正文：按手册附录 A 的函件版式排版 ----
 * 下面的数值来自对用户参考图逐行做像素测量（左边界/行距），不是估的：
 *   正文左边距 x≈117；首行缩进 x≈152（+35px＝两字）；「附件」行 x≈153（同样是左空两字）；
 *   行距恒定 34px（＝正文行高），段与段之间**没有**额外间距；「致」后与「附件」前各空一行。
 * 字体：正文宋体、标题黑体；标题字高约为正文的 1.88 倍，且不额外拉宽字距。 */
.draft-body {
  padding: 44px 22px 22px; font-size: 14px; line-height: 2; color: var(--ink);
  font-family: "SimSun", "宋体", "Songti SC", "Noto Serif CJK SC", serif;
}
.dl-title {
  text-align: center; font-size: 1.85em; line-height: 1.7; font-weight: 700;
  letter-spacing: normal; text-indent: 0; margin: 0 0 .3em;
  font-family: "SimHei", "黑体", "Microsoft YaHei", "PingFang SC", sans-serif;
}
.dl-to { margin: 0 0 2em; }                       /* 「致：」顶格，后接一行空距 */
.dl-flat { margin: 0; color: var(--ink-3); }       /* [如有代建/项目管理单位，并列] 顶格、同字号，但浅灰：
                                                      它是填写条件提示，不是函件正文，靠颜色与正式内容区分开 */
.dl-p { text-indent: 2em; margin: 0; text-align: justify; }   /* 段间无间距，靠缩进分段 */
.dl-h { font-weight: 600; margin: 2em 0 .5em; }
.dl-li { padding-left: 1.7em; text-indent: -1.7em; margin: 0 0 3px; }
.dl-row { display: flex; gap: 12px; margin: 0 0 4px; }
.dl-row > span { flex: 1 1 0; min-width: 0; overflow-wrap: anywhere; }
.dl-row > span:first-child { flex: 0 0 34%; color: var(--ink-2); }
.dl-att { text-indent: 2em; margin: 2em 0 0; }    /* 「附件：」左空两字，前接一行空距 */
.dl-sign { text-align: right; margin: 0; }
.dl-blank { color: var(--brand); border-bottom: 1px solid var(--brand); }
.dl-cid { color: var(--ink-3); }   /* 正文里的「（合同编号：CY-0002）」浅灰：内部标识，与函件正文区分 */
.draft-body.muted {
  padding-top: 20px; color: var(--ink-3); font-family: inherit; line-height: 1.8;
}

/* 编辑区：固定高度、内部滚动。绝不按内容改高度 —— 高度一旦塌陷成 auto，
   浏览器会把光标行滚到框底，就成了"输入一个字这行就跳到最后"。 */
.draft-editor {
  display: block; width: 100%; height: 596px; box-sizing: border-box;
  border: none; border-radius: 0; padding: 44px 22px 22px;
  white-space: pre-wrap; line-height: 2; font-size: 14px;
  font-family: "SimSun", "宋体", "Songti SC", "Noto Serif CJK SC", serif;
  color: var(--ink); background: #fff; outline: none;
  overflow-y: auto; resize: vertical;
}
.gate-ok { color:var(--ok); font-weight:600; }
.gate-bad { color:var(--danger); font-weight:600; }
.amt-unpaid { color:var(--danger); font-weight:600; }   /* 未付金额标红 */
/* 未收款状态徽标（2026-10-26 用户口径）：已逾期=红 / 有欠款=黄 / 无欠款=绿。
   三档互斥，由 app.js 的 `unpaidBadge()` 唯一生成，任何表格都别自己拼这套颜色。 */
.unpaid-badge { display:inline-block; padding:0 6px; border-radius:5px; font-size:11px;
  line-height:18px; margin-left:6px; border:1px solid transparent; white-space:nowrap;
  vertical-align:middle; font-weight:600; }
.unpaid-badge.overdue { background:#fee2e2; color:#b91c1c; border-color:#fecaca; }
.unpaid-badge.owing   { background:#fef3c7; color:#92400e; border-color:#fde68a; }
.unpaid-badge.paid    { background:#dcfce7; color:#15803d; border-color:#bbf7d0; }
/* 项目现实进度色标（与 scripts/ledger.py 的 classify_progress 对应）：
   在建/进行中=绿 · 待验收=黄 · 已完工/已完工待决算=红 · 已竣工=红(应付) · 已结清=灰 */
.prog-tag { display:inline-block; padding:1px 8px; border-radius:6px; font-size:11px;
  white-space:nowrap; border:1px solid transparent; }
.prog-tag.prog-green  { background:#e8f7ef; color:var(--ok);     border-color:#c7ecd7; }
.prog-tag.prog-yellow { background:#fef6e7; color:var(--warn);   border-color:#f7e2bd; }
.prog-tag.prog-red    { background:#fdecec; color:var(--danger); border-color:#f7cccc; }
.prog-tag.prog-grey   { background:#eef1f6; color:var(--ink-3);  border-color:#dfe4ee; }
.prog-tag.prog-none   { background:#f5f7fb; color:var(--ink-3);  border-color:#e6eaf3; }

/* 手动登记标记：主档序号后的「手」小徽标（source=manual）。 */
.src-badge {
  display:inline-block; margin-left:5px; padding:0 5px; border-radius:5px;
  font-size:10px; line-height:15px; vertical-align:1px;
  background:#eef4ff; color:#3563d6; border:1px solid #d6e2fb; cursor:help;
}
/* 台账主档 / 重名池宽表：长项目名允许折行，避免撑破横向滚动条。
 * 2026-10-17 删「序号」列后列序前移：项目 → 第 2 列、业主 → 第 4 列。 */
#lg-contracts td, #lg-contracts th, #rm-contracts td, #rm-contracts th { vertical-align: middle; }
#lg-contracts td:nth-child(2), #rm-contracts td:nth-child(2) { min-width: 220px; }
#lg-contracts td:nth-child(4), #rm-contracts td:nth-child(4) { min-width: 150px; }

/* 2026-10-21 用户口径：台账池行高异常 —— 导入的动态长文本列（项目概况/合同/备注等，
 * 数百字全文进单元格）把行撑到 400px+，垂直居中后每格上下全是空白。
 * 台账池数据单元格限宽 + 单行省略（… 截断），行高回归正常；主表池等其余表不受影响。 */
#lg-contracts tbody td { max-width: 240px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

.kb-hit { border:1px solid var(--line); border-radius:8px; padding:8px 10px; margin-bottom:8px; background:#fbfcff; font-size:12px; }
.kb-hit b { font-size:12px; }

/* 知识库检索结果：片段小框依次向下排列（2026-10-19 第三十三轮：结果由独立卡改为直接落对话区，
   片段框本身沿用这套样式；「已查到 N 个片段」改为气泡顶部一行的 .kb-hit-head）。 */
.kb-card {
  border: 1px solid var(--line); border-radius: 10px; padding: 9px 11px; margin-bottom: 8px;
  background: #fbfcff; cursor: pointer; transition: border-color .15s, box-shadow .15s;
}
.kb-card:hover { border-color: var(--brand); box-shadow: 0 2px 10px rgba(47,107,255,.10); }
.kb-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.kb-card-head b { font-size: 12.5px; color: var(--ink); }
.kb-hit-head { font-size: 12px; color: var(--ink-2); margin-bottom: 8px; }
.kb-hit-head b { color: var(--brand); }
.kb-card-sub { font-size: 11px; color: var(--ink-3); margin-top: 2px; }
.kb-card-snippet {
  font-size: 12px; color: var(--ink-2); margin-top: 5px; line-height: 1.6;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* 片段原文详情弹窗 */
.kb-detail-modal { width: 560px; }
.kb-detail-modal .help-head h3 { font-size: 14px; }
.kb-detail-modal .help-body { white-space: pre-wrap; font-size: 13px; line-height: 1.85; }

/* 「类型」按钮（2026-10-19 第三十三轮用户口径）：与三个工具按钮同一套 .tool 机制，
   位置移到「模型通道」按钮**右边**（在 .composer-tools 工具行内，默认 left:0 向上弹出即可）。 */

/* 「合同概况」合同号：可点，点了载入对话上下文（卡片副标题承诺的行为） */
.cid-link { color: var(--brand); cursor: pointer; }
.cid-link:hover { text-decoration: underline; }

/* ================= 催收队列：表头逐列筛选（与源表 Excel 自动筛选同口径） =================
   表头每列一个 ▾ 按钮 → 点击弹出固定定位浮层（取值列表 / 文本 / 数字 / 日期）；
   已生效的列在表头高亮，条件同时在卡片顶部以 chip 列出，可逐条 × 掉或用「清除全部筛选」。 */
.cq-chips { margin-top: 8px; gap: 6px; }
.cq-chip {
  display: inline-flex; align-items: center; gap: 2px; max-width: 460px;
  padding: 3px 4px 3px 9px; border: 1px solid #cddcff; background: var(--brand-soft);
  color: var(--brand); border-radius: 999px; font-size: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cq-chip-x {
  border: 0; background: transparent; color: var(--brand); cursor: pointer;
  font-size: 13px; line-height: 1; padding: 0 4px; border-radius: 50%;
}
.cq-chip-x:hover { background: #d8e4ff; }

/* 表头 ▾ 与筛选面板：催收队列 / 合同主档 / 动作日志 三张表共用（2026-10-15 起不再只限 #cq-table） */
th.cq-th { white-space: nowrap; }
th.cq-th.on { background: #eef3ff; }
.cq-hwrap { display: inline-flex; align-items: center; gap: 3px; }
.cq-fbtn {
  border: 1px solid transparent; background: transparent; color: var(--ink-3);
  width: 18px; height: 18px; padding: 0; border-radius: 5px; cursor: pointer;
  font-size: 10px; line-height: 1; flex: none;
}
.cq-fbtn:hover { background: #fff; border-color: var(--brand); color: var(--brand); }
.cq-fbtn.on { background: var(--brand); border-color: var(--brand); color: #fff; }

/* 浮层本体：固定定位，位置由 app.js 按表头 ▾ 的矩形算 */
.cq-pop {
  position: fixed; z-index: 60; width: 300px; font-size: 13px;
  background: #fff; border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 16px 40px rgba(22, 33, 59, .18);
  /* 2026-10-27：面板不许超出视口（用户要求「完整显示」），内容区自己滚动 */
  max-height: calc(100vh - 16px);
  display: flex; flex-direction: column;
}
.cq-pop[hidden] { display: none; }
.cq-pop-body { overflow: auto; max-height: 60vh; min-height: 0; }
.cq-pop[hidden] { display: none; }        /* author 样例会盖过 UA 的 [hidden]，必须显式补 */
.cq-pop-head { display: flex; align-items: center; gap: 8px; padding: 9px 10px; border-bottom: 1px solid var(--line); }
.cq-pop-title { flex: 1; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cq-pop-x { border: 0; background: transparent; color: var(--ink-3); font-size: 16px; line-height: 1; cursor: pointer; padding: 0 2px; }
.cq-pop-x:hover { color: var(--danger); }
.cq-pop-body { padding: 10px; display: flex; flex-direction: column; gap: 8px; }
.cq-pop-foot { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-top: 1px solid var(--line); }
.cq-pop-foot .muted { flex: 1; min-width: 0; }
.cq-dim { color: var(--ink-3); font-size: 12px; }

/* ---- 动作日志「备注」列：单元格只放按钮，正文进二级菜单（2026-10-19 第二十八轮） ---- */
.al-note-btn {
  border: 1px solid var(--line); background: var(--panel-2); color: var(--ink-2);
  border-radius: 999px; padding: 2px 12px; font-size: 12px; cursor: pointer;
  line-height: 1.5; white-space: nowrap;
}
.al-note-btn:hover { border-color: var(--brand); color: var(--brand); }
/* 有备注 → 按钮变**实心蓝**（2026-10-19 第三十四轮用户口径：「有备注，备注按钮蓝色」「备注有内容都蓝色」）。
 * ⚠️ 原来只是浅蓝底（--brand-soft）+ 蓝字，颜色太淡、与页面浅色底几乎分不出；
 *    改为品牌色实心填充 + 白字，一眼可辨「哪条有备注」。
 * ⚠️ 必须同时写 :hover 版本：否则悬停时命中上面的 .al-note-btn:hover（蓝字），
 *    会变成「蓝底 + 蓝字」而看不清。 */
.al-note-btn.has { background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 600; }
.al-note-btn.has:hover { background: #2458d6; border-color: #2458d6; color: #fff; }
.al-note-btn.on { outline: 2px solid var(--brand); outline-offset: 1px; }

/* ---- 动作日志「删除模式」（2026-10-19 第三十五轮用户口径） ----
 * 「删除」按钮放在工具条最右＝表格「备注」列正上方那块空白处。
 * 进入后每行「备注」格多一个红色删除按钮；点表格以外空白处退出、恢复原样。 */
.alc-del-toggle { margin-left: auto; }
.alc-del-toggle[data-on="1"] {           /* 已在删除模式：按钮自身变红，一眼看得出当前状态 */
  background: var(--danger); border-color: var(--danger); color: #fff; font-weight: 600;
}
.al-del-btn {
  margin-left: 6px;
  border: 1px solid #f3cfcf; background: #fff; color: var(--danger);
  border-radius: 999px; padding: 2px 10px; font-size: 12px; cursor: pointer;
  line-height: 1.5; white-space: nowrap;
}
.al-del-btn:hover { background: #fdecec; border-color: var(--danger); }
/* 第一下点击后的「待确认」态：红底白字（4 秒内再点才真删） */
.al-del-btn.armed { background: var(--danger); border-color: var(--danger); color: #fff; font-weight: 600; }
/* 备注格里有「备注」+「删除」两个按钮，禁止折行 */
#lg-actions td:last-child { white-space: nowrap; }

/* ---- 备注浮层的多附件列表（2026-10-19 第三十五轮：一个动作可挂多个 PDF） ---- */
.al-note-atts { padding: 0 10px 8px; text-align: left; }
.al-atts-hd { font-size: 12px; color: var(--ink-3); margin-bottom: 4px; }
.al-att-row { display: flex; align-items: center; gap: 6px; padding: 2px 0; font-size: 12px; }
.al-att-row a {
  color: var(--brand); text-decoration: underline; flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.al-att-del {
  flex: none; border: 1px solid #f3cfcf; background: #fff; color: var(--danger);
  border-radius: 6px; min-width: 20px; height: 20px; padding: 0 5px;
  line-height: 1; cursor: pointer; font-size: 12px;
}
.al-att-del:hover { background: #fdecec; border-color: var(--danger); }
.al-att-del.danger-on { background: var(--danger); border-color: var(--danger); color: #fff; }
/* 备注菜单：比筛选面板稍宽，正文可换行、可滚动 */
.al-note-pop { width: 360px; }
.al-note-body {
  padding: 10px; font-size: 13px; line-height: 1.7; color: var(--ink);
  max-height: 260px; overflow: auto; word-break: break-word; white-space: normal;
  text-align: left;
}
.al-note-att { padding: 0 10px 10px; font-size: 12px; color: var(--ink-2); text-align: left; }
.al-note-att a { color: var(--brand); text-decoration: underline; }

/* ---- 台账池单元格「备注」按钮（2026-10-21 用户口径）----
 * 长文本列（项目概况/合同/备注等）的正文收进按钮，点开浮层看全文：
 * 空白 → 灰色（disabled）；有内容 → 实心蓝（沿用 .al-note-btn.has）。 */
.lg-note-btn[disabled] { opacity: .5; cursor: default; }
.lg-note-btn[disabled]:hover { border-color: var(--line); color: var(--ink-2); }
.lg-note-pop { width: 420px; }
.lg-note-body {
  padding: 10px; font-size: 13px; line-height: 1.7; color: var(--ink);
  max-height: 300px; overflow: auto; word-break: break-word; white-space: normal;
  text-align: left;
}
/* 备注浮层底部动作行：上传/替换 PDF、删除附件（2026-10-19 第三十轮） */
.al-note-acts {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 0 10px 10px; text-align: left;
}
.al-note-acts .muted { font-size: 12px; }

/* 「追加动作」右侧的上传 PDF（2026-10-19 第三十轮：按钮从备注框移到此处，随 .row 排布） */
#ac-pdf-name { font-size: 12px; }

.cq-search, .cq-op, .cq-kw, .cq-range input { padding: 6px 9px; font-size: 12px; }
.cq-list { max-height: 232px; overflow: auto; border: 1px solid var(--line); border-radius: 9px; }
.cq-item { display: flex; align-items: center; gap: 7px; padding: 4px 9px; cursor: pointer; }
.cq-item:hover { background: var(--brand-soft); }
.cq-item + .cq-item { border-top: 1px solid #f2f5fb; }
.cq-item[hidden] { display: none; }        /* 搜索命中的行才显示（同样是覆盖 display:flex） */
.cq-item input { width: auto; flex: none; margin: 0; padding: 0; }
.cq-item-top { background: var(--panel-2); position: sticky; top: 0; z-index: 1; }
.cq-t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cq-n { flex: none; color: var(--ink-3); font-size: 11px; }
.cq-range { display: flex; align-items: center; gap: 6px; }
.cq-range input { min-width: 0; }
.cq-range .cq-to { flex: none; }
.cq-to[hidden], .cq-range input[hidden] { display: none; }


/* ================= 新增应收节点卡（2026-10-21 重构） =================
 * 第一行：选择池 / 合同编号 / 实际合同额；下面一圈节点类型圆按钮。 */
.rv-top { grid-template-columns: 180px minmax(240px, 1.4fr) minmax(180px, 1fr); }
.rv-circles { display: flex; flex-wrap: wrap; gap: 14px; margin: 14px 0 6px; }
.rv-circle {
  position: relative; width: 92px; height: 92px; border-radius: 50%;
  border: 2px dashed var(--line); background: var(--panel-2); color: var(--ink-2);
  font-size: 14px; font-weight: 600; cursor: pointer; line-height: 1.2;
  display: inline-flex; align-items: center; justify-content: center; flex-direction: column;
  gap: 2px; transition: all .15s ease;
}
.rv-circle:hover { border-color: var(--brand); color: var(--brand); }
/* 已加过该类型节点 → 实心蓝（与「有备注」同一个颜色语义） */
.rv-circle.on { background: var(--brand); border-color: var(--brand); border-style: solid; color: #fff; }
.rv-circle.on:hover { background: #2458d6; border-color: #2458d6; }
/* 进度款圆按钮右下角的加号：点它加一笔新的进度款 */
.rv-plus {
  position: absolute; right: -2px; bottom: 2px; width: 24px; height: 24px; border-radius: 50%;
  background: #fff; border: 2px solid var(--brand); color: var(--brand);
  font-style: normal; font-size: 16px; font-weight: 700; line-height: 20px; text-align: center;
  cursor: pointer; box-shadow: 0 2px 6px rgba(22,33,59,.18);
}
.rv-plus:hover { background: var(--brand); color: #fff; }
.rv-sub { font-size: 11px; font-style: normal; font-weight: 400; opacity: .8; display: block; }
.rv-node .rv-sub { display: inline; margin-left: 6px; }
/* 节点行：名称 ｜ 金额 ｜ 应付日 ｜ 删除 */
.rv-nodes { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 12px; }
.rv-empty { padding: 10px 2px; }
.rv-node {
  display: grid; grid-template-columns: 150px minmax(140px, 220px) minmax(140px, 200px) 34px;
  align-items: center; gap: 8px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel-2);
}
.rv-node.is-retention { border-style: dashed; background: #fffdf5; }
.rv-node-name { font-weight: 600; color: var(--ink); font-size: 13px; }
.rv-node input {
  border: 1px solid var(--line); border-radius: 8px; padding: 6px 9px; font-size: 13px;
  background: #fff; color: var(--ink); min-width: 0;
}
.rv-node input:focus { outline: none; border-color: var(--brand); }
.rv-node-del {
  width: 26px; height: 26px; border-radius: 50%; border: 1px solid #f3cfcf; background: #fff;
  color: var(--danger); font-size: 15px; line-height: 1; cursor: pointer;
}
.rv-node-del:hover { background: var(--danger); color: #fff; border-color: var(--danger); }
.rv-foot { gap: 12px; flex-wrap: wrap; }
.rv-sum { font-size: 13px; color: var(--ink-2); }
.rv-sum.ok b { color: var(--ok); }
.rv-sum.bad b { color: var(--danger); }

/* ================= 「节点」列 + 二级菜单（2026-10-21） =================
 * 表格最后一栏：有节点＝实心蓝按钮（沿用 .al-note-btn.has），无节点＝灰（disabled）。 */
.node-btn[disabled] { opacity: .5; cursor: default; }
.node-btn[disabled]:hover { border-color: var(--line); color: var(--ink-2); }
.node-pop { width: 440px; }
.node-list { padding: 10px; display: flex; flex-direction: column; gap: 8px; max-height: 340px; overflow: auto; }
.node-item {
  border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px;
  display: flex; flex-direction: column; gap: 6px; background: var(--panel-2); text-align: left;
}
.node-item.is-paid { background: #f4fbf6; border-color: #cdebd6; }
.node-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; font-size: 13px; }
.node-head .muted { font-size: 12px; }
.node-meta { font-size: 12px; color: var(--ink-2); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.node-tag-wait { color: var(--warn); font-weight: 600; }
.node-item .btn.mini { align-self: flex-start; padding: 3px 12px; font-size: 12px; }
/* 小号按钮（节点菜单里的「确认收款」用） */
.btn.mini { padding: 3px 10px; font-size: 12px; border-radius: 8px; }
/* 节点按钮行（2026-10-22）：已收款 + 上传PDF 并排，「上传PDF文件」在「已收款」右边 */
.node-btnrow { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.node-btnrow .btn.mini { align-self: auto; }
/* 已收款节点下方的凭证列表（上传按钮已移到按钮行右侧，这里只列文件） */
.node-atts {
  border-top: 1px dashed #cdebd6; margin-top: 2px; padding-top: 6px;
  display: flex; flex-direction: column; gap: 3px;
}
.node-atts:empty { display: none; }
.node-atts-hd { font-size: 12px; color: var(--ink-3); }
.node-att-row { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.node-att-row a { color: var(--brand); text-decoration: none; word-break: break-all; }
.node-att-row a:hover { text-decoration: underline; }
.node-att-row .al-att-del {
  border: 1px solid var(--line); background: var(--panel); border-radius: 6px;
  width: 18px; height: 18px; line-height: 1; font-size: 12px; cursor: pointer; color: var(--ink-3);
}
.node-att-row .al-att-del:hover { color: var(--danger); border-color: var(--danger); }
.node-att-row .al-att-del.danger-on { color: #fff; background: var(--danger); border-color: var(--danger); }
.node-att-acts { display: flex; align-items: center; gap: 8px; margin-top: 2px; }

/* ============ 表格左侧冻结（2026-10-27） ============
 * 用户反馈：台账池 38 列、横向滚动时左侧列被裁成半截，看着"不完整"。
 * 做法：冻结「序号」+「项目名称」两列（名称列宽 200px 固定，序号 54px），
 *       冻结区右侧加阴影，让"滑动"看起来是有意的，而不是被切坏。
 * ⚠️ 不要用 table-layout: fixed 去压列宽 —— 试过，38 列反而被撑到 1 万像素。
 */
#lg-contracts thead th:nth-child(1), #rm-contracts thead th:nth-child(1),
#lg-contracts tbody td:nth-child(1), #rm-contracts tbody td:nth-child(1) {
  position: sticky; left: 0; z-index: 3; background: var(--panel-2);
  min-width: 54px; max-width: 54px;
}
#lg-contracts tbody td:nth-child(1), #rm-contracts tbody td:nth-child(1) { background: #fff; }
#lg-contracts thead th:nth-child(2), #rm-contracts thead th:nth-child(2),
#lg-contracts tbody td:nth-child(2), #rm-contracts tbody td:nth-child(2) {
  position: sticky; left: 54px; z-index: 3; background: var(--panel-2);
  min-width: 200px; max-width: 200px;
  box-shadow: 2px 0 6px -2px rgba(22, 33, 59, .18);
}
#lg-contracts tbody td:nth-child(2), #rm-contracts tbody td:nth-child(2) {
  background: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#lg-contracts tbody tr:hover td:nth-child(1),
#lg-contracts tbody tr:hover td:nth-child(2),
#rm-contracts tbody tr:hover td:nth-child(1),
#rm-contracts tbody tr:hover td:nth-child(2) { background: #fafbff; }

/* ============ 单元格悬停高亮 + 点击看全文（2026-10-27） ============
 * 用户口径：每一个区块鼠标移过去高亮灰色，点击弹出二级菜单看完整信息。
 */
#lg-contracts tbody td, #rm-contracts tbody td,
#cq-table tbody td, #wb-contracts tbody td, #lg-actions tbody td {
  cursor: pointer; transition: background .08s;
}
#lg-contracts tbody td:hover, #rm-contracts tbody td:hover,
#cq-table tbody td:hover, #wb-contracts tbody td:hover, #lg-actions tbody td:hover {
  background: #eef1f6 !important;
}
#lg-contracts tbody td:first-child:hover, #lg-contracts tbody td:nth-child(2):hover,
#rm-contracts tbody td:first-child:hover, #rm-contracts tbody td:nth-child(2):hover {
  background: #e6eaf2 !important;
}
/* ⚠️ .cq-pop 是 flex 容器，正文会被压成 0 高 —— 这里必须改回 block（实测踩过） */
.cell-pop { display: block; width: 380px; min-width: 260px; max-width: min(560px, 92vw); box-shadow: 0 18px 44px rgba(22,33,59,.22); }
.cell-pop[hidden] { display: none; }
.cell-pop-body {
  padding: 10px 12px; white-space: pre-wrap; word-break: break-word;
  max-height: 55vh; overflow: auto; font-size: 13px; line-height: 1.6;
}
