/* ICT 项目管理 — 全站样式（无框架，纯手写保持零依赖）
   设计约定：.trae/skills/ict-ui-dev/rules/design.md（D33 token 体系 / D35 塞尚受限盘）
   铁律：组件规则里禁止写裸色值/裸阴影——一律引用 :root 语义 token */

:root {
    /* —— D35 塞尚受限盘：色相节制三族（蓝 207° 品牌族 / 赭 ≈35° / 绿 ≈135°），
       其余中性；暖亚麻底盘衬冷蓝块（塞尚温度调和）；彩度纪律：
       品牌蓝 100% 峰值 → 语义色 40-55% → 中性 <5% —— */

    /* 中性（亚麻色温） */
    --bg: #f3f4f1;            /* 页底 */
    --card: #ffffff;          /* 卡片/控件底 */
    --surface-alt: #f7f8f5;   /* 表头/展开行/表单底 */
    --line: #dfe1db;          /* 边框线 */
    --text: #26292b;          /* 正文（中性近黑） */
    --dim: #6a6f6b;           /* 次要文字 */
    --on-accent: #ffffff;     /* 彩色底上的文字/圆点（白） */

    /* 蓝族（207° 单族分级：品牌峰 → 交互主 → 淡底） */
    --info: #0066b3;          /* 电信蓝：品牌强调（胶囊/分配类型色） */
    --info-hover: #00559a;    /* 电信蓝 hover（品牌族黑化） */
    --primary: #1e5a94;       /* 交互主色（D35：原 #305496 Office 蓝 215° 并入 207° 族） */
    --primary-hover: #174a7c; /* 主色 hover（同族黑化） */
    --primary-weak: #e4edf5;  /* 主色淡底/hover 底 */
    --half: #0277bd;          /* 「单位已分」专用蓝 */

    /* 语义三色相（松绿/熟赭/砖红） */
    --ok: #3a7d44;            /* 成功/已分配/合计达标 */
    --warn: #a86800;          /* 警告/缺口（61 份缺归档日期等"要点亮"的信息） */
    --danger: #a63d2f;        /* 危险/作废/冲正/错误 */

    /* 树类型色组（收编 7 个独占色：降到语义同彩度带、明度对齐；
       紫是受限盘登记在册的唯一例外——列收/收入类分类色） */
    --type-award: #35794a;    /* 中标/直签（绿族） */
    --type-approval: #8a621e; /* 审批（赭族） */
    --type-archive: var(--danger);      /* 合同归档（砖红） */
    --type-refund: var(--danger);       /* 冲正/退合同 */
    --type-income: #7a4f92;   /* 列收/收入（降彩紫，例外族） */
    --type-income-weak: #e9e2f2; /* 列收紫淡底（D69 进度条"已规划未列"段） */
    --type-alloc: var(--info);          /* 单位/条线分配（电信蓝） */
    --type-neutral: #64737c;  /* 计划/日志等中性类 + CREATE 徽标（青灰） */

    /* 视角透镜（D67 用户定案，D35 对照勘误后终案）：单位/条线 = 页面级数据
       透镜，两视角互不相交、总和镜像。条线 = 绿族（135° 生长族，盘内在册
       分级）——圣维克多山原生配方（蓝山＋绿植＋赭地），蓝→绿 72° 类似色
       和声，切换可辨语气统一。初选青 187° 经 D35 对照为盘外孤儿色，用户
       拍板改绿族（勘误实录见 design.md D67）。与 --ok 语义绿分工：
       --ok 只做状态徽标（成功/已分配），透镜绿独立分级更沉稳；
       透镜色只允许出现在切换器实底与数据 mark（滑块 connect/手柄/
       大数字），卡底保持中性 */
    --lens-unit: var(--info);         /* 单位视角 = 电信蓝品牌原色 */
    --lens-unit-weak: var(--primary-weak);
    --lens-line: #2d6a37;             /* 条线视角 = 绿族分级（比 --ok 深沉一档） */
    --lens-line-hover: #245730;       /* 透镜绿 hover（同族黑化） */
    --lens-line-weak: #e4efe6;        /* 透镜绿淡底（亚麻底盘上的微绿） */
    /* 消费口（随最近祖先 [data-lens] 切换，组件只准引用这两个） */
    --lens: var(--lens-unit);
    --lens-weak: var(--lens-unit-weak);

    /* 阴影三级台阶（D35：rgba 基于 --text 色相的中性黑，暖底不用纯黑） */
    --shadow-xs: 0 1px 2px rgba(38, 41, 43, .05);    /* 卡片/表格 resting */
    --shadow-sm: 0 2px 8px rgba(38, 41, 43, .10);    /* 下拉面板/悬浮件/hover */
    --shadow-md: 0 8px 24px rgba(38, 41, 43, .16);   /* 下钻浮窗等顶层浮起 */
    --glow-info: 0 2px 8px rgba(0, 102, 179, .35);   /* 电信蓝胶囊品牌光晕（唯一） */

    /* 间距 / 圆角 / 字号（渐进收编：新写与改到的规则必须引用） */
    --space-1: 4px;  --space-2: 8px;  --space-3: 12px;
    --space-4: 16px; --space-5: 20px; --space-6: 24px; --space-8: 32px;
    --radius-sm: 6px; --radius-md: 8px; --radius-lg: 12px; --radius-pill: 999px;
    --font-xs: 12px; --font-sm: 13px; --font-md: 14px; --font-lg: 16px;
    --font-xl: 20px; --font-2xl: 26px;   /* 展示级：页题/大数字（字阶收编，g7） */
    --weight-strong: 600;                /* 徽标/数字强调字重（原 .func-dot 引用未定义 token） */

    /* z 阶梯（g8 层级定档）：th吸顶 < 下拉面板 < 吸顶题眉 < 悬浮件 < 下钻浮窗 < 浮窗顶层 < 任务模态 < toast */
    --z-th: 3; --z-panel: 20; --z-head: 30; --z-fab: 50;
    --z-drill: 60; --z-drill-top: 70; --z-modal: 80; --z-toast: 99;
}

* { box-sizing: border-box; }
/* hidden 属性优先于任何 display 设置（否则 .field-row 的 display:flex 会
   让带 hidden 的行仍然可见——award-row 条件显隐曾因此失效） */
[hidden] { display: none !important; }
body {
    margin: 0; background: var(--bg); color: var(--text);
    font: var(--font-md)/1.6 "Segoe UI", "Microsoft YaHei", sans-serif;
}
.mono { font-family: Consolas, "Courier New", monospace; }
.dim { color: var(--dim); }
.hidden { display: none; }
.num { text-align: right; font-variant-numeric: tabular-nums; }
/* D57 特异性修复：.table th/td 的 text-align:left (0,1,1) 曾覆盖 .num (0,1,0)，
   全站表格数字实际左对齐、个位参差——提高特异性让财务数字恢复右对齐 */
.table .num { text-align: right; }
.table .ctr { text-align: center; }
/* 冲正负金额（D54 语义：负数=冲减方向的事务事实）——蘸 --danger 砖红，
   与徽标/类型列共同承担冲正语义，金额本身不再与正文同色 */
.num.neg { color: var(--danger); }
/* D57 键盘焦点可见性（D33 无障碍底线）：统一 --primary 实色轮廓；
   focus-visible 只在键盘导航时出现，鼠标点击不受视觉干扰 */
:focus-visible {
    outline: 2px solid var(--primary); outline-offset: 2px;
}

/* ---- 布局 ---- */
.container { max-width: 1560px; margin: var(--space-6) auto; padding: 0 var(--space-6); }
/* 窄视口左上安全区：容器贴边时给悬浮按钮让出呼吸空间（D97 起 func-fab
   吸附容器内容盒左缘=72px 处，此 padding 同时保证内容不顶到视口边）；
   宽屏容器居中不受影响。（必须置于 .container 定义之后，否则被 padding 简写覆盖） */
@media (max-width: 1680px) {
    .container { padding-left: 72px; }
}
/* 宽幅变体（D45）：合同管理三子页表格宽 fluid 全宽，长合同名尽量舒展 */
.container-wide { max-width: none; }
h1 { font-size: var(--font-xl); margin: 0 0 var(--space-4); }
h2 { font-size: var(--font-lg); margin: 0 0 var(--space-2); }
h3 { font-size: var(--font-md); margin: 0 0 var(--space-2); }

/* ---- 全站返回通路（D77）：每页 content 首元素，左上角小字「‹ 主页」 ---- */
.crumb { display: inline-block; margin: 0 0 4px; font-size: var(--font-sm);
         color: var(--dim); text-decoration: none; }
.crumb:hover { color: var(--primary); }

/* ---- 搜索与筛选 ---- */
.search {
    width: 380px; padding: var(--space-2) var(--space-3); border: 1px solid var(--line);
    border-radius: var(--radius-sm); background: var(--card); font-size: var(--font-md);
}
.search:focus { outline: 2px solid var(--primary); border-color: var(--primary); }
/* 台账筛选行控件多，搜索框收窄一档（模板零内联，09-22 体检收编） */
#ledger-filters .search { width: 280px; }
/* 台账 200 行截断提示行（ledger_rows.html 截断行，原内联样式收编） */
.row-truncated { text-align: center; padding: var(--space-2) 0; }

.tabs { margin: var(--space-3) 0 var(--space-2); display: flex; gap: 4px; }
.tab {
    border: 1px solid var(--line); background: var(--card); color: var(--text);
    padding: 4px 12px; border-radius: var(--radius-lg); cursor: pointer; font-size: var(--font-sm);
}
.tab.active { background: var(--primary); border-color: var(--primary); color: var(--on-accent); }
/* 页内子页导航（D40）：tab 胶囊承载真实链接 */
a.tab { text-decoration: none; }
/* 题眉（D42）：页题 + 子页入口同行，tab 条自带外距在题眉内归零 */
.page-head .tabs { margin: 0; }
/* 页眉级子导航（D58 用户定案：页签不该是圆角胶囊按钮——页眉层级用
   「分隔线 + 底部指示线」表达，VS Code/GitHub 式文本页签）：
   作用域锁 .page-head，统计卡季度切换（.quarter-bar .tab，控件级）不受影响 */
.page-head .tabs {
    display: flex; gap: var(--space-4);
    border-bottom: 1px solid var(--line);
}
.page-head .tab {
    border: none; background: none; border-radius: 0;
    padding: 8px 2px; color: var(--dim); font-size: var(--font-md);
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;            /* 指示线压住容器分隔线，贴合无缝 */
    transition: color .15s, border-color .15s;
}
.page-head .tab:hover { color: var(--text); }
.page-head .tab.active {
    background: none; color: var(--text); font-weight: 600;
    border-bottom-color: var(--primary);
}
[data-lens="line"] {
    --lens: var(--lens-line);
    --lens-weak: var(--lens-line-weak);
}

/* 页眉吸顶（D61 补记，用户定案）：题眉 sticky 固定，内容从分隔线下方
   穿过——背景实色 --bg 防透字；z 低于浮窗(60)/func-fab(50)、高于页面内容；
   padding-top 给吸顶态呼吸感，margin-bottom 让题眉与首个内容块
   （季度胶囊/筛选栏/滑块卡）保持适当距离 */
.page-head {
    position: sticky; top: 0; z-index: var(--z-head);
    background: var(--bg);
    padding-top: var(--space-2);
    margin-bottom: var(--space-4);
}

/* 题眉行（D67）：页题在左、视角透镜切换器在右——导航（文本 tab）与
   数据开关（胶囊分段）分居两端，层级语义一目了然 */
.page-head .ph-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-3); flex-wrap: wrap;
    border-bottom: 1px solid var(--line);
}
.page-head .ph-row h1 { margin-bottom: 0; }

/* 视角透镜切换器（D67）：控件级胶囊分段（.quarter-bar .tab 同族豁免——
   开关用按钮控件、导航用文本 tab 的既定分工）；active = 透镜色实底，
   整页数据 mark 随 [data-lens] 换色（CSS 变量级联，零 JS） */
.lens-switch {
    display: inline-flex; gap: 2px; padding: 3px;
    background: var(--surface-alt); border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    margin-bottom: var(--space-2);
}
.lens-switch a {
    padding: 3px 12px; border-radius: var(--radius-pill);
    font-size: var(--font-sm); color: var(--dim); text-decoration: none;
    transition: background .15s, color .15s;
}
.lens-switch a:hover { color: var(--text); }
.lens-switch a.active { background: var(--lens); color: var(--on-accent); }
.lens-switch a:focus-visible { outline: 2px solid var(--lens); outline-offset: 1px; }


/* 合同处理页 · 当场补录归档日期（D42）：行内表单布局 */
.quick-archive { display: flex; gap: 4px; align-items: center; }
.quick-archive input { width: 108px; padding: 4px 8px; border: 1px solid var(--line);
                       border-radius: var(--radius-sm); background: var(--card); font-size: var(--font-xs); }
.quick-archive .btn { padding: 4px 8px; font-size: var(--font-xs); }

/* ---- 按钮基类（D36 合一：原 .filters .btn / .op-form .btn-main 重复定义收敛） ----
   实心主按钮；.btn-sub 为描边次按钮。选择器组即唯一出处，模板零改动 */
/* D80 勘误：基类原为 .filters/.op-form 作用域组合选择器，裸 .btn 从未存在——
   目标工作台等新页面容器外按钮全部渲染成浏览器原生灰按钮（「类名在场≠形态在场」）。
   裸 .btn 并入本组：声明不变（老页面零视觉变化），容器外按钮获得标准形态；
   .btn-sm 等后置规则以同特异性后来者胜照常覆盖 */
.btn,
.filters .btn,
.op-form .btn-main {
    padding: var(--space-2) var(--space-4); border: none; border-radius: var(--radius-sm);
    background: var(--primary); color: var(--on-accent); cursor: pointer; font-size: var(--font-sm);
    transition: background .15s; white-space: nowrap;
}
.btn:hover,
.filters .btn:hover,
.op-form .btn-main:hover { background: var(--primary-hover); }
.op-form .btn-sub {
    padding: var(--space-2) var(--space-4); border: 1px solid var(--primary); border-radius: var(--radius-sm);
    background: var(--card); color: var(--primary); cursor: pointer; font-size: var(--font-sm);
    transition: background .15s;
}
.op-form .btn-sub:hover { background: var(--primary-weak); }

/* ---- 声明式筛选容器 ---- */
.filters {
    display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-md);
    padding: var(--space-2) var(--space-3); margin-bottom: var(--space-3);
}
.filters .filter {
    padding: var(--space-2); border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--card); font-size: var(--font-sm); color: var(--text);
}
.filters .filter:focus { outline: 2px solid var(--primary); border-color: var(--primary); }
.filters .search { width: 280px; }   /* 搜索框宽度（D43 自内联样式收敛为类） */
.filters .date-range { display: inline-flex; align-items: center; gap: 4px; }
.filters .filter-label { color: var(--dim); font-size: var(--font-sm); white-space: nowrap; }
.filters .filter-date {
    padding: var(--space-2); border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--card); font-size: var(--font-sm); color: var(--text);
}
.filters .filter-date:focus { outline: 2px solid var(--primary); border-color: var(--primary); }

