:root{
  --brand:#1f4e79; --brand-2:#2f6ba8; --brand-soft:#eaf1f9;
  --ink:#1a2634; --ink-2:#5b6b7c; --ink-3:#8b99a8;
  --line:#e2e8f0; --bg:#f4f6f9; --card:#fff;
  /* 行分界线专用的深一档：--line 是画卡片边框、表头下沿用的，
     铺到多行行的列表上就淡得看不见（项目列表一行三行高）。
     **靠加深、不靠加粗**——2px 试过，线条变笨重，表格显得脏（D-030）；
     1px 只要颜色够深就分得开。只用于「一行 = 一个实体」的表，
     分组表的层级另有 2px 粗线。 */
  --line-2:#aab8c8; --zebra:#f6f8fb;
  /* 行高的唯一开关：数据表行的上下内边距（--row-pad）与分组组头（--row-pad-h）。
     嫌挤就调大、嫌占地方就调小，全系统所有表一起动，不用一张张改。
     2026-08-21 由 12/10 提到 20/16（用户要求「行高再加大 30%」）。
     --row-pad-d 是**明细矩阵**那一类表的紧凑档（见 .tbl-dense）：
     「一行 = 一个实体」的列表（项目/合同/一笔钱）要松，行与行之间得分得开；
     「明细矩阵」（预算执行三十多行 × 九列数字）要紧，读的是列与列的对比，
     紧凑才扫得快。两类表的诉求相反，用一个数迁就不了（D-036）。 */
  --row-pad:20px; --row-pad-h:16px; --row-pad-d:12px;
  --ok:#0f8a5f; --ok-bg:#e6f6ef;
  --warn:#c67c00; --warn-bg:#fdf3e0;
  --danger:#c0392b; --danger-bg:#fdecea;
  /* 往来款专用的橙红：比 warn 的琥珀重、比 danger 的正红略暖。
     用途只有一个——保证金/押金这类「不催就真没了」的钱，
     它比普通逾期更需要一眼看见（普通逾期至少还挂在合同分期上，有人管）。 */
  --owe:#d2521e; --owe-bg:#fdeee6; --owe-bg2:#fbe3d6;
  --l1:#1f4e79; --l2:#4a90c2; --l3:#a8c7e0; --free:#e4eaf0;
  --radius:10px; --shadow:0 1px 3px rgba(16,32,48,.08),0 1px 2px rgba(16,32,48,.04);
}
*{box-sizing:border-box;margin:0;padding:0}
body{
  font-family:-apple-system,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  background:var(--bg); color:var(--ink); font-size:14px; line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
a{color:var(--brand-2);text-decoration:none}
button{font-family:inherit;cursor:pointer}

/* ---------- 布局 ---------- */
.topbar{
  background:var(--brand); color:#fff; padding:0 22px; height:56px;
  display:flex; align-items:center; gap:26px; position:sticky; top:0; z-index:50;
  box-shadow:0 2px 8px rgba(31,78,121,.18);
}
.logo{
  font-size:16px;font-weight:700;letter-spacing:.5px;white-space:nowrap;flex-shrink:0;
  padding-right:22px;margin-right:4px;border-right:1px solid rgba(255,255,255,.22);
}
.topbar .acts{flex-shrink:0}
@media(max-width:820px){
  .logo{padding-right:14px}
  .topbar .acts .btn:last-child{display:none}
}
.nav{display:flex;gap:4px;flex:1;overflow-x:auto;scrollbar-width:none}
.nav::-webkit-scrollbar{display:none}
.nav a{
  color:rgba(255,255,255,.82); padding:7px 14px; border-radius:6px;
  font-size:13.5px; transition:.15s; white-space:nowrap; flex-shrink:0;
}
.nav a:hover{background:rgba(255,255,255,.12);color:#fff}
.nav a.on{background:rgba(255,255,255,.2);color:#fff;font-weight:600}
.topbar .acts{display:flex;gap:8px}
/* 页面主容器。原来也叫 .wrap，跟表格里「这一列允许折行」的 td.wrap 撞了名：
   `.wrap{padding:22px}`（0,1,0）压过 `td{padding:12px}`（0,0,1），
   于是**全系统每一个长文本单元格的内边距都是 22px 而不是 D-031 定的 12px**，
   行高怎么调都不跟手。改名 .page，容器只在 index.html 用一处，改动最小。 */
.page{max-width:1500px;margin:0 auto;padding:22px}

/* ---------- 按钮 ---------- */
.btn{
  border:1px solid var(--line); background:#fff; color:var(--ink);
  padding:7px 14px; border-radius:7px; font-size:13px; transition:.15s;
  display:inline-flex; align-items:center; gap:5px; white-space:nowrap;
}
.btn:hover{border-color:var(--brand-2);color:var(--brand-2)}
.btn.primary{background:var(--brand);border-color:var(--brand);color:#fff;font-weight:500}
.btn.primary:hover{background:var(--brand-2);border-color:var(--brand-2);color:#fff}
.btn.ghost{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.3);color:#fff}
.btn.ghost:hover{background:rgba(255,255,255,.24);color:#fff;border-color:rgba(255,255,255,.5)}
.btn.sm{padding:4px 10px;font-size:12px;border-radius:5px}
/* 深蓝顶栏上的反白按钮。ghost 那套是半透明白底，三个按钮长得一模一样，
   「说明」这种第一次用最该点的入口在里面看不出来。反白（白底品牌蓝字）
   在深底上是最亮的一档，不用动红色（红色只留给告警）。 */
.btn.ghost.solid{background:#fff;border-color:#fff;color:var(--brand);font-weight:600}
.btn.ghost.solid:hover{background:var(--brand-soft);border-color:var(--brand-soft);color:var(--brand)}
.btn.danger{color:var(--danger);border-color:#f0c4bf}
/* 主按钮 + 危险：整块填红。删除、移入回收站这类动作的确认框用它——
   只描红边的话，它跟旁边的「取消」在视觉重量上一样，等于没有主次。 */
.btn.primary.danger{background:var(--danger);border-color:var(--danger);color:#fff}
.btn.primary.danger:hover{background:#a93226;border-color:#a93226;color:#fff}
.btn.danger:hover{background:var(--danger);color:#fff;border-color:var(--danger)}

/* ---------- 卡片 ---------- */
.card{background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);margin-bottom:18px}
.card-h{
  padding:14px 18px; border-bottom:1px solid var(--line);
  display:flex; align-items:center; justify-content:space-between; gap:12px;
}
.card-h h2{font-size:15px;font-weight:600;display:flex;align-items:center;gap:8px}
.card-h h2::before{content:'';width:3px;height:15px;background:var(--brand);border-radius:2px}
.card-h .sub{font-size:12px;color:var(--ink-3);font-weight:400}
.card-b{padding:18px}
.card-b.flush{padding:0}

/* ---------- 指标卡 ---------- */
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(178px,1fr));gap:14px;margin-bottom:18px}
.kpi{background:#fff;border-radius:var(--radius);padding:15px 17px;box-shadow:var(--shadow);border-left:3px solid var(--brand);border:1px solid transparent;border-left:3px solid var(--brand);transition:.15s}
.kpi .k{font-size:12px;color:var(--ink-2);margin-bottom:6px;display:flex;align-items:center;gap:5px}
.kpi .v{font-size:23px;font-weight:700;letter-spacing:-.4px;font-variant-numeric:tabular-nums}
.kpi .u{font-size:12px;font-weight:400;color:var(--ink-3);margin-left:3px}
.kpi .d{font-size:11.5px;color:var(--ink-3);margin-top:5px}
.kpi.ok{border-left-color:var(--ok)} .kpi.ok .v{color:var(--ok)}
.kpi.warn{border-left-color:var(--warn)} .kpi.warn .v{color:var(--warn)}
.kpi.danger{border-left-color:var(--danger)} .kpi.danger .v{color:var(--danger)}
.kpi.lead{border-left-color:var(--brand)} .kpi.lead .v{color:var(--brand)}

/* ---------- 三层锁定条 ---------- */
.lockbar{margin:4px 0 14px}
.lockbar .bar{display:flex;height:26px;border-radius:6px;overflow:hidden;background:var(--free);font-size:11px}
.lockbar .bar span{
  display:flex;align-items:center;justify-content:center;color:#fff;
  transition:.3s; overflow:hidden; white-space:nowrap;
}
.lockbar .s1{background:var(--l1)} .lockbar .s2{background:var(--l2)}
.lockbar .s3{background:var(--l3)}
.lockbar .s0{background:var(--free)}
.lockbar .s9{background:var(--danger)}
/* 浅底的那几段要用深字，**而且必须写成 `.bar span.xx` 才够权重**（D-064）：
   上面那条 `.lockbar .bar span{color:#fff}` 是 (0,2,1)，
   压过 `.lockbar .s0` 的 (0,2,0)——于是浅灰底上印白字，几乎看不见。
   原来这几段只印两三个字的标签、不显眼，条上加了金额之后就露馅了。
   同一个成因三处：三层锁定条的「已批未签」「可支配」和收款条的「未到期」。 */
.lockbar .bar span.s3{color:var(--ink)}
.lockbar .bar span.s0,.lockbar .bar span.r0{color:var(--ink-2)}
.legend{display:flex;gap:16px;flex-wrap:wrap;margin-top:9px;font-size:12px;color:var(--ink-2)}
.legend i{width:11px;height:11px;border-radius:3px;display:inline-block;margin-right:5px;vertical-align:-1px}

/* ---------- 表格 ---------- */
table{width:100%;border-collapse:collapse;font-size:13px}
/* 表头（D-040，先在项目列表上试行、用户认可后推广到全系统）。
   原来这里主次颠倒：底色 #f7f9fc 跟卡片白几乎分不出来、字用 --ink-2 压着、
   **下边界用的 --line 比行分隔线 --line-2 还淡**——表头的边界弱于行的边界，
   等于说「换一行」比「这里是表头」更重要。
   底色压出一层、字提到正文色、下沿加重到 2px 品牌色；
   上下内边距跟数据行的 --row-pad 挂钩（少 6px，表头不该比数据行还挤）。
   加重的是**区域边界**，不是行与行之间——D-030「靠加深不靠加粗」说的是后者。 */
th{
  background:#eaf0f7; color:var(--ink); font-weight:600; font-size:12.5px;
  letter-spacing:.3px; text-align:left;
  padding:calc(var(--row-pad) - 6px) 12px;
  border-bottom:2px solid var(--brand); white-space:nowrap;
}
/* 数据表的行样式统一在这里定，别再按表分两套（D-031）：
   原来只有 .list-tbl/.ledger-tbl 用 12px + 深分隔线，其余 6 张只写了
   class="sortable" 的表还是 9px + 近白线，翻页时行高行距忽紧忽松。
   **行高只有 --row-pad 这一个开关**（上下内边距），要调只改 :root 里那个数。
   在 .wrap 改名 .page 之前这个开关是失灵的：容器的 `.wrap{padding:22px}`
   压过 `td{padding}`，凡是带长文本列的行都被顶到 22px，怎么改都不动。 */
td{padding:var(--row-pad) 12px;border-bottom:1px solid var(--line-2);
   vertical-align:middle;white-space:nowrap}

/* 测算依据：跟明细名称同一行的灰字注脚。
   另起副行会把展开后的明细行拉高四成，等于把刚压下去的高度还回去（D-037）。 */
.bx-basis{margin-left:10px;color:var(--ink-3);font-size:11.5px;font-weight:400}

/* 明细矩阵：一行是一个数据点，不是一个实体。给它紧凑档。
   **只调内边距，其余（分隔线、隔行底、hover）一律跟基础规则走**——
   一旦开始逐表覆盖别的属性，D-031 那种「六张表行高对不上」就会重演。 */
.tbl-dense > tbody > tr > td{padding-top:var(--row-pad-d);padding-bottom:var(--row-pad-d)}

/* 隔行浅底：行一高，光靠一条线眼睛还是会串行。底色是"这一整条是一体的"，
   线是"到这儿换人了"，两者管的不是一回事。 */
tbody > tr:nth-of-type(even){background:var(--zebra)}
/* 分组表按**组**铺，不按行——一份合同占三行，按行铺会把它拆成两种底色，
   看着像三份不同的东西（D-003 那条「组内换行 vs 换一份合同」的老问题）。 */
tbody.cg > tr, tbody.lgrp > tr{background:transparent}
tbody.cg:nth-of-type(even) > tr,
tbody.lgrp:nth-of-type(even) > tr{background:var(--zebra)}
/* 数据表默认不换行、横向滚动 —— 中文列一窄就逐字竖排，比滚动难读得多。
   长文本列单独标 .wrap 允许折行。 */
td.wrap{white-space:normal;min-width:14em;max-width:26em}
td .t-sub{white-space:normal}
/* ---- 表格容器：默认**不做**滚动容器 ----
   `overflow-x:auto` 会让 `overflow-y` 跟着算成 `auto`（规范如此，一轴非 visible
   另一轴就不能是 visible），于是这个 div 变成滚动容器，
   里面 `position:sticky` 的表头贴的是它自己、跟着页面一起滚走——冻结表头就失效了。
   所以默认 visible，**真的装不下时**才由 fitTables() 加回 .scrollx：
   那张表放弃冻结表头、换回横向滚动条。二者不可兼得，按「装不装得下」自动选。 */
.tbl-wrap{overflow:visible}
.tbl-wrap.scrollx{overflow-x:auto;-webkit-overflow-scrolling:touch}
.tbl-wrap table{min-width:100%}

/* ---- 冻结列头 ----
   往下拉之后不知道这一列是什么，是长表格最常见的抱怨。
   `top` 要让开顶部导航（.topbar 高 56px，sticky，z-index:50）。
   边框用 inset box-shadow 不用 border-bottom：表是 border-collapse:collapse，
   合并后的边框不跟着 sticky 元素走，滚起来那条线会留在原地。
   .scrollx 的表放弃冻结（见上），免得表头贴在一个跟着页面滚的盒子上白费劲。 */
.tbl-wrap:not(.scrollx) > table > thead > tr > th{
  position:sticky; top:56px; z-index:6;
  /* 冻结时 border-bottom 不跟着走（border-collapse），用 inset 影子补同一条线 */
  box-shadow:inset 0 -2px 0 var(--brand);
}
/* 卡片里的小表（明细展开、进度节点那种）不冻——它们本来就没几行，
   贴一条表头在半空反而挡事 */
/* 嵌在卡片/单元格里的小表（明细展开、进度节点那种）不跟着变重：
   三五行的小表压一条 2px 深蓝，比它要说的内容还响。 */
.sub-tbl th,.pne-t th,.bgt-detail th{
  position:static; box-shadow:none;
  background:#f2f6fa; color:var(--ink-2); letter-spacing:0;
  border-bottom:1px solid var(--line);
}
tbody tr:hover{background:#fafcfe}
/* 整行可点的表格：hover 时明确给出"这行能点"的信号，
   否则只有底色变化，用户根本不知道能进去。 */
tbody tr.clickable{cursor:pointer}
tbody tr.clickable:hover{background:var(--brand-soft)}
tbody tr.clickable:hover .t-name{color:var(--brand);text-decoration:underline}
tbody tr.clickable .t-name::after{
  content:'›';margin-left:6px;color:var(--brand-2);font-weight:700;
  opacity:0;transition:.15s;display:inline-block;
}
tbody tr.clickable:hover .t-name::after{opacity:1;transform:translateX(2px)}
/* 整张表的最后一行不画线——下面就是卡片边缘了，再画一条是双线。
   **必须限定在最后一个 tbody**：这条按「一张表一个 tbody」写的规则，
   在分组表上会变成「每一组的最后一行都不画线」，于是有子行的组画线、
   没子行的不画，横线看着像分区，其实只在说「这个科目有没有明细」（D-037）。 */
table > tbody:last-of-type > tr:last-child > td{border-bottom:none}

/* 表内合计行（D-065）。原来三张表各写一遍 `style="background:#f7f9fc;font-weight:600"`，
   底色铺在 tr 上——按 D-031 该铺在 td 上，才压得过 --zebra 的隔行底。
   **它同时是 sortTable 的钉子**：排序时合计行被排除并重新 appendChild 到末尾，
   不这么做的话「合计」会冒到表格最上面（见 sortTable 里的注释）。 */
tr.sum-row > td{background:#f7f9fc;font-weight:600}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
td.mid,th.mid{text-align:center}
.t-name{font-weight:500}
.t-sub{font-size:11.5px;color:var(--ink-3)}
.empty{text-align:center;padding:40px 20px;color:var(--ink-3);font-size:13px}

/* ---------- 徽章 ---------- */
.tag{
  display:inline-block;padding:2px 8px;border-radius:4px;font-size:11.5px;
  background:var(--brand-soft);color:var(--brand);white-space:nowrap;font-weight:500;
}
.tag.ok{background:var(--ok-bg);color:var(--ok)}
.tag.warn{background:var(--warn-bg);color:var(--warn)}
.tag.danger{background:var(--danger-bg);color:var(--danger)}
.tag.gray{background:#eef1f5;color:var(--ink-2)}
.tag.in{background:#e7f2fb;color:#1a6aab}
.tag.out{background:#fdeee8;color:#b5541f}

/* 可点的标签（文件库组头上那排归档类别）＝筛选的另一个入口。
   要长得像能点：手型 + hover 加深。选中态跟 .kpi.on 用同一套语言
   （实心品牌色），全站「正按这一格筛着」只有一种样子。 */
.tag-pick{cursor:pointer;transition:background .12s,color .12s}
.tag-pick:hover{background:#d3e3f3}
.tag-pick.on{background:var(--brand);color:#fff}

/* ---------- 提醒 ---------- */
.alert{padding:10px 14px;border-radius:7px;font-size:13px;margin-bottom:9px;display:flex;gap:9px;align-items:flex-start}
.alert .kind{
  flex-shrink:0;font-size:11px;font-weight:700;padding:1px 7px;border-radius:4px;
  background:rgba(255,255,255,.65);margin-top:2px;letter-spacing:.5px;
}
.alert-more{
  text-align:center;font-size:12.5px;color:var(--ink-2);cursor:pointer;
  padding:7px;border:1px dashed var(--line);border-radius:7px;margin-bottom:9px;
}
.alert-more:hover{border-color:var(--brand-2);color:var(--brand-2);background:var(--brand-soft)}
.alert.danger{background:var(--danger-bg);color:var(--danger);border-left:3px solid var(--danger)}
.alert.warn{background:var(--warn-bg);color:var(--warn);border-left:3px solid var(--warn)}
.alert.ok{background:var(--ok-bg);color:var(--ok);border-left:3px solid var(--ok)}
/* 中性说明条（D-072）：既不是告警也不是好消息，只是「这类项目不适用某条规则」。
   不能拿 warn 凑合——一片黄底会被读成「有件事我该去办」，
   而「技术服务不走预算」是规则本身，没有任何人需要为它做什么。 */
.alert.info{background:var(--brand-soft);color:var(--ink-2);border-left:3px solid var(--brand-2)}

/* ---------- 项目卡 ---------- */
/* 项目页的列表视图要有右边界（D-031）。其他页面的表都包在 .card 里，
   自带白底+圆角+投影，右边一眼看得到头；项目页的表直接铺在灰底上，
   右侧散着没有收口，翻过来就觉得这一页"没做完"。 */
#cards.tbl-wrap{
  background:var(--card); border-radius:var(--radius); box-shadow:var(--shadow);
}
/* 圆角靠给四个角上的单元格各自设半径，**不能用 overflow:hidden 裁**（D-039）：
   `overflow:hidden` 会让 <table> 变成 sticky 的定位容器，冻结表头于是相对
   表格往下滑，压在第一行上——项目列表第一行的项目名整个被盖住。
   同 .tbl-wrap 那条（D-035）：**任何祖先元素上的 overflow 都会静默废掉 sticky**，
   加圆角/裁切之前先想一下这条链上有没有 sticky。 */
#cards.tbl-wrap > table{border-radius:var(--radius)}
#cards.tbl-wrap > table > thead > tr > th:first-child{border-top-left-radius:var(--radius)}
#cards.tbl-wrap > table > thead > tr > th:last-child{border-top-right-radius:var(--radius)}
#cards.tbl-wrap > table > tbody:last-of-type > tr:last-child > td:first-child{
  border-bottom-left-radius:var(--radius)}
#cards.tbl-wrap > table > tbody:last-of-type > tr:last-child > td:last-child{
  border-bottom-right-radius:var(--radius)}

.pcards{display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:15px}
/* 一排几个由人定（D-030）。原来只有 auto-fill，宽屏一排四个卡片被压窄、
   长项目名折三行，想看清楚只能拖窄窗口。
   窄屏仍然兜底：放不下四列时自动降，否则四列会挤成不可读。 */
.pcards.c4{grid-template-columns:repeat(4,minmax(0,1fr))}
.pcards.c2{grid-template-columns:repeat(2,minmax(0,1fr))}
@media(max-width:1360px){ .pcards.c4{grid-template-columns:repeat(3,minmax(0,1fr))} }
@media(max-width:1040px){ .pcards.c4{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media(max-width:760px){ .pcards.c4,.pcards.c2{grid-template-columns:1fr} }
.pcard{background:#fff;border-radius:var(--radius);box-shadow:var(--shadow);padding:16px 18px;cursor:pointer;transition:.16s;border-top:3px solid var(--brand)}
.pcard:hover{transform:translateY(-2px);box-shadow:0 6px 18px rgba(16,32,48,.12)}
.pcard.danger{border-top-color:var(--danger)}
.pcard.warn{border-top-color:var(--warn)}
.pcard.ok{border-top-color:var(--ok)}
.pcard.done{border-top-color:var(--ink-3);opacity:.78}
.pcard h3{font-size:15px;font-weight:600;margin-bottom:3px;line-height:1.4}
.pcard .meta{font-size:12px;color:var(--ink-3);margin-bottom:11px;display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.pcard .fig{display:flex;justify-content:space-between;margin-top:11px;font-size:12px}
.pcard .fig div{text-align:center;flex:1}
.pcard .fig .n{font-size:15px;font-weight:700;font-variant-numeric:tabular-nums;display:block}
.pcard .fig .l{color:var(--ink-3);font-size:11px}
/* 卡片底行：左进度、右负责人。右下角原来是空的，而「谁在带这个项目」
   是扫卡片时最常问的一件事（D-029）。 */
.pcard-foot{display:flex;align-items:baseline;gap:10px;margin-top:9px}
.pcard-owner{margin-left:auto;flex-shrink:0;color:var(--ink-2)}

/* ---------- 表单 / 弹窗 ---------- */
.mask{position:fixed;inset:0;background:rgba(16,28,42,.5);z-index:200;display:flex;align-items:flex-start;justify-content:center;padding:40px 20px;overflow-y:auto}
.modal{background:#fff;border-radius:12px;width:100%;max-width:760px;box-shadow:0 20px 50px rgba(0,0,0,.25);animation:pop .16s ease}
.modal.wide{max-width:1080px}
/* 确认框（D-068）：比表单窄一档，一眼能读完 */
.modal.cfm{max-width:520px}
.cfm-msg{font-size:13.5px;line-height:1.8;color:var(--ink-2)}
.cfm-msg b{color:var(--ink)}
.cfm-msg code{background:var(--bg);border:1px solid var(--line);border-radius:4px;padding:1px 5px}
@keyframes pop{from{opacity:0;transform:translateY(-12px)}to{opacity:1;transform:none}}
.modal-h{padding:16px 22px;border-bottom:1px solid var(--line);display:flex;justify-content:space-between;align-items:center}
.modal-h h3{font-size:16px;font-weight:600}
.modal-b{padding:20px 22px;max-height:66vh;overflow-y:auto}
.modal-f{padding:14px 22px;border-top:1px solid var(--line);display:flex;justify-content:flex-end;gap:9px;background:#fbfcfe;border-radius:0 0 12px 12px}
.x{background:none;border:none;font-size:22px;color:var(--ink-3);line-height:1;padding:0 4px}
.x:hover{color:var(--ink)}
.grid{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}

/* ---------- 说明与术语（D-068）----------
   顶上一排跳转按钮吸顶，内容一节一条。**不做成两栏**：
   66vh 的弹窗里再切一竖，正文只剩一半宽，一段话要折五行。 */
.help-nav{
  position:sticky; top:-20px; z-index:2; background:#fff;
  padding:2px 0 12px; margin:-2px 0 4px; display:flex; flex-wrap:wrap; gap:7px;
  border-bottom:1px solid var(--line);
}
.help-sec{padding:16px 0; border-bottom:1px dashed var(--line); scroll-margin-top:60px}
.help-sec:last-child{border-bottom:none}
.help-sec h4{font-size:14.5px; font-weight:600; color:var(--brand); margin-bottom:8px}
.help-sec p{margin:7px 0; color:var(--ink-2); line-height:1.75}
.help-sec ul,.help-sec ol{margin:7px 0 7px 20px; color:var(--ink-2); line-height:1.85}
.help-sec b{color:var(--ink)}
/* 公式单独摆一行：夹在段落里念不出来 */
.help-sec p.hl{
  background:var(--brand-soft); border-left:3px solid var(--brand);
  padding:9px 13px; border-radius:0 6px 6px 0; color:var(--ink); font-weight:500;
}
/* 从别处跳进来的那一条闪一下——用描边不用底色（同 D-063） */
.help-sec.hl-help{animation:helpflash 1.4s ease}
@keyframes helpflash{
  0%{box-shadow:inset 0 0 0 2px var(--brand-2)}
  70%{box-shadow:inset 0 0 0 2px var(--brand-2)}
  100%{box-shadow:inset 0 0 0 2px transparent}
}
/* 正文里指向术语表的链接：虚线下划线，跟普通跳转链接分得开 */
.tref{color:var(--brand-2); border-bottom:1px dashed var(--brand-2); cursor:pointer}
.tref:hover{color:var(--brand); border-bottom-style:solid}
.grid.c3{grid-template-columns:repeat(3,1fr)}
.fld{display:flex;flex-direction:column;gap:5px}
.fld.full{grid-column:1/-1}
.fld label{font-size:12.5px;color:var(--ink-2);font-weight:500}
.fld label i{color:var(--danger);font-style:normal}
.fld input,.fld select,.fld textarea{
  border:1px solid var(--line); border-radius:7px; padding:8px 11px; font-size:13.5px;
  font-family:inherit; color:var(--ink); background:#fff; transition:.15s; width:100%;
}
.fld input:focus,.fld select:focus,.fld textarea:focus{outline:none;border-color:var(--brand-2);box-shadow:0 0 0 3px rgba(47,107,168,.12)}
.fld textarea{resize:vertical;min-height:64px}
.fld .hint{font-size:11.5px;color:var(--ink-3)}
.fld input[type=number],.fld input.amt{font-variant-numeric:tabular-nums}
/* 必填没写的格子（D-068）。报字段名是「告诉你哪儿错了」，
   标红加聚焦是「带你到那儿」——十来个格子的表单里，前者等于让人自己找。
   标签也一起变红：只描红框的话，视线还得往上找这是哪一项。 */
.fld.bad input,.fld.bad select,.fld.bad textarea{border-color:var(--danger);background:var(--danger-bg)}
.fld.bad label{color:var(--danger)}

/* ---------- 页签 ---------- */
/* ---------- 项目页签（D-074）----------
   原来是一排纯文字 + 2px 下划线，用户反馈「太不显眼」。毛病在于：
   它是**整个项目页的主导航**，视觉重量却比正文还轻——扫过去不像能点的东西，
   选中的那个也只靠一条 2px 细线区分，跟表头的下沿线长得一样。

   改成**真正的立体页签**：整条是一道浅蓝渐变的轨，底边压一条 2px 品牌色；
   每一片是能看见边界的小卡，未选中的白底细边、微投影、比轨面低 2px，
   选中那片用品牌色实心填充、抬到齐平、投影加重——「浮起来的那片就是当前页」
   这个隐喻不用学就懂。

   **配色仍只用 :root 那套**（政务气质，红色继续只给告警）：
   彩色来自品牌蓝的深浅与渐变，不是给每个页签配一个颜色——
   页签之间是并列关系，各配一色反而会让人以为颜色在表达分类。 */
.tabs{
  display:flex;gap:6px;padding:11px 14px 0;overflow-x:auto;
  /* 轨面要压得住白色页签：第一版用的 #f4f7fb→#e9eff7 太浅，
     未选中的白片浮在近乎白的底上分不开，「浮起来」那层意思就没了 */
  background:linear-gradient(180deg,#dfe8f3 0%,#cfdcec 100%);
  border-bottom:3px solid var(--brand);
  border-radius:var(--radius) var(--radius) 0 0;
  box-shadow:inset 0 2px 4px rgba(31,78,121,.10);
}
.tabs button{
  border:1px solid #a9bdd6;border-bottom:none;color:var(--ink-2);
  background:linear-gradient(180deg,#fff 0%,#f2f6fb 100%);
  padding:9px 16px 11px;font-size:13.5px;white-space:nowrap;
  border-radius:8px 8px 0 0;position:relative;top:3px;
  /* 顶边一道白高光 + 底下一层投影 = 最省事也最像「实体薄片」的做法 */
  box-shadow:inset 0 1px 0 #fff, 0 1px 2px rgba(20,45,70,.14);
  transition:.14s;
}
.tabs button:hover{
  color:var(--brand);border-color:var(--brand-2);top:0;
  background:linear-gradient(180deg,#fff 0%,#e8f0fa 100%);
  box-shadow:inset 0 1px 0 #fff, 0 4px 9px rgba(20,45,70,.20);
}
/* 选中那片：实心品牌色 + 抬到与轨面齐平 + 投影加重。
   顶边留一道半透明白高光，深色块才不会看着是"挖下去的洞" */
.tabs button.on{
  background:linear-gradient(180deg,#3d7cb8 0%,var(--brand) 100%);
  border-color:var(--brand);color:#fff;font-weight:600;top:0;
  padding-bottom:13px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.34), 0 5px 12px rgba(20,45,70,.34);
}
/* 计数做成小药丸：原来是跟标题挤在一起的灰字，页签一多就糊成一片。
   未选中那档底色要压得住白片，太浅等于没有 */
.tabs .cnt{
  font-size:11px;margin-left:7px;padding:1px 7px;border-radius:9px;
  background:#d7e2ef;color:#3f5a77;font-weight:600;
  font-variant-numeric:tabular-nums;
}
.tabs button.on .cnt{background:rgba(255,255,255,.28);color:#fff}

/* ---------- 杂项 ---------- */
.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.row.end{justify-content:flex-end}
.sp{flex:1}
.mini{font-size:12px;color:var(--ink-3)}
.bar-mini{height:5px;background:#eef1f5;border-radius:3px;overflow:hidden;margin-top:5px}
/* 执行率格：百分比在左、条在右，一行放下。
   上下摞的话这一格就是两行高，而它常常是整行最高的那格——
   一张三十多行的表被一个格子顶高一屏（D-036）。 */
.exec-c{display:flex;align-items:center;gap:8px;white-space:nowrap}
.exec-c .mini{min-width:44px;text-align:right;font-variant-numeric:tabular-nums}
/* 执行率的颜色只回答一件事：超没超总预算。绿＝没超，红＝超了（D-038） */
/* 三档语义色的通用写法：好 / 提醒 / 有问题。
   原来在 .exec-c 和 .lgrp-exec 里各定了一遍，第三处要用时不上色——
   同一件事定两遍的老毛病（D-031）。提到这里，谁都能用。 */
.okv{color:var(--ok);font-weight:600}
.warnv{color:var(--warn);font-weight:600}
.dangerv{color:var(--danger);font-weight:600}
.exec-c .bar-mini{flex:1;margin-top:0;min-width:36px}
.bar-mini i{display:block;height:100%;background:var(--brand);border-radius:3px}
.bar-mini i.ok{background:var(--ok)}
.bar-mini i.over{background:var(--danger)}
.crumb{font-size:12.5px;color:var(--ink-3);margin-bottom:12px}
.crumb a:hover{text-decoration:underline}
/* 没有卡片头的页面（目前只有项目列表）用它放「这页回答什么问题」（D-068）。
   跟 .card-h .sub 同一档字号和颜色，位置不同但读起来是同一句话。 */
.page-sub{font-size:12px;color:var(--ink-3);margin:-4px 0 12px}
/* 切页的加载态（D-068）。转圈用纯 CSS —— 外部图标库是硬约束里禁掉的。 */
.loading{
  display:flex; align-items:center; justify-content:center; gap:10px;
  padding:70px 20px; color:var(--ink-3); font-size:13px;
}
.spin{
  width:16px; height:16px; border-radius:50%;
  border:2px solid var(--line); border-top-color:var(--brand-2);
  animation:spin .7s linear infinite;
}
@keyframes spin{to{transform:rotate(360deg)}}
/* ---------- 筛选工具条 ----------
   原来是几个浅边框的框子浮在白底上，既看不出「这一条是干嘛的」，
   也分不清哪个是筛选、哪个是会跳走的按钮。
   现在：整条压一层浅蓝底 + 左侧主色竖条（与卡片标题同一套记号），
   左边只放筛选、右边只放动作，中间用 .sp 撑开。 */
.filters{
  display:flex; gap:10px; flex-wrap:wrap; align-items:center; margin-bottom:16px;
  background:#eef3f9; border:1px solid #d4dfeb; border-left:3px solid var(--brand);
  border-radius:9px; padding:12px 14px;
}
.filters input,.filters select{
  border:1px solid #c3cedb; border-radius:7px; padding:8px 12px; font-size:13.5px;
  font-family:inherit; background:#fff; color:var(--ink); height:38px; font-weight:500;
}
.filters input::placeholder{color:#93a1b2;font-weight:400}
/* 放大镜与下拉箭头都内联成 data URI —— 不引外部资源（技术约束第六节） */
.filters input{
  min-width:262px; padding-left:34px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='%235b6b7c' stroke-width='2.4' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.5-3.5'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:11px center;
}
.filters select{
  appearance:none; -webkit-appearance:none; padding-right:30px; cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 24 24' fill='none' stroke='%231f4e79' stroke-width='2.6' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 10px center;
}
/* 焦点态原来完全没有，看不出光标在哪个框里 */
.filters input:focus,.filters select:focus{
  outline:none; border-color:var(--brand); box-shadow:0 0 0 3px rgba(31,78,121,.16);
}
/* 已经选了值的下拉填实主色——一眼看出「这里正筛着东西」，
   比只换个边框色显眼得多 */
.filters select.act{
  background-color:var(--brand); border-color:var(--brand); color:#fff; font-weight:600;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.6' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}
/* 工具条右侧的动作按钮：白底 + 主色描边，和左边的筛选控件区分开 */
.filters .btn{
  height:38px; padding:0 14px; font-size:13px; background:#fff;
  border:1px solid var(--brand-2); color:var(--brand); font-weight:500;
}
.filters .btn:hover{background:var(--brand-soft)}
/* 列表页计数条（countBox，D-065）。整句不许断行——「共 7 条　·　收入合同
   3,640,800.00 元」拆成两行读起来像两个数。.filters 是 flex-wrap，
   装不下时它整块换行，那是对的。 */
.filters .listcnt{white-space:nowrap;font-variant-numeric:tabular-nums}
.filters .listcnt b{color:var(--ink);font-weight:600}
.filters .btn.primary{background:var(--brand);border-color:var(--brand);color:#fff}
.filters .btn.primary:hover{background:var(--brand-2)}

.toast{
  position:fixed;bottom:26px;left:50%;transform:translateX(-50%);z-index:999;
  background:var(--ink);color:#fff;padding:11px 22px;border-radius:8px;font-size:13.5px;
  box-shadow:0 8px 24px rgba(0,0,0,.25);animation:up .2s ease;
}
.toast.err{background:var(--danger)}
.toast.ok{background:var(--ok)}
/* 提醒但不是错（老式 .doc 传上来了、只是搜起来不准）——
   用琥珀不用红：红色只给告警（:root 那条），这里事情已经办成了 */
.toast.warn{background:var(--warn)}
@keyframes up{from{opacity:0;transform:translate(-50%,14px)}to{opacity:1;transform:translate(-50%,0)}}
.drop{
  border:2px dashed var(--line);border-radius:10px;padding:30px;text-align:center;
  color:var(--ink-3);transition:.15s;cursor:pointer;
}
.drop:hover,.drop.over{border-color:var(--brand-2);background:var(--brand-soft);color:var(--brand)}
@media(max-width:860px){
  .grid,.grid.c3{grid-template-columns:1fr}
  .page{padding:14px}
  .nav{overflow-x:auto}
}

/* ---------- 进度健康对比 ---------- */
.prog-wrap{background:#fbfcfe;border:1px solid var(--line);border-radius:10px;padding:16px 18px}
.prog-row{display:flex;align-items:center;gap:12px;margin-bottom:11px}
.prog-row:last-child{margin-bottom:0}
.prog-lab{width:96px;font-size:12.5px;color:var(--ink-2);flex-shrink:0;text-align:right}
.prog-bar{flex:1;height:16px;background:#eef1f5;border-radius:8px;overflow:hidden;position:relative}
.prog-bar i{display:block;height:100%;border-radius:8px;transition:width .4s ease}
.prog-bar i.plan{background:#b9c6d4}
.prog-bar i.actual{background:var(--brand)}
.prog-bar i.paid{background:#e0a458}
.prog-bar i.lock{background:#8fb4d4}
.prog-val{width:52px;font-size:12.5px;font-weight:600;font-variant-numeric:tabular-nums;flex-shrink:0}
.prog-note{font-size:11.5px;color:var(--ink-3);margin-top:10px;line-height:1.7}
.prog-gap{display:inline-block;padding:1px 7px;border-radius:4px;font-weight:600;font-size:11.5px}
.prog-gap.bad{background:var(--danger-bg);color:var(--danger)}
.prog-gap.ok{background:var(--ok-bg);color:var(--ok)}
.prog-gap.mid{background:var(--warn-bg);color:var(--warn)}
.ms-key{color:var(--danger);font-weight:700;margin-left:4px}

/* ---------- 已归档项目标识 ---------- */
.archived-bar{
  background:linear-gradient(90deg,#eef3f8,#f8fafc);
  border-left:3px solid var(--ink-3);
  padding:12px 16px;font-size:13px;color:var(--ink-2);
  border-bottom:1px solid var(--line);
}
.archived-bar b{color:var(--ink)}
td.closed-note{
  max-width:22em;max-height:4.6em;overflow:hidden;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;
}

/* 资金一行 */
.fin-row{
  display:flex;background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);
  margin-bottom:16px;overflow:hidden;flex-wrap:wrap;
}
.fin-cell{flex:1;min-width:160px;padding:13px 18px;border-right:1px solid var(--line)}
.fin-cell:last-child{border-right:none}
.fin-cell .k{font-size:12px;color:var(--ink-3);margin-bottom:4px}
.fin-cell .v{font-size:19px;font-weight:700;font-variant-numeric:tabular-nums;letter-spacing:-.3px}
.fin-cell .d{font-size:11.5px;color:var(--ink-3);margin-top:3px}
.fin-cell.good .v{color:var(--ok)} .fin-cell.bad .v{color:var(--danger)}
/* 卡片内部的次级标签页（合同导入的「新建项目 / 挂到已有」）——
   去掉 .tabs 为整卡设计的内边距和圆角，只留下划线指示 */
.sub-tabs{padding:0;background:none;border-radius:0}
.sub-tabs button{padding:9px 2px;margin-right:22px;font-size:13.5px}

/* 预算明细：一级科目做成分组标题行，明细缩进挂在下面 */
.bgt-detail tbody tr{background:#fff}
.bgt-detail tr.grp td{
  background:var(--brand-soft); border-top:1px solid #d3e0ee;
  padding-top:9px; padding-bottom:9px;
}
.bgt-detail tr.grp b{color:var(--brand)}
.bgt-detail tr.sub td{color:var(--ink-2)}
.bgt-detail tr.sub:hover td{background:#f7fafd}
.bgt-detail tr.tot td{background:#f4f6f9;border-top:2px solid var(--line)}

/* 差异对照的提交区：整页唯一的写入动作，得让人看出它管的是全页 */
.submit-bar{
  display:flex; align-items:center; gap:18px; margin-top:18px;
  padding:14px 16px; background:var(--brand-soft);
  border:1px solid #d3e0ee; border-radius:var(--radius);
}
.submit-bar .sb-txt{flex:1; font-size:13px; line-height:1.6}
.submit-bar .btn{flex-shrink:0}
.submit-bar .btn[disabled]{opacity:.45; cursor:not-allowed}

/* 收款进度条：绿=已到账，橙=开票在途，红=逾期未收，灰=未到期 */
.recvbar .r1{background:var(--ok)}
.recvbar .r2{background:var(--warn)}
.recvbar .r3{background:var(--danger)}
/* 字色不在这里定——权重不够，见上面 `.lockbar .bar span.r0` */
.recvbar .r0{background:var(--free)}

/* 可钻取的 KPI：这块是项目总览，哪格不对劲点进去就是那件事的明细 */
.kpi.act{cursor:pointer}
.kpi.act:hover{
  border-color:var(--brand-2);
  box-shadow:0 2px 10px rgba(31,78,121,.12);
  transform:translateY(-1px);
}
.kpi.act .k::after{content:' ›';color:var(--ink-3);font-weight:400}
/* 正按这一格筛着。样式在下面 .kpi.on 那条——原来 .kpi.act 在这里和
   下面各定了一遍（cursor、hover 边框重复），已合并（D-031） */
.kpi.act:hover .k{color:var(--brand)}
.kpi.act:hover .k::after{color:var(--brand-2)}
.prog-bar i.recv{background:var(--ok)}

/* 一级科目行可展开明细 */
tr.cat-row{cursor:pointer}
tr.cat-row:hover td{background:var(--brand-soft)}
tr.cat-row .caret{color:var(--ink-3);margin:0 6px 0 7px;font-size:11px}
tr.cat-row:hover .caret{color:var(--brand)}
tr.sub-wrap td{background:#f7fafd;padding:0}
.sub-box{padding:12px 16px 14px 40px}
.sub-tbl{font-size:12.5px;background:#fff;border:1px solid var(--line);border-radius:6px}
.sub-tbl th{background:#f2f6fa;color:var(--ink-2);font-weight:600;padding:6px 10px}
.sub-tbl td{padding:6px 10px;border-bottom-color:var(--line)}

/* 页面内的取消按钮：白底浅灰，不跟主操作抢注意力 */
.btn.cancel{background:#fff;border-color:var(--line);color:var(--ink-2);margin-right:10px}
.btn.cancel:hover{background:#f5f7fa;border-color:var(--ink-3);color:var(--ink)}
/* 出错的提示停留更久，点一下可关掉 */
.toast{cursor:pointer}
.toast.err{max-width:min(560px,80vw);line-height:1.6}

/* 台账表：列数压到一屏放得下，长文本列换行而不是撑宽表格 */
.ledger-tbl{table-layout:fixed;width:100%}
.ledger-tbl td.wrap{white-space:normal;word-break:break-word}

/* 多行行的表：行与行之间必须一眼分得开（D-029）。
   通用的 td 分隔线是 #f0f3f7，那是给单行表配的；项目列表一行三行高、
   台账一行两行高，用那个颜色几行就糊成一片，看不出哪儿是一个项目的边界。
   这里提到 --line 并把行内边距拉开。合同台账的分组边界另有 2px 粗线
   （tbody.cg，在本文件后面），层级不会被这条抹平——它排在后面，会覆盖这条。 */

.ledger-tbl .t-sub{font-size:11.5px;color:var(--ink-3);line-height:1.5;margin-top:2px}

/* 数据导入：四个入口并列成宫格，解析结果在下面全宽展开 */
.imp-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}
@media(max-width:1100px){ .imp-grid{grid-template-columns:1fr} }
.imp-cell{
  border:1px solid var(--line); border-radius:var(--radius);
  padding:16px 18px 18px; background:#fff; transition:.15s;
  display:flex; flex-direction:column;
}
.imp-cell:hover{border-color:#c8d8e8; box-shadow:0 2px 10px rgba(16,32,48,.06)}
.imp-h{font-size:14.5px;font-weight:600;color:var(--ink);display:flex;align-items:center;gap:8px}
.imp-no{
  display:inline-flex;align-items:center;justify-content:center;
  width:22px;height:22px;border-radius:50%;background:var(--brand-soft);
  color:var(--brand);font-size:12px;font-weight:700;flex-shrink:0;
}
.imp-desc{font-size:12.5px;color:var(--ink-2);margin:7px 0 5px}
.imp-gain{font-size:12px;color:var(--ink-3);line-height:1.7;margin-bottom:12px;flex:1}
.imp-gain b{color:var(--brand);font-weight:600}
.imp-cell .drop{margin:0;padding:20px 12px;font-size:13px}

/* 合同导入预览：点了「删行」的分期行（D-086）。置灰划线但留在原地——
   真移走的话手一抖点错只能整个重新上传；保存时才真正跳过这些行 */
tr.term-del td{opacity:.45}
tr.term-del input{text-decoration:line-through}

/* ================= 新驾驶舱 ================= */
.dash{display:flex;flex-direction:column;gap:16px}

/* 状态条：分类统计压成一行，它是导航不是概览 */
.dash-bar{
  display:flex;align-items:center;gap:18px;flex-wrap:wrap;
  background:var(--brand);color:#fff;border-radius:var(--radius);
  padding:13px 20px;box-shadow:var(--shadow);
}
.dash-bar-l{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.dash-bar-r{display:flex;align-items:center;gap:22px;margin-left:auto;flex-wrap:wrap}
.dash-total{font-size:13px;opacity:.85;margin-right:4px}
.dash-total b{font-size:19px;font-weight:700;margin-right:3px}
.dash-chip{
  display:inline-flex;align-items:center;gap:5px;font-size:12.5px;
  color:rgba(255,255,255,.9);background:rgba(255,255,255,.14);
  padding:3px 9px;border-radius:20px;transition:.15s;
}
.dash-chip:hover{background:rgba(255,255,255,.28);color:#fff}
.dash-chip b{font-weight:700}
.dash-chip.dim{opacity:.72;font-weight:400}
.dash-chip.dim:hover{opacity:1}
/* 三组 chip 答的是三个不同的问题（干到哪一步了 / 我们是什么角色 / 卡在哪个阶段），
   分隔太淡就会被读成平级的一排，于是「进行中 6」和「乙方·承接 6」被当成两批项目
   ——其实是同一批项目数了两遍（D-094）。加深不加粗，同表格分界线那条。 */
.dash-sep{width:1px;height:18px;background:rgba(255,255,255,.38);margin:0 5px}
/* 组前缀：只给阶段那组用（D-094）。比 chip 轻一档，它是标签不是可点的分类 */
.dash-glab{font-size:11.5px;color:rgba(255,255,255,.62);margin-right:1px}
/* 计数为 0 的分类：摆出来，但不可点——点进去是空列表，那不叫导航 */
.dash-chip.zero{background:none;color:rgba(255,255,255,.45);cursor:default;padding:3px 3px}
.dash-chip.zero b{font-weight:600}
.dash-fin{display:flex;flex-direction:column;line-height:1.3}
.dash-fin i{font-size:11px;opacity:.75;font-style:normal;transition:.15s}
.dash-fin i:hover{opacity:1}
.dash-fin b{font-size:16px;font-weight:700;margin:1px 0}
/* 副标题：这一排最容易被读错，一格一句说清它是什么钱。
   不做成 hover 才显示——靠悬停才看得见的信息等于默认不存在（D-053）。 */
.dash-fin em{font-size:10.5px;font-style:normal;opacity:.68;letter-spacing:.2px}
.dash-fin b.good{color:#7ee2b8} .dash-fin b.bad{color:#ffb4ab} .dash-fin b.warn{color:#ffd48a}
/* 深色条上的术语链接：.tref 那套品牌蓝是给浅底配的，这里跟着白字走 */
.dash-fin .tref{color:inherit;border-bottom-color:rgba(255,255,255,.5)}
.dash-fin .tref:hover{color:#fff;border-bottom-color:#fff}
/* 分隔两组数（能花多少 | 收回来多少），比左侧那道分类分隔高，够着三行 */
.dash-sep.tall{height:36px;margin:0 4px;background:rgba(255,255,255,.38)}

.dash-card{background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow)}
.dash-h{display:flex;align-items:center;gap:12px;padding:14px 20px;border-bottom:1px solid var(--line)}
.dash-h h2{font-size:15px;font-weight:600}
.dash-h .sub{font-size:12.5px;color:var(--ink-3)}
.dash-b{padding:6px 20px 16px}
.dash-clear{padding:22px 0;text-align:center;color:var(--ok);font-size:13.5px}

/* 待办：左边时间、中间事项、右边直接能点的动作 */
/* 待办列表：用台账那张 ledger-tbl，只补一个「到期」药丸和操作列的按钮排布。
   原来是自定义 flex 行，金额/对方单位/约定日期全塞在一行小灰字里——
   那三样恰恰是要动手时最需要看清的（D-022）。 */
.todo-when{
  display:inline-block;min-width:74px;text-align:center;
  font-size:12px;padding:3px 7px;border-radius:5px;
  background:#eef2f6;color:var(--ink-2);white-space:nowrap;
}
.todo-when.over{background:var(--danger-bg);color:var(--danger);font-weight:600}
.todo-when.soon{background:var(--warn-bg);color:var(--warn);font-weight:600}
#todotbl td{vertical-align:middle}
#todotbl .t-name{font-weight:600;line-height:1.45}
/* 「合同到期」为什么在这儿：履行期过了多久、状态还挂着什么、还差多少没了结。
   它跟同一份合同的收付款条目长得几乎一样（合同名、对方单位都一样），
   不写清楚就只剩两个对不上的数（D-023）。 */
#todotbl .todo-why{margin-top:3px;color:var(--ink-2)}

/* 往来款（保证金/押金）行：整行铺橙红底 + 橙红左条。
   别的逾期至少还挂在合同分期上、有台账有对方催；保证金没人催就真没了，
   所以它值得比「逾期 202 天的应收款」更扎眼。 */
tr.row-owe > td{background:var(--owe-bg)}
tr.row-owe:hover > td{background:var(--owe-bg2)}
.ledger-tbl tr.row-owe > td:first-child{border-left:5px solid var(--owe)}
tr.row-owe .todo-when{background:var(--owe);color:#fff;font-weight:600}
tr.row-owe .tag.gray{background:var(--owe-bg2);color:var(--owe);font-weight:600}
#todotbl .todo-why b{color:var(--danger);font-weight:600}
.dash-act{display:flex;gap:6px;justify-content:flex-end}
.dash-more{padding:10px 0 2px;font-size:12.5px}

/* 风险：只列有问题的 */
.dash-risk{
  display:flex;align-items:center;gap:10px;padding:11px 0;cursor:pointer;
  border-bottom:1px solid #f1f4f8;font-size:13px;
}
.dash-risk:last-child{border-bottom:none}
.dash-risk:hover b{color:var(--brand)}
.dash-risk .dash-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
.dash-risk.danger .dash-dot{background:var(--danger)}
.dash-risk.warn .dash-dot{background:var(--warn)}
.dash-risk.info .dash-dot{background:var(--ink-3)}
.dash-risk b{flex-shrink:0;max-width:34%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dash-risk span:not(.dash-dot):not(.dash-go){color:var(--ink-2)}
.dash-risk .dash-go{margin-left:auto;color:var(--ink-3)}

/* 项目卡：驾驶舱与项目页共用 .pcard（同一个项目两处必须长得一样、讲同样的话）。
   两处唯一的差别是这里：项目页的卡浮在底色上，用阴影；驾驶舱的卡嵌在「项目」那张卡里，
   再叠一层阴影就成了卡中卡，改用描边。
   顶边不能碰——那 3px 是 D-017 的风险配色（红＝要人管、绿＝干完没事）。
   所以**不能用 border 简写**：简写会把顶边颜色一起设成灰，四张卡全变灰，
   等于把问题藏起来。只描另外三边。 */
.dash-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:14px;padding-top:10px}
.dash-grid .pcard{box-shadow:none;
  border-left:1px solid var(--line);border-right:1px solid var(--line);
  border-bottom:1px solid var(--line)}
.dash-grid .pcard:hover{transform:none;box-shadow:0 2px 10px rgba(16,32,48,.08);
  border-left-color:var(--brand-2);border-right-color:var(--brand-2);
  border-bottom-color:var(--brand-2)}


.pne-item{border:1px solid var(--line);border-radius:8px;padding:12px 14px;margin-bottom:10px;background:#fbfcfd}
.pne-h{display:flex;align-items:center;gap:8px;cursor:pointer;margin-bottom:8px}
.pne-t{border-collapse:collapse;margin-top:4px}
.pne-t td{padding:3px 10px 3px 0;border:0}

/* ---- 台账按项目分组（文件库 / 支出 / 收款共用一套） ----
   一开始只有文件库分组，类名叫 doc-g*；支出、收款台账要收成同样的形状时，
   要么再写一套、要么把它提成通用的。提成 lgrp（ledger group）——
   同一件事两处定义，迟早各自漂移（D-031 刚吃过一次）。 */
/* 组间那条线由「上一组最后一行的下边框」画（限定 last-of-type 之后它回来了）。
   这里再补一条 border-top 就是双线——原来需要它，是因为那时每组最后一行的线
   被上面那条通用规则吃掉了。病根治好，这剂药就得停。 */
.lgrp-h{background:#f6f8fa}
.lgrp-h:hover{background:#eef2f6}
.lgrp-h td{padding:var(--row-pad-h) 12px !important;white-space:nowrap;overflow:hidden}
/* 折叠机制本身：只管「收起来」，不管长什么样。
   台账按项目折（.lgrp）、预算按科目折（.bgrp），皮不同、机制同一套——
   各写一套的话，「筛过要自动展开」这类规矩就得记两遍（D-022 吃过亏）。 */
tbody.fold > tr:not(.fold-h){display:none !important}
.fold-h{cursor:pointer}
/* 折叠箭头做成一枚带底色的小方块（D-041）。
   原来是一个 --ink-3 的裸字符，在一行加粗项目名旁边基本看不见——
   而它是这一行唯一可点的东西，最该被看见的反倒最淡。
   **颜色跟着这一组的收付方向走**（支出橙 / 收款蓝），跟左边那道色条、
   「收/付」标签是同一套语言：钱进来蓝、钱出去橙（D-003）。 */
.fold-arrow{
  display:inline-flex; align-items:center; justify-content:center;
  width:19px; height:19px; margin-right:7px; vertical-align:-4px;
  border-radius:5px; background:#e3ebf4; color:var(--brand);
  font-size:10.5px; line-height:1; font-weight:700;
  transition:transform .14s, background .14s, color .14s;
}
/* 没有子行的那些占位空箭头不能露出底色，否则平白多出一排空方块
   （九大项里有四项没有二级明细，见 D-036 的占位规则） */
.fold-arrow:empty{background:none}
tbody.fold .fold-arrow{transform:rotate(-90deg)}
tbody.lgrp-out .fold-arrow{background:#fae3cd;color:#b3651a}
tbody.lgrp-in  .fold-arrow{background:#d9e6f4;color:#255d94}
.fold-h:hover .fold-arrow{background:var(--brand);color:#fff}
tbody.lgrp-out .fold-h:hover .fold-arrow{background:#d9822b;color:#fff}
tbody.lgrp-in  .fold-h:hover .fold-arrow{background:#2f6ba8;color:#fff}
.lgrp-h b{font-size:14px}
.lgrp-code{margin-left:8px;color:var(--ink-3);font-size:12px;font-variant-numeric:tabular-nums}
.lgrp-num{margin-left:14px;color:var(--ink-2);font-size:12px}
/* 「17 / 31 笔」——正筛着，下面不是这一组的全部。染成主色，
   因为组头右边那串数还是项目全量，得让人一眼看出两者不同口径。 */
.lgrp-num.part{color:var(--brand-2);font-weight:600}
.lgrp-tags{margin-left:14px}
.lgrp-tags .tag{margin-right:4px}
.lgrp-go{float:right;font-size:12px;color:var(--brand);text-decoration:none}
.lgrp-go:hover{text-decoration:underline}
/* 左侧色条：钱进来＝蓝、钱出去＝橙，与合同台账（tbody.cg-in/out）同一套语言。
   条子铺在 tbody 上而不是逐行加类——组头和它下面的每一笔连成一道竖线，
   折起来时那道色条就是这一组还在的凭据。
   文件库的组没有方向，不套这两个类，也就不会平白多出 5px 缩进。 */
tbody.lgrp-out > tr > td:first-child{border-left:5px solid #d9822b}
tbody.lgrp-in  > tr > td:first-child{border-left:5px solid #2f6ba8}

/* 预算执行表：按一级科目折叠。科目行本来就有自己的底色（超支染红、
   零预算染红），所以不套台账那层灰底，只加箭头和指针——
   给它再铺一层灰会把「这一行超支了」这个更要紧的信号盖掉。 */
tbody.bgrp > tr.fold-h > td:first-child{font-weight:600}
tbody.bgrp.fold > tr.fold-h > td{opacity:.92}

/* 组头右侧的执行情况：这一串是「已付 / 另有已签未付 / 预算 / 执行率」，
   金额要能上下对齐扫下来，所以走等宽数字。 */
.lgrp-exec{float:right;font-size:12px;color:var(--ink-2);font-variant-numeric:tabular-nums}
.lgrp-exec b{font-size:12px;font-weight:600;color:var(--ink-1)}
.lgrp-exec .sep{margin:0 9px;color:var(--line-2)}
.lgrp-exec a{color:var(--brand);text-decoration:none}
.lgrp-exec a:hover{text-decoration:underline}
/* 组头一行里左边是项目名、右边是执行情况，中间不留浮动塌陷 */
.lgrp-h td::after{content:'';display:block;clear:both}
/* 日期列：日期绝不折行（「2026-08-」换行到「01」看着像两个字段）。
   td.wrap 的 14em 下限对这一列太宽，这里不套 wrap，单独定。 */
.ledger-tbl td.lgrp-d{min-width:0;white-space:nowrap;font-variant-numeric:tabular-nums}

/* ---------- 合同分组：一份合同占三行，得让人一眼看出边界在哪 ----------
   原来主行、OA 行、期次行的下边框粗细完全一样，于是「一份合同内部的换行」
   和「换了一份合同」看起来是同一级边界——密度够了，层级没了。
   一份合同包成一个 tbody（与文件库的 tbody.lgrp 同一套路），
   组内不画线、组间画粗线、左侧色条把三行绑成一块、悬停整组一起亮。 */
tbody.cg > tr > td{border-bottom:none}
tbody.cg + tbody.cg > tr:first-child > td{border-top:2px solid var(--line)}
tbody.cg > tr.cg-head > td{padding-top:13px}
tbody.cg > tr.cg-sub > td{background:#f8fafc;padding:5px 12px 5px 34px}
tbody.cg > tr:last-child > td{padding-bottom:12px}
/* 左侧色条：收入侧蓝、支出侧橙，与「收/付」标签同色，整组连成一道竖线 */
tbody.cg > tr > td:first-child{border-left:5px solid transparent}
tbody.cg-in  > tr > td:first-child{border-left-color:#2f6ba8}
tbody.cg-out > tr > td:first-child{border-left-color:#d9822b}
/* 悬停整组一起亮：只亮一行会让三行看着像三份不同的东西 */
tbody.cg:hover > tr > td{background:#f4f8fc}

/* 合同表：长文本列给上限并允许折行，否则合同名一行 428px，
   整表 1610px 塞进 1200px 的容器，「操作」列直接被切掉。 */
.ctr-tbl td.t-name.wrap{min-width:15em;max-width:22em}
.ctr-tbl td.wrap{min-width:8em;max-width:14em}
.ctr-tbl th,.ctr-tbl td{padding-left:10px;padding-right:10px}

/* ---------- 台账行：让「合同名」当主角 ----------
   副行的项目名常与合同名前二十字雷同，原来还染成链接蓝，
   比正题更抢眼；七行里五行如此，整页就糊成一片。 */
.ledger-tbl .sub-k,.list-tbl .sub-k{
  display:inline-block;margin-right:5px;padding:0 5px;border-radius:3px;
  background:#eef2f7;color:var(--ink-3);font-size:10.5px;
}
.ledger-tbl a.sub-link,.list-tbl a.sub-link{color:var(--ink-2);text-decoration:none}
.ledger-tbl a.sub-link:hover,.list-tbl a.sub-link:hover{color:var(--brand-2);text-decoration:underline}
.ledger-tbl .t-name,.list-tbl .t-name{font-weight:600;color:var(--ink);line-height:1.45}
/* 已结清的「未了结」压灰——非零的才是要盯的 */
.ledger-tbl td.num.zero,.list-tbl td.num.zero{color:var(--ink-3)}
/* 左侧色条：与项目页合同分组同一套语言，收入蓝、支出橙，扫一眼就分得开收付 */
.ledger-tbl tr.dir-in > td:first-child,.list-tbl tr.dir-in > td:first-child{border-left:5px solid #2f6ba8}
.ledger-tbl tr.dir-out > td:first-child,.list-tbl tr.dir-out > td:first-child{border-left:5px solid #d9822b}
/* 合同台账列多，窗口一窄「对方单位」会被压成一字一行——
   中文逐字竖排比左右拖难读得多，所以到底线就退回横向滚动。 */
.lt-contract{min-width:1120px}

/* ---------- 可排序表头 ----------
   静止时给一个淡淡的双箭头示意「这里能点」，排序后换成实心单箭头并染主色。
   「操作」列不参与（装的是按钮，没有可比较的值）。 */
table.sortable thead th:not(.nosort){cursor:pointer;user-select:none;position:relative;padding-right:19px}
table.sortable thead th:not(.nosort)::after{
  content:'⇅';position:absolute;right:6px;top:50%;transform:translateY(-50%);
  /* 默认压到 .25：十列各挂一个 ⇅，常亮时比列名还抢眼。
     hover 到那一列才亮起来——需要它的时候它在，不需要时不吵。 */
  font-size:10.5px;color:var(--ink-3);opacity:.25;
}
table.sortable thead th:not(.nosort):hover{background:#dfe9f5;color:var(--brand)}
table.sortable thead th:not(.nosort):hover::after{opacity:.75}
table.sortable thead th.sort-asc::after{content:'↑';opacity:1;color:var(--brand);font-weight:700}
table.sortable thead th.sort-desc::after{content:'↓';opacity:1;color:var(--brand);font-weight:700}

/* KPI 卡按收付方向配色，与表格左色条、「收/付」标签同一套语言：
   客户＝我们收钱＝蓝，供应商＝我们付钱＝橙。
   四格全是同一种深蓝时，「客户 5 家」和「供应商 2 家」看着是一类东西。 */
.kpi.in{border-left-color:#4a90c2}  .kpi.in .v{color:#1a6aab}
.kpi.out{border-left-color:#e8b06a} .kpi.out .v{color:#b5541f}

/* 「两者」既是客户又是供应商，色条用中性灰，不硬塞进收/付二选一 */
.list-tbl tr.dir-both > td:first-child{border-left:5px solid #8b99a8}
/* 被点亮的 KPI 卡：告诉用户「现在按这一格筛着」 */
.kpi.on{background:var(--brand-soft);border-color:var(--brand-2)}

/* 抬头统计：数字加重、文字压灰，「共 7 条 / 合计 469 万」里真正要读的是数字 */
.card-h .sub b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}

/* ---------- 段式切换按钮（方块 / 列表）----------
   两个选项连成一体、选中的填实，一眼看出「现在是哪个、还能切到哪个」；
   做成两个独立按钮的话，看着像两个动作，而不是一个二选一。 */
.segbtn{display:inline-flex;border:1px solid var(--brand-2);border-radius:7px;overflow:hidden;height:38px}
.segbtn button{
  border:0;background:#fff;color:var(--brand);font-size:13px;font-weight:500;
  padding:0 14px;height:100%;cursor:pointer;white-space:nowrap;
}
.segbtn button+button{border-left:1px solid var(--brand-2)}
.segbtn button:hover{background:var(--brand-soft);color:var(--brand)}
.segbtn button.on{background:var(--brand);color:#fff;font-weight:600}
/* 项目一览 11 列，「项目名称」带了委托方/负责人副行后独占 388px，
   把表撑出容器——给它上限并允许折行。 */
.list-tbl td.wrap{min-width:13em;max-width:20em}

/* 表头也带一段中性色条，让左边这条彩色带从表头一直贯到最后一行，
   不然色条从第二行才开始，看着像没对齐。 */
.ledger-tbl thead th:first-child,.list-tbl thead th:first-child{border-left:5px solid #c8d4e2}

/* ---------- 项目卡片拖拽排序 ----------
   抓手平时淡、hover 才显——不能让它抢了卡片内容的注意力，
   但也不能藏到人找不着「原来这儿能拖」。 */
.pcard{position:relative}
.pcard .grip{
  position:absolute; top:10px; right:10px; cursor:grab;
  color:var(--ink-3); opacity:0; transition:.15s; font-size:15px; line-height:1;
  letter-spacing:-2px; user-select:none;
}
.pcard:hover .grip{opacity:.55}
.pcard .grip:hover{opacity:1;color:var(--brand)}
.pcard .grip:active{cursor:grabbing}
/* 被拖起来的那张压暗，让人看清自己在搬哪一个 */
.pcard.dragging{opacity:.4;border-style:dashed}
/* 落点提示：在目标卡的左边或右边画一道主色竖线 */
.pcard.drop-before{box-shadow:-3px 0 0 0 var(--brand)}
.pcard.drop-after{box-shadow:3px 0 0 0 var(--brand)}

/* 台账组头上的「来源 / 更新时间」（D-052，布局见 D-053）。
   压到最灰最小：它是排错时才去看的元数据，平时不该跟金额抢注意力，
   但必须一直在——出处只有在数据可疑时才被想起，那时候再去翻库就晚了。

   **单独成块、`clear:both` 落到浮动的执行数据下面**：原来跟
   `.lgrp-exec`（float:right）挤同一行，长文件名一来就互相撞，
   只能把来源掐短——而掐掉的正是「是哪一版」这个排错时唯一有用的后半截。
   来源与更新各占一行（`.l`），组头因此长到三行，这是用户要的「增加行宽」。 */
.lgrp-src{display:block;clear:both;margin:6px 0 0;padding-top:6px;
          border-top:1px dashed var(--line);
          color:var(--ink-3);font-size:11.5px;line-height:1.7;
          white-space:normal;font-variant-numeric:tabular-nums}
.lgrp-src .l{display:block}
/* 「来源」「更新」两个词当标签用：加重但不加色，让后面的值读起来是值 */
.lgrp-src b{font-weight:600;color:var(--ink-2);font-size:11px;
            letter-spacing:.3px}

/* 支出页顶部的「还能花多少」条（D-056）。
   它不是告警（多数时候一切正常），所以默认走中性的品牌浅底；
   真出了超支或预算外支出才转红。**放在页首**——
   决定「要不要再花这笔」之前就该看见它，而不是翻到底再去切页签。 */
.exp-strip{background:var(--brand-soft);border:1px solid #d6e3f0;
           border-left:3px solid var(--brand);border-radius:7px;
           padding:11px 14px;margin-bottom:16px;font-size:13px}
.exp-strip.bad{background:var(--danger-bg);border-color:#f0c4bf;
               border-left-color:var(--danger)}
.exp-strip .l1{font-variant-numeric:tabular-nums}
.exp-strip .l2{margin-top:5px;color:var(--ink-2);font-size:12.5px;
               font-variant-numeric:tabular-nums}
.exp-strip .mini{color:var(--ink-3);font-size:11.5px;margin-left:2px}

/* 全量台账的数据体检条（D-057）。压成一行灰字：它是「顺便说一声」，
   不是告警——缺收款方不影响算账，但攒到一定数量就该补。
   全齐时转绿说一句「都齐了」，不留空：空着看不出是没问题还是没检查。 */
.flow-q{margin:2px 0 12px;font-size:12.5px;color:var(--ink-2);
        font-variant-numeric:tabular-nums}
.flow-q a{color:var(--brand-2);text-decoration:none;border-bottom:1px dashed #b9cde0}
.flow-q a:hover{color:var(--brand);border-bottom-style:solid}
.flow-q .mini{color:var(--ink-3);font-size:11.5px}
.flow-q.ok{color:var(--ok)}

/* 行内链接文字。`.lnk` 一直被上传区的「选择文件」用着，却从来没定义过
   ——那两处至今是黑色正文字，看不出可以点。 */
.lnk{color:var(--brand-2);cursor:pointer;text-decoration:none;
     border-bottom:1px dashed #b9cde0}
.lnk:hover{color:var(--brand);border-bottom-style:solid}

/* ---------- 文件库：归档原件的全文检索（D-059） ----------
   摆在筛选条和表格之间。位置是有讲究的：它回答的是
   「上面那张表里没找到，是不是就真没有」——摆到表格下面就等于没人看见。 */
.ftr{margin:2px 0 14px}
/* 词换了、新结果还没到：旧的命中卡先褪掉。延迟 .18s 起效，
   本地检索通常在那之前就回来了，不会平白闪一下。 */
.ftr-stale{opacity:.4;transition:opacity .12s .18s}
/* 覆盖率那一行。压成一行灰字：跟数据体检条（.flow-q）同一个语气——
   它是「顺便交代一句我搜过哪些」，不是告警。 */
.ftr-cov{color:var(--ink-2);font-size:12.5px;margin:6px 0 0;
         font-variant-numeric:tabular-nums}
.ftr-cov b{color:var(--ink)}
.ftr-h{font-size:13px;color:var(--ink);font-weight:600;margin:2px 0 8px}
.ftr-h b{color:var(--brand)}
.ftr-h .sub-k{font-weight:400;color:var(--ink-3);font-size:12px;margin-left:8px}
.ftr-none{font-weight:400;color:var(--ink-2)}
/* 命中卡。左边框走品牌蓝——文件库的组没有收付方向，
   不套 --owe / lgrp-in/out 那套语言（D-032）。 */
.ftr-c{background:var(--brand-soft);border:1px solid #d6e3f0;
       border-left:3px solid var(--brand);border-radius:7px;
       padding:10px 13px;margin-bottom:8px}
.ftr-c-h{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.ftr-c-h b{font-size:13px;color:var(--ink)}
.ftr-c-f{color:var(--ink-3);font-size:11.5px;margin-top:3px;
         display:flex;align-items:baseline;gap:12px}
.ftr-c-fn{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ftr-lossy{margin-left:8px;color:var(--warn)}
/* 归档件的三个动作（打开原件 / 看正文 / 下载一份），**全系统同一套**：
   文件库表格、项目页文件留痕、合同详情页的附件、全文命中卡。
   **用文字链接不用按钮**：三个按钮要 176×40，摆进表格会把行顶高一半（同 D-036），
   而这三件事都是「顺手点一下」，不该有按钮那种视觉分量。
   命中卡里它挤在文件名行右端（那儿有的是宽度），表格里另起一行
   ——挤同一行的话文件名只剩 244px，而「…合同(3).docx」被截掉的
   正是排错时唯一有用的那半截（D-053：挤不下先想换行，别先想截断）。 */
.doc-acts{display:flex;gap:14px;white-space:nowrap;font-size:12px;margin-top:5px}
/* 命中卡里跟文件名同行，不要那 5px 上边距 */
.ftr-c-f .doc-acts{margin-top:0}
/* 不能打开的类型（压缩包、可执行文件）：位置留着但不可点，
   免得同一列里有的三个动作、有的两个，看着像漏渲染了 */
.lnk.off{color:var(--ink-3);cursor:default;border-bottom-style:dotted}
.lnk.off:hover{color:var(--ink-3);border-bottom-style:dotted}

/* 「看正文」面板：正文本来就在库里，看一眼犯不上启动 Word，更犯不上下载。 */
.dtx-meta{color:var(--ink-3);margin-bottom:8px;word-break:break-all}
.dtx-meta .sub-k{margin-left:10px;color:var(--ink-3)}
.dtx-note{background:var(--brand-soft);border-left:3px solid var(--brand-2);
          border-radius:0 5px 5px 0;padding:7px 11px;margin-bottom:12px;
          color:var(--ink-2);line-height:1.7}
.dtx-note b{color:var(--ink)}
/* pre-wrap：抽出来的正文靠换行分段，用普通段落会糊成一大块。
   不用等宽字体——正文是中文，等宽只会让它更难读。 */
.dtx-body{white-space:pre-wrap;word-break:break-word;font-size:13px;
          line-height:1.9;color:var(--ink)}
.dtx-body mark{background:var(--warn-bg);color:var(--ink);font-weight:600;
               padding:0 2px;border-radius:3px}
.ftr-n{color:var(--ink-3);font-size:11.5px}
.ftr-go{margin-left:auto;font-size:12px;white-space:nowrap}
/* 片段：命中行是主角，上下文行退成灰的——两行同色的话，
   人还得自己找哪一行才是命中的那行。 */
.ftr-s{margin:8px 0 0;padding:7px 10px;background:var(--card);
       border-radius:5px;font-size:12.5px;line-height:1.75}
/* 命中行最多折两行，上下文行永远一行。**一格把整块顶高是这里最实际的风险**
   （同 D-036 的执行率格）：合同一条款项两百多字，原样铺开一张卡就半屏，
   下面的表格被推出视口——检索结果反倒把「这个词在不在表里」这件事挡住了。 */
.ftr-s-hit{color:var(--ink);display:-webkit-box;-webkit-line-clamp:2;
           -webkit-box-orient:vertical;overflow:hidden}
.ftr-s-ctx{color:var(--ink-3);white-space:nowrap;overflow:hidden;
           text-overflow:ellipsis}
.ftr-s mark{background:var(--warn-bg);color:var(--ink);font-weight:600;
            padding:0 2px;border-radius:3px}
/* 读不出内容的清单。默认收着——它是「点开看是哪几个」，
   平时占一行字说清有几个就够了。 */
.ftr-miss{background:var(--card);border:1px solid var(--line);
          border-radius:7px;padding:8px 12px;margin-top:7px}
.ftr-miss-r{padding:7px 0;border-bottom:1px solid var(--line)}
.ftr-miss-r:last-child{border-bottom:none}
.ftr-miss-r b{font-size:12.5px;color:var(--ink);margin-left:5px}
.ftr-miss-r .sub-k{color:var(--ink-3);font-size:11.5px;margin-left:8px}


/* ---------- 可折叠区块（D-062）----------
   合同详情页从「本合同的文件」往下有五六块，一屏放不下、要一路滚到底。
   **跟 D-035 那套折叠不是一回事**：那套折的是表格里的行（`tbody.fold`），
   这里折的是整个区块（标题 + 按钮 + 表格）——对象不同，套不上。
   但**交互语言必须一样**：同一个 `.fold-arrow` 方块、点标题行折叠、
   一对「全部展开 / 全部折叠」，鼠标悬停时箭头反白也照旧继承 `.fold-h:hover`。 */
.sec-row{margin:2px 0 12px}
.fcard .sec-row{cursor:pointer;user-select:none;border-radius:6px;
                transition:background .12s}
.fcard .sec-row:hover{background:var(--brand-soft)}
.fcard.folded .fold-body{display:none}
.fcard.folded .fold-arrow{transform:rotate(-90deg)}
/* 折起来之后标题下面那 12px 就成了白边，跟卡片内边距叠一块儿显得空 */
.fcard.folded .sec-row{margin-bottom:0}
/* 页签里的可折叠区块（D-067）。跟 .fcard 共用全部折叠样式，只是**不套卡片外观**
   ——它本来就在一张卡的 .card-b 里，再包一层就成了卡中卡。
   区块之间的间距由它自己给，原来那几个 <div style="height:26px"> 已删：
   折起来的时候那种硬间隔留不下来，会让两条折叠标题贴在一起。 */
.fsec{margin-bottom:26px}
.fsec:last-child{margin-bottom:0}
/* 折叠时也要看得出这块有没有东西、有多少——**折叠是浓缩不是消失**
   （同文件库组头折起来仍报「7 个文件 · 777KB」）。跟 .lgrp-num 一个样子。 */
.fold-num{margin-left:14px;color:var(--ink-2);font-size:12px;
          font-variant-numeric:tabular-nums}
/* ---------- 「全部展开 / 全部折叠」（D-074）----------
   用户反馈「太不显眼，看着费劲，找不到」。原来是两个 .btn sm，
   跟旁边一排「＋ 登记 xx」的深蓝实心主按钮并排——**浅灰描边的它们在视觉
   重量上排最后一位，而它管的范围其实最大**（整页所有区块，那几个按钮各自只管一块）。

   改成一个带标签的分段控件：① 标签说清管的是什么（「本页区块」），
   原来两个光秃秃的按钮没说清折的是谁；② 给箭头图标，跟区块标题上那个
   折叠箭头同一套语言（▾ 展开 / ▸ 收起）；③ 淡蓝渐变底 + 细边 + 投影，
   一眼能认出这是一组开关，而不是两个孤立的次要按钮。 */
.cfold-bar{margin:-2px 0 14px}
.cfold-lab{font-size:12px;color:var(--ink-3);margin-right:2px}
.cfold-grp{
  display:inline-flex;border:1px solid #c3d2e4;border-radius:8px;overflow:hidden;
  box-shadow:0 1px 3px rgba(31,78,121,.12);
}
.cfold-grp button{
  border:none;background:linear-gradient(180deg,#fff 0%,#edf2f9 100%);
  color:var(--brand);font-size:12.5px;font-weight:600;padding:7px 13px;
  display:inline-flex;align-items:center;gap:5px;white-space:nowrap;transition:.15s;
}
.cfold-grp button+button{border-left:1px solid #c3d2e4}
.cfold-grp button:hover{background:var(--brand);color:#fff}
.cfold-grp .ico{font-size:10px;line-height:1}

/* ---------- 待办钻取的落点高亮（D-063）----------
   从驾驶舱待办点「看合同 / 看往来款」跳过来时，标出「你点的就是这一条」。
   **用描边不用底色**：底色那一层已经被占满了——隔行 `--zebra` 在 tr 上、
   `row-owe`（保证金那笔钱挂在外面，D-027）与 `dir-in/out` 在 td 上，
   再铺一层就会把「这笔钱没收回」的橙红盖掉，那正是它最该被看见的时候。
   描边走 inset box-shadow：不占位、不撑行高，跟 `border-left` 那条色条也不抢。 */
tr.hl-row > td{box-shadow:inset 0 2px 0 var(--brand-2),inset 0 -2px 0 var(--brand-2)}
tr.hl-row > td:first-child{box-shadow:inset 0 2px 0 var(--brand-2),
  inset 0 -2px 0 var(--brand-2),inset 3px 0 0 var(--brand-2)}
tr.hl-row > td:last-child{box-shadow:inset 0 2px 0 var(--brand-2),
  inset 0 -2px 0 var(--brand-2),inset -3px 0 0 var(--brand-2)}
/* 质保金那条待办落到的是整个区块（它没有表格行可指），描整块 */
.fcard.hl-card{box-shadow:0 0 0 2px var(--brand-2),var(--shadow)}

/* 待办副行里的项目名是**真链接**（D-063）：行和行尾按钮都指「这一条待办」，
   要看项目就走这里。样式压住不抢——它是副行里的一个去处，不是这一行的主角。 */
.sub-lnk{color:var(--ink-2);text-decoration:none;border-bottom:1px dotted var(--ink-3)}
.sub-lnk:hover{color:var(--brand-2);border-bottom-color:var(--brand-2)}

/* ---------- 登录与改密（网络版 A1）----------
   全屏层盖住整个系统（含顶栏，z-index 在弹窗 .mask 200 之上、toast 999 之下），
   顶部一条品牌色带接着系统顶栏的颜色，卡片落在色带与底色的交界上——
   跟系统里的卡片是同一套外观（白底、圆角、左侧 3px 品牌色竖条标题），
   登录进去不会觉得换了一个系统。红色只给出错那一行（.alert.danger）。 */
body.auth-on{overflow:hidden}
.authv{position:fixed;inset:0;z-index:300;background:var(--bg);overflow-y:auto}
.authv::before{content:'';position:absolute;left:0;right:0;top:0;height:250px;
  background:linear-gradient(180deg,var(--brand) 0%,var(--brand-2) 100%)}
.auth-wrap{position:relative;max-width:420px;margin:70px auto 40px;padding:0 20px}
.auth-head{color:#fff;text-align:center;margin-bottom:22px}
.auth-org{font-size:13px;opacity:.85;letter-spacing:2px}
.auth-sys{font-size:24px;font-weight:700;letter-spacing:2px;margin-top:6px}
.auth-card{background:#fff;border-radius:12px;padding:26px 28px 22px;
  box-shadow:0 12px 32px rgba(16,32,48,.14);display:flex;flex-direction:column;gap:14px}
.auth-card h2{font-size:16px;font-weight:600;display:flex;align-items:center;gap:8px}
.auth-card h2::before{content:'';width:3px;height:15px;background:var(--brand);border-radius:2px}
.auth-card .alert{margin:0}
.auth-rm{font-size:13px;color:var(--ink);display:flex;gap:7px;align-items:baseline;cursor:pointer}
.auth-rm input{align-self:center;flex-shrink:0}
.auth-rm b{font-weight:400;white-space:nowrap;flex-shrink:0}   /* 不许被说明挤成两行 */
.auth-rm span{color:var(--ink-3);font-size:12px}
.auth-go{justify-content:center;padding:10px 14px;font-size:14px}
.auth-go:disabled{opacity:.7;cursor:default}
.auth-lead{font-size:13px;color:var(--ink-2)}
.auth-rule{font-size:12px;color:var(--ink-2);background:var(--brand-soft);border-radius:6px;padding:8px 10px}
.auth-foot{font-size:12px;color:var(--ink-3);text-align:center}
.auth-foot a{cursor:pointer}

/* 顶栏右侧「当前用户 · 退出」。竖线与 .logo 右边那条同一种写法，把它和动作按钮分开 */
.ubox{display:flex;align-items:center;gap:12px;flex-shrink:0;color:#fff;font-size:13px;
  padding-left:16px;border-left:1px solid rgba(255,255,255,.22);white-space:nowrap}
.ubox:empty{display:none}
.ubox{position:relative}
.ubox .ub-name{font-family:inherit;font-size:13px;font-weight:600;color:#fff;cursor:pointer;padding:6px 8px;border-radius:6px;
  background:none;border:0}
.ubox .ub-name:hover{background:rgba(255,255,255,.12)}
.ubox .ub-caret{font-size:10px;opacity:.8}
/* 账号菜单：白底卡片从名字下面垂下来，跟系统里的弹窗同一套阴影与圆角 */
.ub-menu{position:absolute;right:0;top:40px;min-width:250px;white-space:normal;background:#fff;color:var(--ink);
  border-radius:9px;box-shadow:0 10px 28px rgba(16,32,48,.2);padding:6px 0;z-index:60}
.ub-menu a{display:block;padding:9px 16px;color:var(--ink);font-size:13px;cursor:pointer}
.ub-menu a:hover{background:var(--brand-soft);color:var(--brand)}
.ub-menu .ub-who{padding:8px 16px 10px;border-bottom:1px solid var(--line);margin-bottom:4px}
.ub-menu .ub-who b{display:block;font-size:14px}
.ub-menu .ub-who span{font-size:12px;color:var(--ink-3)}
.ub-menu .ub-out{border-top:1px solid var(--line);margin-top:4px;color:var(--ink-2)}

/* 用户与角色：停用的账号整行压灰，一眼分得出还在用的和不用了的 */
tr.u-off > td{color:var(--ink-3)}
/* 初始口令：大号等宽，逐字念得清（去掉了 0/O、1/l 这些易混字符） */
.pw-show{display:flex;align-items:center;gap:14px;margin:12px 0 14px;padding:12px 16px;
  background:var(--brand-soft);border-radius:8px}
.pw-show code{font:600 22px/1.2 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:2px;color:var(--brand)}
/* 我的账号：左标签右值 */
.me-kv{display:grid;grid-template-columns:110px 1fr;gap:12px 18px;font-size:13.5px;max-width:760px}
.me-kv .me-k{color:var(--ink-3)}

/* 操作日志的明细：新增 / 删除会整行原值进日志，一段 JSON 能有两百字。
   默认收成三行、末尾给「展开全文」链接（不靠鼠标悬停，D-053）。 */
.lg-d{max-height:4.8em;overflow:hidden;word-break:break-all;font-size:12.5px;color:var(--ink-2)}
.lg-d.open{max-height:none}
/* 工具条里的日期框不是搜索框：去掉放大镜、别吃搜索框那 262px 的最小宽 */
.filters input[type=date]{min-width:0;width:152px;padding-left:12px;background-image:none}
/* 项目名常有二三十个字，下拉按最长那项撑开会独占一行，把日期挤下去 */
.filters select.lg-proj{max-width:300px}
/* API 令牌 46 个字符：初始口令那套 22px 大字放不下，缩小、允许在任意处断行 */
.pw-show code.tok{font-size:14px;letter-spacing:0;word-break:break-all;flex:1}
.pw-show code.tok.cmd{font-size:12px;font-weight:400;color:var(--ink)}
.pw-show .lnk{white-space:nowrap}

/* ---------- 权限对照表（A2，N-28：矩阵印在「用户与角色」页给人看）----------
   只用既有的配色变量：✓ 用品牌蓝不用绿（绿在本系统表示「钱收齐了/没超支」，
   借过来会串味），「—」用最淡的一档灰，**红色一律不用**——
   「这个角色不能改合同」是分工不是告警（:root 那条「红色只用于告警」）。 */
.pm-roles{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  gap:10px;margin-bottom:16px}
.pm-role{background:var(--brand-soft);border-radius:var(--radius);padding:10px 12px}
.pm-role b{display:block;color:var(--brand);margin-bottom:3px}
.pm-role span{font-size:12.5px;color:var(--ink-2);line-height:1.55}
.pm-y{color:var(--brand);font-weight:700}
.pm-r{color:var(--ink-2);font-size:12.5px}
.pm-n{color:var(--ink-3)}
.pm-s{color:var(--brand-2);font-size:12px;font-weight:600}
/* 「动作」那条分隔行：表级矩阵与特殊动作在同一张表里（它们是同一个问题的两半，
   拆成两张表就得对着看），中间要有一道看得出来的界 */
.pm-sep td{background:var(--brand-soft);color:var(--brand);font-weight:600;
  letter-spacing:1px;padding-top:8px;padding-bottom:8px}
.pm-h{margin:22px 0 4px;font-size:14.5px;color:var(--ink)}
.pm-notes{margin:6px 0 0 18px;color:var(--ink-2);font-size:13px;line-height:1.75}

/* ---------- 系统设置页的体检卡（A3）----------
   跟驾驶舱的 .alert 不同：那是一条条铺开的告警，这里是并排的小格，
   要的是「一眼扫完有没有毛病」。左边一道色条表示轻重（同台账的 lgrp-out/in）。*/
.set-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  gap:10px;margin-bottom:6px}
.set-chk{background:var(--zebra);border-radius:var(--radius);padding:10px 12px;
  border-left:4px solid var(--line-2)}
.set-chk.ok{border-left-color:var(--ok)}
.set-chk.warn{border-left-color:var(--warn);background:var(--warn-bg)}
.set-chk.danger{border-left-color:var(--danger);background:var(--danger-bg)}
.set-chk b{display:block;color:var(--ink);margin-bottom:3px}
.set-chk span{display:block;font-size:12.5px;color:var(--ink-2);line-height:1.55}
.set-chk i{display:block;font-style:normal;font-size:12px;color:var(--ink-3);margin-top:4px}