/* ---- 筛选结果合同金额之和（D49）：冲正后净额，醒目展示「一个数字」 ---- */
.contract-net-sum {
    display: flex; align-items: baseline; gap: var(--space-2);
    padding: var(--space-2) var(--space-3); margin-bottom: var(--space-3);
    background: var(--surface-alt); border: 1px solid var(--line);
    border-radius: var(--radius-md);
}
.contract-net-sum strong {
    font-size: var(--font-xl); font-weight: 700; color: var(--primary);
    font-variant-numeric: tabular-nums;
}
.contract-net-sum .dim { font-size: var(--font-sm); }

/* ---- 考核分配子页（D51）：快捷预设 chips + 宽时间桶滚动网格 ---- */
.preset-row {
    display: flex; align-items: center; gap: 4px;
    margin: 0 0 var(--space-3);
}
.preset-label { color: var(--dim); font-size: var(--font-xs); }
.chip-link {
    border: 1px solid var(--line); border-radius: var(--radius-pill);
    background: var(--card); color: var(--text); font-size: var(--font-xs);
    padding: 3px 12px; text-decoration: none;
    transition: border-color .15s, color .15s;
}
.chip-link:hover { border-color: var(--primary); color: var(--primary); }
.chip-link.active {
    border-color: var(--primary); background: var(--primary-weak);
    color: var(--primary);
}
/* ---- 通报统计区（D57）：六表选一控制行——表型 chips（激活=主色淡底）
   + 维度胶囊按钮（复用控件级 .tab 胶囊语义，.quarter-bar 同款豁免） ---- */
.bulletin-head { justify-content: space-between; flex-wrap: wrap; gap: var(--space-2); }
.bulletin-switches {
    display: inline-flex; align-items: center;
    gap: var(--space-3); flex-wrap: wrap;
}
.bulletin-chips { display: inline-flex; gap: 4px; }
.bulletin-dims { display: inline-flex; gap: 4px; }
.alloc-sub { margin: var(--space-3) 0 4px; font-size: var(--font-sm); }

/* ---- 考核分配滑块卡 + 聚焦卡（D52）：noUiSlider 主题走 token，组件规则禁裸值 ---- */
.alloc-slider-card {
    display: flex; align-items: center; gap: var(--space-3);
    background: var(--card); border: 1px solid var(--line);
    border-radius: var(--radius-md); box-shadow: var(--shadow-xs);
    padding: var(--space-5) var(--space-4) var(--space-8); margin-bottom: var(--space-3);
}
.alloc-slider { flex: 1; }
/* 时间轴随视角换色（D67）：connect/手柄引用透镜消费口，最近祖先
   [data-lens] 一变整条时间轴跟随，页面级全局感零 JS 实现 */
.alloc-slider .noUi-connect { background: var(--lens); }
.alloc-slider .noUi-handle {
    width: 16px; height: 16px; right: -8px; top: -7px;
    border: 2px solid var(--lens); background: var(--card);
    box-shadow: none; cursor: grab;
}
.alloc-slider .noUi-handle:active { cursor: grabbing; }
.alloc-slider .noUi-handle:before, .alloc-slider .noUi-handle:after { content: none; }
.alloc-slider .noUi-tooltip {
    background: var(--card); border: 1px solid var(--line);
    color: var(--text); font-size: var(--font-xs); padding: 2px 4px;
}
.alloc-slider .noUi-pips { font-size: var(--font-xs); color: var(--dim); }
.alloc-slider .noUi-value-large { color: var(--text); }
/* 小节标题（D69）：与主表拉开一档组间距（D105 当日流量退役，今由「未分配项目规划」标题复用） */
.today-head { margin: var(--space-6) 0 var(--space-2); }
/* 通报导出中心（D135）：tabs 内右置入口 chip + 卡片栅格两视角预览 */
.tab-bulletin { margin-left: var(--space-3); }
.bulletin-toolbar {
    display: flex; align-items: center; gap: var(--space-4);
    margin: var(--space-3) 0;
}
.b-date-form { display: flex; align-items: center; gap: var(--space-2); }
.bulletin-grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(560px, 1fr));
    gap: var(--space-4); align-items: start;
}
.bulletin-card {
    background: var(--card); border: 1px solid var(--line);
    border-radius: var(--radius-md); box-shadow: var(--shadow-xs);
    padding: var(--space-4);
}
.bulletin-card .b-head {
    display: flex; align-items: center; gap: var(--space-3);
    margin-bottom: var(--space-3);
}
.bulletin-card .b-head form { margin-left: auto; }
/* 预览表自适应宽（D104b 金额纪律：金额宽度适应内容），合计行加粗定格 */
.bulletin-card .b-tbl { table-layout: auto; }
.bulletin-card .b-tbl .b-total td { font-weight: 600; }
/* 未分配项目规划（D73）：行式清单 + 展开规划表单（复用 .alloc-sys/.alloc-row） */
.unassigned-row {
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--card); margin-bottom: var(--space-2);
    flex-wrap: wrap;
}
.unassigned-row .u-name { flex: 1 1 320px; min-width: 240px;
    font-weight: var(--weight-strong);   /* D126：项目名统一加粗 */
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.unassigned-row .u-obj { color: var(--dim); font-size: var(--font-sm); }
.unassigned-row .u-budget { min-width: 108px; }
.unassigned-row .plan-box { flex-basis: 100%; max-width: 520px; }
/* 规划分配下拉（D84）：输入列定宽不吃满容器——考核对象多为两三字单位名；
   金额输入此前无样式（浏览器默认宽），补齐 .a-name/.a-ratio 同款
   （仅 .plan-box 作用域，工作台规划表单不受影响） */
.plan-box .alloc-row .a-name { flex: 0 0 188px; }
.plan-box .alloc-row .a-ratio { flex: 0 0 92px; }
.plan-box .alloc-row .a-amount { flex: 0 0 128px;
    padding: var(--space-2); border: 1px solid var(--line);
    border-radius: var(--radius-sm); font-size: var(--font-sm); background: var(--card); }
.btn-sub2 {
    padding: 4px 8px; border: 1px solid var(--primary); border-radius: var(--radius-sm);
    background: var(--card); color: var(--primary); cursor: pointer; font-size: var(--font-sm);
    transition: background .15s;
}
.btn-sub2:hover:not(:disabled) { background: var(--primary-weak); }
.btn-sub2:disabled { opacity: .5; cursor: not-allowed; }
.plan-actions { display: flex; align-items: center; gap: var(--space-3);
    flex-wrap: wrap; margin-top: var(--space-2); }
/* D104 口径行下钻三角（考核容器表三考核组首列前 ▸）：复用全站下钻浮窗
   drillWindow（台账大卡片同款容器）；旧 .ledger-main-row/.detail-row
   展开样式随 D104 交互退役删除 */
.det-toggle { color: var(--primary); font-weight: 600; cursor: pointer; }
.det-toggle:hover { color: var(--primary-hover); }
/* 下钻三角轴线（D122 用户定案「每组三角保持一条 Y 轴线，与左侧分组竖线
   稳定相对距离」）：组首列为 num 右对齐，行内三角 X 随金额位数漂移——
   改绝对定位钉死单元格左缘（分组竖线内缘 8px），金额区让出等量左衬；
   :has 只命中携三角的三组首列（today_budget 无三角不吃衬），跨行/跨组/
   合计行轴线严格一致；垂直取单元格中线，行高变化不失稳 */
.assess-tbl td:has(> .det-toggle) { position: relative; padding-left: 24px; }
.assess-tbl td:has(> .det-toggle) .det-toggle {
    position: absolute; left: 8px; top: 50%; transform: translateY(-50%);
}
/* 考核容器表自适应宽（D94 用户指正：720px 定宽切金额=买椟还珠）——弃
   fixed 定宽布局：表格收缩到内容宽（金额列随数值完整展开，不再省略号），
   窄字段（对象名/完成率）按内容自然窄；居中保留（D92），min/max 双护栏 */
.table.assess-tbl { width: auto; min-width: 640px; max-width: 100%; margin: 0 auto; }
.table.assess-tbl th, .table.assess-tbl td { white-space: nowrap; }
/* D95 双参照系列组分隔 + D102 列收组 + D106 当日组：组首列（全年/季度
   目标列、当期列收、当日预算）左侧 2px 竖线——会计报表分栏式（用户
   拍板细竖线方案），行(tfoot)同吃分隔 */
.assess-tbl th[data-col="target_y"], .assess-tbl td[data-col="target_y"],
.assess-tbl th[data-col="target_q"], .assess-tbl td[data-col="target_q"],
.assess-tbl th[data-col="income"], .assess-tbl td[data-col="income"],
.assess-tbl th[data-col="today_budget"], .assess-tbl td[data-col="today_budget"],
.assess-tbl th[data-col="quarter_archive"], .assess-tbl td[data-col="quarter_archive"],
.assess-tbl th[data-col="target_b"], .assess-tbl td[data-col="target_b"],
.assess-tbl th[data-col="quarter_budget"], .assess-tbl td[data-col="quarter_budget"],
.assess-tbl th[data-col="as_actual"], .assess-tbl td[data-col="as_actual"] {
    border-left: 2px solid var(--dim);
}
/* D140 组标题行（thead 首行跨列组名）：段带式说明「这是什么考核组」，
   组首列竖线贯通到标题行（分栏视觉闭合）；colToggler 按组内可见列数
   重算 colspan（app.js），全隐整格隐藏 */
.assess-tbl tr.group-head th {
    text-align: left; font-weight: 600; color: var(--dim);
    font-size: var(--font-xs); letter-spacing: .02em;
    border-bottom: 1px solid var(--line); background: none;
}
.assess-tbl tr.group-head th.gstart { border-left: 2px solid var(--dim); }
/* ⚙面板分组（D95）：组主开关加粗 + 组内项缩进分隔 */
.col-group { padding: 4px 0; border-bottom: 1px dashed var(--line); }
.col-group:last-of-type { border-bottom: none; }
.col-master { font-weight: 600; }
.col-group-items { display: flex; flex-wrap: wrap; gap: 4px 16px; padding-left: var(--space-5); }
.focus-head { display: flex; align-items: baseline; gap: var(--space-3); }
/* 统计卡行容器归一（D110）：行布局统一走台账 .stats-bar；.focus-stats 仅作
   margin 修饰（三格在换入区内需要上下留白，台账页首栏只要底部） */
.stats-bar {
    display: flex; align-items: stretch; gap: var(--space-3); flex-wrap: wrap;
    margin-bottom: var(--space-3);
}
.focus-stats { margin-top: 0; }   /* D111：上距由滑块卡 12px 下距承担，节奏对齐台账单向下距 */
/* 考核三格（D109 容器复用）：卡壳统一走 .stat-card（栅格/边框/圆角/内距/
   flex 全继承），.focus-stat 仅作底色修饰（口径汇总区淡底语义）——
   ⚠修饰规则必须排在 .stat-card 之后（同特异性靠源顺序取胜），见台账统计栏段 */
.detail-pairs .cell-pair {
    display: inline-block; margin: 0 12px 4px 0; white-space: nowrap;
}
.detail-pairs .cell-pair b { font-weight: 600; }
/* 宽表样式 alloc-fold/alloc-grid/table-scroll 已删（D62 补记：宽表从页面移除） */

/* ---- 活动筛选 chips + 表头排序（D37 分面检索） ---- */
.chips-row td.chips { padding: 4px 8px; background: var(--primary-weak); }
/* 台账容器内滚（D61）：表格限高在容器内滚动，页身不再被 200 行拉长；
   表头 sticky 吸顶（border-collapse 下底边框随滚消失，用内阴影替代） */
.ledger-scroll {
    overflow: auto;
    max-height: calc(100vh - 330px);
    min-height: 240px;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
}
/* Chrome 下 border-collapse:collapse 的表格 th sticky 不生效——
   台账表局部改 separate+零间距（单元格只有底边框，视觉无差）；
   .table 自带的 overflow:hidden（圆角裁切）会截断 sticky 包含块，必须放开
   ——外层 .ledger-scroll 自带裁切，视觉不受影响 */
.ledger-scroll .table { border-collapse: separate; border-spacing: 0; overflow: visible; }
.ledger-scroll thead th { position: sticky; top: 0; z-index: var(--z-th);
                          box-shadow: inset 0 -1px 0 var(--line); }
/* 画框不限高修饰（D125 通用化，原 D111 .assess-scroll）：考核容器表/列收
   进度表复用台账 .ledger-scroll 画框（边框/圆角/框内横滚/separate/sticky
   表头全继承），行数少不限高——仅覆盖台账 200 行限高档 */
.ledger-scroll.no-limit { max-height: none; min-height: 0; }
/* 列显隐（D60；D84 泛化到考核容器表；D96 col 摘除归一化）：td/th 整体 display:none；
   col 分两路（app.js colToggler 施加）——有内联宽度的表把隐藏列 <col> 整体摘出
   colgroup 并把可见列宽度归一化补位（visibility:collapse 在 Chromium 遇 colspan
   全跨行如 chips/空态行会宽度重分失效，滞留为表格右侧空白）；无宽度列沿用
   visibility:collapse（table-layout:fixed 下 <col> 的 display 无效，collapse 才能收窄
   列盒）——所有带 data-col 的表格共用 */
[data-col].col-off { display: none; }
col.col-off { visibility: collapse; }
.cols-config-wrap { position: relative; display: flex; justify-content: flex-end;
                     margin-bottom: 4px; }
.chip-clear {
    border: 1px solid var(--primary); border-radius: var(--radius-lg); background: var(--card);
    color: var(--primary); cursor: pointer; font-size: var(--font-xs);
    padding: 2px 8px; margin-right: 4px; transition: background .15s, color .15s;
}
.chip-clear:hover { background: var(--primary); color: #fff; }
th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
th.sortable:hover { color: var(--primary); }
.sort-ind::after { content: "↕"; color: var(--line); margin-left: 3px; font-size: var(--font-xs); }
th.sort-asc .sort-ind::after { content: "↑"; color: var(--primary); }
th.sort-desc .sort-ind::after { content: "↓"; color: var(--primary); }

/* ---- 树内合同页横幅（D37）：台账行直达时显示树上下文与「查看全部」出口 ---- */
.tree-scope-banner {
    background: var(--primary-weak); border: 1px solid var(--line);
    border-radius: var(--radius-md); padding: var(--space-2) var(--space-3); margin-bottom: var(--space-3);
    display: flex; align-items: center; gap: var(--space-4);
}
.tree-scope-banner a { margin-left: auto; }

/* ---- 台账统计栏（D23：常态化统计卡片 + 统计项显隐配置；D36 卡片可下钻） ---- */
.stats-bar { display: flex; align-items: stretch; gap: var(--space-3); flex-wrap: wrap;
             margin-bottom: var(--space-3); }
.stat-card {
    flex: 1 1 220px; min-width: 200px;
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-md);
    padding: var(--space-2) var(--space-3); box-shadow: var(--shadow-xs);
    display: flex; flex-direction: column; gap: 2px;
}
/* 可下钻卡片（D36）：hover 提示可点，点击弹下钻浮窗（app.js drillWindow） */
.stat-card.drillable { cursor: pointer; transition: border-color .15s, box-shadow .15s; }
.stat-card.drillable:hover { border-color: var(--primary); box-shadow: var(--shadow-sm); }
/* 考核三格淡底修饰（D110）：必须位于 .stat-card 之后（同特异性源顺序取胜） */
.stat-card.focus-stat { background: var(--surface-alt); }
.stat-label { color: var(--dim); font-size: var(--font-xs); }
.stat-value { font-size: var(--font-xl); font-weight: 700; color: var(--primary);
              font-variant-numeric: tabular-nums; }
.stats-config-wrap { position: relative; display: flex; align-items: center;
                     margin-left: auto; }
.stats-config-panel {
    position: absolute; top: calc(100% + 4px); right: 0; z-index: var(--z-panel);
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm); padding: var(--space-2) var(--space-3); min-width: 220px;
    display: flex; flex-direction: column; gap: 4px;
}
.stats-check { display: flex; align-items: center; gap: 4px; font-size: var(--font-sm);
               cursor: pointer; }
/* 考核年度选择器（D86）：面板内链接项 + 当前视图高亮 */
.stats-config-panel a.stats-check { color: var(--text); text-decoration: none;
    padding: 2px 4px; border-radius: var(--radius-sm); }
.stats-config-panel a.stats-check:hover { background: var(--primary-weak); }
.stats-config-panel a.stats-check.cur { color: var(--primary); font-weight: 600; }
/* 统计栏右侧竖排双小卡（D86）：考核年度/统计项——蓝底卡（规范色 --primary-weak），
   两卡 flex 平分统计栏行高（align-items:stretch 拉到未归档大卡高，高之和相等） */
.stats-side { display: flex; flex-direction: column; gap: 8px;
              flex: 0 0 188px; min-width: 176px; }
.stats-side-card { position: relative; flex: 1; display: flex; }
.stats-side-card .side-btn {
    width: 100%; display: flex; flex-direction: column; justify-content: center;
    align-items: flex-start; gap: 2px; text-align: left; cursor: pointer;
    background: var(--primary); border: none;
    border-radius: var(--radius-md); padding: var(--space-2) var(--space-3);
    font-size: var(--font-xs); color: var(--on-accent);
}
.stats-side-card .side-btn:hover { background: var(--primary-hover); }
.stats-side-card .side-label { color: var(--on-accent); opacity: .78; }
.stats-side-card .side-btn b { font-size: var(--font-sm); color: var(--on-accent); }
/* 未纳入考核行（D86）：无分配项目灰显——统计不计入，台账保留可见 */
.row-unassessed { opacity: .55; }

/* ---- 合同管理页 · 目标达成统计区（M3/D31；D36 达成卡/达成行可下钻） ---- */
.achieve { margin-bottom: var(--space-4); }
.quarter-bar { margin: 0 0 var(--space-2); }
/* 考核年度切换（D86）：达成区年度链接组标签间距 */
.quarter-bar .year-label { margin-right: 4px; }
.achieve-cards { display: flex; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-3); }
.achieve-main { flex: 2 1 320px; }
.achieve-main .stat-value { font-size: var(--font-2xl); }
.stat-sub { color: var(--dim); font-size: var(--font-xs); }
.dim-card { opacity: .75; }
.dim-card .stat-value { color: var(--warn); }
.achieve-ratio { font-size: var(--font-sm); font-weight: 600; }
.achieve-ratio small { color: var(--dim); font-weight: 400; }
/* 完成比例三档：≥100% 绿 / ≥60% 黄 / <60% 红（阈值判在服务端 _ratio） */
.ratio-ok   { color: var(--ok); }
.ratio-mid  { color: var(--warn); }
.ratio-low  { color: var(--danger); }
.achieve-title { margin: var(--space-3) 0 4px; }
.achieve-total td { font-weight: 700; border-top: 2px solid var(--line); }

/* ---- 合同管理页 · 合同跟进面板（D38：四桶 + 明细深链） ---- */
.followup { background: var(--card); border: 1px dashed var(--line); border-radius: var(--radius-md);
            padding: var(--space-2) var(--space-3); margin-bottom: var(--space-3); }
.fu-line { display: flex; align-items: center; gap: 12px; padding: 4px 0; }
.fu-line .drop-btn { min-width: 240px; text-align: left; }
.fu-amt { font-weight: 700; color: var(--primary); font-variant-numeric: tabular-nums; }
.fu-panel { border-top: 1px solid var(--line); margin-top: 4px; padding: 4px 0; }
.fu-item { display: flex; align-items: center; gap: var(--space-3); padding: 4px 8px;
           color: var(--text); text-decoration: none; border-radius: var(--radius-sm); }
.fu-item:hover { background: var(--primary-weak); color: var(--primary); }
.fu-name { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fu-amount { font-variant-numeric: tabular-nums; }
.fu-empty { display: block; padding: 4px 8px; font-size: var(--font-xs); }

/* ---- 全部合同页 · 翻页器（D41：TOAST UI Pagination vendor 本地，仅布局微调） ---- */
.contract-pager { display: flex; justify-content: center; margin: var(--space-4) 0 var(--space-2); }
/* 达成表行可下钻（D36）：行 hover 语义同 stat-card.drillable */
.achieve-row { cursor: pointer; }
.achieve-row:hover { background: var(--primary-weak); }

/* ---- 表格 ---- */
.table {
    width: 100%; border-collapse: collapse; background: var(--card);
    border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--shadow-xs);
}
.table th, .table td { padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--line); text-align: left; }
.table th { background: var(--surface-alt); color: var(--dim); font-weight: 600; font-size: var(--font-xs); }
.table tbody tr:hover { background: var(--primary-weak); }
.ledger-row { cursor: pointer; }
.name { font-weight: 600; }
/* 合同名语义组（D126 用户定案「合同名统一主题色蓝色，项目名统一加粗」）：
   蓝色 = 合同名（fu-link 锚点形态——此前零定义渲染 UA 默认蓝 #0000EE
   非主题色；fu-name/flow-ct-name/np-ct-name/ct-name = 各页文本形态）；
   粗体 = 项目名（.name 基类）——色彩与字重各归其主，两类名一眼可辨 */
.fu-link, .fu-name, .flow-ct-name, .np-ct-name, .ct-name { color: var(--primary); }
.fu-link { text-decoration: none; }
.fu-link:hover { text-decoration: underline; }
.empty { text-align: center; color: var(--dim); padding: 40px 0 !important; }
.hint { color: var(--dim); font-size: var(--font-xs); }

/* ---- 列收进度条（D69）----
   分段语义：实底紫 = 已列占应列比例（--type-income 分类色同源），
   浅紫 = 已规划未列段（--type-income-weak 淡底，绘制在下层），
   空段（轨道底色）= 尚未规划的没列部分；悬停 title 携带精确四金额。
   比例服务端算好内联 width，前端零计算；无解析目标的合同不渲染比例 */
.prog { display: flex; align-items: center; gap: var(--space-2); }
.prog-track {
    position: relative; flex: 1 1 auto; height: 12px;
    background: var(--bg); border: 1px solid var(--line);
    border-radius: var(--radius-pill); overflow: hidden;
}
.prog-plan, .prog-fill { position: absolute; top: 0; bottom: 0; left: 0; }
.prog-plan { background: var(--type-income-weak); }
.prog-fill { background: var(--type-income); }
.prog-pct {
    flex: 0 0 auto; min-width: 32px; text-align: right;
    font-size: var(--font-xs); color: var(--dim);
    font-variant-numeric: tabular-nums;
}
/* 超列收（已列>应列，没列为负）：百分比标签蘸 danger 提示方向异常 */
.prog-pct-over { color: var(--danger); font-weight: 600; }
/* 工作台合同归档节点预览块（D70）：进度条 + 四金额速览行 */
.prog-box {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
    margin-bottom: var(--space-3);
}
.prog-box .prog { flex: 1 1 260px; }
.prog-amounts { font-size: var(--font-xs); color: var(--dim); }
.prog-amounts.neg { color: var(--danger); }

/* ---- 严格画框：固定表格布局 ----
   table-layout:fixed + colgroup 列宽配比 -> 列位置不随内容漂移；
   超长文本单行省略，悬停 title 可见全文。所有列表页表格沿用 .fixed。 */
.table.fixed { table-layout: fixed; }
.table.fixed th, .table.fixed td {
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.table.fixed td.name:hover { text-decoration: underline dotted; }

/* ---- 考核结果容器表（D139）：金额列自适应内容（D94 纪律豁免，
   同 .drill-body 先例——大额千分位串禁止省略号截断；超宽由区块横滚承接） ---- */
.table.fixed.assess-result-tbl { table-layout: auto; }
.table.fixed.assess-result-tbl td,
.table.fixed.assess-result-tbl th { overflow: visible; text-overflow: clip; }
#assessment-result { overflow-x: auto; }

/* ---- 复制成功提示（右键复制根事件号） ---- */
#toast {
    position: fixed; left: 50%; bottom: 36px; transform: translateX(-50%);
    background: var(--text); color: var(--on-accent); padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-sm); font-size: var(--font-sm); opacity: 0;
    transition: opacity .25s; pointer-events: none; z-index: var(--z-toast);
}
#toast.show { opacity: .92; }

/* ---- 下钻明细浮窗（D36）：统计卡/达成卡点击弹出构成行 ----
   可拖拽（手柄=标题栏）+ 左右边缘吸附 + localStorage 记忆（app.js drillWindow，
   惯例同 funcFabDrag）；内容 = htmx 拉取的 stat_drill partial */
.drill-win {
    position: fixed; left: 50%; top: 96px; z-index: var(--z-drill);
    /* D104b 用户定案：浮窗宽度必须保证显示容器内元素——fit-content 随
       内容舒展（表格金额列 auto 布局的实测宽即窗口宽），短内容保持
       560px 旧默认宽；超出视口由 max-width 钳制（余量走 body 横向滚动） */
    width: fit-content; min-width: 560px; max-width: calc(100vw - 32px);
    background: var(--card); border: 1px solid var(--line);
    border-radius: var(--radius-md); box-shadow: var(--shadow-md);
    display: none; flex-direction: column; overflow: hidden;
}
.drill-win.open { display: flex; }
.drill-head {
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-2) var(--space-3); background: var(--surface-alt);
    border-bottom: 1px solid var(--line); cursor: grab; user-select: none;
}
.drill-win.dragging .drill-head { cursor: grabbing; }
.drill-title { font-size: var(--font-sm); font-weight: 600; flex: 1; min-width: 0;
               white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.drill-close {
    border: none; background: none; color: var(--dim); cursor: pointer;
    font-size: var(--font-md); padding: 2px 4px; flex: none;
}
.drill-close:hover { color: var(--danger); }
.drill-body { max-height: 60vh; overflow: auto; padding: var(--space-3); }
/* D104b 金额列纪律（用户定案：金额字段宽度必须适应内容，而非内容适应
   宽度）——fixed+ellipsis 会把大额千分位串截断成 "58,504,7…（D94 同款
   教训：含金额的表必须自适应）。下钻表在浮窗内改 auto 布局：colgroup
   百分比退化为配比建议，金额列随内容舒展；列宽超窗由 .drill-body 横向
   滚动承接（画框=配比建议仍在，截断不再有） */
.drill-body .table.fixed { table-layout: auto; }
.drill-body .table.fixed td, .drill-body .table.fixed th {
    overflow: visible; text-overflow: clip; }
/* 五态：loading / error / empty（缺行时 partial 自带 .empty 行） */
.drill-state { text-align: center; color: var(--dim); font-size: var(--font-sm); padding: var(--space-6) 0; }
.drill-state.error { color: var(--danger); }
.drill-body .table.inner { box-shadow: none; border: 1px solid var(--line); }
.drill-body .table.inner th { font-size: var(--font-xs); padding: 4px 8px; }
.drill-body .table.inner td { padding: 4px 8px; font-size: var(--font-xs); }
/* 未落季（缺归档日期）行：熟赭点亮——D35 暖族承担缺口职能 */
.drill-row-na td { color: var(--warn); }
.drill-foot { padding: 4px var(--space-3) var(--space-2); color: var(--dim); font-size: var(--font-xs);
              border-top: 1px dashed var(--line); }

/* ---- 合同预览下拉 ---- */
.drop-btn {
    border: 1px solid var(--primary); background: var(--primary-weak);
    color: var(--primary); padding: 3px 8px; border-radius: var(--radius-sm);
    cursor: pointer; font-size: var(--font-xs);
}
.drop-btn:hover { background: var(--primary); color: var(--on-accent); }
/* 面板行本体塌缩不可见（D61：展开不再挤动台账布局）——内容提升为 fixed 浮层，
   td 仅作 DOM 宿主，高度/字号归零避免留缝 */
tr.contract-panel > td { padding: 0 !important; border: 0 !important;
                         height: 0; font-size: 0; line-height: 0; background: transparent; }
/* 合同明细浮层：fixed 定位锚定下拉按钮（app.js placePanelFloat 定位），
   z 20 = 下拉面板层级（高于 sticky 表头 3，低于 func-fab 50/浮窗 60）；
   显式重置字号——宿主 td 为消行盒设了 font-size:0，fixed 元素仍按 DOM 继承 */
.panel-float { position: fixed; z-index: var(--z-panel); overflow: hidden;
               display: flex; flex-direction: column;
               font-size: var(--font-md); line-height: 1.6;
               background: var(--card); border: 1px solid var(--line);
               border-radius: var(--radius-md); box-shadow: var(--shadow-md); }
/* D127 拖拽把手条（drill-head 同族语言）：拖动自由 + 松手吸附左右视口缘
   + localStorage 钉住（panel-pos）——钉住后打开任何合同 ▾ 都在钉点换内容；
   滚动区下沉 .pf-body（hx-get swap innerHTML 不吞把手） */
.pf-grip { display: flex; align-items: center; gap: var(--space-2);
           flex: none; padding: 3px var(--space-2);
           background: var(--surface-alt); border-bottom: 1px solid var(--line);
           cursor: grab; user-select: none; touch-action: none; }
.pf-grip:active { cursor: grabbing; }
.pf-grip-label { flex: 1 1 auto; min-width: 0; font-size: var(--font-xs);
                 color: var(--dim); overflow: hidden;
                 text-overflow: ellipsis; white-space: nowrap; }
.pf-unpin { display: none; }
.panel-float.pinned .pf-unpin { display: inline-flex; }
.panel-float.pinned .pf-grip { background: var(--primary-weak);
                               border-bottom-color: var(--primary); }
.pf-body { flex: 1 1 auto; min-height: 0; overflow: auto;
           padding: var(--space-2); }
.panel-cell { border-radius: var(--radius-sm); }
/* D104b 嵌套下拉（列收按合同聚合）：浮窗内生成的面板浮层必须盖过浮窗
   本体（全局 .panel-float z 20 < .drill-win z 60，不提层会被浮窗遮住） */
.drill-win .panel-float { z-index: var(--z-drill-top); }
.table.inner { box-shadow: none; border: 1px solid var(--line); }
.table.inner th { font-size: var(--font-xs); padding: 4px 8px; }
.table.inner td { padding: 4px 8px; }

/* ---- 状态徽标（四态） ---- */
.badge {
    display: inline-block; padding: 1px var(--space-2); border-radius: var(--radius-pill);
    font-size: var(--font-xs); color: var(--on-accent);
}
.badge-status-已分配   { background: var(--ok); }
.badge-status-单位已分 { background: var(--half); }
.badge-status-条线已分 { background: var(--warn); }
.badge-status-未分配   { background: var(--dim); }
.badge-change-CREATE  { background: var(--type-neutral); }
.badge-change-SET     { background: var(--warn); }
.badge-change-APPEND  { background: var(--half); }

/* ---- 项目工作台：左树右明细 ---- */
.workbench { display: flex; gap: var(--space-4); align-items: flex-start; }
.tree-col { flex: 0 0 400px; min-width: 0; background: var(--card); border-radius: var(--radius-md); padding: var(--space-4);
            box-shadow: var(--shadow-xs); }
.detail-col { flex: 1; background: var(--card); border-radius: var(--radius-md); padding: var(--space-4);
              box-shadow: var(--shadow-xs); min-height: 300px;
              /* D57：flex 子项默认 min-width:auto——右侧操作日志/相邻卡等宽内容
                 曾把整行撑破（scrollWidth 1039 > 853 视口，徽标与按钮被裁）；
                 min-width:0 放行收缩 + 内部横向滚动兜底 */
              min-width: 0; overflow-x: auto; }

.summary-line { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: var(--space-3); }

/* ---- 工作台树组件（D31）：InspireTree 渲染，定制紧凑风格/类型色/VOID 置灰 ----
   展开收起、缩进层级、选中高亮由组件负责（vendor/inspire-tree-light.min.css）。
   组件实际 DOM：容器自身挂 .inspire-tree 类，节点是 li（无 .node 类），
   文字/类型类（itree.a.attributes.class）都落在 a.title 锚点上 */
.tree { min-height: 120px; }
.tree.inspire-tree { font-size: var(--font-sm); }
.tree.inspire-tree a.title { font-size: var(--font-sm); }
/* D108：树节点标题自动换行——vendor 主题 .title 为 nowrap+25px 定高+ellipsis，
   nowrap 文本的 min-content 会把 .tree-col（flex:0 0 400px，min-width:auto）
   顶宽（省略号根本没机会出现），整行 workbench 被长树名撑破。
   改为多行自动换行：height 放开 + overflow-wrap:anywhere 兜底无空格长串
   （合同名/编号连写）；chevron 是独立 25×25 绝对定位盒，不受行高变化影响 */
.tree.inspire-tree .title {
    height: auto; min-height: 25px;
    white-space: normal; overflow: visible; text-overflow: clip;
    overflow-wrap: anywhere;
}
.tree.inspire-tree li { cursor: pointer; }
.tree.inspire-tree li:hover > .title-wrap > .title { color: var(--primary); }
.tree.inspire-tree li.selected > .title-wrap > .title {
    color: var(--primary); background: var(--primary-weak); border-radius: var(--space-1); }
.tree.inspire-tree a.void {
    color: var(--dim); opacity: .6; text-decoration: line-through; }
/* 图标方案（D31 修订）：弃用主题自带的文件夹/加号字形，改为 VS Code 式极简
   chevron——折叠朝右、展开旋 90° 朝下（toggle 锚点类 icon-expand/icon-collapse
   随状态切换）；标题的 folder/file 字形整体隐藏，层级靠缩进+chevron 表达。
   注意：data URI 内无法引用 CSS 变量，stroke 值镜像 --dim（#6a6f6b），
   改 --dim 时必须同步这里 */
.tree.inspire-tree a.toggle:before {
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M4 2.5l4 3.5-4 3.5' fill='none' stroke='%236a6f6b' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / 10px 10px;
    transition: transform .15s ease; }
.tree.inspire-tree a.toggle.icon-collapse:before {
    transform: translate(-50%, -50%) rotate(90deg); }
.tree.inspire-tree li:hover > .title-wrap > a.toggle:before { filter: brightness(.75); }
.tree.inspire-tree a.title.icon:before { display: none; }
/* 类型色（挂在组件 title 锚点类上，值引用 --type-* 组） */
.tree a.type-submission { color: var(--primary); font-weight: 600; }
.tree a.type-project_award,
.tree a.type-project_direct { color: var(--type-award); font-weight: 600; }
.tree a.type-contract_approval,
.tree a.type-investment_approval { color: var(--type-approval); }
.tree a.type-contract_archive { color: var(--type-archive); font-weight: 600; }
.tree a.type-contract_income { color: var(--type-income); }
.tree a.type-contract_refund,
.tree a.type-contract_reversal { color: var(--type-refund); }
.tree a.type-unit_allocation,
.tree a.type-line_allocation { color: var(--type-alloc); }
.tree a.type-integration_income_plan,
.tree a.type-agency_income_plan,
.tree a.type-telecom_income_plan,
.tree a.type-device_sales_plan,
.tree a.type-contract_parse,
.tree a.type-contract_income_plan,
.tree a.type-contract_flow_parse,
.tree a.type-contract_flow_start,
.tree a.type-contract_flow_procurement,
.tree a.type-contract_flow_cost_contract,
.tree a.type-contract_flow_acceptance,
.tree a.type-contract_flow_income_adjust,
.tree a.type-contract_flow_cost_match,
.tree a.type-contract_flow_bpm,
.tree a.type-project_log,
.tree a.type-investment_income_plan { color: var(--dim); }

.op-count { color: var(--dim); font-size: var(--font-xs); margin-left: auto; }
.back { display: inline-block; margin-top: var(--space-3); color: var(--primary); text-decoration: none; }

.parent-hint { color: var(--dim); font-size: var(--font-xs); font-weight: 400; margin-left: var(--space-2); }
.value { font-weight: 600; }

/* ---- 工作台节点操作区（挂子/补录/作废恢复） ---- */
.node-actions {
    display: flex; gap: var(--space-2); flex-wrap: wrap;
    margin-top: var(--space-3); padding-top: var(--space-2); border-top: 1px dashed var(--line);
}
.act-btn {
    border: 1px solid var(--primary); background: var(--card); color: var(--primary);
    padding: 4px var(--space-3); border-radius: var(--radius-sm); cursor: pointer; font-size: var(--font-sm);
}
.act-btn:hover { background: var(--primary-weak); }
.act-btn.danger { border-color: var(--danger); color: var(--danger); }
.act-btn.danger:hover { background: var(--danger); color: var(--on-accent); }
.act-btn.warn { border-color: var(--warn); color: var(--warn); }
.act-btn.warn:hover { background: var(--warn); color: var(--on-accent); }

/* ---- VOID 节点徽标 ---- */
.badge-void { background: var(--dim); }

/* ---- 面板内嵌操作表单卡 ---- */
.op-form {
    margin-top: var(--space-3); padding: var(--space-3);
    border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--surface-alt);
}
.op-form .form-title { font-size: var(--font-sm); font-weight: 600; margin-bottom: var(--space-2); }
.op-form .field-row { display: flex; flex-direction: column; gap: 3px; margin-bottom: var(--space-2); }
.op-form .field-row label { font-size: var(--font-xs); color: var(--dim); }
.op-form input, .op-form select, .op-form textarea {
    padding: var(--space-2); border: 1px solid var(--line); border-radius: var(--radius-sm);
    font: inherit; background: var(--card); width: 100%; max-width: 420px;
}
.op-form textarea { max-width: 100%; }
.op-form .form-actions { display: flex; gap: var(--space-2); align-items: center; margin-top: 4px; }
.op-form .form-close {
    border: none; background: none; color: var(--dim); cursor: pointer; font-size: var(--font-sm);
}
.op-form .form-close:hover { color: var(--text); }
.op-form .cascade-note { color: var(--warn); font-size: var(--font-xs); margin: 0 0 var(--space-2); }

/* ---- 录入项目页（新建项目树） ---- */
.op-form.new-project { max-width: 560px; margin: var(--space-4) auto 0; background: var(--card); }
.op-form.new-project .form-error {
    color: var(--danger); font-size: var(--font-sm); margin: 4px 0 var(--space-2);
}

/* 滑块开关（现代 toggle）：隐藏原生 checkbox，滑块纯 CSS 绘制。
   注意 .op-form input 的 width:100% 会把 checkbox 撑满 -> 文字被挤到最右，
   故 switch-input 显式收回宽度 */
.op-form input.switch-input {
    position: absolute; opacity: 0; pointer-events: none;
    width: auto; max-width: none;
}
.switch-label {
    display: inline-flex; align-items: center; gap: var(--space-2);
    cursor: pointer; font-size: var(--font-md); color: var(--text);
    flex-direction: row !important;   /* 覆盖 .field-row 的纵向 flex */
}
.switch-slider {
    flex: none; width: 40px; height: 22px; border-radius: var(--radius-pill);
    background: var(--line); position: relative; transition: background .2s;
}
.switch-slider::after {
    content: ""; position: absolute; top: 2px; left: 2px;
    width: 18px; height: 18px; border-radius: 50%; background: var(--card);
    box-shadow: var(--shadow-xs); transition: transform .2s;
}
.switch-input:checked + .switch-slider { background: var(--ok); }
.switch-input:checked + .switch-slider::after { transform: translateX(18px); }
.switch-input:focus-visible + .switch-slider { outline: 2px solid var(--primary); }

/* ---- 跟进纳管录入页（D145 体验地图 v2；勘误批：用户面叫「新建项目」） ---- */
/* 挂网时间三框日期行（D145 勘误）：年/月/日下拉——选择即合法值，禁自由文本 */
.fu-date-row {
    display: flex; gap: var(--space-2);
}
.fu-date-row select { flex: 1; min-width: 0; }
/* 金额行：输入框 + 单位分段选择器并排 */
.fu-amount-row {
    display: flex; align-items: center; gap: var(--space-2);
}
.fu-amount-row input { flex: 1; min-width: 0; }
/* 金额单位分段选择器（新容器登记 components.md D145）：行内 [元|万元] */
.seg {
    display: inline-flex; flex: none; overflow: hidden;
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--card);
}
.seg-btn {
    padding: var(--space-2) 14px; border: none; cursor: pointer;
    background: transparent; color: var(--dim); font-size: var(--font-sm);
    transition: background .15s, color .15s;
}
.seg-btn + .seg-btn { border-left: 1px solid var(--line); }
.seg-btn.active { background: var(--primary); color: var(--on-accent); }
.seg-btn:hover:not(.active) { background: var(--primary-weak); color: var(--primary); }

/* ---- 母卡片栅格（D148 建）→ D149 tile 重排：一类评估一张卡（tile 即
   唯一入口），4pt 栅格归位（--space-* 全 token，无 2/3/6px 裸值） ---- */
.fu-review { margin: 0 0 var(--space-4); }
.fr-head { display: flex; align-items: baseline; gap: var(--space-2);
           margin-bottom: var(--space-2); }
.fr-head h2 { font-size: var(--font-lg); margin: 0; }
.fr-count { color: var(--dim); font-size: var(--font-sm); }
.fu-cards { display: grid; grid-template-columns: 1fr; gap: var(--space-4); }
.fu-card { background: var(--card); border: 1px solid var(--line);
           border-radius: var(--radius-md); padding: var(--space-4);
           display: grid; gap: var(--space-3); min-width: 0; }
.fu-card.overdue { border-color: var(--danger); }   /* 挂网规划过期未实现 */
.fc-head { display: flex; align-items: center; gap: var(--space-2);
           flex-wrap: wrap; min-width: 0; }
.fc-name { font-weight: 600; color: var(--text); text-decoration: none;
           overflow-wrap: anywhere; }
.fc-name:hover { color: var(--primary); }
.fc-dim { color: var(--dim); font-size: var(--font-xs); }
.badge-overdue { background: var(--danger); color: var(--on-accent);
                 padding: var(--space-1) var(--space-2);
                 border-radius: var(--radius-pill); font-size: var(--font-xs); }
.fc-form { border-top: 1px dashed var(--line); padding-top: var(--space-3); }
.fc-form .form-error { color: var(--danger); font-size: var(--font-sm);
                       margin: var(--space-1) 0; }
.fc-form-foot { display: flex; gap: var(--space-2); margin-top: var(--space-2); }

/* ---- 母卡片二级区（D149 重排）：一类评估一张 tile 卡，tile 即唯一入口 ---- */
.fh-log { display: flex; align-items: baseline; gap: var(--space-3);
          flex-wrap: wrap; min-width: 0; border-top: 1px solid var(--line);
          padding-top: var(--space-3); }
.fh-log.stale { background: var(--surface-alt); border-radius: var(--radius-md);
                margin: 0 calc(-1 * var(--space-3));
                padding: var(--space-2) var(--space-3) var(--space-2) var(--space-3); }
.fh-tag { flex: none; font-size: var(--font-xs); color: var(--on-accent);
          background: var(--type-neutral); border-radius: var(--radius-sm);
          padding: var(--space-1) var(--space-2); }
.fh-log-main { display: flex; align-items: baseline; gap: var(--space-3);
               flex: 1; min-width: 0; flex-wrap: wrap; }
.fh-log-text { margin: 0; font-size: var(--font-sm); color: var(--text);
               min-width: 0; overflow-wrap: anywhere; }
.fh-log-text.dim { color: var(--dim); }
.fh-log-time { color: var(--dim); font-size: var(--font-xs); }
.fh-more { margin-left: auto; font-size: var(--font-xs); color: var(--primary);
           text-decoration: none; }
.fh-more:hover { text-decoration: underline; }
.fh-assess { display: flex; flex-direction: column; gap: var(--space-3);
             min-width: 0; border-top: 1px solid var(--line);
             padding-top: var(--space-3); }
.fh-sec-head { display: flex; align-items: baseline; gap: var(--space-3); }
.fh-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
            gap: var(--space-3); min-width: 0; }
.fh-tile { display: flex; flex-direction: column; gap: var(--space-1);
           background: var(--surface-alt); border: 1px solid var(--line);
           border-radius: var(--radius-md); padding: var(--space-3); min-width: 0; }
.fh-tile.pending { border-style: dashed; border-color: var(--primary);
                   background: var(--card); color: var(--primary); cursor: pointer;
                   text-align: left; font: inherit; }
.fh-tile.pending:hover { background: var(--primary-weak); }
.fh-tile.pending:focus-visible { outline: 2px solid var(--primary); }
.fh-tile.warn, .fh-tile.overdue { border-color: var(--danger); }
.ft-label { font-size: var(--font-xs); color: var(--dim); }
.ft-value { font-size: var(--font-md); font-weight: 600; color: var(--text);
            overflow-wrap: anywhere; }
.ft-days { font-size: var(--font-xs); color: var(--danger); font-weight: 600; }
.ft-hint { font-size: var(--font-xs); color: var(--dim); }
.ft-action { font-size: var(--font-xs); color: var(--primary); background: none;
             border: none; padding: 0; cursor: pointer; text-align: left; }
.ft-action:hover { text-decoration: underline; }
.fu-card.done { opacity: .72; }   /* 暂停/归档树沉底置灰 */

/* ---- 母卡片两态（D152）：收起态摘要行 + 展开态 lazy 明细 ---- */
/* 头部右端：变更信息✎（工作台留痕通路）+ 展开 toggle */
.fc-edit { margin-left: auto; color: var(--dim); text-decoration: none;
           font-size: var(--font-sm); padding: 0 var(--space-1); }
.fc-edit:hover { color: var(--primary); }
.fc-toggle { flex: none; border: 1px solid var(--line); background: var(--card);
             color: var(--dim); border-radius: var(--radius-pill);
             padding: var(--space-1) var(--space-3); cursor: pointer;
             font-size: var(--font-xs); }
.fc-toggle:hover { border-color: var(--primary); color: var(--primary); }
.fc-toggle[aria-expanded="true"] { border-color: var(--primary); color: var(--primary); }
/* 紧凑摘要行：评估节点单行 + 最新日志一行（收起态全部信息密度所在） */
.fc-brief { display: grid; gap: var(--space-2); border-top: 1px solid var(--line);
            padding-top: var(--space-3); min-width: 0; }
.fb-row { display: flex; align-items: baseline; gap: var(--space-3);
          flex-wrap: wrap; min-width: 0; }
.fb-node { display: inline-flex; align-items: baseline; gap: var(--space-1);
           min-width: 0; }
.fb-k { font-size: var(--font-xs); color: var(--dim); flex: none; }
.fb-v { font-size: var(--font-sm); color: var(--text); min-width: 0; }
.fb-node.pending .fb-v { color: var(--dim); }
.fb-node.warn .fb-v, .fb-node.overdue .fb-v { color: var(--danger); font-weight: 600; }
.fb-assess .fh-more { margin-left: auto; }
.fb-log-text { font-size: var(--font-sm); color: var(--text); min-width: 0;
               overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fb-log-text.dim { color: var(--dim); }
.fb-log-time { font-size: var(--font-xs); color: var(--dim); flex: none; }
.fb-log.stale { background: var(--surface-alt); border-radius: var(--radius-md);
                padding: var(--space-1) var(--space-2); }   /* D152 勘误：负 margin 出血致摘要行横向溢出 8px，回内容盒 */
.fb-log .fh-more { margin-left: auto; }
/* 展开态宿主与内嵌表单骨架（.fc-form 表单形态补齐——D80「类名在场≠形态在场」
   同款勘误：btn-main/form-close/form-title 原为 .op-form/.btn 作用域，卡片
   行内表单从未获得形态；D152 日志表单入场时一并补齐） */
.fc-detail { border-top: 1px dashed var(--line); padding-top: var(--space-3);
             display: grid; gap: var(--space-3); min-width: 0; }
/* D152 mockup 两栏：左 = 评估卡纵向单列（作业面主体），右 = 项目日志栏 */
.fd-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 360px);
             gap: var(--space-3); align-items: start; }
@media (max-width: 960px) { .fd-layout { grid-template-columns: 1fr; } }
.fc-form .form-title { font-size: var(--font-sm); font-weight: 600;
                       margin-bottom: var(--space-2); }
.fc-form .btn-main { padding: var(--space-2) var(--space-4); border: none;
                     border-radius: var(--radius-sm); background: var(--primary);
                     color: var(--on-accent); cursor: pointer;
                     font-size: var(--font-sm); transition: background .15s; }
.fc-form .btn-main:hover { background: var(--primary-hover); }
.fc-form .form-close { border: none; background: none; color: var(--dim);
                       cursor: pointer; font-size: var(--font-sm); }
.fc-form .form-close:hover { color: var(--text); }
.fc-form textarea, .fc-form input {
    padding: var(--space-2); border: 1px solid var(--line);
    border-radius: var(--radius-sm); font: inherit; background: var(--card);
    width: 100%; max-width: 420px; }
/* 展开态①：项目日志卡（条目 = 大日期 + 删除标记 + 正文缩进） */
.fd-log { background: var(--surface-alt); border: 1px solid var(--line);
          border-radius: var(--radius-md); padding: var(--space-3);
          display: grid; gap: var(--space-2); min-width: 0; }
.fd-head { display: flex; align-items: baseline; gap: var(--space-3); }
.fd-head h3 { font-size: var(--font-md); margin: 0; }
.fd-newlog { margin-left: auto; border: 1px solid var(--line); background: var(--card);
             color: var(--text); border-radius: var(--radius-pill); cursor: pointer;
             font-size: var(--font-xs); padding: var(--space-1) var(--space-3); }
.fd-newlog:hover { border-color: var(--primary); color: var(--primary); }
.fd-logform[hidden] { display: none; }
.fd-log-item { background: var(--card); border: 1px solid var(--line);
               border-radius: var(--radius-md); padding: var(--space-3);
               min-width: 0; }
.fd-log-item.marked { opacity: .55; }
.fd-log-head { display: flex; align-items: baseline; gap: var(--space-2); }
.fd-log-date { font-size: var(--font-md); font-weight: 600; color: var(--text); }
.fd-log-by { font-size: var(--font-xs); color: var(--dim); }
.fd-log-del { margin-left: auto; border: none; background: none; color: var(--dim);
              cursor: pointer; font-size: var(--font-sm); line-height: 1;
              padding: var(--space-1); }
.fd-log-del:hover { color: var(--danger); }
.fd-log-body { margin: 0; padding-left: var(--space-4); font-size: var(--font-sm);
               color: var(--text); overflow-wrap: anywhere; }
/* 展开态②：类型评估卡纵向单列（mockup：左栏一列白卡，明细多行） */
.fd-types { display: grid; gap: var(--space-3); min-width: 0; }
.fd-type { background: var(--card); border: 1px solid var(--line);
           border-radius: var(--radius-md); padding: var(--space-3);
           display: grid; gap: var(--space-2); min-width: 0;
           align-content: start; }
.fd-type.warn, .fd-type.overdue { border-color: var(--danger); }
/* 卡头行（mockup：「签约评估｜完成期限:… 签约目标:… …… 右端变更评估✎」同行） */
.fd-type-head { display: flex; align-items: center; gap: var(--space-2);
                flex-wrap: wrap; min-width: 0; }
.fd-type-head h3 { font-size: var(--font-md); margin: 0; flex: none; }
.fd-sep { color: var(--line); flex: none; }
.fd-deadline { font-size: var(--font-xs); color: var(--text); flex: none; }
.fd-edit { margin-left: auto; border: 1px solid var(--line); background: var(--card);
           color: var(--text); border-radius: var(--radius-pill); cursor: pointer;
           font-size: var(--font-xs); padding: var(--space-1) var(--space-3);
           flex: none; }
.fd-edit:hover { border-color: var(--primary); color: var(--primary); }
.fd-minor { border: none; background: none; color: var(--primary); cursor: pointer;
            font-size: var(--font-xs); padding: 0; flex: none; }
.fd-minor:hover { text-decoration: underline; }
/* 状态 pill（D152 明细行）：ok = 语义绿描边（--ok 徽标分工，D67）；pending = 灰 */
.pill { display: inline-block; font-size: var(--font-xs); line-height: 1;
        padding: var(--space-1) var(--space-2); border-radius: var(--radius-pill);
        border: 1px solid var(--line); color: var(--dim); flex: none; }
.pill.ok { border-color: var(--ok); color: var(--ok); }
.pill-amount { border-color: var(--line); color: var(--text); }
.pill-big { font-size: var(--font-sm); font-weight: 600;
            padding: var(--space-1) var(--space-3); }
.fd-rows { list-style: none; margin: 0; padding: 0; display: grid;
           gap: var(--space-1); min-width: 0; }
.fd-row { display: flex; align-items: center; gap: var(--space-2);
          font-size: var(--font-sm); min-width: 0; flex-wrap: wrap; }
.fd-row-name { color: var(--text); font-weight: 600; font-size: var(--font-xs);
               flex: none; }
.fd-row-meta { font-size: var(--font-xs); color: var(--ok); flex: none; }
/* 页脚右对齐（mockup）：已完成灰 / 未完成·超期红色强调，天数加大加粗 */
.fd-foot { display: flex; align-items: baseline; gap: var(--space-4);
           justify-content: flex-end; flex-wrap: wrap; min-width: 0;
           font-size: var(--font-sm); color: var(--text);
           border-top: 1px solid var(--line); padding-top: var(--space-2); }
.fd-foot-left { color: var(--danger); font-weight: 600; }
.fd-foot-days { color: var(--danger); font-weight: 700;
                font-size: var(--font-md); }
.fd-foot-done { color: var(--ok); font-weight: 600; }
/* 收起态头部金额 chip 未评态：虚线描边可点（评估入口，tile 退役后唯一金额口） */
.chip-dashed { border: 1px dashed var(--primary); color: var(--primary);
               background: var(--card); cursor: pointer; }
.chip-dashed:hover { background: var(--primary-weak); }

/* ---- 评估详情二级页（D148）：六类型分节 + 列收账期子卡 ---- */
.as-sections { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
               gap: var(--space-3); }
.as-type { background: var(--card); border: 1px solid var(--line);
           border-radius: var(--radius-md); padding: var(--space-3); min-width: 0; }
.as-type.overdue, .as-type.warn { border-color: var(--danger); }
.as-head { display: flex; align-items: center; gap: var(--space-2);
           margin-bottom: var(--space-2); }
.as-head h2 { font-size: var(--font-md); margin: 0; flex: 1; min-width: 0; }
.as-body { display: flex; flex-direction: column; gap: var(--space-2); }
.as-row { display: flex; gap: var(--space-2); font-size: var(--font-sm);
          min-width: 0; }
.as-k { flex: none; color: var(--dim); }
.as-v { min-width: 0; overflow-wrap: anywhere; font-weight: 600; }
.as-sub { font-size: var(--font-sm); color: var(--dim); }
.as-contract { border: 1px dashed var(--line); border-radius: var(--radius-sm);
               padding: var(--space-2); min-width: 0; }
.as-contract h3 { margin: 0 0 var(--space-2); font-size: var(--font-sm); }
.as-plan-tbl { width: 100%; font-size: var(--font-xs); }
.as-plan-tbl th, .as-plan-tbl td { padding: var(--space-1) var(--space-2); text-align: left; }
.as-plan-tbl .num { text-align: right; }
.as-plan-tbl .as-income td { color: var(--ok); }

/* ---- 登记审批表页：收入规划行式容器（D19） ---- */
.income-row {
    display: flex; align-items: center; gap: var(--space-2);
    background: var(--primary-weak); border-radius: var(--radius-sm);
    padding: 4px 8px; margin-bottom: var(--space-2);
}
.income-row .row-type {
    flex: 0 0 188px; padding: var(--space-2); border: 1px solid var(--line);
    border-radius: var(--radius-sm); font-size: var(--font-sm); background: var(--card);
}
.income-row .row-fields {
    flex: 1; display: flex; gap: 4px; flex-wrap: wrap;
}
.income-row .row-fields input {
    flex: 1 1 128px; min-width: 108px; padding: var(--space-2);
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    font-size: var(--font-sm); background: var(--card);
}
.income-row .row-del {
    flex: none; border: none; background: none; color: var(--danger);
    cursor: pointer; font-size: var(--font-md); padding: 4px;
}

/* ---- 工作台：相邻节点卡（D24-S1）——父 + 直接子，点击跳转选中 ---- */
.adjacent-box {
    display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
    margin: 0 0 var(--space-3); padding: var(--space-2);
    background: var(--bg); border-radius: var(--radius-md);
}
.adj-label { font-size: var(--font-xs); color: var(--dim); flex: none; }
.adj-card {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 4px 8px; border: 1px solid var(--line); border-radius: var(--radius-lg);
    background: var(--card); font-size: var(--font-xs); cursor: pointer; color: var(--text);
    transition: border-color .15s, color .15s;
}
.adj-card:hover { border-color: var(--primary); color: var(--primary); }
.adj-card.void { opacity: .55; text-decoration: line-through; }
.adj-none { font-size: var(--font-xs); color: var(--dim); }

/* ---- 树操作列（D30 终版）：workbench 最左独立竖排画框，透明无填充 ----
   树级全局功能依次向下排列；表单展开在树列摘要区下（.tree-op-form） */
.tree-ops {
    flex: 0 0 148px; padding: var(--space-3) var(--space-2); align-self: flex-start;
    background: transparent; border: 1px dashed var(--line); border-radius: var(--radius-lg);
    display: flex; flex-direction: column; gap: var(--space-2);
}
.tree-ops .pill-btn { width: 100%; padding: var(--space-2); font-size: var(--font-sm); }

/* 电信蓝胶囊按钮：两头全圆、白字（树级主操作视觉）——品牌强调色 --info */
.pill-btn {
    padding: var(--space-2) var(--space-5); border: none; border-radius: var(--radius-pill);
    background: var(--info); color: var(--on-accent); font-size: var(--font-sm); font-weight: 600;
    cursor: pointer; letter-spacing: 1px;
    transition: background .15s, box-shadow .15s;
}
.pill-btn:hover { background: var(--info-hover); box-shadow: var(--glow-info); }

/* 树级表单容器（分配规划等全局动作的展开区，复用 op-form 内部样式体系） */
.tree-op-form { margin-top: var(--space-2); }
.tree-op-form .form-title { margin-bottom: var(--space-2); }

/* 收入规划行式容器（D58）：行 = 类型下拉 + 随类型重渲字段区 + 删行；
   虚线框与全站"行式容器"语言一致（D19 登记页收入规划同范式） */
.income-row {
    display: grid; gap: var(--space-2);
    padding: var(--space-2); margin-bottom: var(--space-2);
    border: 1px dashed var(--line); border-radius: var(--radius-md);
}
.tree-op-form .income-add { width: 100%; }

/* ---- 工作台：迁移向导预览卡（D24） ---- */
.reparent-preview:empty { display: none; }
.preview-card {
    margin-top: var(--space-2); padding: var(--space-2) var(--space-3);
    background: var(--bg); border-radius: var(--radius-md); font-size: var(--font-sm);
}
.preview-line { margin-bottom: 4px; }
.preview-warn { color: var(--warn); font-size: var(--font-xs); margin-top: 4px; }

/* ---- 工作台：分配规划表单（D23，planner 前端化）——单位/条线行式容器 ---- */
.alloc-sys { margin-bottom: var(--space-3); }
.alloc-sys-head {
    display: flex; align-items: center; gap: var(--space-2);
    font-size: var(--font-sm); font-weight: 600; margin-bottom: 4px;
}
.alloc-sum { font-size: var(--font-xs); font-weight: 400; color: var(--dim); }
.alloc-sum.ok { color: var(--ok); font-weight: 600; }   /* 合计=100% 达标绿 */
.alloc-add {
    margin-left: auto; font-size: var(--font-xs); padding: 3px 8px;
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--card); cursor: pointer;
}
.alloc-add:hover { border-color: var(--primary); color: var(--primary); }
.alloc-row { display: flex; gap: 4px; margin-bottom: 4px; }
.alloc-row .a-name {
    flex: 2; padding: var(--space-2); border: 1px solid var(--line);
    border-radius: var(--radius-sm); font-size: var(--font-sm); background: var(--card);
}
.alloc-row .a-ratio {
    flex: 1; padding: var(--space-2); border: 1px solid var(--line);
    border-radius: var(--radius-sm); font-size: var(--font-sm); background: var(--card);
}
.alloc-row .row-del {
    flex: none; border: none; background: none; color: var(--danger);
    cursor: pointer; font-size: var(--font-md); padding: 4px;
}

/* ---- 悬浮录入按钮（FAB）：右下角 + 悬停浮出快捷录入菜单 ----
   D97：菜单改 absolute 悬浮（不占布局）——收起态 hover 热区收缩到按钮本体
   （旧实现 opacity:0 仍占布局，热区=按钮+整块隐形菜单，离按钮很远即触发）；
   box 尺寸随之=按钮本体，拖拽吸附/夹取判定精准，贴左缘时按钮真正贴边。
   at-top（app.js 施加）：按钮靠屏幕上半时菜单改为向下弹出，防裁切 */
.fab {
    position: fixed; right: 28px; bottom: 28px; z-index: var(--z-fab);
}
.fab-main {
    width: 52px; height: 52px; border: none; border-radius: 50%;
    background: var(--primary); color: var(--on-accent); font-size: var(--font-2xl); line-height: 1;
    cursor: grab; box-shadow: var(--shadow-sm); touch-action: none;
    transition: transform .2s, background .2s;
}
.fab-main:hover { background: var(--primary-hover); }
.fab:hover .fab-main { transform: rotate(45deg); }   /* 悬停时 + 转 × */
/* 拖拽态（D76，app.js fabDrag）：按住拖动时压制 hover 菜单展开与「＋」旋转、
   禁过渡防拖动闪烁；touch-action:none 防触屏手势接管拖拽 */
.fab.dragging { cursor: grabbing; }
.fab.dragging .fab-menu { opacity: 0; pointer-events: none; visibility: hidden; transition: none; }
.fab.dragging .fab-main { transform: none; transition: none; }

/* 菜单：absolute 悬浮于按钮上方（紧贴按钮顶缘 + padding 造视觉间距，
   热区连续——鼠标在按钮与菜单间移动不丢 :hover），收起 visibility 隐藏。
   width:max-content 必须：absolute 盒的 shrink-to-fit 以包含块（=按钮盒
   52px）为可用宽度，条目会被压到逐字换行成纵向（D99）；max-content 让
   菜单按内容单行舒展。at-left（app.js 施加）：按钮贴左缘时菜单改向右
   展开+条目左对齐，防菜单伸出屏幕左缘 */
.fab-menu {
    position: absolute; right: 0; bottom: 100%; width: max-content;
    display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-2);
    padding-bottom: var(--space-2);
    opacity: 0; transform: translateY(10px); pointer-events: none; visibility: hidden;
    transition: opacity .18s, transform .18s, visibility .18s;
}
.fab:hover .fab-menu { opacity: 1; transform: translateY(0); pointer-events: auto; visibility: visible; }
.fab.at-top .fab-menu { bottom: auto; top: 100%; padding-bottom: 0; padding-top: var(--space-2);
                        transform: translateY(-10px); }
.fab.at-left .fab-menu { right: auto; left: 0; align-items: flex-start; }

.fab-item {
    display: flex; align-items: center; gap: var(--space-2);
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-pill);
    padding: var(--space-2) var(--space-4); cursor: pointer; font-size: var(--font-md); color: var(--text);
    box-shadow: var(--shadow-sm);
    text-decoration: none;
    transition: background .15s, transform .15s;
}
.fab-item:hover { background: var(--primary-weak); transform: translateX(-2px); }
.fab-item .fab-ico {
    font-size: var(--font-xs); color: var(--primary); background: var(--primary-weak);
    border-radius: var(--space-1); padding: 1px 4px;
}
.fab-item.disabled { color: var(--dim); cursor: not-allowed; }
.fab-item.disabled .fab-ico { color: var(--dim); background: var(--bg); }
.fab-item.disabled:hover { background: var(--card); transform: none; }

/* ---- 悬浮功能入口（D20）：应用按钮（四宫格图标），
   可拖拽+自动吸附左右边框（app.js funcFabDrag），悬停弹出功能面板 ----
   D97：面板改 absolute 悬浮（不占布局）——收起态 hover 热区收缩到按钮本体；
   box 尺寸=按钮本体，拖拽吸附判定精准。方向适配：at-right 面板右对齐弹出、
   at-bottom 面板向上弹出（类由 app.js 按吸附方位施加） */
.func-fab {
    position: fixed; left: var(--space-4); top: var(--space-4); z-index: var(--z-fab);
}
.func-fab.dragging { user-select: none; }
.func-fab.dragging .func-menu { opacity: 0; pointer-events: none; visibility: hidden; }
.func-main {
    position: relative;
    width: 52px; height: 52px; border-radius: 50%;   /* g9 同族几何：与录入 FAB 同径全圆 */
    background: var(--card); border: 1px solid var(--line);
    color: var(--primary); cursor: grab;
    display: flex; align-items: center; justify-content: center;
    box-shadow: var(--shadow-sm);
    transition: transform .2s, box-shadow .2s, border-color .2s;
}
/* 待办未办角标（D81）：应用按钮右上红点数字 + 面板待办卡内数字徽标 */
.func-dot {
    position: absolute; top: -6px; right: -6px;
    min-width: 18px; height: 18px; padding: 0 5px;
    border-radius: var(--radius-pill);
    background: var(--danger); color: var(--on-accent);
    font-weight: var(--weight-strong); font-size: var(--font-xs);
    line-height: 18px; text-align: center;
    box-shadow: var(--shadow-xs);
}
.func-badge {
    display: inline-block; min-width: 18px; padding: 0 5px;
    border-radius: var(--radius-pill);
    background: var(--danger); color: var(--on-accent);
    font-weight: var(--weight-strong); font-size: var(--font-xs);
    line-height: 16px; text-align: center;
    vertical-align: 1px;
}
.func-fab.dragging .func-main { cursor: grabbing; transition: none; }
.func-fab:hover .func-main {
    border-color: var(--primary);
    box-shadow: var(--shadow-sm);
}

/* 功能面板：absolute 悬浮于按钮下方（紧贴按钮底缘 + padding 造视觉间距，
   热区连续），收起 visibility 隐藏；贴右缘右对齐（at-right）、
   贴底向上弹出（at-bottom），均由 app.js 按吸附方位施加。
   width:max-content 必须：absolute 盒 shrink-to-fit 以包含块（=按钮盒
   52px）为可用宽度，卡片会被压到文字逐字换行（D99 同 fab-menu） */
.func-menu {
    position: absolute; top: 100%; left: 0; width: max-content;
    display: flex; flex-direction: column; gap: var(--space-2);
    padding-top: var(--space-2);
    opacity: 0; transform: translateY(-8px); pointer-events: none; visibility: hidden;
    transition: opacity .18s, transform .18s, visibility .18s;
}
.func-fab.at-right .func-menu { left: auto; right: 0; }
.func-fab.at-bottom .func-menu { top: auto; bottom: 100%; padding-top: 0;
                                 padding-bottom: var(--space-2); transform: translateY(8px); }
.func-fab:hover .func-menu { opacity: 1; transform: translateY(0); pointer-events: auto; visibility: visible; }

/* 面板内功能卡片：图标块 + 名称/描述（数据由 FUNCTIONS 注入） */
.func-item {
    display: flex; align-items: center; gap: var(--space-3);
    width: 260px; padding: var(--space-3);
    background: var(--card); border: 1px solid var(--line);
    border-radius: var(--radius-lg); text-decoration: none; color: var(--text);
    box-shadow: var(--shadow-sm);
    transition: background .15s, transform .15s, border-color .15s;
}
.func-item:hover {
    background: var(--primary-weak); border-color: var(--primary);
    transform: translateX(2px);
}
.func-ico {
    width: 40px; height: 40px; border-radius: var(--radius-md); flex: none;
    background: var(--primary); color: var(--on-accent); font-size: var(--font-sm);
    display: flex; align-items: center; justify-content: center;
}
.func-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.func-name { font-size: var(--font-md); font-weight: 600; }
.func-desc {
    font-size: var(--font-xs); color: var(--dim);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ---- 目标方案编辑器（D70）：分口径矩阵录入——行=名册对象、列=时段； 体检错误块 + 合计行淡底强调；样式引用既有 token，无裸值 ---- */
.plan-grid .plan-sys th {
    background: var(--surface-alt);
    font-size: var(--font-xs);
    color: var(--dim);
    text-align: left;
    padding: 4px 8px;
}
.plan-grid .plan-tot th { font-weight: 600; }
.plan-grid .plan-tot td { background: var(--surface-alt); }
.plan-cell {
    width: 100%; min-width: 72px;
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--card); padding: 4px;
    font-size: var(--font-xs); text-align: right;
    font-variant-numeric: tabular-nums;
}
.plan-cell:focus { outline: 2px solid var(--primary); border-color: var(--primary); }
.plan-total { font-weight: 600; }
.plan-errors {
    background: var(--card); border: 1px solid var(--danger);
    border-radius: var(--radius-md); padding: var(--space-2) var(--space-3);
    margin-bottom: var(--space-3);
}
.plan-errors ul { margin: 4px 0; padding-left: var(--space-5); }
.plan-errors li { color: var(--danger); }

/* ---- 目标域日期选择器 + 次级导航（D75）：季/月 chips（label+radio， :has 选中态）+ 粒度联动显隐（CSS :has 零 JS）+ 目标域子页 tabs ---- */
.pick-chips { display: inline-flex; gap: 4px; flex-wrap: wrap; vertical-align: middle; }
.pick-chip {
    position: relative; display: inline-flex; align-items: center;
    border: 1px solid var(--line); border-radius: var(--radius-pill);
    background: var(--card); color: var(--dim);
    font-size: var(--font-xs); padding: 4px 12px; cursor: pointer;
    transition: border-color .15s, color .15s, background .15s;
}
.pick-chip:hover { border-color: var(--primary); color: var(--primary); }
.pick-chip input { position: absolute; opacity: 0; pointer-events: none; }
.pick-chip:has(input:checked) {
    background: var(--primary); border-color: var(--primary); color: var(--on-accent);
}
.pick-chip:has(input:focus-visible) { outline: 2px solid var(--primary); outline-offset: 1px; }

/* 粒度联动（D75 选日期不手输）：季/月选择器仅对应粒度选中时出场 */
.gf-qtr, .gf-mon { display: none; }
.gf-gran:has(input[value="quarterly"]:checked) ~ .gf-qtr,
.pick-chips:has(input[value="quarterly"]:checked) ~ .gf-qtr { display: inline-flex; }
.gf-gran:has(input[value="monthly"]:checked) ~ .gf-mon,
.pick-chips:has(input[value="monthly"]:checked) ~ .gf-mon { display: inline-flex; }

/* 目标域次级导航（目标库|方案）：同页签级文本 tab 语义 */
.tg-nav { margin: 0 0 var(--space-3); }

/* ---- 目标域工作台（D77）：单版面主从布局（项目树工作台同款语言）—— 左栏方案树/目标库 360px 卡片，右侧订立台自适应 ---- */
.targets-bench { align-items: flex-start; }
.targets-bench .tree-col { flex: 0 0 400px; }   /* g6 栏宽归一：同项目树工作台 400px */
/* D80：右侧订立台补全站同款卡壳（原裸奔无背景，与左栏 tree-col 卡片不对等） */
.wb-panel { flex: 1 1 auto; min-width: 0;
            background: var(--card); border-radius: var(--radius-md);
            padding: var(--space-4); box-shadow: var(--shadow-xs); }
/* ---- 目标域工作台 D82 重构：左栏 = 方案树（VS Code 式 chevron，参考项目树
   组件配方）+ 目标库（拖拽入方案 + ✎编辑/⧉复制）；方案级动作收纳进 ⋯ 菜单 ---- */
.bench-head { display: flex; align-items: center; gap: var(--space-2); margin-bottom: 4px; }
.bench-title { margin: 0; font-size: var(--font-md); font-weight: 600; }
.bench-sec { margin-top: var(--space-4); padding-top: var(--space-3);
             border-top: 1px solid var(--line); }
/* 图标钮（D82 登记件）：树行/条目行内小动作的统一形态——图标即操作，
   hover 淡底主色，替代旧版一排文字按钮 */
.icon-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; padding: 0; flex: none;   /* g9 热区下限 24px */
    border: none; background: none; color: var(--dim);
    font-size: var(--font-md); line-height: 1; text-decoration: none;
    border-radius: var(--radius-sm); cursor: pointer;
    transition: background .15s, color .15s;
}
.icon-btn:hover { background: var(--primary-weak); color: var(--primary); }
/* D89 删除入口（垃圾桶）危险态：悬停/武装确认蘸 --danger 砖红；
   .menu-dim = 守卫禁点态（锁定方案/被锁定方案引用），不可删如实呈现。
   菜单危险态选择器带 .scheme-menu 前缀压过 .menu-item:hover（特异性） */
.icon-danger:hover, .icon-btn.armed {
    background: var(--danger); color: var(--on-accent);
}
.scheme-menu .menu-danger:hover,
.scheme-menu .menu-danger.armed {
    background: var(--danger); color: var(--on-accent);
}
.menu-dim, .scheme-menu .menu-dim {
    color: var(--dim); cursor: not-allowed; opacity: .6;
}
.bench-form { margin: 0 0 var(--space-2); }
.bench-form input.filter { width: 100%; margin-bottom: 4px; }
/* D90 导入表单：模板下载链接行 */
.import-links { display: flex; gap: 4px; margin-bottom: 4px; }

/* 方案树：节点行（拖拽落点）+ chevron 展开 + ⋯ 菜单 + 子行装配目标 */
.scheme-node { margin-bottom: 2px; }
.scheme-node.open > .scheme-row .chev { transform: rotate(90deg); }
.scheme-row {
    position: relative; display: flex; align-items: center; gap: 4px;
    padding: 4px; border-radius: var(--radius-sm); cursor: pointer;
}
.scheme-row:hover { background: var(--surface-alt); }
.scheme-row.active { background: var(--primary-weak); }
.scheme-row.active .scheme-name { font-weight: 600; color: var(--primary); }
/* 拖拽悬停目标态：虚线内描边（落点提示） */
.scheme-row.drop-hover { outline: 2px dashed var(--primary); outline-offset: -2px; }
/* chevron：同工作台树组件配方（折叠朝右/展开旋 90° 朝下）；
   data URI 内无法引用 CSS 变量，stroke 值镜像 --dim（#6a6f6b），
   改 --dim 时必须同步这里 */
.chev {
    flex: none; width: 16px; height: 16px; padding: 0; border: none; cursor: pointer;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M4 2.5l4 3.5-4 3.5' fill='none' stroke='%236a6f6b' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / 10px 10px;
    transition: transform .15s ease;
}
.scheme-name { flex: 1 1 auto; min-width: 0; color: var(--text); text-decoration: none;
               font-size: var(--font-sm);
               overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.scheme-name:hover { color: var(--primary); }
.scheme-count { flex: none; font-size: var(--font-xs); }
.scheme-more { opacity: 0; transition: opacity .12s; }   /* 悬停浮现 */
.scheme-row:hover .scheme-more, .scheme-more:focus-visible { opacity: 1; }
.scheme-menu {
    position: absolute; top: calc(100% + 2px); right: 4px; z-index: var(--z-panel);
    min-width: 148px; padding: 4px; display: flex; flex-direction: column;
    background: var(--card); border: 1px solid var(--line);
    border-radius: var(--radius-md); box-shadow: var(--shadow-sm);
}
.scheme-menu .menu-item {
    display: block; width: 100%; padding: 4px 8px; text-align: left;
    border: none; background: none; color: var(--text);
    font-size: var(--font-sm); text-decoration: none; cursor: pointer;
    border-radius: var(--radius-sm);
}
.scheme-menu .menu-item:hover { background: var(--primary-weak); color: var(--primary); }
/* 装配目标子行：点击进右侧编辑；✕ 移出悬停浮现 */
.scheme-goals { list-style: none; margin: 2px 0 4px; padding: 0 0 0 var(--space-4); }
.scheme-goal {
    display: flex; align-items: center; gap: 4px;
    padding: 2px 4px; border-radius: var(--radius-sm);
}
.scheme-goal > a { flex: 1 1 auto; min-width: 0; color: var(--text); text-decoration: none;
                   font-size: var(--font-xs);
                   overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.scheme-goal > a:hover { color: var(--primary); }
.scheme-goal .goal-remove { display: none; }
.scheme-goal:hover .goal-remove { display: inline-flex; }

/* 目标库条目：拖拽源 + ✎/⧉ 行内图标（悬停浮现） */
.goal-item {
    display: flex; align-items: center; gap: 4px;
    padding: 4px; border-radius: var(--radius-sm); cursor: grab;
}
.goal-item:hover { background: var(--surface-alt); }
.goal-item:active { cursor: grabbing; }
.goal-name { flex: 1 1 auto; min-width: 0; font-size: var(--font-sm);
             overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.goal-ops { display: inline-flex; gap: 2px; opacity: 0; transition: opacity .12s; }
.goal-item:hover .goal-ops { opacity: 1; }
/* 当前生效方案徽标（旧版 .badge 无底色是白字隐形缺陷，D82 顺手修复） */
.badge-cur { background: var(--ok); }
/* 右侧订立台：题头动作组（透镜 + 新建目标 CTA）+ 空态引导 */
.bench-actions { margin-left: auto; display: flex; align-items: center;
                 gap: var(--space-3); }
.bench-empty { text-align: center; color: var(--dim); padding: var(--space-6) 0; }
.bench-empty-title { font-size: var(--font-md); font-weight: 600; color: var(--text); margin: 0 0 4px; }

/* ---- 目标工作台宽度纪律（D77 勘误，用户指正）：两列矩阵表内容就两行字， 禁止全宽拉伸——订立台矩阵/表单区限宽 640px；工作台回归标准容器（不 用 container-wide，主从布局右侧自适应即可，同项目树工作台） ---- */
.plan-grid { max-width: 640px; }
.wb-panel .filters { max-width: 720px; }

/* ---- 目标工作台按钮形态收敛（D78 组件纪律）：行内小动作 .btn-sm/.icon-btn， 新建方案表单（.bench-form）全宽控件，禁内联样式 ---- */
.btn-sm { padding: 2px 8px; font-size: var(--font-xs); }
.bench-form .btn { width: 100%; }

/* ---- 目标工作台提示/输入形态收敛（D79 组件纪律）：语义类替代内联样式 ---- */
.bench-note { font-size: var(--font-xs); }
.hint-ok { color: var(--ok); }
.hint-warn { color: var(--warn); }
.filter-name { width: 240px; }

/* ---- 待办清单（D81）：TodoMVC 精简范式（htmx 交换单元 #todo-list） ---- */
.todo-add {
    display: flex; gap: var(--space-2); margin-bottom: var(--space-4);
}
.todo-add input {
    flex: 1 1 auto; padding: var(--space-2) var(--space-3);
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--card); font-size: var(--font-md);
}
.todo-add input:focus { outline: 2px solid var(--primary); border-color: var(--primary); }
.todo-list {
    background: var(--card); border: 1px solid var(--line);
    border-radius: var(--radius-md); padding: var(--space-2) var(--space-4);
    box-shadow: var(--shadow-xs);
}
.todo-items { list-style: none; margin: 0; padding: 0; }
.todo-item {
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--space-2) 0; border-bottom: 1px solid var(--line);
}
.todo-item:last-child { border-bottom: none; }
.todo-item input[type="checkbox"] { width: 16px; height: 16px; cursor: pointer; flex: 0 0 auto; }
.todo-content {
    flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.todo-item.done .todo-content {
    color: var(--dim); text-decoration: line-through;
}
.todo-done-at { flex: 0 0 auto; color: var(--dim); font-size: var(--font-xs); }
.todo-del {
    flex: 0 0 auto; width: 24px; height: 24px; border: none; border-radius: var(--radius-sm);
    background: transparent; color: var(--dim); font-size: var(--font-lg);
    line-height: 1; cursor: pointer; opacity: 0; transition: opacity .12s, color .12s;
}
.todo-item:hover .todo-del { opacity: 1; }
.todo-del:hover { color: var(--danger); }
.todo-count {
    margin: var(--space-2) 0 0; color: var(--dim); font-size: var(--font-xs);
}
.todo-empty { color: var(--dim); text-align: center; padding: var(--space-6) 0; }

/* ---- 列收流程工作台（D113）：项目流程卡 .flow-card + 合同步进条
   .flow-track（组件登记 rules/components.md §6，全站单一实现禁二开；
   配色全 token：列收紫族承接 D69 进度条语义，零新色相） ---- */
.flow-toolbar { margin-left: auto; display: flex; align-items: center;
                gap: var(--space-2); flex-wrap: wrap; }
.flow-card {
    background: var(--card); border: 1px solid var(--line);
    border-radius: var(--radius-md); box-shadow: var(--shadow-xs);
    padding: var(--space-3) var(--space-4); margin-bottom: var(--space-3);
}
.flow-card-head { display: flex; align-items: flex-start; justify-content: space-between;
                  gap: var(--space-3); flex-wrap: wrap; }
.flow-proj { display: flex; align-items: baseline; gap: var(--space-2); flex-wrap: wrap; }
.flow-proj-name { font-size: var(--font-lg); font-weight: var(--weight-strong); }
.flow-proj-sub { font-size: var(--font-xs); color: var(--dim); }
.flow-fold { border: none; background: none; cursor: pointer; color: var(--dim);
             font-size: var(--font-xs); padding: 2px 4px; }
.flow-fold:hover { color: var(--text); }
.flow-amts { display: flex; gap: var(--space-4); flex-wrap: wrap; }
.flow-amt { text-align: right; }
.flow-amt b { display: block; font-family: Consolas, "Courier New", monospace;
              font-size: var(--font-sm); font-variant-numeric: tabular-nums; }
.flow-amt span { font-size: var(--font-xs); color: var(--dim); }
.flow-amt.hot span { color: var(--warn); font-weight: var(--weight-strong); }
.flow-amt.over span { color: var(--danger); }
/* 步进条：三态段（done 实底/cur 描边/todo 浅底）+ 节点标签行——状态步进条
   与 .prog（金额比例分段条）语义不同，禁互相借用样式（components.md §6.1） */
.flow-track { display: flex; gap: var(--space-1); margin: var(--space-3) 0 var(--space-1); }
.flow-track .seg { flex: 1 1 0; height: 10px; border-radius: var(--radius-pill);
                   background: var(--surface-alt); border: 1px solid var(--line); }
.flow-track .seg.done { background: var(--type-income); border-color: var(--type-income); }
.flow-track .seg.cur { background: var(--type-income-weak);
                       border-color: var(--type-income);
                       box-shadow: inset 0 0 0 2px var(--card); }
.flow-track-labels { display: flex; gap: var(--space-1); margin-bottom: var(--space-2); }
.flow-track-labels span { flex: 1 1 0; text-align: center; font-size: var(--font-xs);
                          color: var(--dim); overflow: hidden;
                          text-overflow: ellipsis; white-space: nowrap; }
.flow-track-labels span.cur { color: var(--text); font-weight: var(--weight-strong); }
.flow-meta { display: flex; align-items: center; justify-content: space-between;
             gap: var(--space-3); flex-wrap: wrap; margin-top: var(--space-2); }
.flow-actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.flow-contracts { margin-top: var(--space-3); border-top: 1px dashed var(--line);
                  padding-top: var(--space-3); }
.flow-contract { border: 1px solid var(--line); border-radius: var(--radius-sm);
                 background: var(--surface-alt);
                 padding: var(--space-2) var(--space-3); margin-bottom: var(--space-2); }
.flow-contract:last-child { margin-bottom: 0; }
.flow-ct-head { display: flex; align-items: center; justify-content: space-between;
                gap: var(--space-3); flex-wrap: wrap; }
.flow-ct-name { font-size: var(--font-sm); font-weight: var(--weight-strong); }
.flow-ct-no { font-family: Consolas, "Courier New", monospace;
              font-size: var(--font-xs); color: var(--dim); }
.flow-ct-state { font-size: var(--font-xs); color: var(--dim); }
/* 徽标修饰：沿用 .badge 基类（底色家族照 .badge-status-* 惯例） */
.badge-flow-diverge { background: var(--warn); }
.badge-flow-cue { background: var(--ok); }
.badge-flow-draft { background: var(--type-neutral); }
/* 周提交确认 / 新建流程弹层（原型 .flow-modal 同款收编，token 化；
   z 用 --z-modal（D114 层级定档：任务模态盖过下钻浮窗 60/70，toast 99 之上不打架） */
.flow-overlay { position: fixed; inset: 0; z-index: var(--z-modal);
                background: rgba(38, 41, 43, .35);
                display: flex; align-items: center; justify-content: center; }
.flow-modal { background: var(--card); border-radius: var(--radius-lg);
              box-shadow: var(--shadow-md); padding: var(--space-4);
              width: min(560px, calc(100vw - 32px)); max-height: 80vh; overflow: auto; }
.flow-modal h3 { margin: 0 0 var(--space-2); font-size: var(--font-lg); }
.flow-modal .flow-note { margin: 0 0 var(--space-3); color: var(--dim);
                         font-size: var(--font-xs); }
.flow-modal .delta-list { border: 1px solid var(--line); border-radius: var(--radius-sm);
                          padding: var(--space-2) var(--space-3);
                          margin: var(--space-2) 0 var(--space-3);
                          max-height: 40vh; overflow: auto; }
.flow-modal .delta-item { padding: var(--space-1) 0; font-size: var(--font-sm); }
.flow-modal .delta-item + .delta-item { border-top: 1px solid var(--line); }
.flow-modal .delta-item b { font-weight: var(--weight-strong); }
.flow-modal .inc { font-family: Consolas, "Courier New", monospace; color: var(--ok); }
.flow-modal-foot { display: flex; justify-content: flex-end; gap: var(--space-2); }
.flow-form-grid { display: grid; grid-template-columns: 1fr 1fr;
                  gap: var(--space-2) var(--space-3); margin-bottom: var(--space-3); }
.flow-form-grid .full { grid-column: 1 / -1; }
.flow-form-grid label { display: block; font-size: var(--font-xs); color: var(--dim);
                        margin-bottom: 2px; }
.flow-form-grid input { width: 100%; padding: var(--space-2) var(--space-3);
                        border: 1px solid var(--line); border-radius: var(--radius-sm);
                        font-size: var(--font-md); }
.flow-form-grid input:focus { outline: 2px solid var(--primary); border-color: var(--primary); }
/* 新建流程弹层 .np-*（D123 收编：app.js 两段式选项目引用的类此前零定义
   ——浏览器裸奔渲染是「列收前端看不得」的头号乱源；形态对齐全站组件语言：
   候选行=adj-card 淡底 hover、勾选行=行式容器、搜索框=search 同款） */
.np-q { width: 100%; padding: var(--space-2) var(--space-3);
        border: 1px solid var(--line); border-radius: var(--radius-sm);
        font-size: var(--font-md); background: var(--card);
        margin-bottom: var(--space-3); }
.np-q:focus { outline: 2px solid var(--primary); border-color: var(--primary); }
.np-results { display: flex; flex-direction: column; gap: var(--space-2);
              max-height: 40vh; overflow: auto; margin-bottom: var(--space-3); }
.np-item { display: flex; flex-direction: column; gap: 2px; width: 100%;
           text-align: left; padding: var(--space-2) var(--space-3);
           border: 1px solid var(--line); border-radius: var(--radius-sm);
           background: var(--card); cursor: pointer;
           transition: border-color .15s, background .15s; }
.np-item:hover { border-color: var(--primary); background: var(--primary-weak); }
.np-name { font-size: var(--font-sm); font-weight: var(--weight-strong); }
.np-sub { font-size: var(--font-xs); color: var(--dim); }
.np-picked { display: flex; align-items: center; gap: var(--space-2);
             margin-bottom: var(--space-3); }
.np-picked .np-name { flex: 1 1 auto; min-width: 0;
                      overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.np-ct-list { display: flex; flex-direction: column; gap: var(--space-2);
              max-height: 40vh; overflow: auto; margin-bottom: var(--space-3); }
.np-ct { display: flex; align-items: center; gap: var(--space-2);
         padding: var(--space-2) var(--space-3);
         border: 1px solid var(--line); border-radius: var(--radius-sm);
         background: var(--card); cursor: pointer; }
.np-ct:hover { border-color: var(--primary); }
.np-ct.np-ct-na { opacity: .55; cursor: not-allowed; }
.np-ct input { flex: none; width: 16px; height: 16px; cursor: pointer; }
.np-ct input:disabled { cursor: not-allowed; }
.np-ct-name { flex: 1 1 auto; min-width: 0; font-size: var(--font-sm);
              font-weight: var(--weight-strong);
              overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.np-ct-amt { flex: none; font-size: var(--font-xs); color: var(--dim);
             font-variant-numeric: tabular-nums; }
.np-manual summary { cursor: pointer; font-size: var(--font-xs); color: var(--dim);
                     margin-bottom: var(--space-2); }
.np-manual summary:hover { color: var(--text); }

/* ---- 跟进日志（D119）：时间线 feed + 工作台日志面板（组件登记
   rules/components.md §6.4，全站单一实现禁二开）。日志是变高叙述文本，
   「严格画框」登记例外——不进 c-table/table.fixed（截断长文=买椟还珠）；
   锚点/挂载点徽标用 --type-neutral（token 在册语义「日志中性类」）；
   间距全 4pt 栅格（D109），z 引用阶梯 ---- */
/* 日分隔行：小字 + 右延细线（时间线的时间刻度） */
.day { display: flex; align-items: center; gap: var(--space-3);
       margin: var(--space-5) 0 var(--space-2); color: var(--dim);
       font-size: var(--font-xs); }
.day::after { content: ""; flex: 1; height: 1px; background: var(--line); }
/* feed 容器：左轴（--type-neutral 青灰锚点色） */
.log-feed, .lp-feed { position: relative; }
.log-feed::before, .lp-feed::before { content: ""; position: absolute;
    left: 5px; top: var(--space-2); bottom: var(--space-2); width: 2px;
    background: var(--line); border-radius: 1px; }
.log-item { position: relative; padding: 0 0 var(--space-4) var(--space-5); }
.log-item .dot { position: absolute; left: 0; top: 7px; width: 12px; height: 12px;
    border-radius: var(--radius-pill); background: var(--card);
    border: 2px solid var(--type-neutral); }
.log-item.void .dot { border-color: var(--line); }
.log-item.void .log-text { color: var(--dim); }
.log-body { background: var(--card); border: 1px solid var(--line);
    border-radius: var(--radius-md); box-shadow: var(--shadow-xs);
    padding: var(--space-3) var(--space-4); }
.log-text { margin: 0; overflow-wrap: anywhere; }   /* 叙述文本自适应换行，禁截断 */
.log-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
    margin-top: var(--space-2); color: var(--dim); font-size: var(--font-xs); }
.log-meta .time { margin-left: auto; font-family: Consolas, "Courier New", monospace; }
.proj-link { color: var(--info); font-weight: var(--weight-strong);
             text-decoration: none; }
.proj-link:hover { color: var(--info-hover); text-decoration: underline; }
/* 挂载点徽标：报文根挂载淡蓝底（宿主入口）、其余中性灰 */
.chip { display: inline-block; padding: 0 var(--space-2); border-radius: var(--radius-pill);
    background: var(--type-neutral-weak, #eceef0); color: var(--type-neutral);
    font-size: var(--font-xs); line-height: 18px; }
.chip.root { background: var(--primary-weak); color: var(--primary); }
/* 工作台日志面板（右栏顶部）：进页首屏即见（用户拍板） */
.log-panel { background: var(--card); border: 1px solid var(--line);
    border-radius: var(--radius-lg); padding: var(--space-4) var(--space-5); }
.lp-head { display: flex; align-items: center; gap: var(--space-2);
           margin-bottom: var(--space-2); }
.lp-head h2 { margin: 0; font-size: var(--font-lg); }
.lp-count { color: var(--dim); font-size: var(--font-xs); }
.lp-add { margin-left: auto; border: 1px solid var(--primary);
    background: var(--primary-weak); color: var(--primary);
    border-radius: var(--radius-pill); cursor: pointer;
    font-size: var(--font-sm); padding: var(--space-1) var(--space-3);
    transition: background .15s, color .15s; }
.lp-add:hover { background: var(--primary); color: var(--on-accent); }
/* 写日志表单（面板内就地展开 / 录入页 form-card 共用形态） */
.compose { margin: var(--space-2) 0 var(--space-3) var(--space-5);
    padding: var(--space-3); background: var(--surface-alt);
    border: 1px solid var(--line); border-radius: var(--radius-md); }
.compose textarea { width: 100%; min-height: 72px; resize: vertical; box-sizing: border-box;
    font-size: var(--font-md); line-height: 22px; color: var(--text);
    padding: var(--space-2) var(--space-3); border: 1px solid var(--line);
    border-radius: var(--radius-sm); background: var(--card); }
.compose-row { display: flex; align-items: center; gap: var(--space-2);
               margin-top: var(--space-2); flex-wrap: wrap; }
.compose-row label { color: var(--dim); font-size: var(--font-xs); }
.compose select { font-size: var(--font-sm); padding: var(--space-1) var(--space-2);
    border: 1px solid var(--line); border-radius: var(--radius-sm);
    background: var(--card); color: var(--text); max-width: 100%;
    flex: 1 1 200px; }   /* D129 挂载位置下拉（app.js 从 PAGE.nodes 填充） */
.compose-row input[type="text"] { flex: 1 1 200px; font-size: var(--font-sm);
    padding: var(--space-1) var(--space-2); border: 1px solid var(--line);
    border-radius: var(--radius-sm); background: var(--card); }
.compose .compose-cancel { background: var(--card); color: var(--text); border: 1px solid var(--line); }
.compose .compose-cancel:hover { border-color: var(--primary); color: var(--primary); background: var(--card); }
/* 全局页空态（.empty 基类 546 行的日志特化：虚线画框弱化无数据的挫败感） */
.empty-log { border: 1px dashed var(--line); border-radius: var(--radius-md);
             background: var(--card); }
/* 录入日志页：表单卡 + 项目联想下拉（z 用 --z-panel，D119 P2 勘位） */
.form-card { background: var(--card); border: 1px solid var(--line);
    border-radius: var(--radius-lg); padding: var(--space-5); max-width: 640px; }
.form-card .field { margin-bottom: var(--space-4); }
.form-card .field > label { display: block; margin-bottom: var(--space-1);
    font-weight: var(--weight-strong); font-size: var(--font-sm); }
.form-card input[type="text"], .form-card textarea { width: 100%; box-sizing: border-box;
    font-size: var(--font-md); color: var(--text); padding: var(--space-1) var(--space-3);
    border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--card); }
.form-card textarea { min-height: 110px; resize: vertical; line-height: 22px; }
.form-card input:focus, .form-card textarea:focus,
.compose textarea:focus, .compose-row input:focus {
    outline: 2px solid var(--primary-weak); border-color: var(--primary); }
.ac { position: relative; }
.ac-list { position: absolute; left: 0; right: 0; top: 100%; z-index: var(--z-panel);
    margin-top: 2px; background: var(--card); border: 1px solid var(--line);
    border-radius: var(--radius-sm); box-shadow: var(--shadow-sm); overflow: hidden; }
.ac-item { display: block; width: 100%; text-align: left; border: 0; background: none;
    cursor: pointer; padding: var(--space-2) var(--space-3);
    font-size: var(--font-sm); color: var(--text); }
.ac-item:hover { background: var(--primary-weak); }
.ac-item .mono { color: var(--dim); font-size: var(--font-xs); }
.picked { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
    margin-top: var(--space-2); padding: var(--space-2) var(--space-3);
    background: var(--primary-weak); border-radius: var(--radius-sm);
    font-size: var(--font-sm); color: var(--primary); }

/* 规划先行（D124，用户拍板「新建流程的前提是规划」）：行内规划输入 +
   参照行（未列余额/本期后剩/超余额 danger）+ 合计行；np-ct-main 双行主列。
   ⚠ 本段原为 M8a 旧版 .np-* 重复定义（D123 重建时源顺序覆盖新形态），
   重复部分已删——.np-* 基础形态唯 D123 段（1405 行起）单一出处；
   .np-manual 容器规则 D123 段缺，此处补齐。 */
.np-ct-main { display: flex; flex-direction: column; gap: 0; min-width: 0; flex: 1 1 auto; }
.np-plan { display: flex; flex-direction: column; align-items: flex-end;
           flex: 0 0 auto; }
.np-plan input { width: 128px; text-align: right;
                 font-family: Consolas, "Courier New", monospace;
                 font-size: var(--font-sm); padding: var(--space-1) var(--space-2);
                 border: 1px solid var(--line); border-radius: var(--radius-sm); }
.np-plan input:focus { outline: 2px solid var(--primary); border-color: var(--primary); }
.np-plan input.over { border-color: var(--danger); }
.np-plan-ref { font-size: var(--font-xs); color: var(--dim); white-space: nowrap; }
.np-total { text-align: right; font-size: var(--font-sm); margin: 0 0 var(--space-2); }
.np-total b { font-family: Consolas, "Courier New", monospace; }
.np-manual { margin-top: var(--space-2); border-top: 1px dashed var(--line);
             padding-top: var(--space-2); }

/* ================= 数据导入 · 签约清单核对（D136） =================
   工具条 / 新建项目回挂提示条 / 归档弹窗表单 / [复制] 摘要行。
   复用：.flow-overlay/.flow-modal 弹层、.np-item 候选行、.stats-bar、
   .tabs/.tab、.btn-sm——本段只新增签约专属容器。 */
.signing-toolbar { display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-3); margin: var(--space-3) 0 var(--space-2);
    padding: var(--space-2) var(--space-3); background: var(--card);
    border: 1px solid var(--line); border-radius: var(--radius-md); }
.signing-snap { display: flex; align-items: baseline; gap: var(--space-2);
    min-width: 0; flex-wrap: wrap; }

.signing-pending { display: flex; align-items: center; gap: var(--space-3);
    flex-wrap: wrap; margin: var(--space-2) 0; padding: var(--space-2) var(--space-3);
    background: var(--primary-weak); border: 1px solid var(--primary);
    border-radius: var(--radius-md); font-size: var(--font-sm); }

/* 立项转化信息卡（D151）：跟进工作台转化后信息主权切换——立项树权威信息
   （项目名/预算/归档/列收）+ 跟进期记录行；L1 只读看数，跳转链接仅 L2/L3 */
.convert-card { margin: var(--space-2) 0 var(--space-3); padding: var(--space-3);
    background: var(--card); border: 1px solid var(--primary);
    border-radius: var(--radius-md); font-size: var(--font-sm); }
.convert-card .cv-head { display: flex; align-items: center; gap: var(--space-3);
    flex-wrap: wrap; }
.convert-card .cv-title { font-weight: 600; color: var(--primary); }
.convert-card .cv-link { margin-left: auto; }
.convert-card .cv-grid { display: flex; gap: var(--space-2) var(--space-3);
    flex-wrap: wrap; margin-top: var(--space-2); }
.convert-card .cv-cell { display: flex; flex-direction: column; gap: 2px;
    min-width: 96px; }
.convert-card .cv-k { font-size: var(--font-xs); color: var(--dim); }
.convert-card .cv-v { color: var(--text); }
.convert-card .cv-tbl { margin-top: var(--space-2); }
.convert-card .cv-past { margin-top: var(--space-2); padding-top: var(--space-2);
    border-top: 1px dashed var(--line); font-size: var(--font-xs);
    color: var(--dim); }

/* 归档弹窗内：搜索框 / 候选列表（滚动）/ 六字段表单 */
.sg-search { width: 100%; margin: var(--space-2) 0; }
.sg-results { max-height: 260px; overflow: auto; display: flex;
    flex-direction: column; gap: var(--space-1); margin-top: var(--space-2); }
.sg-form { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2)
    var(--space-3); margin-top: var(--space-2); }
.sg-form label { display: flex; flex-direction: column; gap: 4px;
    font-size: var(--font-xs); color: var(--dim); }
.sg-form label input { color: var(--text); font-size: var(--font-sm); }
.sg-form .sg-form-wide, .sg-form label:first-child { grid-column: 1 / -1; }
.sg-field { display: flex; flex-direction: column; gap: 4px; margin: var(--space-2) 0;
    font-size: var(--font-xs); color: var(--dim); }

/* 页面底部 [复制] 摘要行（用户复制惯例，D136） */
.signing-summary { margin-top: var(--space-2); padding: var(--space-2) var(--space-3);
    background: var(--surface-alt); border-radius: var(--radius-sm);
    font-size: var(--font-xs); user-select: all; }

/* 归档弹窗·归档日期口径选择（D137 勘误：表值不静默落库，三选一询问） */
.sg-arch-mode { display: flex; flex-direction: column; gap: 6px;
    margin-top: var(--space-2); padding: var(--space-2) var(--space-3);
    background: var(--surface-alt); border: 1px solid var(--line);
    border-radius: var(--radius-sm); font-size: var(--font-sm); }
.sg-arch-mode label { display: flex; align-items: center; gap: 8px;
    font-size: var(--font-sm); color: var(--text); }
.sg-arch-mode input[type="radio"] { accent-color: var(--primary); }
.sg-arch-ref { font-size: var(--font-sm); color: var(--dim); }
.sg-arch-custom { width: 110px; padding: 2px 8px; }
.sg-arch-mode label:has(input:disabled) { color: var(--dim);
    text-decoration: line-through; }

/* ================= 用户角标（D141 三级权限） =================
   右上角固定：用户名 + 级别徽标（电信蓝胶囊）+ 登出直链。
   z 取 --z-fab（与悬浮件同级 fixtures；角标被动展示不遮交互面板） */
.user-chip { position: fixed; top: var(--space-4); right: var(--space-6);
    display: flex; align-items: center; gap: var(--space-2);
    padding: 3px var(--space-3); background: var(--card);
    border: 1px solid var(--line); border-radius: var(--radius-pill);
    box-shadow: var(--shadow-xs); font-size: var(--font-sm); z-index: var(--z-fab); }
.user-chip .user-name { font-weight: var(--weight-strong); color: var(--text); }
.user-chip .user-role { color: var(--on-accent); background: var(--info);
    border-radius: var(--radius-pill); padding: 0 var(--space-2);
    font-size: var(--font-xs); line-height: 18px; }
/* D152：L1 数据可见范围标签（范围对用户可见——fail-closed 空数据的解释处；
   未配置 = danger 警示）。分隔竖线与角色徽标区隔 */
.user-chip .user-scope { color: var(--dim); font-size: var(--font-xs);
    padding-left: var(--space-2); border-left: 1px solid var(--line); }
.user-chip .user-scope.miss { color: var(--danger); }
.user-chip .user-out { color: var(--dim); border: 1px solid var(--line);
    border-radius: var(--radius-sm); padding: 1px var(--space-2); }
.user-chip .user-out:hover { color: var(--danger); border-color: var(--danger);
    background: var(--card); }

/* ================= 归档锁定清单（D157，L3 专属管理页） =================
   每期必归档项目锁定账：期次卡片 + 条目表 + 行内加条目表单；
   全部走 token 通道（色彩禁裸值），卡片语言与 stats-bar 同族 */
.pa-open, .pa-add { display: flex; align-items: center; gap: var(--space-2);
    flex-wrap: wrap; margin: var(--space-3) 0; }
.pa-open label { color: var(--dim); font-size: var(--font-sm); }
.pa-period { background: var(--card); border: 1px solid var(--line);
    border-radius: var(--radius-md, 8px); padding: var(--space-3) var(--space-4);
    margin: var(--space-3) 0; }
.pa-head { display: flex; align-items: baseline; gap: var(--space-3);
    flex-wrap: wrap; margin-bottom: var(--space-2); }
.pa-head h2 { margin: 0; font-size: var(--font-lg); }
.pa-note { color: var(--dim); font-size: var(--font-sm); }
.pa-head form { margin-left: auto; }
.pa-tbl { margin-bottom: var(--space-2); }
.pa-tbl td, .pa-tbl th { vertical-align: middle; }
.pa-no { font-family: var(--font-mono, monospace); font-size: var(--font-xs); }
.pa-carried { color: var(--warn); border: 1px solid var(--warn); }
.pa-move { display: flex; align-items: center; gap: var(--space-1); }
.pa-move input[type="month"] { width: 118px; padding: 2px 6px; }
.pa-del:hover { color: var(--danger); border-color: var(--danger); }
.hint-err { color: var(--danger); }

/* ===== 可列收闭环通报（D161）：五节点格三态着色（token 唯一通道） ===== */
/* td 状态色：已完成绿 / 超期红 / 未到期警示黄 / 未规划·未到期灰 */
td.cl-done { color: var(--ok); }
td.cl-overdue { color: var(--danger); }
td.cl-warn { color: var(--warn); }
td.cl-due, td.cl-none { color: var(--dim); }
/* 节点格两行：状态行强调 + 日期行小字灰（实际日期优先，规划次之） */
.cl-st { font-weight: var(--weight-strong); }
.cl-dt { display: block; font-size: var(--font-xs); color: var(--dim); }
/* 汇总区与明细区间距 */
.cl-summary { margin-bottom: var(--space-3); }
